Popular sites on the NTP: Try to keep the ordering constant
[chromium-blink-merge.git] / content / public / browser / screen_orientation_provider.cc
blobb575f0942f1b5f6e977d9f6f660fea4c20f126b8
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/WebScreenInfo.h"
13 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebLockOrientationError.h"
15 namespace content {
17 ScreenOrientationDelegate* ScreenOrientationProvider::delegate_ = nullptr;
19 ScreenOrientationProvider::LockInformation::LockInformation(int request_id,
20 blink::WebScreenOrientationLockType lock)
21 : request_id(request_id),
22 lock(lock) {
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);
42 return;
45 if (delegate_->FullScreenRequired(web_contents())) {
46 RenderViewHost* rvh = web_contents()->GetRenderViewHost();
47 if (!rvh) {
48 dispatcher_->NotifyLockError(request_id,
49 blink::WebLockOrientationErrorCanceled);
50 return;
52 RenderViewHostDelegate* rvhd = rvh->GetDelegate();
53 if (!rvhd) {
54 dispatcher_->NotifyLockError(request_id,
55 blink::WebLockOrientationErrorCanceled);
56 return;
58 if (!rvhd->IsFullscreenForCurrentTab()) {
59 dispatcher_->NotifyLockError(request_id,
60 blink::WebLockOrientationErrorFullScreenRequired);
61 return;
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);
71 return;
75 lock_applied_ = true;
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
80 // request.
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);
87 return;
90 pending_lock_.reset(new LockInformation(request_id, lock_orientation));
93 void ScreenOrientationProvider::UnlockOrientation() {
94 if (!lock_applied_ || !delegate_)
95 return;
97 delegate_->Unlock(web_contents());
99 lock_applied_ = false;
100 pending_lock_.reset();
103 void ScreenOrientationProvider::OnOrientationChange() {
104 if (!pending_lock_.get())
105 return;
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_)
121 return;
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()))
126 return;
128 DCHECK(!entered_fullscreen);
129 UnlockOrientation();
132 blink::WebScreenOrientationLockType
133 ScreenOrientationProvider::GetNaturalLockType() const {
134 RenderWidgetHost* rwh = web_contents()->GetRenderViewHost();
135 if (!rwh)
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:
157 NOTREACHED();
158 return blink::WebScreenOrientationLockDefault;
161 NOTREACHED();
162 return blink::WebScreenOrientationLockDefault;
165 bool ScreenOrientationProvider::LockMatchesCurrentOrientation(
166 blink::WebScreenOrientationLockType lock) {
167 RenderWidgetHost* rwh = web_contents()->GetRenderViewHost();
168 if (!rwh)
169 return false;
171 blink::WebScreenInfo screen_info;
172 rwh->GetWebScreenInfo(&screen_info);
174 switch (lock) {
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:
198 return true;
199 case blink::WebScreenOrientationLockNatural:
200 case blink::WebScreenOrientationLockDefault:
201 NOTREACHED();
202 return false;
205 NOTREACHED();
206 return false;
209 } // namespace content