OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "content/public/browser/screen_orientation_provider.h" |
| 6 |
| 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" |
| 14 |
| 15 namespace content { |
| 16 |
| 17 ScreenOrientationDelegate* ScreenOrientationProvider::delegate_ = NULL; |
| 18 |
| 19 ScreenOrientationProvider::LockInformation::LockInformation(int request_id, |
| 20 blink::WebScreenOrientationLockType lock) |
| 21 : request_id(request_id), |
| 22 lock(lock) { |
| 23 } |
| 24 |
| 25 ScreenOrientationProvider::ScreenOrientationProvider( |
| 26 ScreenOrientationDispatcherHost* dispatcher_host, |
| 27 WebContents* web_contents) |
| 28 : WebContentsObserver(web_contents), |
| 29 dispatcher_(dispatcher_host), |
| 30 lock_applied_(false) { |
| 31 } |
| 32 |
| 33 ScreenOrientationProvider::~ScreenOrientationProvider() { |
| 34 } |
| 35 |
| 36 void ScreenOrientationProvider::LockOrientation(int request_id, |
| 37 blink::WebScreenOrientationLockType lock_orientation) { |
| 38 |
| 39 if (!delegate_ || !delegate_->ScreenOrientationProviderSupported()) { |
| 40 dispatcher_->NotifyLockError(request_id, |
| 41 blink::WebLockOrientationErrorNotAvailable); |
| 42 return; |
| 43 } |
| 44 |
| 45 if (delegate_->FullScreenRequired(web_contents())) { |
| 46 RenderViewHost* rvh = web_contents()->GetRenderViewHost(); |
| 47 if (!rvh) { |
| 48 dispatcher_->NotifyLockError(request_id, |
| 49 blink::WebLockOrientationErrorCanceled); |
| 50 } |
| 51 RenderViewHostDelegate* rvhd = rvh->GetDelegate(); |
| 52 if (!rvhd) { |
| 53 dispatcher_->NotifyLockError(request_id, |
| 54 blink::WebLockOrientationErrorCanceled); |
| 55 } |
| 56 if (!rvhd->IsFullscreenForCurrentTab()) { |
| 57 dispatcher_->NotifyLockError(request_id, |
| 58 blink::WebLockOrientationErrorFullScreenRequired); |
| 59 } |
| 60 return; |
| 61 } |
| 62 |
| 63 if (lock_orientation == blink::WebScreenOrientationLockNatural) { |
| 64 lock_orientation = GetNaturalLockType(); |
| 65 if (lock_orientation == blink::WebScreenOrientationLockDefault) { |
| 66 // We are in a broken state, let's pretend we got canceled. |
| 67 dispatcher_->NotifyLockError(request_id, |
| 68 blink::WebLockOrientationErrorCanceled); |
| 69 return; |
| 70 } |
| 71 } |
| 72 |
| 73 lock_applied_ = true; |
| 74 delegate_->Lock(lock_orientation); |
| 75 |
| 76 // If two calls happen close to each other some platforms will ignore the |
| 77 // first. A successful lock will be once orientation matches the latest |
| 78 // request. |
| 79 pending_lock_.reset(); |
| 80 |
| 81 // If the orientation we are locking to matches the current orientation, we |
| 82 // should succeed immediately. |
| 83 if (LockMatchesCurrentOrientation(lock_orientation)) { |
| 84 dispatcher_->NotifyLockSuccess(request_id); |
| 85 return; |
| 86 } |
| 87 |
| 88 pending_lock_.reset(new LockInformation(request_id, lock_orientation)); |
| 89 } |
| 90 |
| 91 void ScreenOrientationProvider::UnlockOrientation() { |
| 92 if (!lock_applied_ || !delegate_) |
| 93 return; |
| 94 |
| 95 delegate_->Unlock(); |
| 96 |
| 97 lock_applied_ = false; |
| 98 pending_lock_.reset(); |
| 99 } |
| 100 |
| 101 void ScreenOrientationProvider::OnOrientationChange() { |
| 102 if (!pending_lock_.get()) |
| 103 return; |
| 104 |
| 105 if (LockMatchesCurrentOrientation(pending_lock_->lock)) { |
| 106 dispatcher_->NotifyLockSuccess(pending_lock_->request_id); |
| 107 pending_lock_.reset(); |
| 108 } |
| 109 } |
| 110 |
| 111 void ScreenOrientationProvider::SetDelegate( |
| 112 ScreenOrientationDelegate* delegate) { |
| 113 delegate_ = delegate; |
| 114 } |
| 115 |
| 116 void ScreenOrientationProvider::DidToggleFullscreenModeForTab( |
| 117 bool entered_fullscreen) { |
| 118 if (!lock_applied_ || !delegate_) |
| 119 return; |
| 120 |
| 121 // If fullscreen is not required in order to lock orientation, don't unlock |
| 122 // when fullscreen state changes. |
| 123 if (!delegate_->FullScreenRequired(web_contents())) |
| 124 return; |
| 125 |
| 126 DCHECK(!entered_fullscreen); |
| 127 UnlockOrientation(); |
| 128 } |
| 129 |
| 130 blink::WebScreenOrientationLockType |
| 131 ScreenOrientationProvider::GetNaturalLockType() const { |
| 132 RenderWidgetHost* rwh = web_contents()->GetRenderViewHost(); |
| 133 if (!rwh) |
| 134 return blink::WebScreenOrientationLockDefault; |
| 135 |
| 136 blink::WebScreenInfo screen_info; |
| 137 rwh->GetWebScreenInfo(&screen_info); |
| 138 |
| 139 switch (screen_info.orientationType) { |
| 140 case blink::WebScreenOrientationPortraitPrimary: |
| 141 case blink::WebScreenOrientationPortraitSecondary: |
| 142 if (screen_info.orientationAngle == 0 || |
| 143 screen_info.orientationAngle == 180) { |
| 144 return blink::WebScreenOrientationLockPortraitPrimary; |
| 145 } |
| 146 return blink::WebScreenOrientationLockLandscapePrimary; |
| 147 case blink::WebScreenOrientationLandscapePrimary: |
| 148 case blink::WebScreenOrientationLandscapeSecondary: |
| 149 if (screen_info.orientationAngle == 0 || |
| 150 screen_info.orientationAngle == 180) { |
| 151 return blink::WebScreenOrientationLockLandscapePrimary; |
| 152 } |
| 153 return blink::WebScreenOrientationLockPortraitPrimary; |
| 154 case blink::WebScreenOrientationUndefined: |
| 155 NOTREACHED(); |
| 156 return blink::WebScreenOrientationLockDefault; |
| 157 } |
| 158 |
| 159 NOTREACHED(); |
| 160 return blink::WebScreenOrientationLockDefault; |
| 161 } |
| 162 |
| 163 bool ScreenOrientationProvider::LockMatchesCurrentOrientation( |
| 164 blink::WebScreenOrientationLockType lock) { |
| 165 RenderWidgetHost* rwh = web_contents()->GetRenderViewHost(); |
| 166 if (!rwh) |
| 167 return false; |
| 168 |
| 169 blink::WebScreenInfo screen_info; |
| 170 rwh->GetWebScreenInfo(&screen_info); |
| 171 |
| 172 switch (lock) { |
| 173 case blink::WebScreenOrientationLockPortraitPrimary: |
| 174 return screen_info.orientationType == |
| 175 blink::WebScreenOrientationPortraitPrimary; |
| 176 case blink::WebScreenOrientationLockPortraitSecondary: |
| 177 return screen_info.orientationType == |
| 178 blink::WebScreenOrientationPortraitSecondary; |
| 179 case blink::WebScreenOrientationLockLandscapePrimary: |
| 180 return screen_info.orientationType == |
| 181 blink::WebScreenOrientationLandscapePrimary; |
| 182 case blink::WebScreenOrientationLockLandscapeSecondary: |
| 183 return screen_info.orientationType == |
| 184 blink::WebScreenOrientationLandscapeSecondary; |
| 185 case blink::WebScreenOrientationLockLandscape: |
| 186 return screen_info.orientationType == |
| 187 blink::WebScreenOrientationLandscapePrimary || |
| 188 screen_info.orientationType == |
| 189 blink::WebScreenOrientationLandscapeSecondary; |
| 190 case blink::WebScreenOrientationLockPortrait: |
| 191 return screen_info.orientationType == |
| 192 blink::WebScreenOrientationPortraitPrimary || |
| 193 screen_info.orientationType == |
| 194 blink::WebScreenOrientationPortraitSecondary; |
| 195 case blink::WebScreenOrientationLockAny: |
| 196 return true; |
| 197 case blink::WebScreenOrientationLockNatural: |
| 198 case blink::WebScreenOrientationLockDefault: |
| 199 NOTREACHED(); |
| 200 return false; |
| 201 } |
| 202 |
| 203 NOTREACHED(); |
| 204 return false; |
| 205 } |
| 206 |
| 207 } // namespace content |
OLD | NEW |