Upstream version 7.36.152.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / ui / native_app_window_tizen.cc
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.
4
5 #include "xwalk/runtime/browser/ui/native_app_window_tizen.h"
6
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/top_view_layout_views.h"
16 #include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"
17
18 namespace {
19
20 static gfx::Display::Rotation ToDisplayRotation(gfx::Display display,
21     blink::WebScreenOrientationType orientation) {
22   gfx::Display::Rotation rot = gfx::Display::ROTATE_0;
23   switch (orientation) {
24     case blink::WebScreenOrientationUndefined:
25     case blink::WebScreenOrientationPortraitPrimary:
26       rot = gfx::Display::ROTATE_0;
27       break;
28     case blink::WebScreenOrientationLandscapeSecondary:
29       rot = gfx::Display::ROTATE_90;
30       break;
31     case blink::WebScreenOrientationPortraitSecondary:
32       rot = gfx::Display::ROTATE_180;
33       break;
34     case blink::WebScreenOrientationLandscapePrimary:
35       rot = gfx::Display::ROTATE_270;
36       break;
37   default:
38       NOTREACHED();
39   }
40
41   if (display.bounds().width() > display.bounds().height()) {
42     // Landscape devices have landscape-primary as default.
43     rot = static_cast<gfx::Display::Rotation>((rot - 1) % 4);
44   }
45
46   return rot;
47 }
48
49 static void SetWindowRotation(aura::Window* window, gfx::Display display) {
50   // This methods assumes that window is fullscreen.
51
52 #if defined(OS_TIZEN_MOBILE)
53   // Assumes portrait display; shows overlay indicator in landscape only.
54   bool useOverlay = display.rotation() == gfx::Display::ROTATE_90 ||
55       display.rotation() == gfx::Display::ROTATE_180);
56   top_view_layout()->SetUseOverlay(enableOverlay);
57   indicator_widget_->SetDisplay(display);
58 #endif
59
60   // As everything is calculated from the fixed position we do
61   // not update the display bounds after rotation change.
62   gfx::Transform rotate;
63   float one_pixel = 1.0f / display.device_scale_factor();
64   switch (display.rotation()) {
65     case gfx::Display::ROTATE_0:
66       break;
67     case gfx::Display::ROTATE_90:
68       rotate.Translate(display.bounds().width() - one_pixel, 0);
69       rotate.Rotate(90);
70       break;
71     case gfx::Display::ROTATE_270:
72       rotate.Translate(0, display.bounds().height() - one_pixel);
73       rotate.Rotate(270);
74       break;
75     case gfx::Display::ROTATE_180:
76       rotate.Translate(display.bounds().width() - one_pixel,
77                        display.bounds().height() - one_pixel);
78       rotate.Rotate(180);
79       break;
80   }
81
82   window->SetTransform(rotate);
83 }
84
85 }  // namespace.
86
87 namespace xwalk {
88
89 NativeAppWindowTizen::NativeAppWindowTizen(
90     const NativeAppWindow::CreateParams& create_params)
91     : NativeAppWindowViews(create_params),
92 #if defined(OS_TIZEN_MOBILE)
93       indicator_widget_(new TizenSystemIndicatorWidget()),
94       indicator_container_(new WidgetContainerView(indicator_widget_)),
95 #endif
96       orientation_lock_(blink::WebScreenOrientationLockAny) {
97 }
98
99 void NativeAppWindowTizen::Initialize() {
100   NativeAppWindowViews::Initialize();
101
102   // Get display info such as device_scale_factor, and current
103   // rotation (orientation).
104   // NOTE: This is a local copy of the info.
105   display_ = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
106
107   aura::Window* root_window = GetNativeWindow()->GetRootWindow();
108   DCHECK(root_window);
109   root_window->AddObserver(this);
110
111   if (SensorProvider* sensor = SensorProvider::GetInstance()) {
112     sensor->AddObserver(this);
113     OnScreenOrientationChanged(sensor->GetScreenOrientation());
114   }
115 }
116
117 NativeAppWindowTizen::~NativeAppWindowTizen() {
118   if (SensorProvider::GetInstance())
119     SensorProvider::GetInstance()->RemoveObserver(this);
120 }
121
122 void NativeAppWindowTizen::LockOrientation(
123       blink::WebScreenOrientationLockType lock) {
124   orientation_lock_ = lock;
125   if (SensorProvider* sensor = SensorProvider::GetInstance())
126     OnScreenOrientationChanged(sensor->GetScreenOrientation());
127 }
128
129 void NativeAppWindowTizen::ViewHierarchyChanged(
130     const ViewHierarchyChangedDetails& details) {
131   if (details.is_add && details.child == this) {
132     NativeAppWindowViews::ViewHierarchyChanged(details);
133
134 #if defined(OS_TIZEN_MOBILE)
135     indicator_widget_->Initialize(GetNativeWindow());
136     top_view_layout()->set_top_view(indicator_container_.get());
137     AddChildView(indicator_container_.get());
138 #endif
139   }
140 }
141
142 void NativeAppWindowTizen::OnWindowBoundsChanged(
143     aura::Window* window,
144     const gfx::Rect& old_bounds,
145     const gfx::Rect& new_bounds) {
146   aura::Window* root_window = GetNativeWindow()->GetRootWindow();
147   DCHECK_EQ(root_window, window);
148
149   // Change the bounds of child windows to make touch work correctly.
150   GetNativeWindow()->parent()->SetBounds(new_bounds);
151   GetNativeWindow()->SetBounds(new_bounds);
152
153   GetWidget()->GetRootView()->SetSize(new_bounds.size());
154 }
155
156 void NativeAppWindowTizen::OnWindowDestroying(aura::Window* window) {
157   // Must be removed here and not in the destructor, as the aura::Window is
158   // already destroyed when our destructor runs.
159   window->RemoveObserver(this);
160 }
161
162 void NativeAppWindowTizen::OnWindowVisibilityChanging(
163     aura::Window* window, bool visible) {
164   if (!visible)
165     return;
166   SetDisplayRotation(display_);
167 }
168
169 blink::WebScreenOrientationType
170     NativeAppWindowTizen::FindNearestAllowedOrientation(
171         blink::WebScreenOrientationType orientation) const {
172   switch (orientation_lock_) {
173     case blink::WebScreenOrientationLockDefault:
174     case blink::WebScreenOrientationLockAny:
175       return orientation;
176     case blink::WebScreenOrientationLockLandscape: {
177       switch (orientation) {
178         case blink::WebScreenOrientationLandscapePrimary:
179         case blink::WebScreenOrientationLandscapeSecondary:
180           return orientation;
181         default:
182           return blink::WebScreenOrientationLandscapePrimary;
183       }
184       break;
185     }
186     case blink::WebScreenOrientationLockPortrait: {
187       switch (orientation) {
188         case blink::WebScreenOrientationPortraitPrimary:
189         case blink::WebScreenOrientationPortraitSecondary:
190           return orientation;
191         default:
192           return blink::WebScreenOrientationPortraitPrimary;
193       }
194       break;
195     }
196     case blink::WebScreenOrientationLockPortraitPrimary:
197       return blink::WebScreenOrientationPortraitPrimary;
198     case blink::WebScreenOrientationLockPortraitSecondary:
199       return blink::WebScreenOrientationPortraitSecondary;
200     case blink::WebScreenOrientationLockLandscapePrimary:
201       return blink::WebScreenOrientationLandscapePrimary;
202     case blink::WebScreenOrientationLockLandscapeSecondary:
203       return blink::WebScreenOrientationLandscapeSecondary;
204   default:
205       NOTREACHED();
206   }
207   return orientation;
208 }
209
210 void NativeAppWindowTizen::OnScreenOrientationChanged(
211     blink::WebScreenOrientationType orientation) {
212
213   // We always store the current sensor position, even if we do not
214   // apply it in case the window is invisible.
215   gfx::Display::Rotation rot = ToDisplayRotation(display_,
216       FindNearestAllowedOrientation(orientation));
217   if (display_.rotation() == rot)
218     return;
219
220   display_.set_rotation(rot);
221   SetDisplayRotation(display_);
222 }
223
224 void NativeAppWindowTizen::SetDisplayRotation(gfx::Display display) {
225   aura::Window* window = GetNativeWindow()->GetRootWindow();
226   if (!window->IsVisible())
227     return;
228
229   SetWindowRotation(window, display);
230 }
231
232 }  // namespace xwalk