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/public/browser/screen_orientation_provider.h"
7 #include "content/browser/renderer_host/render_view_host_delegate.h"
8 #include "content/public/browser/render_view_host.h"
9 #include "content/public/browser/screen_orientation_delegate.h"
10 #include "content/public/browser/screen_orientation_dispatcher_host.h"
11 #include "content/public/browser/web_contents.h"
12 #include "third_party/WebKit/public/platform/WebLockOrientationError.h"
13 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
17 ScreenOrientationDelegate
* ScreenOrientationProvider::delegate_
= nullptr;
19 ScreenOrientationProvider::LockInformation::LockInformation(int request_id
,
20 blink::WebScreenOrientationLockType lock
)
21 : request_id(request_id
),
25 ScreenOrientationProvider::ScreenOrientationProvider(
26 ScreenOrientationDispatcherHost
* dispatcher_host
,
27 WebContents
* web_contents
)
28 : WebContentsObserver(web_contents
),
29 dispatcher_(dispatcher_host
),
30 lock_applied_(false) {
33 ScreenOrientationProvider::~ScreenOrientationProvider() {
36 void ScreenOrientationProvider::LockOrientation(int request_id
,
37 blink::WebScreenOrientationLockType lock_orientation
) {
39 if (!delegate_
|| !delegate_
->ScreenOrientationProviderSupported()) {
40 dispatcher_
->NotifyLockError(request_id
,
41 blink::WebLockOrientationErrorNotAvailable
);
45 if (delegate_
->FullScreenRequired(web_contents())) {
46 RenderViewHost
* rvh
= web_contents()->GetRenderViewHost();
48 dispatcher_
->NotifyLockError(request_id
,
49 blink::WebLockOrientationErrorCanceled
);
52 RenderViewHostDelegate
* rvhd
= rvh
->GetDelegate();
54 dispatcher_
->NotifyLockError(request_id
,
55 blink::WebLockOrientationErrorCanceled
);
58 if (!rvhd
->IsFullscreenForCurrentTab()) {
59 dispatcher_
->NotifyLockError(request_id
,
60 blink::WebLockOrientationErrorFullScreenRequired
);
65 if (lock_orientation
== blink::WebScreenOrientationLockNatural
) {
66 lock_orientation
= GetNaturalLockType();
67 if (lock_orientation
== blink::WebScreenOrientationLockDefault
) {
68 // We are in a broken state, let's pretend we got canceled.
69 dispatcher_
->NotifyLockError(request_id
,
70 blink::WebLockOrientationErrorCanceled
);
76 delegate_
->Lock(web_contents(), lock_orientation
);
78 // If two calls happen close to each other some platforms will ignore the
79 // first. A successful lock will be once orientation matches the latest
81 pending_lock_
.reset();
83 // If the orientation we are locking to matches the current orientation, we
84 // should succeed immediately.
85 if (LockMatchesCurrentOrientation(lock_orientation
)) {
86 dispatcher_
->NotifyLockSuccess(request_id
);
90 pending_lock_
.reset(new LockInformation(request_id
, lock_orientation
));
93 void ScreenOrientationProvider::UnlockOrientation() {
94 if (!lock_applied_
|| !delegate_
)
97 delegate_
->Unlock(web_contents());
99 lock_applied_
= false;
100 pending_lock_
.reset();
103 void ScreenOrientationProvider::OnOrientationChange() {
104 if (!pending_lock_
.get())
107 if (LockMatchesCurrentOrientation(pending_lock_
->lock
)) {
108 dispatcher_
->NotifyLockSuccess(pending_lock_
->request_id
);
109 pending_lock_
.reset();
113 void ScreenOrientationProvider::SetDelegate(
114 ScreenOrientationDelegate
* delegate
) {
115 delegate_
= delegate
;
118 void ScreenOrientationProvider::DidToggleFullscreenModeForTab(
119 bool entered_fullscreen
) {
120 if (!lock_applied_
|| !delegate_
)
123 // If fullscreen is not required in order to lock orientation, don't unlock
124 // when fullscreen state changes.
125 if (!delegate_
->FullScreenRequired(web_contents()))
128 DCHECK(!entered_fullscreen
);
132 blink::WebScreenOrientationLockType
133 ScreenOrientationProvider::GetNaturalLockType() const {
134 RenderWidgetHost
* rwh
= web_contents()->GetRenderViewHost();
136 return blink::WebScreenOrientationLockDefault
;
138 blink::WebScreenInfo screen_info
;
139 rwh
->GetWebScreenInfo(&screen_info
);
141 switch (screen_info
.orientationType
) {
142 case blink::WebScreenOrientationPortraitPrimary
:
143 case blink::WebScreenOrientationPortraitSecondary
:
144 if (screen_info
.orientationAngle
== 0 ||
145 screen_info
.orientationAngle
== 180) {
146 return blink::WebScreenOrientationLockPortraitPrimary
;
148 return blink::WebScreenOrientationLockLandscapePrimary
;
149 case blink::WebScreenOrientationLandscapePrimary
:
150 case blink::WebScreenOrientationLandscapeSecondary
:
151 if (screen_info
.orientationAngle
== 0 ||
152 screen_info
.orientationAngle
== 180) {
153 return blink::WebScreenOrientationLockLandscapePrimary
;
155 return blink::WebScreenOrientationLockPortraitPrimary
;
156 case blink::WebScreenOrientationUndefined
:
158 return blink::WebScreenOrientationLockDefault
;
162 return blink::WebScreenOrientationLockDefault
;
165 bool ScreenOrientationProvider::LockMatchesCurrentOrientation(
166 blink::WebScreenOrientationLockType lock
) {
167 RenderWidgetHost
* rwh
= web_contents()->GetRenderViewHost();
171 blink::WebScreenInfo screen_info
;
172 rwh
->GetWebScreenInfo(&screen_info
);
175 case blink::WebScreenOrientationLockPortraitPrimary
:
176 return screen_info
.orientationType
==
177 blink::WebScreenOrientationPortraitPrimary
;
178 case blink::WebScreenOrientationLockPortraitSecondary
:
179 return screen_info
.orientationType
==
180 blink::WebScreenOrientationPortraitSecondary
;
181 case blink::WebScreenOrientationLockLandscapePrimary
:
182 return screen_info
.orientationType
==
183 blink::WebScreenOrientationLandscapePrimary
;
184 case blink::WebScreenOrientationLockLandscapeSecondary
:
185 return screen_info
.orientationType
==
186 blink::WebScreenOrientationLandscapeSecondary
;
187 case blink::WebScreenOrientationLockLandscape
:
188 return screen_info
.orientationType
==
189 blink::WebScreenOrientationLandscapePrimary
||
190 screen_info
.orientationType
==
191 blink::WebScreenOrientationLandscapeSecondary
;
192 case blink::WebScreenOrientationLockPortrait
:
193 return screen_info
.orientationType
==
194 blink::WebScreenOrientationPortraitPrimary
||
195 screen_info
.orientationType
==
196 blink::WebScreenOrientationPortraitSecondary
;
197 case blink::WebScreenOrientationLockAny
:
199 case blink::WebScreenOrientationLockNatural
:
200 case blink::WebScreenOrientationLockDefault
:
209 } // namespace content