5ced0191e66efeb7d4a91142dd39b4a661e47996
[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.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 SplashScreen(
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   if (SensorProvider* sensor = SensorProvider::GetInstance()) {
119     sensor->AddObserver(this);
120     OnScreenOrientationChanged(sensor->GetScreenOrientation());
121   }
122 }
123
124 NativeAppWindowTizen::~NativeAppWindowTizen() {
125   if (SensorProvider::GetInstance())
126     SensorProvider::GetInstance()->RemoveObserver(this);
127 }
128
129 void NativeAppWindowTizen::LockOrientation(
130       blink::WebScreenOrientationLockType lock) {
131   orientation_lock_ = lock;
132   if (SensorProvider* sensor = SensorProvider::GetInstance())
133     OnScreenOrientationChanged(sensor->GetScreenOrientation());
134 }
135
136 void NativeAppWindowTizen::ViewHierarchyChanged(
137     const ViewHierarchyChangedDetails& details) {
138   if (details.is_add && details.child == this) {
139     NativeAppWindowViews::ViewHierarchyChanged(details);
140
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());
145 #endif
146   }
147 }
148
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);
155
156   // Change the bounds of child windows to make touch work correctly.
157   GetNativeWindow()->parent()->SetBounds(new_bounds);
158   GetNativeWindow()->SetBounds(new_bounds);
159
160   GetWidget()->GetRootView()->SetSize(new_bounds.size());
161 }
162
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);
167 }
168
169 void NativeAppWindowTizen::OnWindowVisibilityChanging(
170     aura::Window* window, bool visible) {
171   if (!visible)
172     return;
173   SetDisplayRotation(display_);
174 }
175
176 blink::WebScreenOrientationType
177     NativeAppWindowTizen::FindNearestAllowedOrientation(
178         blink::WebScreenOrientationType orientation) const {
179   switch (orientation_lock_) {
180     case blink::WebScreenOrientationLockDefault:
181     case blink::WebScreenOrientationLockAny:
182       return orientation;
183     case blink::WebScreenOrientationLockLandscape: {
184       switch (orientation) {
185         case blink::WebScreenOrientationLandscapePrimary:
186         case blink::WebScreenOrientationLandscapeSecondary:
187           return orientation;
188         default:
189           return blink::WebScreenOrientationLandscapePrimary;
190       }
191       break;
192     }
193     case blink::WebScreenOrientationLockPortrait: {
194       switch (orientation) {
195         case blink::WebScreenOrientationPortraitPrimary:
196         case blink::WebScreenOrientationPortraitSecondary:
197           return orientation;
198         default:
199           return blink::WebScreenOrientationPortraitPrimary;
200       }
201       break;
202     }
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;
211   default:
212       NOTREACHED();
213   }
214   return orientation;
215 }
216
217 void NativeAppWindowTizen::OnScreenOrientationChanged(
218     blink::WebScreenOrientationType orientation) {
219
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)
225     return;
226
227   display_.set_rotation(rot);
228   SetDisplayRotation(display_);
229 }
230
231 void NativeAppWindowTizen::SetDisplayRotation(gfx::Display display) {
232   aura::Window* window = GetNativeWindow()->GetRootWindow();
233   if (!window->IsVisible())
234     return;
235
236   SetWindowRotation(window, display);
237 }
238
239 }  // namespace xwalk