Title: [279420] trunk/Source
Revision
279420
Author
[email protected]
Date
2021-06-30 10:09:59 -0700 (Wed, 30 Jun 2021)

Log Message

[Model] [iOS] Add support for displaying <model> in fullscreen
https://bugs.webkit.org/show_bug.cgi?id=227443
<rdar://problem/79859937>

Reviewed by Sam Weinig.

Source/WebCore:

Expose a new enterFullscreen() method on HTMLModelElement allowing to enter a fullscreen AR experience
where the resource may be displayed in the user's environment. This differs from the existing
Element.requestFullscreen() method since the experience is provided by the platform and we're not
presenting the inline <model> element in a fullscreen window.

>From the WebProcess side, this requires obtaining a reference to the content layer for the <model> element
and sending it in an IPC message to the UIProcess.

* Modules/model-element/HTMLModelElement.cpp:
(WebCore::HTMLModelElement::enterFullscreen):
* Modules/model-element/HTMLModelElement.h:
* Modules/model-element/HTMLModelElement.idl:
* loader/EmptyClients.cpp:
(WebCore::EmptyChromeClient::takeModelElementFullscreen const):
* loader/EmptyClients.h:
* page/ChromeClient.h:
(WebCore::ChromeClient::takeModelElementFullscreen const):
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::contentsLayerIDForModel const):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::contentsLayerIDForModel const):
* platform/graphics/ca/GraphicsLayerCA.h:

Source/WebCore/PAL:

Declare additional ASVInlinePreview methods required for fullscreen support.

* pal/spi/ios/SystemPreviewSPI.h:

Source/WebKit:

Displaying a model element in fullscreen requires making some calls on the ASVInlinePreview object
created by a WKModelView. We send the content layer ID we receive through an IPC call from the
WebProcess to the new ModelElementController. We then look at the remote layer tree for a node
matching that ID and find its related UIView. If we find a WKModelView, as expected, we can carry
on and call -[ASVInlinePreview createFullscreenInstanceWithInitialFrame:previewOptions:completionHandler:]
to enter fullscreen using the presentingViewController provided by the UI client, and then observe
when we exit fullscreen using -[ASVInlinePreview observeDismissFullscreenWithCompletionHandler:]
to make sure the presenting view controller is removed.

* Sources.txt:
* SourcesCocoa.txt:
* UIProcess/Cocoa/ModelElementControllerCocoa.mm: Added.
(WebKit::ModelElementController::takeModelElementFullscreen):
* UIProcess/ModelElementController.cpp: Added.
(WebKit::ModelElementController::ModelElementController):
* UIProcess/ModelElementController.h: Added.
(WebKit::ModelElementController::page):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didAttachToRunningProcess):
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::takeModelElementFullscreen):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::takeModelElementFullscreen const):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::takeModelElementFullscreen):
* WebProcess/WebPage/WebPage.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (279419 => 279420)


--- trunk/Source/WebCore/ChangeLog	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/ChangeLog	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1,3 +1,34 @@
+2021-06-30  Antoine Quint  <[email protected]>
+
+        [Model] [iOS] Add support for displaying <model> in fullscreen
+        https://bugs.webkit.org/show_bug.cgi?id=227443
+        <rdar://problem/79859937>
+
+        Reviewed by Sam Weinig.
+
+        Expose a new enterFullscreen() method on HTMLModelElement allowing to enter a fullscreen AR experience
+        where the resource may be displayed in the user's environment. This differs from the existing
+        Element.requestFullscreen() method since the experience is provided by the platform and we're not
+        presenting the inline <model> element in a fullscreen window.
+
+        From the WebProcess side, this requires obtaining a reference to the content layer for the <model> element
+        and sending it in an IPC message to the UIProcess.
+
+        * Modules/model-element/HTMLModelElement.cpp:
+        (WebCore::HTMLModelElement::enterFullscreen):
+        * Modules/model-element/HTMLModelElement.h:
+        * Modules/model-element/HTMLModelElement.idl:
+        * loader/EmptyClients.cpp:
+        (WebCore::EmptyChromeClient::takeModelElementFullscreen const):
+        * loader/EmptyClients.h:
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::takeModelElementFullscreen const):
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::contentsLayerIDForModel const):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::contentsLayerIDForModel const):
+        * platform/graphics/ca/GraphicsLayerCA.h:
+
 2021-06-30  Tim Nguyen  <[email protected]>
 
         Add modal dialog UA styles

Modified: trunk/Source/WebCore/Modules/model-element/HTMLModelElement.cpp (279419 => 279420)


--- trunk/Source/WebCore/Modules/model-element/HTMLModelElement.cpp	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/Modules/model-element/HTMLModelElement.cpp	2021-06-30 17:09:59 UTC (rev 279420)
@@ -37,10 +37,22 @@
 #include "JSEventTarget.h"
 #include "JSHTMLModelElement.h"
 #include "Model.h"
+#include "RenderLayerModelObject.h"
 #include "RenderModel.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/URL.h>
 
+#if HAVE(ARKIT_INLINE_PREVIEW_IOS)
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Document.h"
+#include "GraphicsLayer.h"
+#include "GraphicsLayerCA.h"
+#include "Page.h"
+#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
+#endif
+
 namespace WebCore {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLModelElement);
@@ -214,6 +226,29 @@
     m_readyPromise->resolve(*this);
 }
 
+void HTMLModelElement::enterFullscreen()
+{
+#if HAVE(ARKIT_INLINE_PREVIEW_IOS)
+    auto* page = document().page();
+    if (!page)
+        return;
+
+    if (!is<RenderLayerModelObject>(this->renderer()))
+        return;
+
+    auto& renderLayerModelObject = downcast<RenderLayerModelObject>(*this->renderer());
+    if (!renderLayerModelObject.isComposited() || !renderLayerModelObject.layer() || !renderLayerModelObject.layer()->backing())
+        return;
+
+    auto* graphicsLayer = renderLayerModelObject.layer()->backing()->graphicsLayer();
+    if (!graphicsLayer)
+        return;
+
+    if (auto contentLayerId = graphicsLayer->contentsLayerIDForModel())
+        page->chrome().client().takeModelElementFullscreen(contentLayerId);
+#endif
 }
 
+}
+
 #endif // ENABLE(MODEL_ELEMENT)

Modified: trunk/Source/WebCore/Modules/model-element/HTMLModelElement.h (279419 => 279420)


--- trunk/Source/WebCore/Modules/model-element/HTMLModelElement.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/Modules/model-element/HTMLModelElement.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -59,6 +59,8 @@
     WEBCORE_EXPORT static void setModelElementCacheDirectory(const String&);
     WEBCORE_EXPORT static const String& modelElementCacheDirectory();
 
+    void enterFullscreen();
+
 private:
     HTMLModelElement(const QualifiedName&, Document&);
 

Modified: trunk/Source/WebCore/Modules/model-element/HTMLModelElement.idl (279419 => 279420)


--- trunk/Source/WebCore/Modules/model-element/HTMLModelElement.idl	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/Modules/model-element/HTMLModelElement.idl	2021-06-30 17:09:59 UTC (rev 279420)
@@ -31,4 +31,6 @@
     [URL] readonly attribute USVString currentSrc;
 
     readonly attribute Promise<HTMLModelElement> ready;
+
+    undefined enterFullscreen();
 };

Modified: trunk/Source/WebCore/PAL/ChangeLog (279419 => 279420)


--- trunk/Source/WebCore/PAL/ChangeLog	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/PAL/ChangeLog	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1,3 +1,15 @@
+2021-06-30  Antoine Quint  <[email protected]>
+
+        [Model] [iOS] Add support for displaying <model> in fullscreen
+        https://bugs.webkit.org/show_bug.cgi?id=227443
+        <rdar://problem/79859937>
+
+        Reviewed by Sam Weinig.
+
+        Declare additional ASVInlinePreview methods required for fullscreen support.
+
+        * pal/spi/ios/SystemPreviewSPI.h:
+
 2021-06-28  Antoine Quint  <[email protected]>
 
         [Model] [iOS] Add support for manipulating <model> inline

Modified: trunk/Source/WebCore/PAL/pal/spi/ios/SystemPreviewSPI.h (279419 => 279420)


--- trunk/Source/WebCore/PAL/pal/spi/ios/SystemPreviewSPI.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/PAL/pal/spi/ios/SystemPreviewSPI.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -83,6 +83,8 @@
 - (void)setupRemoteConnectionWithCompletionHandler:(void (^)(NSError * _Nullable error))handler;
 - (void)preparePreviewOfFileAtURL:(NSURL *)url completionHandler:(void (^)(NSError * _Nullable error))handler;
 - (void)updateFrame:(CGRect)newFrame completionHandler:(void (^)(CAFenceHandle * _Nullable fenceHandle, NSError * _Nullable error))handler;
+- (void)createFullscreenInstanceWithInitialFrame:(CGRect)initialFrame previewOptions:(NSDictionary *)previewOptions completionHandler:(void (^)(UIViewController *remoteViewController, CAFenceHandle * _Nullable fenceHandle, NSError * _Nullable error))handler;
+- (void)observeDismissFullscreenWithCompletionHandler:(void (^)(CAFenceHandle * _Nullable fenceHandle, NSDictionary * _Nonnull payload, NSError * _Nullable error))handler;
 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
 - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;

Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (279419 => 279420)


--- trunk/Source/WebCore/loader/EmptyClients.cpp	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp	2021-06-30 17:09:59 UTC (rev 279420)
@@ -578,6 +578,12 @@
 {
 }
 
+#if ENABLE(MODEL_ELEMENT)
+void EmptyChromeClient::takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID) const
+{
+}
+#endif
+
 void EmptyFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction&, const ResourceRequest&, FormState*, const String&, PolicyCheckIdentifier, FramePolicyFunction&&)
 {
 }

Modified: trunk/Source/WebCore/loader/EmptyClients.h (279419 => 279420)


--- trunk/Source/WebCore/loader/EmptyClients.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/loader/EmptyClients.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -216,6 +216,10 @@
     void didAssociateFormControls(const Vector<RefPtr<Element>>&, Frame&) final { }
     bool shouldNotifyOnFormChanges() final { return false; }
 
+#if ENABLE(MODEL_ELEMENT)
+    void takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID) const final;
+#endif
+
     RefPtr<Icon> createIconForFiles(const Vector<String>& /* filenames */) final { return nullptr; }
 };
 

Modified: trunk/Source/WebCore/page/ChromeClient.h (279419 => 279420)


--- trunk/Source/WebCore/page/ChromeClient.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/page/ChromeClient.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -596,6 +596,10 @@
     virtual void textAutosizingUsesIdempotentModeChanged() { }
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+    virtual void takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID) const { }
+#endif
+
 protected:
     virtual ~ChromeClient() = default;
 };

Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (279419 => 279420)


--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -524,6 +524,7 @@
     virtual void setContentsToPlatformLayer(PlatformLayer*, ContentsLayerPurpose) { }
 #if ENABLE(MODEL_ELEMENT)
     virtual void setContentsToModel(RefPtr<Model>&&) { }
+    virtual PlatformLayerID contentsLayerIDForModel() const { return 0; }
 #endif
     virtual bool usesContentsLayer() const { return false; }
 

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (279419 => 279420)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1299,6 +1299,12 @@
 
     noteLayerPropertyChanged(ContentsRectsChanged | OpacityChanged);
 }
+
+GraphicsLayer::PlatformLayerID GraphicsLayerCA::contentsLayerIDForModel() const
+{
+    return m_contentsLayerPurpose == ContentsLayerPurpose::Model ? m_contentsLayer->layerID() : 0;
+}
+
 #endif
 
 void GraphicsLayerCA::setContentsToPlatformLayer(PlatformLayer* platformLayer, ContentsLayerPurpose purpose)

Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (279419 => 279420)


--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -153,6 +153,7 @@
     WEBCORE_EXPORT void setContentsToSolidColor(const Color&) override;
 #if ENABLE(MODEL_ELEMENT)
     WEBCORE_EXPORT void setContentsToModel(RefPtr<Model>&&) override;
+    WEBCORE_EXPORT PlatformLayerID contentsLayerIDForModel() const override;
 #endif
 
     bool usesContentsLayer() const override { return m_contentsLayerPurpose != ContentsLayerPurpose::None; }

Modified: trunk/Source/WebKit/ChangeLog (279419 => 279420)


--- trunk/Source/WebKit/ChangeLog	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/ChangeLog	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1,3 +1,42 @@
+2021-06-30  Antoine Quint  <[email protected]>
+
+        [Model] [iOS] Add support for displaying <model> in fullscreen
+        https://bugs.webkit.org/show_bug.cgi?id=227443
+        <rdar://problem/79859937>
+
+        Reviewed by Sam Weinig.
+
+        Displaying a model element in fullscreen requires making some calls on the ASVInlinePreview object
+        created by a WKModelView. We send the content layer ID we receive through an IPC call from the
+        WebProcess to the new ModelElementController. We then look at the remote layer tree for a node
+        matching that ID and find its related UIView. If we find a WKModelView, as expected, we can carry 
+        on and call -[ASVInlinePreview createFullscreenInstanceWithInitialFrame:previewOptions:completionHandler:]
+        to enter fullscreen using the presentingViewController provided by the UI client, and then observe
+        when we exit fullscreen using -[ASVInlinePreview observeDismissFullscreenWithCompletionHandler:]
+        to make sure the presenting view controller is removed.
+
+        * Sources.txt:
+        * SourcesCocoa.txt:
+        * UIProcess/Cocoa/ModelElementControllerCocoa.mm: Added.
+        (WebKit::ModelElementController::takeModelElementFullscreen):
+        * UIProcess/ModelElementController.cpp: Added.
+        (WebKit::ModelElementController::ModelElementController):
+        * UIProcess/ModelElementController.h: Added.
+        (WebKit::ModelElementController::page):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::didAttachToRunningProcess):
+        (WebKit::WebPageProxy::resetState):
+        (WebKit::WebPageProxy::takeModelElementFullscreen):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::takeModelElementFullscreen const):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::takeModelElementFullscreen):
+        * WebProcess/WebPage/WebPage.h:
+
 2021-06-30  Chris Dumez  <[email protected]>
 
         Unreviewed, reverting r276969.

Modified: trunk/Source/WebKit/Sources.txt (279419 => 279420)


--- trunk/Source/WebKit/Sources.txt	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/Sources.txt	2021-06-30 17:09:59 UTC (rev 279420)
@@ -297,6 +297,7 @@
 UIProcess/LegacyGlobalSettings.cpp
 UIProcess/MediaKeySystemPermissionRequestManagerProxy.cpp
 UIProcess/MediaKeySystemPermissionRequestProxy.cpp
+UIProcess/ModelElementController.cpp
 UIProcess/PageLoadState.cpp
 UIProcess/ProcessAssertion.cpp
 UIProcess/ProcessThrottler.cpp

Modified: trunk/Source/WebKit/SourcesCocoa.txt (279419 => 279420)


--- trunk/Source/WebKit/SourcesCocoa.txt	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/SourcesCocoa.txt	2021-06-30 17:09:59 UTC (rev 279420)
@@ -400,6 +400,7 @@
 UIProcess/Cocoa/LegacyCustomProtocolManagerClient.mm
 UIProcess/Cocoa/MediaUtilities.mm
 UIProcess/Cocoa/MediaPermissionUtilities.mm
+UIProcess/Cocoa/ModelElementControllerCocoa.mm
 UIProcess/Cocoa/NavigationState.mm
 UIProcess/Cocoa/PageClientImplCocoa.mm
 UIProcess/Cocoa/PlatformXRSystem.mm

Added: trunk/Source/WebKit/UIProcess/Cocoa/ModelElementControllerCocoa.mm (0 => 279420)


--- trunk/Source/WebKit/UIProcess/Cocoa/ModelElementControllerCocoa.mm	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/Cocoa/ModelElementControllerCocoa.mm	2021-06-30 17:09:59 UTC (rev 279420)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "ModelElementController.h"
+
+#if ENABLE(MODEL_ELEMENT)
+
+#import "APIUIClient.h"
+#import "Logging.h"
+#import "RemoteLayerTreeDrawingAreaProxy.h"
+#import "RemoteLayerTreeHost.h"
+#import "RemoteLayerTreeViews.h"
+#import "WKModelView.h"
+#import "WebPageProxy.h"
+#import <pal/spi/cocoa/QuartzCoreSPI.h>
+#if HAVE(ARKIT_INLINE_PREVIEW_IOS)
+#import <pal/spi/ios/SystemPreviewSPI.h>
+#endif
+
+SOFT_LINK_PRIVATE_FRAMEWORK(AssetViewer);
+SOFT_LINK_CLASS(AssetViewer, ASVInlinePreview);
+
+namespace WebKit {
+
+#if HAVE(ARKIT_INLINE_PREVIEW_IOS)
+void ModelElementController::takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId)
+{
+    if (!is<RemoteLayerTreeDrawingAreaProxy>(m_webPageProxy.drawingArea()))
+        return;
+
+    auto* node = downcast<RemoteLayerTreeDrawingAreaProxy>(*m_webPageProxy.drawingArea()).remoteLayerTreeHost().nodeForID(contentLayerId);
+    if (!node)
+        return;
+
+    auto *view = node->uiView();
+    if (!view)
+        return;
+
+    if (![view isKindOfClass:[WKModelView class]])
+        return;
+
+    auto *presentingViewController = m_webPageProxy.uiClient().presentingViewController();
+    if (!presentingViewController)
+        return;
+
+    WKModelView *modelView = (WKModelView *)view;
+    CGRect initialFrame = [modelView convertRect:modelView.frame toView:nil];
+
+    ASVInlinePreview *preview = [modelView preview];
+    NSDictionary *previewOptions = @{@"WebKit": @"Model element fullscreen"};
+    [preview createFullscreenInstanceWithInitialFrame:initialFrame previewOptions:previewOptions completionHandler:^(UIViewController *remoteViewController, CAFenceHandle *fenceHandle, NSError *creationError) {
+        if (creationError) {
+            LOG(ModelElement, "Unable to create fullscreen instance: %@", [creationError localizedDescription]);
+            [fenceHandle invalidate];
+            return;
+        }
+
+        dispatch_async(dispatch_get_main_queue(), ^{
+            remoteViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
+            remoteViewController.view.backgroundColor = UIColor.clearColor;
+
+            [presentingViewController presentViewController:remoteViewController animated:NO completion:^(void) {
+                [CATransaction begin];
+                [view.layer.superlayer.context addFence:fenceHandle];
+                [CATransaction commit];
+                [fenceHandle invalidate];
+            }];
+
+            [preview observeDismissFullscreenWithCompletionHandler:^(CAFenceHandle *dismissFenceHandle, NSDictionary *payload, NSError *dismissError) {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    if (dismissError || !dismissFenceHandle) {
+                        LOG(ModelElement, "Unable to get fence handle when dismissing fullscreen instance: %@", [dismissError localizedDescription]);
+                        [dismissFenceHandle invalidate];
+                        return;
+                    }
+
+                    [CATransaction begin];
+                    [view.layer.superlayer.context addFence:dismissFenceHandle];
+                    [CATransaction setCompletionBlock:^{
+                        [remoteViewController dismissViewControllerAnimated:NO completion:nil];
+                    }];
+                    [CATransaction commit];
+                    [dismissFenceHandle invalidate];
+                });
+            }];
+        });
+    }];
+}
+#endif
+
+}
+
+#endif

Added: trunk/Source/WebKit/UIProcess/ModelElementController.cpp (0 => 279420)


--- trunk/Source/WebKit/UIProcess/ModelElementController.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/ModelElementController.cpp	2021-06-30 17:09:59 UTC (rev 279420)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ModelElementController.h"
+
+#if ENABLE(MODEL_ELEMENT)
+
+#include "WebPageProxy.h"
+
+namespace WebKit {
+
+ModelElementController::ModelElementController(WebPageProxy& webPageProxy)
+    : m_webPageProxy(webPageProxy)
+{
+}
+
+}
+
+#endif

Added: trunk/Source/WebKit/UIProcess/ModelElementController.h (0 => 279420)


--- trunk/Source/WebKit/UIProcess/ModelElementController.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/ModelElementController.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(MODEL_ELEMENT)
+
+#include <WebCore/ElementContext.h>
+#include <WebCore/GraphicsLayer.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/URL.h>
+#include <wtf/WeakPtr.h>
+
+#if HAVE(ARKIT_INLINE_PREVIEW_MAC)
+OBJC_CLASS ASVInlinePreview;
+#endif
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class ModelElementController : public CanMakeWeakPtr<ModelElementController> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit ModelElementController(WebPageProxy&);
+
+    WebPageProxy& page() { return m_webPageProxy; }
+
+#if HAVE(ARKIT_INLINE_PREVIEW_IOS)
+    void takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId);
+#endif
+
+private:
+    WebPageProxy& m_webPageProxy;
+};
+
+}
+
+#endif

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (279419 => 279420)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1023,6 +1023,11 @@
     m_systemPreviewController = makeUnique<SystemPreviewController>(*this);
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+    ASSERT(!m_modelElementController);
+    m_modelElementController = makeUnique<ModelElementController>(*this);
+#endif
+
 #if ENABLE(WEB_AUTHN)
     ASSERT(!m_credentialsMessenger);
     m_credentialsMessenger = makeUnique<WebAuthenticatorCoordinatorProxy>(*this);
@@ -7771,6 +7776,10 @@
     m_systemPreviewController = nullptr;
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+    m_modelElementController = nullptr;
+#endif
+
 #if ENABLE(WEB_AUTHN)
     m_credentialsMessenger = nullptr;
 #endif
@@ -10679,6 +10688,15 @@
 
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+void WebPageProxy::takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId)
+{
+#if HAVE(ARKIT_INLINE_PREVIEW_IOS)
+    modelElementController()->takeModelElementFullscreen(contentLayerId);
+#endif
+}
+#endif
+
 #if !PLATFORM(COCOA)
 SandboxExtension::HandleArray WebPageProxy::createNetworkExtensionsSandboxExtensions(WebProcessProxy& process)
 {

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (279419 => 279420)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -189,6 +189,10 @@
 #include "PlatformXRSystem.h"
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+#include "ModelElementController.h"
+#endif
+
 namespace API {
 class Attachment;
 class ContentWorld;
@@ -569,6 +573,11 @@
     void systemPreviewActionTriggered(const WebCore::SystemPreviewInfo&, const String&);
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+    ModelElementController* modelElementController() { return m_modelElementController.get(); }
+    void takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId);
+#endif
+
 #if ENABLE(CONTEXT_MENUS)
     API::ContextMenuClient& contextMenuClient() { return *m_contextMenuClient; }
     void setContextMenuClient(std::unique_ptr<API::ContextMenuClient>&&);
@@ -2597,6 +2606,10 @@
     std::unique_ptr<SystemPreviewController> m_systemPreviewController;
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+    std::unique_ptr<ModelElementController> m_modelElementController;
+#endif
+
 #if ENABLE(WEB_AUTHN)
     std::unique_ptr<WebAuthenticatorCoordinatorProxy> m_credentialsMessenger;
 #endif

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (279419 => 279420)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2021-06-30 17:09:59 UTC (rev 279420)
@@ -592,4 +592,8 @@
 #if PLATFORM(MAC)
     ChangeUniversalAccessZoomFocus(WebCore::IntRect viewRect, WebCore::IntRect caretRect)
 #endif
+
+#if ENABLE(MODEL_ELEMENT)
+    TakeModelElementFullscreen(uint64_t contentLayerID)
+#endif
 }

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (279419 => 279420)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1322,6 +1322,7 @@
 		6EE849C81368D9390038D481 /* WKInspectorPrivateMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE849C61368D92D0038D481 /* WKInspectorPrivateMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		711725A9228D564300018514 /* WebsiteLegacyOverflowScrollingTouchPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 711725A8228D563A00018514 /* WebsiteLegacyOverflowScrollingTouchPolicy.h */; };
 		7134A3DA2603B92500624BD3 /* WKModelInteractionGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7134A3D92603B80E00624BD3 /* WKModelInteractionGestureRecognizer.h */; };
+		7137BA8025F1542000914EE3 /* ModelElementController.h in Headers */ = {isa = PBXBuildFile; fileRef = 7137BA7F25F1540C00914EE3 /* ModelElementController.h */; };
 		71A676A622C62325007D6295 /* WKTouchActionGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A676A422C62318007D6295 /* WKTouchActionGestureRecognizer.h */; };
 		71BAA73325FFD09800D7CD5D /* WKModelView.h in Headers */ = {isa = PBXBuildFile; fileRef = 71BAA73125FFCCBA00D7CD5D /* WKModelView.h */; };
 		71FB810B2260627E00323677 /* WebsiteSimulatedMouseEventsDispatchPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 71FB810A2260627A00323677 /* WebsiteSimulatedMouseEventsDispatchPolicy.h */; };
@@ -4575,6 +4576,9 @@
 		711725A8228D563A00018514 /* WebsiteLegacyOverflowScrollingTouchPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebsiteLegacyOverflowScrollingTouchPolicy.h; sourceTree = "<group>"; };
 		7134A3D82603B80E00624BD3 /* WKModelInteractionGestureRecognizer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKModelInteractionGestureRecognizer.mm; path = ios/WKModelInteractionGestureRecognizer.mm; sourceTree = "<group>"; };
 		7134A3D92603B80E00624BD3 /* WKModelInteractionGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKModelInteractionGestureRecognizer.h; path = ios/WKModelInteractionGestureRecognizer.h; sourceTree = "<group>"; };
+		7137BA7D25F153E900914EE3 /* ModelElementControllerCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ModelElementControllerCocoa.mm; sourceTree = "<group>"; };
+		7137BA7E25F1540B00914EE3 /* ModelElementController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModelElementController.cpp; sourceTree = "<group>"; };
+		7137BA7F25F1540C00914EE3 /* ModelElementController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModelElementController.h; sourceTree = "<group>"; };
 		71A676A422C62318007D6295 /* WKTouchActionGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKTouchActionGestureRecognizer.h; path = ios/WKTouchActionGestureRecognizer.h; sourceTree = "<group>"; };
 		71A676A522C62318007D6295 /* WKTouchActionGestureRecognizer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKTouchActionGestureRecognizer.mm; path = ios/WKTouchActionGestureRecognizer.mm; sourceTree = "<group>"; };
 		71BAA73125FFCCBA00D7CD5D /* WKModelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKModelView.h; path = ios/WKModelView.h; sourceTree = "<group>"; };
@@ -7044,6 +7048,7 @@
 				9342588F2555DCA50059EEDD /* MediaPermissionUtilities.mm */,
 				411286EF21C8A90C003A8550 /* MediaUtilities.h */,
 				411286F021C8A90D003A8550 /* MediaUtilities.mm */,
+				7137BA7D25F153E900914EE3 /* ModelElementControllerCocoa.mm */,
 				1ABC3DF41899E437004F0626 /* NavigationState.h */,
 				1ABC3DF31899E437004F0626 /* NavigationState.mm */,
 				5C6CE6D31F59EA350007C6CB /* PageClientImplCocoa.h */,
@@ -9987,6 +9992,8 @@
 				9ACC07B225C815F300DC6386 /* MediaKeySystemPermissionRequestManagerProxy.h */,
 				9ACC07B425C8160B00DC6386 /* MediaKeySystemPermissionRequestProxy.h */,
 				93425898255B534B0059EEDD /* MediaPermissionUtilities.h */,
+				7137BA7E25F1540B00914EE3 /* ModelElementController.cpp */,
+				7137BA7F25F1540C00914EE3 /* ModelElementController.h */,
 				BC6EDAA5111271C600E7678B /* PageClient.h */,
 				1AC75379183A9FDA0072CB15 /* PageLoadState.cpp */,
 				1AC7537A183A9FDB0072CB15 /* PageLoadState.h */,
@@ -12085,6 +12092,7 @@
 				57DCEDC7214F18300016B847 /* MockLocalConnection.h in Headers */,
 				57DCEDC3214F114C0016B847 /* MockLocalService.h in Headers */,
 				57B8264C230603C100B72EB0 /* MockNfcService.h in Headers */,
+				7137BA8025F1542000914EE3 /* ModelElementController.h in Headers */,
 				C0E3AA7C1209E83C00A49D01 /* Module.h in Headers */,
 				2D50366B1BCDE17900E20BB3 /* NativeWebGestureEvent.h in Headers */,
 				263172CF18B469490065B9C3 /* NativeWebTouchEvent.h in Headers */,

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (279419 => 279420)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1515,4 +1515,11 @@
     m_page.didHandleOrPreventMouseDownOrMouseUpEvent();
 }
 
+#if ENABLE(MODEL_ELEMENT)
+void WebChromeClient::takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId) const
+{
+    m_page.takeModelElementFullscreen(contentLayerId);
+}
+#endif
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (279419 => 279420)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -452,6 +452,10 @@
     void enumerateImmersiveXRDevices(CompletionHandler<void(const PlatformXR::Instance::DeviceList&)>&&) final;
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+    void takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId) const final;
+#endif
+
     mutable bool m_cachedMainFrameHasHorizontalScrollbar { false };
     mutable bool m_cachedMainFrameHasVerticalScrollbar { false };
 

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (279419 => 279420)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-06-30 17:09:59 UTC (rev 279420)
@@ -7669,7 +7669,14 @@
 {
     send(Messages::WebPageProxy::HandleContextMenuTranslation(info));
 }
+#endif
 
+#if ENABLE(MODEL_ELEMENT)
+void WebPage::takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId)
+{
+    send(Messages::WebPageProxy::TakeModelElementFullscreen(contentLayerId));
+}
+
 #endif
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (279419 => 279420)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-06-30 16:43:38 UTC (rev 279419)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-06-30 17:09:59 UTC (rev 279420)
@@ -1461,6 +1461,10 @@
     PlatformXRSystemProxy& xrSystemProxy();
 #endif
 
+#if ENABLE(MODEL_ELEMENT)
+    void takeModelElementFullscreen(WebCore::GraphicsLayer::PlatformLayerID contentLayerId);
+#endif
+
     void didHandleOrPreventMouseDownOrMouseUpEvent();
     void prepareToRunModalJavaScriptDialog();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to