1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "xwalk/runtime/browser/ui/native_app_window_tizen.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "ui/aura/window.h"
10 #include "ui/gfx/transform.h"
11 #include "ui/gfx/rect.h"
12 #include "ui/gfx/screen.h"
13 #include "ui/views/view.h"
14 #include "ui/views/widget/widget.h"
15 #include "xwalk/runtime/browser/ui/splash_screen_tizen.h"
16 #include "xwalk/runtime/browser/ui/top_view_layout_views.h"
17 #include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"
21 static gfx::Display::Rotation ToDisplayRotation(gfx::Display display,
22 blink::WebScreenOrientationType orientation) {
23 gfx::Display::Rotation rot = gfx::Display::ROTATE_0;
24 switch (orientation) {
25 case blink::WebScreenOrientationUndefined:
26 case blink::WebScreenOrientationPortraitPrimary:
27 rot = gfx::Display::ROTATE_0;
29 case blink::WebScreenOrientationLandscapeSecondary:
30 rot = gfx::Display::ROTATE_90;
32 case blink::WebScreenOrientationPortraitSecondary:
33 rot = gfx::Display::ROTATE_180;
35 case blink::WebScreenOrientationLandscapePrimary:
36 rot = gfx::Display::ROTATE_270;
42 if (display.bounds().width() > display.bounds().height()) {
43 // Landscape devices have landscape-primary as default.
44 rot = static_cast<gfx::Display::Rotation>((rot - 1) % 4);
50 static void SetWindowRotation(aura::Window* window, gfx::Display display) {
51 // This methods assumes that window is fullscreen.
53 #if defined(OS_TIZEN_MOBILE)
54 // Assumes portrait display; shows overlay indicator in landscape only.
55 bool useOverlay = display.rotation() == gfx::Display::ROTATE_90 ||
56 display.rotation() == gfx::Display::ROTATE_180;
57 top_view_layout()->SetUseOverlay(enableOverlay);
58 indicator_widget_->SetDisplay(display);
61 // As everything is calculated from the fixed position we do
62 // not update the display bounds after rotation change.
63 gfx::Transform rotate;
64 float one_pixel = 1.0f / display.device_scale_factor();
65 switch (display.rotation()) {
66 case gfx::Display::ROTATE_0:
68 case gfx::Display::ROTATE_90:
69 rotate.Translate(display.bounds().width() - one_pixel, 0);
72 case gfx::Display::ROTATE_270:
73 rotate.Translate(0, display.bounds().height() - one_pixel);
76 case gfx::Display::ROTATE_180:
77 rotate.Translate(display.bounds().width() - one_pixel,
78 display.bounds().height() - one_pixel);
83 window->SetTransform(rotate);
90 NativeAppWindowTizen::NativeAppWindowTizen(
91 const NativeAppWindow::CreateParams& create_params)
92 : NativeAppWindowViews(create_params),
93 #if defined(OS_TIZEN_MOBILE)
94 indicator_widget_(new TizenSystemIndicatorWidget()),
95 indicator_container_(new WidgetContainerView(indicator_widget_)),
97 orientation_lock_(blink::WebScreenOrientationLockAny) {}
99 void NativeAppWindowTizen::Initialize() {
100 NativeAppWindowViews::Initialize();
102 const base::FilePath& splash_screen_path = create_params().splash_screen_path;
103 if (!splash_screen_path.empty()) {
104 splash_screen_.reset(new SplashScreenTizen(
105 GetWidget(), splash_screen_path, create_params().web_contents));
106 splash_screen_->Start();
109 // Get display info such as device_scale_factor, and current
110 // rotation (orientation).
111 // NOTE: This is a local copy of the info.
112 display_ = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
114 aura::Window* root_window = GetNativeWindow()->GetRootWindow();
116 root_window->AddObserver(this);
118 SensorProvider::GetInstance()->AddObserver(this);
120 if (SensorProvider::GetInstance()->connected()) {
121 OnScreenOrientationChanged(
122 SensorProvider::GetInstance()->GetScreenOrientation());
126 NativeAppWindowTizen::~NativeAppWindowTizen() {
127 if (SensorProvider::GetInstance()->connected())
128 SensorProvider::GetInstance()->RemoveObserver(this);
131 void NativeAppWindowTizen::LockOrientation(
132 blink::WebScreenOrientationLockType lock) {
133 orientation_lock_ = lock;
134 if (SensorProvider::GetInstance()->connected())
135 OnScreenOrientationChanged(
136 SensorProvider::GetInstance()->GetScreenOrientation());
139 void NativeAppWindowTizen::ViewHierarchyChanged(
140 const ViewHierarchyChangedDetails& details) {
141 if (details.is_add && details.child == this) {
142 NativeAppWindowViews::ViewHierarchyChanged(details);
144 #if defined(OS_TIZEN_MOBILE)
145 indicator_widget_->Initialize(GetNativeWindow());
146 top_view_layout()->set_top_view(indicator_container_.get());
147 AddChildView(indicator_container_.get());
152 void NativeAppWindowTizen::OnWindowBoundsChanged(
153 aura::Window* window,
154 const gfx::Rect& old_bounds,
155 const gfx::Rect& new_bounds) {
156 aura::Window* root_window = GetNativeWindow()->GetRootWindow();
157 DCHECK_EQ(root_window, window);
159 // Change the bounds of child windows to make touch work correctly.
160 GetNativeWindow()->parent()->SetBounds(new_bounds);
161 GetNativeWindow()->SetBounds(new_bounds);
163 GetWidget()->GetRootView()->SetSize(new_bounds.size());
166 void NativeAppWindowTizen::OnWindowDestroying(aura::Window* window) {
167 // Must be removed here and not in the destructor, as the aura::Window is
168 // already destroyed when our destructor runs.
169 window->RemoveObserver(this);
172 void NativeAppWindowTizen::OnWindowVisibilityChanging(
173 aura::Window* window, bool visible) {
176 SetDisplayRotation(display_);
179 blink::WebScreenOrientationType
180 NativeAppWindowTizen::FindNearestAllowedOrientation(
181 blink::WebScreenOrientationType orientation) const {
182 switch (orientation_lock_) {
183 case blink::WebScreenOrientationLockDefault:
184 case blink::WebScreenOrientationLockAny:
186 case blink::WebScreenOrientationLockLandscape: {
187 switch (orientation) {
188 case blink::WebScreenOrientationLandscapePrimary:
189 case blink::WebScreenOrientationLandscapeSecondary:
192 return blink::WebScreenOrientationLandscapePrimary;
196 case blink::WebScreenOrientationLockPortrait: {
197 switch (orientation) {
198 case blink::WebScreenOrientationPortraitPrimary:
199 case blink::WebScreenOrientationPortraitSecondary:
202 return blink::WebScreenOrientationPortraitPrimary;
206 case blink::WebScreenOrientationLockPortraitPrimary:
207 return blink::WebScreenOrientationPortraitPrimary;
208 case blink::WebScreenOrientationLockPortraitSecondary:
209 return blink::WebScreenOrientationPortraitSecondary;
210 case blink::WebScreenOrientationLockLandscapePrimary:
211 return blink::WebScreenOrientationLandscapePrimary;
212 case blink::WebScreenOrientationLockLandscapeSecondary:
213 return blink::WebScreenOrientationLandscapeSecondary;
220 void NativeAppWindowTizen::OnScreenOrientationChanged(
221 blink::WebScreenOrientationType orientation) {
223 // We always store the current sensor position, even if we do not
224 // apply it in case the window is invisible.
225 gfx::Display::Rotation rot = ToDisplayRotation(display_,
226 FindNearestAllowedOrientation(orientation));
227 if (display_.rotation() == rot)
230 display_.set_rotation(rot);
231 SetDisplayRotation(display_);
234 void NativeAppWindowTizen::OnSensorConnected() {
235 OnScreenOrientationChanged(
236 SensorProvider::GetInstance()->GetScreenOrientation());
239 void NativeAppWindowTizen::SetDisplayRotation(gfx::Display display) {
240 aura::Window* window = GetNativeWindow()->GetRootWindow();
241 if (!window->IsVisible())
244 SetWindowRotation(window, display);