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.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 SplashScreen(
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 if (SensorProvider* sensor = SensorProvider::GetInstance()) {
119 sensor->AddObserver(this);
120 OnScreenOrientationChanged(sensor->GetScreenOrientation());
124 NativeAppWindowTizen::~NativeAppWindowTizen() {
125 if (SensorProvider::GetInstance())
126 SensorProvider::GetInstance()->RemoveObserver(this);
129 void NativeAppWindowTizen::LockOrientation(
130 blink::WebScreenOrientationLockType lock) {
131 orientation_lock_ = lock;
132 if (SensorProvider* sensor = SensorProvider::GetInstance())
133 OnScreenOrientationChanged(sensor->GetScreenOrientation());
136 void NativeAppWindowTizen::ViewHierarchyChanged(
137 const ViewHierarchyChangedDetails& details) {
138 if (details.is_add && details.child == this) {
139 NativeAppWindowViews::ViewHierarchyChanged(details);
141 #if defined(OS_TIZEN_MOBILE)
142 indicator_widget_->Initialize(GetNativeWindow());
143 top_view_layout()->set_top_view(indicator_container_.get());
144 AddChildView(indicator_container_.get());
149 void NativeAppWindowTizen::OnWindowBoundsChanged(
150 aura::Window* window,
151 const gfx::Rect& old_bounds,
152 const gfx::Rect& new_bounds) {
153 aura::Window* root_window = GetNativeWindow()->GetRootWindow();
154 DCHECK_EQ(root_window, window);
156 // Change the bounds of child windows to make touch work correctly.
157 GetNativeWindow()->parent()->SetBounds(new_bounds);
158 GetNativeWindow()->SetBounds(new_bounds);
160 GetWidget()->GetRootView()->SetSize(new_bounds.size());
163 void NativeAppWindowTizen::OnWindowDestroying(aura::Window* window) {
164 // Must be removed here and not in the destructor, as the aura::Window is
165 // already destroyed when our destructor runs.
166 window->RemoveObserver(this);
169 void NativeAppWindowTizen::OnWindowVisibilityChanging(
170 aura::Window* window, bool visible) {
173 SetDisplayRotation(display_);
176 blink::WebScreenOrientationType
177 NativeAppWindowTizen::FindNearestAllowedOrientation(
178 blink::WebScreenOrientationType orientation) const {
179 switch (orientation_lock_) {
180 case blink::WebScreenOrientationLockDefault:
181 case blink::WebScreenOrientationLockAny:
183 case blink::WebScreenOrientationLockLandscape: {
184 switch (orientation) {
185 case blink::WebScreenOrientationLandscapePrimary:
186 case blink::WebScreenOrientationLandscapeSecondary:
189 return blink::WebScreenOrientationLandscapePrimary;
193 case blink::WebScreenOrientationLockPortrait: {
194 switch (orientation) {
195 case blink::WebScreenOrientationPortraitPrimary:
196 case blink::WebScreenOrientationPortraitSecondary:
199 return blink::WebScreenOrientationPortraitPrimary;
203 case blink::WebScreenOrientationLockPortraitPrimary:
204 return blink::WebScreenOrientationPortraitPrimary;
205 case blink::WebScreenOrientationLockPortraitSecondary:
206 return blink::WebScreenOrientationPortraitSecondary;
207 case blink::WebScreenOrientationLockLandscapePrimary:
208 return blink::WebScreenOrientationLandscapePrimary;
209 case blink::WebScreenOrientationLockLandscapeSecondary:
210 return blink::WebScreenOrientationLandscapeSecondary;
217 void NativeAppWindowTizen::OnScreenOrientationChanged(
218 blink::WebScreenOrientationType orientation) {
220 // We always store the current sensor position, even if we do not
221 // apply it in case the window is invisible.
222 gfx::Display::Rotation rot = ToDisplayRotation(display_,
223 FindNearestAllowedOrientation(orientation));
224 if (display_.rotation() == rot)
227 display_.set_rotation(rot);
228 SetDisplayRotation(display_);
231 void NativeAppWindowTizen::SetDisplayRotation(gfx::Display display) {
232 aura::Window* window = GetNativeWindow()->GetRootWindow();
233 if (!window->IsVisible())
236 SetWindowRotation(window, display);