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.
5 #include "xwalk/runtime/browser/ui/native_app_window_tizen.h"
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"
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;
28 case blink::WebScreenOrientationLandscapeSecondary:
29 rot = gfx::Display::ROTATE_90;
31 case blink::WebScreenOrientationPortraitSecondary:
32 rot = gfx::Display::ROTATE_180;
34 case blink::WebScreenOrientationLandscapePrimary:
35 rot = gfx::Display::ROTATE_270;
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);
49 static void SetWindowRotation(aura::Window* window, gfx::Display display) {
50 // This methods assumes that window is fullscreen.
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);
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:
67 case gfx::Display::ROTATE_90:
68 rotate.Translate(display.bounds().width() - one_pixel, 0);
71 case gfx::Display::ROTATE_270:
72 rotate.Translate(0, display.bounds().height() - one_pixel);
75 case gfx::Display::ROTATE_180:
76 rotate.Translate(display.bounds().width() - one_pixel,
77 display.bounds().height() - one_pixel);
82 window->SetTransform(rotate);
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_)),
96 orientation_lock_(blink::WebScreenOrientationLockAny) {
99 void NativeAppWindowTizen::Initialize() {
100 NativeAppWindowViews::Initialize();
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();
107 aura::Window* root_window = GetNativeWindow()->GetRootWindow();
109 root_window->AddObserver(this);
111 if (SensorProvider* sensor = SensorProvider::GetInstance()) {
112 sensor->AddObserver(this);
113 OnScreenOrientationChanged(sensor->GetScreenOrientation());
117 NativeAppWindowTizen::~NativeAppWindowTizen() {
118 if (SensorProvider::GetInstance())
119 SensorProvider::GetInstance()->RemoveObserver(this);
122 void NativeAppWindowTizen::ViewHierarchyChanged(
123 const ViewHierarchyChangedDetails& details) {
124 if (details.is_add && details.child == this) {
125 NativeAppWindowViews::ViewHierarchyChanged(details);
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());
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);
142 // Change the bounds of child windows to make touch work correctly.
143 GetNativeWindow()->parent()->SetBounds(new_bounds);
144 GetNativeWindow()->SetBounds(new_bounds);
146 GetWidget()->GetRootView()->SetSize(new_bounds.size());
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);
155 void NativeAppWindowTizen::OnWindowVisibilityChanging(
156 aura::Window* window, bool visible) {
159 SetDisplayRotation(display_);
162 blink::WebScreenOrientationType
163 NativeAppWindowTizen::FindNearestAllowedOrientation(
164 blink::WebScreenOrientationType orientation) const {
165 switch (orientation_lock_) {
166 case blink::WebScreenOrientationLockDefault:
167 case blink::WebScreenOrientationLockAny:
169 case blink::WebScreenOrientationLockLandscape: {
170 switch (orientation) {
171 case blink::WebScreenOrientationLandscapePrimary:
172 case blink::WebScreenOrientationLandscapeSecondary:
175 return blink::WebScreenOrientationLandscapePrimary;
179 case blink::WebScreenOrientationLockPortrait: {
180 switch (orientation) {
181 case blink::WebScreenOrientationPortraitPrimary:
182 case blink::WebScreenOrientationPortraitSecondary:
185 return blink::WebScreenOrientationPortraitPrimary;
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;
203 void NativeAppWindowTizen::LockOrientation(
204 blink::WebScreenOrientationLockType lock) {
205 orientation_lock_ = lock;
206 if (SensorProvider* sensor = SensorProvider::GetInstance())
207 OnScreenOrientationChanged(sensor->GetScreenOrientation());
210 void NativeAppWindowTizen::UnlockOrientation() {
211 LockOrientation(blink::WebScreenOrientationLockDefault);
214 void NativeAppWindowTizen::OnScreenOrientationChanged(
215 blink::WebScreenOrientationType orientation) {
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)
224 display_.set_rotation(rot);
225 SetDisplayRotation(display_);
228 void NativeAppWindowTizen::SetDisplayRotation(gfx::Display display) {
229 aura::Window* window = GetNativeWindow()->GetRootWindow();
230 if (!window->IsVisible())
233 SetWindowRotation(window, display);