Upstream version 10.39.225.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/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"
18
19 namespace {
20
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;
28       break;
29     case blink::WebScreenOrientationLandscapeSecondary:
30       rot = gfx::Display::ROTATE_90;
31       break;
32     case blink::WebScreenOrientationPortraitSecondary:
33       rot = gfx::Display::ROTATE_180;
34       break;
35     case blink::WebScreenOrientationLandscapePrimary:
36       rot = gfx::Display::ROTATE_270;
37       break;
38   default:
39       NOTREACHED();
40   }
41
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);
45   }
46
47   return rot;
48 }
49
50 static void SetWindowRotation(aura::Window* window, gfx::Display display) {
51   // This methods assumes that window is fullscreen.
52
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);
59 #endif
60
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:
67       break;
68     case gfx::Display::ROTATE_90:
69       rotate.Translate(display.bounds().width() - one_pixel, 0);
70       rotate.Rotate(90);
71       break;
72     case gfx::Display::ROTATE_270:
73       rotate.Translate(0, display.bounds().height() - one_pixel);
74       rotate.Rotate(270);
75       break;
76     case gfx::Display::ROTATE_180:
77       rotate.Translate(display.bounds().width() - one_pixel,
78                        display.bounds().height() - one_pixel);
79       rotate.Rotate(180);
80       break;
81   }
82
83   window->SetTransform(rotate);
84 }
85
86 }  // namespace.
87
88 namespace xwalk {
89
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_)),
96 #endif
97       orientation_lock_(blink::WebScreenOrientationLockAny) {}
98
99 void NativeAppWindowTizen::Initialize() {
100   NativeAppWindowViews::Initialize();
101
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();
107   }
108
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();
113
114   aura::Window* root_window = GetNativeWindow()->GetRootWindow();
115   DCHECK(root_window);
116   root_window->AddObserver(this);
117
118   SensorProvider::GetInstance()->AddObserver(this);
119
120   if (SensorProvider::GetInstance()->connected()) {
121     OnScreenOrientationChanged(
122         SensorProvider::GetInstance()->GetScreenOrientation());
123   }
124 }
125
126 NativeAppWindowTizen::~NativeAppWindowTizen() {
127   if (SensorProvider::GetInstance()->connected())
128     SensorProvider::GetInstance()->RemoveObserver(this);
129 }
130
131 void NativeAppWindowTizen::LockOrientation(
132       blink::WebScreenOrientationLockType lock) {
133   orientation_lock_ = lock;
134   if (SensorProvider::GetInstance()->connected())
135     OnScreenOrientationChanged(
136         SensorProvider::GetInstance()->GetScreenOrientation());
137 }
138
139 void NativeAppWindowTizen::ViewHierarchyChanged(
140     const ViewHierarchyChangedDetails& details) {
141   if (details.is_add && details.child == this) {
142     NativeAppWindowViews::ViewHierarchyChanged(details);
143
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());
148 #endif
149   }
150 }
151
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);
158
159   // Change the bounds of child windows to make touch work correctly.
160   GetNativeWindow()->parent()->SetBounds(new_bounds);
161   GetNativeWindow()->SetBounds(new_bounds);
162
163   GetWidget()->GetRootView()->SetSize(new_bounds.size());
164 }
165
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);
170 }
171
172 void NativeAppWindowTizen::OnWindowVisibilityChanging(
173     aura::Window* window, bool visible) {
174   if (!visible)
175     return;
176   SetDisplayRotation(display_);
177 }
178
179 blink::WebScreenOrientationType
180     NativeAppWindowTizen::FindNearestAllowedOrientation(
181         blink::WebScreenOrientationType orientation) const {
182   switch (orientation_lock_) {
183     case blink::WebScreenOrientationLockDefault:
184     case blink::WebScreenOrientationLockAny:
185       return orientation;
186     case blink::WebScreenOrientationLockLandscape: {
187       switch (orientation) {
188         case blink::WebScreenOrientationLandscapePrimary:
189         case blink::WebScreenOrientationLandscapeSecondary:
190           return orientation;
191         default:
192           return blink::WebScreenOrientationLandscapePrimary;
193       }
194       break;
195     }
196     case blink::WebScreenOrientationLockPortrait: {
197       switch (orientation) {
198         case blink::WebScreenOrientationPortraitPrimary:
199         case blink::WebScreenOrientationPortraitSecondary:
200           return orientation;
201         default:
202           return blink::WebScreenOrientationPortraitPrimary;
203       }
204       break;
205     }
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;
214   default:
215       NOTREACHED();
216   }
217   return orientation;
218 }
219
220 void NativeAppWindowTizen::OnScreenOrientationChanged(
221     blink::WebScreenOrientationType orientation) {
222
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)
228     return;
229
230   display_.set_rotation(rot);
231   SetDisplayRotation(display_);
232 }
233
234 void NativeAppWindowTizen::OnSensorConnected() {
235   OnScreenOrientationChanged(
236       SensorProvider::GetInstance()->GetScreenOrientation());
237 }
238
239 void NativeAppWindowTizen::SetDisplayRotation(gfx::Display display) {
240   aura::Window* window = GetNativeWindow()->GetRootWindow();
241   if (!window->IsVisible())
242     return;
243
244   SetWindowRotation(window, display);
245 }
246
247 }  // namespace xwalk