Skip to content

Commit

Permalink
[iOS] Add screen orientation locking / unlocking support outside layo…
Browse files Browse the repository at this point in the history
…ut tests

https://bugs.webkit.org/show_bug.cgi?id=246435

Reviewed by Wenson Hsieh.

Add screen orientation locking / unlocking support outside layout tests, on iOS
devices. Outside tests, the fullscreen API uses the WKFullScreenWindowController
to display a new fullscreen view on top of the current one. This new view has its
own UIViewController that WebKit controls. As a result, when locking the screen
orientation (which is gated on being in fullscreen), we need to do so via the
WKFullScreenWindowController, instead of relying on the client application.

* Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp:
(WebKit::WebFullScreenManagerProxy::lockFullscreenOrientation):
(WebKit::WebFullScreenManagerProxy::unlockFullscreenOrientation):
* Source/WebKit/UIProcess/WebFullScreenManagerProxy.h:
(WebKit::WebFullScreenManagerProxyClient::lockFullscreenOrientation):
(WebKit::WebFullScreenManagerProxyClient::unlockFullscreenOrientation):
* Source/WebKit/UIProcess/WebScreenOrientationManagerProxy.cpp:
(WebKit::WebScreenOrientationManagerProxy::lock):
(WebKit::WebScreenOrientationManagerProxy::unlock):
* Source/WebKit/UIProcess/ios/PageClientImplIOS.h:
* Source/WebKit/UIProcess/ios/PageClientImplIOS.mm:
(WebKit::toUIInterfaceOrientationMask):
(WebKit::PageClientImpl::lockFullscreenOrientation):
(WebKit::PageClientImpl::unlockFullscreenOrientation):
* Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h:
* Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm:
(-[WKFullScreenViewController initWithWebView:]):
(-[WKFullScreenViewController setSupportedOrientation:]):
(-[WKFullScreenViewController supportedInterfaceOrientations]):
* Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.h:
* Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
(-[WKFullScreenWindowController setSupportedOrientations:]):

Canonical link: https://commits.webkit.org/255555@main
  • Loading branch information
cdumez committed Oct 14, 2022
1 parent 734d5db commit d6f850a
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 5 deletions.
11 changes: 11 additions & 0 deletions Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp
Expand Up @@ -36,6 +36,7 @@
#include "WebProcessPool.h"
#include "WebProcessProxy.h"
#include <WebCore/IntRect.h>
#include <WebCore/ScreenOrientationType.h>

namespace WebKit {
using namespace WebCore;
Expand Down Expand Up @@ -211,6 +212,16 @@ void WebFullScreenManagerProxy::beganExitFullScreen(const IntRect& initialFrame,
m_client.beganExitFullScreen(initialFrame, finalFrame);
}

bool WebFullScreenManagerProxy::lockFullscreenOrientation(WebCore::ScreenOrientationType orientation)
{
return m_client.lockFullscreenOrientation(orientation);
}

void WebFullScreenManagerProxy::unlockFullscreenOrientation()
{
m_client.unlockFullscreenOrientation();
}

} // namespace WebKit

#endif // ENABLE(FULLSCREEN_API)
7 changes: 7 additions & 0 deletions Source/WebKit/UIProcess/WebFullScreenManagerProxy.h
Expand Up @@ -38,6 +38,8 @@ namespace WebCore {
class FloatSize;
class IntRect;

enum class ScreenOrientationType : uint8_t;

template <typename> class RectEdges;
using FloatBoxExtent = RectEdges<float>;
}
Expand All @@ -60,6 +62,9 @@ class WebFullScreenManagerProxyClient {
virtual void exitFullScreen() = 0;
virtual void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) = 0;
virtual void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) = 0;

virtual bool lockFullscreenOrientation(WebCore::ScreenOrientationType) { return false; }
virtual void unlockFullscreenOrientation() { }
};

class WebFullScreenManagerProxy : public IPC::MessageReceiver {
Expand Down Expand Up @@ -96,6 +101,8 @@ class WebFullScreenManagerProxy : public IPC::MessageReceiver {
void setFullscreenAutoHideDuration(Seconds);
void setFullscreenControlsHidden(bool);
void closeWithCallback(CompletionHandler<void()>&&);
bool lockFullscreenOrientation(WebCore::ScreenOrientationType);
void unlockFullscreenOrientation();

private:
void supportsFullScreen(bool withKeyboard, CompletionHandler<void(bool)>&&);
Expand Down
31 changes: 27 additions & 4 deletions Source/WebKit/UIProcess/WebScreenOrientationManagerProxy.cpp
Expand Up @@ -27,6 +27,7 @@
#include "WebScreenOrientationManagerProxy.h"

#include "APIUIClient.h"
#include "WebFullScreenManagerProxy.h"
#include "WebPageProxy.h"
#include "WebScreenOrientationManagerMessages.h"
#include "WebScreenOrientationManagerProxyMessages.h"
Expand Down Expand Up @@ -92,9 +93,22 @@ void WebScreenOrientationManagerProxy::lock(WebCore::ScreenOrientationLockType l
auto currentOrientation = m_provider->currentOrientation();
auto resolvedLockedOrientation = resolveScreenOrientationLockType(currentOrientation, lockType);
bool shouldOrientationChange = currentOrientation != resolvedLockedOrientation;
if (resolvedLockedOrientation != m_currentlyLockedOrientation && !m_page.uiClient().lockScreenOrientation(m_page, resolvedLockedOrientation)) {
m_currentLockRequest(WebCore::Exception { WebCore::NotSupportedError, "Screen orientation locking is not supported"_s });
return;

if (resolvedLockedOrientation != m_currentlyLockedOrientation) {
bool didLockOrientation = false;
#if ENABLE(FULLSCREEN_API)
if (m_page.fullScreenManager() && m_page.fullScreenManager()->isFullScreen()) {
if (!m_page.fullScreenManager()->lockFullscreenOrientation(resolvedLockedOrientation)) {
m_currentLockRequest(WebCore::Exception { WebCore::NotSupportedError, "Screen orientation locking is not supported"_s });
return;
}
didLockOrientation = true;
}
#endif
if (!didLockOrientation && !m_page.uiClient().lockScreenOrientation(m_page, resolvedLockedOrientation)) {
m_currentLockRequest(WebCore::Exception { WebCore::NotSupportedError, "Screen orientation locking is not supported"_s });
return;
}
}
m_currentlyLockedOrientation = resolvedLockedOrientation;
if (!shouldOrientationChange)
Expand All @@ -109,7 +123,16 @@ void WebScreenOrientationManagerProxy::unlock()
if (m_currentLockRequest)
m_currentLockRequest(WebCore::Exception { WebCore::AbortError, "Unlock request was received"_s });

m_page.uiClient().unlockScreenOrientation(m_page);
bool didUnlockOrientation = false;
#if ENABLE(FULLSCREEN_API)
if (m_page.fullScreenManager() && m_page.fullScreenManager()->isFullScreen()) {
m_page.fullScreenManager()->unlockFullscreenOrientation();
didUnlockOrientation = true;
}
#endif
if (!didUnlockOrientation)
m_page.uiClient().unlockScreenOrientation(m_page);

m_currentlyLockedOrientation = std::nullopt;
}

Expand Down
2 changes: 2 additions & 0 deletions Source/WebKit/UIProcess/ios/PageClientImplIOS.h
Expand Up @@ -230,6 +230,8 @@ class PageClientImpl final : public PageClientImplCocoa
void exitFullScreen() override;
void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override;
void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override;
bool lockFullscreenOrientation(WebCore::ScreenOrientationType) override;
void unlockFullscreenOrientation() override;
#endif

void didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference&) override;
Expand Down
28 changes: 28 additions & 0 deletions Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
Expand Up @@ -67,6 +67,7 @@
#import <WebCore/NotImplemented.h>
#import <WebCore/PlatformScreen.h>
#import <WebCore/PromisedAttachmentInfo.h>
#import <WebCore/ScreenOrientationType.h>
#import <WebCore/ShareData.h>
#import <WebCore/SharedBuffer.h>
#import <WebCore/TextIndicator.h>
Expand Down Expand Up @@ -741,6 +742,33 @@ - (BOOL)_isHostedInAnotherProcess;
[[m_webView fullScreenWindowController] exitFullScreen];
}

static UIInterfaceOrientationMask toUIInterfaceOrientationMask(WebCore::ScreenOrientationType orientation)
{
switch (orientation) {
case WebCore::ScreenOrientationType::PortraitPrimary:
return UIInterfaceOrientationMaskPortrait;
case WebCore::ScreenOrientationType::PortraitSecondary:
return UIInterfaceOrientationMaskPortraitUpsideDown;
case WebCore::ScreenOrientationType::LandscapePrimary:
return UIInterfaceOrientationMaskLandscapeLeft;
case WebCore::ScreenOrientationType::LandscapeSecondary:
return UIInterfaceOrientationMaskLandscapeRight;
}
ASSERT_NOT_REACHED();
return UIInterfaceOrientationMaskPortrait;
}

bool PageClientImpl::lockFullscreenOrientation(WebCore::ScreenOrientationType orientation)
{
[[m_webView fullScreenWindowController] setSupportedOrientations:toUIInterfaceOrientationMask(orientation)];
return true;
}

void PageClientImpl::unlockFullscreenOrientation()
{
[[m_webView fullScreenWindowController] resetSupportedOrientations];
}

void PageClientImpl::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame)
{
[[m_webView fullScreenWindowController] beganEnterFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame];
Expand Down
Expand Up @@ -47,6 +47,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)hideUI;
- (void)videoControlsManagerDidChange;
- (void)setAnimatingViewAlpha:(CGFloat)alpha;
- (void)setSupportedOrientations:(UIInterfaceOrientationMask)supportedOrientations;
- (void)resetSupportedOrientations;
#if HAVE(UIKIT_WEBKIT_INTERNALS)
- (void)hideMediaControls:(BOOL)hidden;
#endif
Expand Down
Expand Up @@ -124,6 +124,7 @@ @implementation WKFullScreenViewController {
WebKit::FullscreenTouchSecheuristic _secheuristic;
WKFullScreenViewControllerPlaybackSessionModelClient _playbackClient;
CGFloat _nonZeroStatusBarHeight;
std::optional<UIInterfaceOrientationMask> _supportedOrientations;
#if HAVE(UIKIT_WEBKIT_INTERNALS)
BOOL m_shouldHideMediaControls;
#endif
Expand All @@ -145,7 +146,6 @@ - (id)initWithWebView:(WKWebView *)webView
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_statusBarFrameDidChange:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
ALLOW_DEPRECATED_DECLARATIONS_END
_secheuristic.setParameters(WebKit::FullscreenTouchSecheuristicParameters::iosParameters());

self._webView = webView;

_playbackClient.setParent(self);
Expand Down Expand Up @@ -180,6 +180,25 @@ - (void)dealloc
[super dealloc];
}

- (void)setSupportedOrientations:(UIInterfaceOrientationMask)supportedOrientations
{
_supportedOrientations = supportedOrientations;
[self setNeedsUpdateOfSupportedInterfaceOrientations];
}

- (void)resetSupportedOrientations
{
_supportedOrientations = std::nullopt;
[self setNeedsUpdateOfSupportedInterfaceOrientations];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if (!_supportedOrientations)
return [super supportedInterfaceOrientations];
return *_supportedOrientations;
}

- (void)showUI
{
ASSERT(_valid);
Expand Down
Expand Up @@ -40,6 +40,8 @@
- (void)requestExitFullScreen;
- (void)exitFullScreen;
- (void)beganExitFullScreenWithInitialFrame:(CGRect)initialFrame finalFrame:(CGRect)finalFrame;
- (void)setSupportedOrientations:(UIInterfaceOrientationMask)orientations;
- (void)resetSupportedOrientations;
- (void)close;
- (void)webViewDidRemoveFromSuperviewWhileInFullscreen;
- (void)videoControlsManagerDidChange;
Expand Down
Expand Up @@ -526,6 +526,16 @@ - (UIView *)webViewPlaceholder
#pragma mark -
#pragma mark External Interface

- (void)setSupportedOrientations:(UIInterfaceOrientationMask)orientations
{
[_fullscreenViewController setSupportedOrientations:orientations];
}

- (void)resetSupportedOrientations
{
[_fullscreenViewController resetSupportedOrientations];
}

- (void)enterFullScreen:(CGSize)videoDimensions
{
if ([self isFullScreen])
Expand Down

0 comments on commit d6f850a

Please sign in to comment.