Upstream version 7.36.149.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::ViewHierarchyChanged(
123     const ViewHierarchyChangedDetails& details) {
124   if (details.is_add && details.child == this) {
125     NativeAppWindowViews::ViewHierarchyChanged(details);
126
127 #if defined(OS_TIZEN_MOBILE)
128     indicator_widget_->Initialize(GetNativeWindow());
129     top_view_layout()->set_top_view(indicator_container_.get());
130     AddChildView(indicator_container_.get());
131 #endif
132   }
133 }
134
135 void NativeAppWindowTizen::OnWindowBoundsChanged(
136     aura::Window* window,
137     const gfx::Rect& old_bounds,
138     const gfx::Rect& new_bounds) {
139   aura::Window* root_window = GetNativeWindow()->GetRootWindow();
140   DCHECK_EQ(root_window, window);
141
142   // Change the bounds of child windows to make touch work correctly.
143   GetNativeWindow()->parent()->SetBounds(new_bounds);
144   GetNativeWindow()->SetBounds(new_bounds);
145
146   GetWidget()->GetRootView()->SetSize(new_bounds.size());
147 }
148
149 void NativeAppWindowTizen::OnWindowDestroying(aura::Window* window) {
150   // Must be removed here and not in the destructor, as the aura::Window is
151   // already destroyed when our destructor runs.
152   window->RemoveObserver(this);
153 }
154
155 void NativeAppWindowTizen::OnWindowVisibilityChanging(
156     aura::Window* window, bool visible) {
157   if (!visible)
158     return;
159   SetDisplayRotation(display_);
160 }
161
162 blink::WebScreenOrientationType
163     NativeAppWindowTizen::FindNearestAllowedOrientation(
164         blink::WebScreenOrientationType orientation) const {
165   switch (orientation_lock_) {
166     case blink::WebScreenOrientationLockDefault:
167     case blink::WebScreenOrientationLockAny:
168       return orientation;
169     case blink::WebScreenOrientationLockLandscape: {
170       switch (orientation) {
171         case blink::WebScreenOrientationLandscapePrimary:
172         case blink::WebScreenOrientationLandscapeSecondary:
173           return orientation;
174         default:
175           return blink::WebScreenOrientationLandscapePrimary;
176       }
177       break;
178     }
179     case blink::WebScreenOrientationLockPortrait: {
180       switch (orientation) {
181         case blink::WebScreenOrientationPortraitPrimary:
182         case blink::WebScreenOrientationPortraitSecondary:
183           return orientation;
184         default:
185           return blink::WebScreenOrientationPortraitPrimary;
186       }
187       break;
188     }
189     case blink::WebScreenOrientationLockPortraitPrimary:
190       return blink::WebScreenOrientationPortraitPrimary;
191     case blink::WebScreenOrientationLockPortraitSecondary:
192       return blink::WebScreenOrientationPortraitSecondary;
193     case blink::WebScreenOrientationLockLandscapePrimary:
194       return blink::WebScreenOrientationLandscapePrimary;
195     case blink::WebScreenOrientationLockLandscapeSecondary:
196       return blink::WebScreenOrientationLandscapeSecondary;
197   default:
198       NOTREACHED();
199   }
200   return orientation;
201 }
202
203 void NativeAppWindowTizen::LockOrientation(
204       blink::WebScreenOrientationLockType lock) {
205   orientation_lock_ = lock;
206   if (SensorProvider* sensor = SensorProvider::GetInstance())
207     OnScreenOrientationChanged(sensor->GetScreenOrientation());
208 }
209
210 void NativeAppWindowTizen::UnlockOrientation() {
211   LockOrientation(blink::WebScreenOrientationLockDefault);
212 }
213
214 void NativeAppWindowTizen::OnScreenOrientationChanged(
215     blink::WebScreenOrientationType orientation) {
216
217   // We always store the current sensor position, even if we do not
218   // apply it in case the window is invisible.
219   gfx::Display::Rotation rot = ToDisplayRotation(display_,
220       FindNearestAllowedOrientation(orientation));
221   if (display_.rotation() == rot)
222     return;
223
224   display_.set_rotation(rot);
225   SetDisplayRotation(display_);
226 }
227
228 void NativeAppWindowTizen::SetDisplayRotation(gfx::Display display) {
229   aura::Window* window = GetNativeWindow()->GetRootWindow();
230   if (!window->IsVisible())
231     return;
232
233   SetWindowRotation(window, display);
234 }
235
236 }  // namespace xwalk