Upstream version 6.35.131.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 xwalk {
19
20 NativeAppWindowTizen::NativeAppWindowTizen(
21     const NativeAppWindow::CreateParams& create_params)
22     : NativeAppWindowViews(create_params),
23 #if defined(OS_TIZEN_MOBILE)
24       indicator_widget_(new TizenSystemIndicatorWidget()),
25       indicator_container_(new WidgetContainerView(indicator_widget_)),
26 #endif
27       allowed_orientations_(ANY) {
28 }
29
30 void NativeAppWindowTizen::Initialize() {
31   NativeAppWindowViews::Initialize();
32
33   // Get display info such as device_scale_factor, and current
34   // rotation (orientation). NOTE: This is a local copy of the info.
35   display_ = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
36
37   aura::Window* root_window = GetNativeWindow()->GetRootWindow();
38   DCHECK(root_window);
39   root_window->AddObserver(this);
40
41   OrientationMask ua_default =
42       XWalkBrowserMainPartsTizen::GetAllowedUAOrientations();
43   OnAllowedOrientationsChanged(ua_default);
44
45   if (SensorProvider* sensor = SensorProvider::GetInstance()) {
46     gfx::Display::Rotation rotation
47       = GetClosestAllowedRotation(sensor->GetCurrentRotation());
48     display_.set_rotation(rotation);
49     ApplyDisplayRotation();
50     sensor->AddObserver(this);
51   }
52 }
53
54 NativeAppWindowTizen::~NativeAppWindowTizen() {
55   if (SensorProvider::GetInstance())
56     SensorProvider::GetInstance()->RemoveObserver(this);
57 }
58
59 void NativeAppWindowTizen::ViewHierarchyChanged(
60     const ViewHierarchyChangedDetails& details) {
61   if (details.is_add && details.child == this) {
62     NativeAppWindowViews::ViewHierarchyChanged(details);
63 #if defined(OS_TIZEN_MOBILE)
64     indicator_widget_->Initialize(GetNativeWindow());
65     top_view_layout()->set_top_view(indicator_container_.get());
66     AddChildView(indicator_container_.get());
67 #endif
68   }
69 }
70
71 void NativeAppWindowTizen::OnWindowBoundsChanged(
72     aura::Window* window,
73     const gfx::Rect& old_bounds,
74     const gfx::Rect& new_bounds) {
75   aura::Window* root_window = GetNativeWindow()->GetRootWindow();
76   DCHECK_EQ(root_window, window);
77
78   // Change the bounds of child windows to make touch work correctly.
79   GetNativeWindow()->parent()->SetBounds(new_bounds);
80   GetNativeWindow()->SetBounds(new_bounds);
81
82   GetWidget()->GetRootView()->SetSize(new_bounds.size());
83 }
84
85 void NativeAppWindowTizen::OnWindowDestroying(aura::Window* window) {
86   // Must be removed here and not in the destructor, as the aura::Window is
87   // already destroyed when our destructor runs.
88   window->RemoveObserver(this);
89 }
90
91 void NativeAppWindowTizen::OnWindowVisibilityChanging(
92     aura::Window* window, bool visible) {
93   if (visible)
94     ApplyDisplayRotation();
95 }
96
97 gfx::Transform NativeAppWindowTizen::GetRotationTransform() const {
98   // This method assumed a fixed portrait device. As everything
99   // is calculated from the fixed position we do not update the
100   // display bounds after rotation change.
101   // FIXME : Add proper support for landscape devices.
102   gfx::Transform rotate;
103   float one_pixel = 1.0f / display_.device_scale_factor();
104   switch (display_.rotation()) {
105     case gfx::Display::ROTATE_0:
106       break;
107     case gfx::Display::ROTATE_90:
108       rotate.Translate(display_.bounds().width() - one_pixel, 0);
109       rotate.Rotate(90);
110       break;
111     case gfx::Display::ROTATE_270:
112       rotate.Translate(0, display_.bounds().height() - one_pixel);
113       rotate.Rotate(270);
114       break;
115     case gfx::Display::ROTATE_180:
116       rotate.Translate(display_.bounds().width() - one_pixel,
117                        display_.bounds().height() - one_pixel);
118       rotate.Rotate(180);
119       break;
120   }
121
122   return rotate;
123 }
124
125 namespace {
126
127 #if defined(OS_TIZEN_MOBILE)
128 Orientation ToOrientation(const gfx::Display::Rotation& rotation) {
129   switch (rotation) {
130     case gfx::Display::ROTATE_0:
131       return PORTRAIT_PRIMARY;
132     case gfx::Display::ROTATE_90:
133       return LANDSCAPE_PRIMARY;
134     case gfx::Display::ROTATE_180:
135       return PORTRAIT_SECONDARY;
136     case gfx::Display::ROTATE_270:
137       return LANDSCAPE_SECONDARY;
138     default:
139       NOTREACHED();
140   }
141   return PORTRAIT_PRIMARY;
142 }
143 #else
144 Orientation ToOrientation(const gfx::Display::Rotation& rotation) {
145   switch (rotation) {
146     case gfx::Display::ROTATE_0:
147       return LANDSCAPE_PRIMARY;
148     case gfx::Display::ROTATE_90:
149       return PORTRAIT_PRIMARY;
150     case gfx::Display::ROTATE_180:
151       return LANDSCAPE_SECONDARY;
152     case gfx::Display::ROTATE_270:
153       return PORTRAIT_SECONDARY;
154     default:
155       NOTREACHED();
156   }
157   return LANDSCAPE_PRIMARY;
158 }
159 #endif
160
161 inline gfx::Display::Rotation ToRotation(unsigned rotation) {
162   return static_cast<gfx::Display::Rotation>(rotation % 4);
163 }
164
165 bool IsLandscapeOrientation(const gfx::Display::Rotation& rotation) {
166   return ToOrientation(rotation) & LANDSCAPE;
167 }
168
169 }  // namespace.
170
171 gfx::Display::Rotation NativeAppWindowTizen::GetClosestAllowedRotation(
172     gfx::Display::Rotation rotation) const {
173
174   // Test current orientation
175   if (allowed_orientations_ & ToOrientation(rotation))
176     return rotation;
177
178   // Test orientation right of current one.
179   if (allowed_orientations_ & ToOrientation(ToRotation(rotation + 1)))
180     return ToRotation(rotation + 1);
181
182   // Test orientation left of current one.
183   if (allowed_orientations_ & ToOrientation(ToRotation(rotation + 3)))
184     return ToRotation(rotation + 3);
185
186   // Test orientation opposite of current one.
187   if (allowed_orientations_ & ToOrientation(ToRotation(rotation + 1)))
188     return ToRotation(rotation + 1);
189
190   NOTREACHED();
191   return rotation;
192 }
193
194 Orientation NativeAppWindowTizen::GetCurrentOrientation() const {
195   return ToOrientation(display_.rotation());
196 }
197
198 void NativeAppWindowTizen::OnAllowedOrientationsChanged(
199     OrientationMask orientations) {
200   allowed_orientations_ = orientations;
201
202   // As we might have been locked before our current orientation
203   // might not fit with the sensor orienation.
204   gfx::Display::Rotation rotation = display_.rotation();
205   if (SensorProvider* sensor = SensorProvider::GetInstance())
206     rotation = sensor->GetCurrentRotation();
207
208   rotation = GetClosestAllowedRotation(rotation);
209   if (display_.rotation() == rotation)
210     return;
211
212   display_.set_rotation(rotation);
213   ApplyDisplayRotation();
214 }
215
216 void NativeAppWindowTizen::OnRotationChanged(
217     gfx::Display::Rotation rotation) {
218   // We always store the current sensor position, even if we do not
219   // apply it in case the window is invisible.
220
221   rotation = GetClosestAllowedRotation(rotation);
222   if (display_.rotation() == rotation)
223     return;
224
225   display_.set_rotation(rotation);
226
227   ApplyDisplayRotation();
228 }
229
230 void NativeAppWindowTizen::UpdateTopViewOverlay() {
231   top_view_layout()->SetUseOverlay(
232       IsLandscapeOrientation(display_.rotation()));
233 }
234
235 void NativeAppWindowTizen::ApplyDisplayRotation() {
236   if (observer())
237     observer()->OnOrientationChanged(GetCurrentOrientation());
238
239   aura::Window* root_window = GetNativeWindow()->GetRootWindow();
240   if (!root_window->IsVisible())
241     return;
242   UpdateTopViewOverlay();
243
244 #if defined(OS_TIZEN_MOBILE)
245   indicator_widget_->SetDisplay(display_);
246 #endif
247   root_window->SetTransform(GetRotationTransform());
248 }
249
250 }  // namespace xwalk