1 // Copyright 2014 The Chromium Authors. 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 "content/browser/screen_orientation/screen_orientation_provider_android.h"
7 #include "content/browser/android/content_view_core_impl.h"
8 #include "content/browser/screen_orientation/screen_orientation_dispatcher_host.h"
9 #include "content/browser/web_contents/web_contents_impl.h"
10 #include "content/public/browser/render_view_host.h"
11 #include "content/public/browser/render_widget_host.h"
12 #include "jni/ScreenOrientationProvider_jni.h"
13 #include "third_party/WebKit/public/platform/WebLockOrientationError.h"
14 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
18 ScreenOrientationProviderAndroid::LockInformation::LockInformation(
19 int request_id
, blink::WebScreenOrientationLockType lock
)
20 : request_id(request_id
), lock(lock
) {}
22 ScreenOrientationProviderAndroid::ScreenOrientationProviderAndroid(
23 ScreenOrientationDispatcherHost
* dispatcher
,
24 WebContents
* web_contents
)
25 : ScreenOrientationProvider(),
26 WebContentsObserver(web_contents
),
27 dispatcher_(dispatcher
),
32 ScreenOrientationProviderAndroid::~ScreenOrientationProviderAndroid() {
37 WebContentsImpl
* ScreenOrientationProviderAndroid::web_contents_impl() {
38 return static_cast<WebContentsImpl
*>(web_contents());
42 bool ScreenOrientationProviderAndroid::Register(JNIEnv
* env
) {
43 return RegisterNativesImpl(env
);
46 void ScreenOrientationProviderAndroid::LockOrientation(
48 blink::WebScreenOrientationLockType lock_orientation
) {
49 ContentViewCoreImpl
* cvc
=
50 ContentViewCoreImpl::FromWebContents(web_contents());
51 bool fullscreen_required
= cvc
? cvc
->IsFullscreenRequiredForOrientationLock()
54 if (fullscreen_required
&&
55 !web_contents_impl()->IsFullscreenForCurrentTab()) {
56 dispatcher_
->NotifyLockError(
58 blink::WebLockOrientationErrorFullScreenRequired
);
62 if (lock_orientation
== blink::WebScreenOrientationLockNatural
) {
63 lock_orientation
= GetNaturalLockType();
64 if (lock_orientation
== blink::WebScreenOrientationLockDefault
) {
65 // We are in a broken state, let's pretend we got canceled.
66 dispatcher_
->NotifyLockError(request_id
,
67 blink::WebLockOrientationErrorCanceled
);
73 Java_ScreenOrientationProvider_lockOrientation(
74 base::android::AttachCurrentThread(), lock_orientation
);
76 // If two calls happen close to each other, Android will ignore the first.
82 // If the orientation we are locking to matches the current orientation, we
83 // should succeed immediately.
84 if (LockMatchesCurrentOrientation(lock_orientation
)) {
85 dispatcher_
->NotifyLockSuccess(request_id
);
89 pending_lock_
= new LockInformation(request_id
, lock_orientation
);
92 void ScreenOrientationProviderAndroid::UnlockOrientation() {
96 Java_ScreenOrientationProvider_unlockOrientation(
97 base::android::AttachCurrentThread());
98 lock_applied_
= false;
101 void ScreenOrientationProviderAndroid::OnOrientationChange() {
105 if (LockMatchesCurrentOrientation(pending_lock_
->lock
)) {
106 dispatcher_
->NotifyLockSuccess(pending_lock_
->request_id
);
107 delete pending_lock_
;
108 pending_lock_
= NULL
;
112 void ScreenOrientationProviderAndroid::DidToggleFullscreenModeForTab(
113 bool entered_fullscreen
) {
117 // If fullscreen is not required in order to lock orientation, don't unlock
118 // when fullscreen state changes.
119 ContentViewCoreImpl
* cvc
=
120 ContentViewCoreImpl::FromWebContents(web_contents());
121 if (cvc
&& !cvc
->IsFullscreenRequiredForOrientationLock())
124 DCHECK(!entered_fullscreen
);
128 bool ScreenOrientationProviderAndroid::LockMatchesCurrentOrientation(
129 blink::WebScreenOrientationLockType lock_orientation
) {
130 if (!web_contents()->GetRenderViewHost())
133 RenderWidgetHost
* rwh
= web_contents()->GetRenderViewHost();
134 blink::WebScreenInfo screen_info
;
135 rwh
->GetWebScreenInfo(&screen_info
);
137 switch (lock_orientation
) {
138 case blink::WebScreenOrientationLockPortraitPrimary
:
139 return screen_info
.orientationType
==
140 blink::WebScreenOrientationPortraitPrimary
;
141 case blink::WebScreenOrientationLockPortraitSecondary
:
142 return screen_info
.orientationType
==
143 blink::WebScreenOrientationPortraitSecondary
;
144 case blink::WebScreenOrientationLockLandscapePrimary
:
145 return screen_info
.orientationType
==
146 blink::WebScreenOrientationLandscapePrimary
;
147 case blink::WebScreenOrientationLockLandscapeSecondary
:
148 return screen_info
.orientationType
==
149 blink::WebScreenOrientationLandscapeSecondary
;
150 case blink::WebScreenOrientationLockLandscape
:
151 return screen_info
.orientationType
==
152 blink::WebScreenOrientationLandscapePrimary
||
153 screen_info
.orientationType
==
154 blink::WebScreenOrientationLandscapeSecondary
;
155 case blink::WebScreenOrientationLockPortrait
:
156 return screen_info
.orientationType
==
157 blink::WebScreenOrientationPortraitPrimary
||
158 screen_info
.orientationType
==
159 blink::WebScreenOrientationPortraitSecondary
;
160 case blink::WebScreenOrientationLockAny
:
162 case blink::WebScreenOrientationLockNatural
:
163 case blink::WebScreenOrientationLockDefault
:
172 blink::WebScreenOrientationLockType
173 ScreenOrientationProviderAndroid::GetNaturalLockType() const {
174 if (!web_contents()->GetRenderViewHost())
175 return blink::WebScreenOrientationLockDefault
;
177 RenderWidgetHost
* rwh
= web_contents()->GetRenderViewHost();
178 blink::WebScreenInfo screen_info
;
179 rwh
->GetWebScreenInfo(&screen_info
);
181 switch (screen_info
.orientationType
) {
182 case blink::WebScreenOrientationPortraitPrimary
:
183 case blink::WebScreenOrientationPortraitSecondary
:
184 if (screen_info
.orientationAngle
== 0 ||
185 screen_info
.orientationAngle
== 180) {
186 return blink::WebScreenOrientationLockPortraitPrimary
;
188 return blink::WebScreenOrientationLockLandscapePrimary
;
189 case blink::WebScreenOrientationLandscapePrimary
:
190 case blink::WebScreenOrientationLandscapeSecondary
:
191 if (screen_info
.orientationAngle
== 0 ||
192 screen_info
.orientationAngle
== 180) {
193 return blink::WebScreenOrientationLockLandscapePrimary
;
195 return blink::WebScreenOrientationLockPortraitPrimary
;
196 case blink::WebScreenOrientationUndefined
:
198 return blink::WebScreenOrientationLockDefault
;
202 return blink::WebScreenOrientationLockDefault
;
206 void ScreenOrientationProviderAndroid::StartAccurateListening() {
207 Java_ScreenOrientationProvider_startAccurateListening(
208 base::android::AttachCurrentThread());
212 void ScreenOrientationProviderAndroid::StopAccurateListening() {
213 Java_ScreenOrientationProvider_stopAccurateListening(
214 base::android::AttachCurrentThread());
218 ScreenOrientationProvider
* ScreenOrientationProvider::Create(
219 ScreenOrientationDispatcherHost
* dispatcher
,
220 WebContents
* web_contents
) {
221 return new ScreenOrientationProviderAndroid(dispatcher
, web_contents
);
224 } // namespace content