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 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_)),
27 allowed_orientations_(ANY) {
30 void NativeAppWindowTizen::Initialize() {
31 NativeAppWindowViews::Initialize();
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();
37 aura::Window* root_window = GetNativeWindow()->GetRootWindow();
39 root_window->AddObserver(this);
41 OrientationMask ua_default =
42 XWalkBrowserMainPartsTizen::GetAllowedUAOrientations();
43 OnAllowedOrientationsChanged(ua_default);
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);
54 NativeAppWindowTizen::~NativeAppWindowTizen() {
55 if (SensorProvider::GetInstance())
56 SensorProvider::GetInstance()->RemoveObserver(this);
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());
71 void NativeAppWindowTizen::OnWindowBoundsChanged(
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);
78 // Change the bounds of child windows to make touch work correctly.
79 GetNativeWindow()->parent()->SetBounds(new_bounds);
80 GetNativeWindow()->SetBounds(new_bounds);
82 GetWidget()->GetRootView()->SetSize(new_bounds.size());
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);
91 void NativeAppWindowTizen::OnWindowVisibilityChanging(
92 aura::Window* window, bool visible) {
94 ApplyDisplayRotation();
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:
107 case gfx::Display::ROTATE_90:
108 rotate.Translate(display_.bounds().width() - one_pixel, 0);
111 case gfx::Display::ROTATE_270:
112 rotate.Translate(0, display_.bounds().height() - one_pixel);
115 case gfx::Display::ROTATE_180:
116 rotate.Translate(display_.bounds().width() - one_pixel,
117 display_.bounds().height() - one_pixel);
127 #if defined(OS_TIZEN_MOBILE)
128 Orientation ToOrientation(const gfx::Display::Rotation& 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;
141 return PORTRAIT_PRIMARY;
144 Orientation ToOrientation(const gfx::Display::Rotation& 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;
157 return LANDSCAPE_PRIMARY;
161 inline gfx::Display::Rotation ToRotation(unsigned rotation) {
162 return static_cast<gfx::Display::Rotation>(rotation % 4);
165 bool IsLandscapeOrientation(const gfx::Display::Rotation& rotation) {
166 return ToOrientation(rotation) & LANDSCAPE;
171 gfx::Display::Rotation NativeAppWindowTizen::GetClosestAllowedRotation(
172 gfx::Display::Rotation rotation) const {
174 // Test current orientation
175 if (allowed_orientations_ & ToOrientation(rotation))
178 // Test orientation right of current one.
179 if (allowed_orientations_ & ToOrientation(ToRotation(rotation + 1)))
180 return ToRotation(rotation + 1);
182 // Test orientation left of current one.
183 if (allowed_orientations_ & ToOrientation(ToRotation(rotation + 3)))
184 return ToRotation(rotation + 3);
186 // Test orientation opposite of current one.
187 if (allowed_orientations_ & ToOrientation(ToRotation(rotation + 1)))
188 return ToRotation(rotation + 1);
194 Orientation NativeAppWindowTizen::GetCurrentOrientation() const {
195 return ToOrientation(display_.rotation());
198 void NativeAppWindowTizen::OnAllowedOrientationsChanged(
199 OrientationMask orientations) {
200 allowed_orientations_ = orientations;
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();
208 rotation = GetClosestAllowedRotation(rotation);
209 if (display_.rotation() == rotation)
212 display_.set_rotation(rotation);
213 ApplyDisplayRotation();
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.
221 rotation = GetClosestAllowedRotation(rotation);
222 if (display_.rotation() == rotation)
225 display_.set_rotation(rotation);
227 ApplyDisplayRotation();
230 void NativeAppWindowTizen::UpdateTopViewOverlay() {
231 top_view_layout()->SetUseOverlay(
232 IsLandscapeOrientation(display_.rotation()));
235 void NativeAppWindowTizen::ApplyDisplayRotation() {
237 observer()->OnOrientationChanged(GetCurrentOrientation());
239 aura::Window* root_window = GetNativeWindow()->GetRootWindow();
240 if (!root_window->IsVisible())
242 UpdateTopViewOverlay();
244 #if defined(OS_TIZEN_MOBILE)
245 indicator_widget_->SetDisplay(display_);
247 root_window->SetTransform(GetRotationTransform());