Title: [262858] trunk
Revision
262858
Author
[email protected]
Date
2020-06-10 13:49:59 -0700 (Wed, 10 Jun 2020)

Log Message

Catalyst WebKit apps continue to play audio after quitting
https://bugs.webkit.org/show_bug.cgi?id=212981
<rdar://problem/57089471>

Reviewed by Chris Dumez.

Source/WebKit:

RunningBoard will track whether a process (and it's associated child processes) are "user-visible" by
granting those processes an "endowment", similar to the existing endowment for application visibility.
Track changes to these endowments using a RBSProcessMonitor, and for Catalyst apps, react to losing the
"user-visible" endowment by suspending all media playback.

Move all the endowment-related code into a new class, EndowmentStateTracker, which is a singleton object
that can have mulitple WebPageProxy clients. Update references to the previously global static
isApplicationForeground() function to refer to EndowmentStateTracker instead.

Drive-by fix: move some iOS-only functions in WebPageProxy.cpp into WebPageProxyIOS.mm.

* UIProcess/ApplicationStateTracker.h:
* UIProcess/ApplicationStateTracker.mm:
(WebKit::ApplicationStateTracker::ApplicationStateTracker):
(WebKit::isApplicationForeground): Deleted.
* UIProcess/EndowmentStateTracker.h: Added.
(WebKit::EndowmentStateTracker::isVisible const):
(WebKit::EndowmentStateTracker::isUserFacing const):
* UIProcess/EndowmentStateTracker.mm: Added.
(WebKit::handleForPID):
(WebKit::EndowmentStateTracker::isApplicationForeground):
(WebKit::EndowmentStateTracker::isApplicationUserFacing):
(WebKit::EndowmentStateTracker::singleton):
(WebKit::EndowmentStateTracker::EndowmentStateTracker):
(WebKit::EndowmentStateTracker::addClient):
(WebKit::EndowmentStateTracker::removeClient):
(WebKit::EndowmentStateTracker::setIsUserFacing):
(WebKit::EndowmentStateTracker::setIsVisible):
* UIProcess/WebPageProxy.cpp:
(WebKit::m_limitsNavigationsToAppBoundDomains):
(WebKit::WebPageProxy::~WebPageProxy):
(WebKit::WebPageProxy::processWillBecomeSuspended): Deleted.
(WebKit::WebPageProxy::processWillBecomeForeground): Deleted.
* UIProcess/WebPageProxy.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::isApplicationVisible):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::processWillBecomeSuspended):
(WebKit::WebPageProxy::processWillBecomeForeground):
(WebKit::WebPageProxy::isUserFacingChanged):
(WebKit::WebPageProxy::isVisibleChanged):
* WebKit.xcodeproj/project.pbxproj:

Source/WTF:

Add the ability to call copyToVector() on a WeakHashSet. This requires two changes:
- A template specialization that returns a Vector<WeakPtr<T>> from copyToVector()
- A template specialization that calls calculateSize() rather than size() on the object
  being iterated upon.

* wtf/WeakHashSet.h:
(WTF::copyToVector):

WebKitLibraries:

* WebKitPrivateFrameworkStubs/iOS/13/RunningBoardServices.framework/RunningBoardServices.tbd:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (262857 => 262858)


--- trunk/Source/WTF/ChangeLog	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WTF/ChangeLog	2020-06-10 20:49:59 UTC (rev 262858)
@@ -1,3 +1,19 @@
+2020-06-10  Jer Noble  <[email protected]>
+
+        Catalyst WebKit apps continue to play audio after quitting
+        https://bugs.webkit.org/show_bug.cgi?id=212981
+        <rdar://problem/57089471>
+
+        Reviewed by Chris Dumez.
+
+        Add the ability to call copyToVector() on a WeakHashSet. This requires two changes:
+        - A template specialization that returns a Vector<WeakPtr<T>> from copyToVector()
+        - A template specialization that calls calculateSize() rather than size() on the object
+          being iterated upon.
+
+        * wtf/WeakHashSet.h:
+        (WTF::copyToVector):
+
 2020-06-09  Tim Horton  <[email protected]>
 
         Use os_log instead of asl_log

Modified: trunk/Source/WTF/wtf/WeakHashSet.h (262857 => 262858)


--- trunk/Source/WTF/wtf/WeakHashSet.h	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WTF/wtf/WeakHashSet.h	2020-06-10 20:49:59 UTC (rev 262858)
@@ -155,6 +155,28 @@
     WeakPtrImplSet m_set;
 };
 
+template<typename MapFunction, typename T>
+struct Mapper<MapFunction, const WeakHashSet<T> &, void> {
+    using SourceItemType = WeakPtr<T>;
+    using DestinationItemType = typename std::result_of<MapFunction(SourceItemType&)>::type;
+
+    static Vector<DestinationItemType> map(const WeakHashSet<T>& source, const MapFunction& mapFunction)
+    {
+        Vector<DestinationItemType> result;
+        result.reserveInitialCapacity(source.computeSize());
+        for (auto& item : source)
+            result.uncheckedAppend(mapFunction(item));
+        return result;
+    }
+};
+
+template<typename T>
+inline auto copyToVector(const WeakHashSet<T>& collection) -> Vector<WeakPtr<T>>
+{
+    return WTF::map(collection, [] (auto& v) -> WeakPtr<T> { return makeWeakPtr<T>(v); });
+}
+
+
 } // namespace WTF
 
 using WTF::WeakHashSet;

Modified: trunk/Source/WebKit/ChangeLog (262857 => 262858)


--- trunk/Source/WebKit/ChangeLog	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/ChangeLog	2020-06-10 20:49:59 UTC (rev 262858)
@@ -1,3 +1,54 @@
+2020-06-10  Jer Noble  <[email protected]>
+
+        Catalyst WebKit apps continue to play audio after quitting
+        https://bugs.webkit.org/show_bug.cgi?id=212981
+        <rdar://problem/57089471>
+
+        Reviewed by Chris Dumez.
+
+        RunningBoard will track whether a process (and it's associated child processes) are "user-visible" by
+        granting those processes an "endowment", similar to the existing endowment for application visibility.
+        Track changes to these endowments using a RBSProcessMonitor, and for Catalyst apps, react to losing the
+        "user-visible" endowment by suspending all media playback.
+
+        Move all the endowment-related code into a new class, EndowmentStateTracker, which is a singleton object
+        that can have mulitple WebPageProxy clients. Update references to the previously global static
+        isApplicationForeground() function to refer to EndowmentStateTracker instead.
+
+        Drive-by fix: move some iOS-only functions in WebPageProxy.cpp into WebPageProxyIOS.mm.
+
+        * UIProcess/ApplicationStateTracker.h:
+        * UIProcess/ApplicationStateTracker.mm:
+        (WebKit::ApplicationStateTracker::ApplicationStateTracker):
+        (WebKit::isApplicationForeground): Deleted.
+        * UIProcess/EndowmentStateTracker.h: Added.
+        (WebKit::EndowmentStateTracker::isVisible const):
+        (WebKit::EndowmentStateTracker::isUserFacing const):
+        * UIProcess/EndowmentStateTracker.mm: Added.
+        (WebKit::handleForPID):
+        (WebKit::EndowmentStateTracker::isApplicationForeground):
+        (WebKit::EndowmentStateTracker::isApplicationUserFacing):
+        (WebKit::EndowmentStateTracker::singleton):
+        (WebKit::EndowmentStateTracker::EndowmentStateTracker):
+        (WebKit::EndowmentStateTracker::addClient):
+        (WebKit::EndowmentStateTracker::removeClient):
+        (WebKit::EndowmentStateTracker::setIsUserFacing):
+        (WebKit::EndowmentStateTracker::setIsVisible):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::m_limitsNavigationsToAppBoundDomains):
+        (WebKit::WebPageProxy::~WebPageProxy):
+        (WebKit::WebPageProxy::processWillBecomeSuspended): Deleted.
+        (WebKit::WebPageProxy::processWillBecomeForeground): Deleted.
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::isApplicationVisible):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::processWillBecomeSuspended):
+        (WebKit::WebPageProxy::processWillBecomeForeground):
+        (WebKit::WebPageProxy::isUserFacingChanged):
+        (WebKit::WebPageProxy::isVisibleChanged):
+        * WebKit.xcodeproj/project.pbxproj:
+
 2020-06-10  Antoine Quint  <[email protected]>
 
         Subframes should not autosize independently

Modified: trunk/Source/WebKit/Platform/spi/ios/RunningBoardServicesSPI.h (262857 => 262858)


--- trunk/Source/WebKit/Platform/spi/ios/RunningBoardServicesSPI.h	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/Platform/spi/ios/RunningBoardServicesSPI.h	2020-06-10 20:49:59 UTC (rev 262858)
@@ -37,6 +37,8 @@
 
 #else
 
+NS_ASSUME_NONNULL_BEGIN
+
 @interface RBSAttribute : NSObject
 @end
 
@@ -46,6 +48,7 @@
 
 @interface RBSTarget : NSObject
 + (RBSTarget *)targetWithPid:(pid_t)pid;
++ (RBSTarget *)currentProcess;
 @end
 
 @protocol RBSAssertionObserving;
@@ -91,8 +94,47 @@
 @interface RBSProcessHandle : NSObject
 + (RBSProcessHandle *)handleForIdentifier:(RBSProcessIdentifier *)identifier error:(NSError **)outError;
 + (RBSProcessHandle *)currentProcess;
+@property (nonatomic, readonly, assign) pid_t pid;
 @property (nonatomic, readonly, strong) RBSProcessState *currentState;
 @property (nonatomic, readonly, strong) RBSProcessLimitations *activeLimitations;
 @end
 
+@interface RBSProcessStateUpdate : NSObject
+@property (nonatomic, readonly, strong) RBSProcessHandle *process;
+@property (nonatomic, readonly, strong, nullable) RBSProcessState *state;
+@end
+
+@class RBSProcessMonitor;
+@class RBSProcessPredicate;
+@class RBSProcessStateDescriptor;
+@protocol RBSProcessMonitorConfiguring;
+
+typedef void (^RBSProcessMonitorConfigurator)(id<RBSProcessMonitorConfiguring> config);
+typedef void (^RBSProcessUpdateHandler)(RBSProcessMonitor *monitor, RBSProcessHandle *process, RBSProcessStateUpdate *update);
+
+@protocol RBSProcessMatching <NSObject>
+- (RBSProcessPredicate *)processPredicate;
+@end
+
+@protocol RBSProcessMonitorConfiguring
+- (void)setPredicates:(nullable NSArray<RBSProcessPredicate *> *)predicates;
+- (void)setStateDescriptor:(nullable RBSProcessStateDescriptor *)descriptor;
+- (void)setUpdateHandler:(nullable RBSProcessUpdateHandler)block;
+@end
+
+@interface RBSProcessMonitor : NSObject <NSCopying>
++ (instancetype)monitorWithConfiguration:(NS_NOESCAPE RBSProcessMonitorConfigurator)block;
+@end
+
+@interface RBSProcessPredicate : NSObject <RBSProcessMatching>
++ (RBSProcessPredicate *)predicateMatchingHandle:(RBSProcessHandle *)process;
+@end
+
+@interface RBSProcessStateDescriptor : NSObject <NSCopying>
++ (instancetype)descriptor;
+@property (nonatomic, readwrite, copy, nullable) NSArray<NSString *> *endowmentNamespaces;
+@end
+
+NS_ASSUME_NONNULL_END
+
 #endif

Modified: trunk/Source/WebKit/UIProcess/ApplicationStateTracker.h (262857 => 262858)


--- trunk/Source/WebKit/UIProcess/ApplicationStateTracker.h	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/UIProcess/ApplicationStateTracker.h	2020-06-10 20:49:59 UTC (rev 262858)
@@ -75,7 +75,6 @@
 };
 
 ApplicationType applicationType(UIWindow *);
-bool isApplicationForeground(pid_t);
 
 }
 

Modified: trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm (262857 => 262858)


--- trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm	2020-06-10 20:49:59 UTC (rev 262858)
@@ -29,8 +29,8 @@
 #if PLATFORM(IOS_FAMILY)
 
 #import "AssertionServicesSPI.h"
+#import "EndowmentStateTracker.h"
 #import "Logging.h"
-#import "RunningBoardServicesSPI.h"
 #import "SandboxUtilities.h"
 #import "UIKitSPI.h"
 #import <wtf/ObjCRuntimeExtras.h>
@@ -142,7 +142,7 @@
         pid_t applicationPID = serviceViewController._hostProcessIdentifier;
         ASSERT(applicationPID);
 
-        m_isInBackground = !isApplicationForeground(applicationPID);
+        m_isInBackground = !EndowmentStateTracker::isApplicationForeground(applicationPID);
 
         // Workaround for <rdar://problem/34028921>. If the host application is StoreKitUIService then it is also a ViewService
         // and is always in the background. We need to treat StoreKitUIService as foreground for the purpose of process suspension
@@ -166,34 +166,6 @@
     }
 }
 
-bool isApplicationForeground(pid_t pid)
-{
-    RBSProcessIdentifier *processIdentifier = [RBSProcessIdentifier identifierWithPid:pid];
-    if (!processIdentifier) {
-        RELEASE_LOG_ERROR(ProcessSuspension, "isApplicationForeground: Failed to construct RBSProcessIdentifier from PID %d", pid);
-        // We assume foreground when unable to determine state to maintain pre-existing behavior and to avoid
-        // not rendering anything when we fail.
-        return true;
-    }
-
-    NSError *error = nil;
-    RBSProcessHandle *processHandle = [RBSProcessHandle handleForIdentifier:processIdentifier error:&error];
-    if (!processHandle) {
-        RELEASE_LOG_ERROR(ProcessSuspension, "isApplicationForeground: Failed to get RBSProcessHandle for process with PID %d, error: %{public}@", pid, error);
-        // We assume foreground when unable to determine state to maintain pre-existing behavior and to avoid
-        // not rendering anything when we fail.
-        return true;
-    }
-
-    RBSProcessState *state = processHandle.currentState;
-    if (state.taskState != RBSTaskStateRunningScheduled) {
-        RELEASE_LOG_ERROR(ProcessSuspension, "isApplicationForeground: Process with PID %d is not running", pid);
-        return false;
-    }
-
-    return [[state endowmentNamespaces] containsObject:@"com.apple.frontboard.visibility"];
-}
-
 ApplicationStateTracker::~ApplicationStateTracker()
 {
     RELEASE_LOG(ViewState, "%p - ~ApplicationStateTracker", this);

Added: trunk/Source/WebKit/UIProcess/EndowmentStateTracker.h (0 => 262858)


--- trunk/Source/WebKit/UIProcess/EndowmentStateTracker.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/EndowmentStateTracker.h	2020-06-10 20:49:59 UTC (rev 262858)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 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 PLATFORM(IOS_FAMILY)
+
+#import <wtf/RetainPtr.h>
+#import <wtf/WeakHashSet.h>
+
+OBJC_CLASS RBSProcessMonitor;
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class EndowmentStateTracker {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static EndowmentStateTracker& singleton();
+    ~EndowmentStateTracker();
+
+    class Client : public CanMakeWeakPtr<Client> {
+    public:
+        virtual ~Client() = default;
+        virtual void isUserFacingChanged(bool) { }
+        virtual void isVisibleChanged(bool) { }
+    };
+
+    bool isVisible() const { return m_isVisible; }
+    bool isUserFacing() const { return m_isUserFacing; }
+
+    void addClient(Client&);
+    void removeClient(Client&);
+
+    static bool isApplicationForeground(pid_t);
+
+private:
+    friend class NeverDestroyed<EndowmentStateTracker>;
+    EndowmentStateTracker();
+    void setIsUserFacing(bool);
+    void setIsVisible(bool);
+
+    WeakHashSet<Client> m_clients;
+    RetainPtr<RBSProcessMonitor> m_processMonitor;
+    bool m_isUserFacing;
+    bool m_isVisible;
+};
+
+}
+
+#endif

Added: trunk/Source/WebKit/UIProcess/EndowmentStateTracker.mm (0 => 262858)


--- trunk/Source/WebKit/UIProcess/EndowmentStateTracker.mm	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/EndowmentStateTracker.mm	2020-06-10 20:49:59 UTC (rev 262858)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2020 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 "EndowmentStateTracker.h"
+
+#import "Logging.h"
+#import "RunningBoardServicesSPI.h"
+#include <wtf/NeverDestroyed.h>
+
+#if PLATFORM(IOS_FAMILY)
+
+namespace WebKit {
+
+static NSString* visibilityEndowment = @"com.apple.frontboard.visibility";
+static NSString* userfacingEndowment = @"com.apple.launchservices.userfacing";
+
+static RBSProcessHandle *handleForPID(pid_t pid)
+{
+    RBSProcessIdentifier *processIdentifier = [RBSProcessIdentifier identifierWithPid:pid];
+    if (!processIdentifier) {
+        RELEASE_LOG_ERROR(ProcessSuspension, "handleForPID: Failed to construct RBSProcessIdentifier from PID %d", pid);
+        return nil;
+    }
+
+    NSError *error = nil;
+    RBSProcessHandle *processHandle = [RBSProcessHandle handleForIdentifier:processIdentifier error:&error];
+    if (!processHandle) {
+        RELEASE_LOG_ERROR(ProcessSuspension, "endowmentsForPid: Failed to get RBSProcessHandle for process with PID %d, error: %{public}@", pid, error);
+        return nil;
+    }
+
+    return processHandle;
+}
+
+static NSSet<NSString *> *endowmentsForHandle(RBSProcessHandle *processHandle)
+{
+    if (!processHandle) {
+        // We assume foreground when unable to determine state to maintain pre-existing behavior and to avoid
+        // not rendering anything when we fail.
+        return [NSSet setWithObjects:visibilityEndowment, userfacingEndowment, nil];
+    }
+
+    RBSProcessState *state = processHandle.currentState;
+    if (state.taskState != RBSTaskStateRunningScheduled) {
+        RELEASE_LOG_ERROR(ProcessSuspension, "endowmentsForHandle: Process with PID %d is not running", processHandle.pid);
+        return nil;
+    }
+
+    return [state endowmentNamespaces];
+}
+
+bool EndowmentStateTracker::isApplicationForeground(pid_t pid)
+{
+    return [endowmentsForHandle(handleForPID(pid)) containsObject:visibilityEndowment];
+}
+
+EndowmentStateTracker& EndowmentStateTracker::singleton()
+{
+    static auto tracker = NeverDestroyed<EndowmentStateTracker>();
+    return tracker;
+}
+
+EndowmentStateTracker::EndowmentStateTracker()
+{
+    auto processHandle = [RBSProcessHandle currentProcess];
+    auto endowmentNamespaces = endowmentsForHandle(processHandle);
+
+    m_isUserFacing = [endowmentNamespaces containsObject:userfacingEndowment];
+    m_isVisible = [endowmentNamespaces containsObject:visibilityEndowment];
+
+    m_processMonitor = [RBSProcessMonitor monitorWithConfiguration:[this, processHandle = retainPtr(processHandle)] (id<RBSProcessMonitorConfiguring> config) {
+
+        RBSProcessPredicate *processPredicate = [RBSProcessPredicate predicateMatchingHandle:processHandle.get()];
+
+        RBSProcessStateDescriptor *stateDescriptor = [RBSProcessStateDescriptor descriptor];
+        stateDescriptor.endowmentNamespaces = @[visibilityEndowment, userfacingEndowment];
+
+        [config setPredicates:@[processPredicate]];
+        [config setStateDescriptor:stateDescriptor];
+
+        [config setUpdateHandler:[this] (RBSProcessMonitor * _Nonnull monitor, RBSProcessHandle * _Nonnull process, RBSProcessStateUpdate * _Nonnull update) mutable {
+            dispatch_async(dispatch_get_main_queue(), [this, endowmentNamespaces = retainPtr(update.state.endowmentNamespaces)] {
+                setIsUserFacing([endowmentNamespaces containsObject:userfacingEndowment]);
+                setIsVisible([endowmentNamespaces containsObject:visibilityEndowment]);
+            });
+        }];
+    }];
+}
+
+void EndowmentStateTracker::addClient(Client& client)
+{
+    m_clients.add(client);
+}
+
+void EndowmentStateTracker::removeClient(Client& client)
+{
+    m_clients.remove(client);
+}
+
+void EndowmentStateTracker::setIsUserFacing(bool isUserFacing)
+{
+    if (m_isUserFacing == isUserFacing)
+        return;
+    m_isUserFacing = isUserFacing;
+
+    RELEASE_LOG(ViewState, "%p - EndowmentStateTracker::setIsUserFacing(%{public}s)", this, isUserFacing ? "true" : "false");
+
+    for (auto& client : copyToVector(m_clients)) {
+        if (client)
+            client->isUserFacingChanged(m_isUserFacing);
+    }
+}
+
+void EndowmentStateTracker::setIsVisible(bool isVisible)
+{
+    if (m_isVisible == isVisible)
+        return;
+    m_isVisible = isVisible;
+
+    RELEASE_LOG(ViewState, "%p - EndowmentStateTracker::setIsVisible(%{public}s)", this, isVisible ? "true" : "false");
+
+    for (auto& client : copyToVector(m_clients)) {
+        if (client)
+            client->isVisibleChanged(m_isVisible);
+    }
+}
+
+}
+
+#endif

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (262857 => 262858)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-06-10 20:49:59 UTC (rev 262858)
@@ -525,6 +525,8 @@
     
     if (m_configuration->preferences()->serviceWorkerEntitlementDisabledForTesting())
         disableServiceWorkerEntitlementInNetworkProcess();
+
+    EndowmentStateTracker::singleton().addClient(*this);
 #endif
 
 #if PLATFORM(COCOA)
@@ -566,6 +568,10 @@
 #ifndef NDEBUG
     webPageProxyCounter.decrement();
 #endif
+
+#if PLATFORM(IOS_FAMILY)
+    EndowmentStateTracker::singleton().removeClient(*this);
+#endif
 }
 
 // FIXME: Should return a const PageClient& and add a separate non-const
@@ -7464,29 +7470,6 @@
         handler->stopAllTasksForPage(*this, process);
 }
 
-#if PLATFORM(IOS_FAMILY)
-void WebPageProxy::processWillBecomeSuspended()
-{
-    if (!hasRunningProcess())
-        return;
-
-    m_hasNetworkRequestsOnSuspended = m_pageLoadState.networkRequestsInProgress();
-    if (m_hasNetworkRequestsOnSuspended)
-        setNetworkRequestsInProgress(false);
-}
-
-void WebPageProxy::processWillBecomeForeground()
-{
-    if (!hasRunningProcess())
-        return;
-
-    if (m_hasNetworkRequestsOnSuspended) {
-        setNetworkRequestsInProgress(true);
-        m_hasNetworkRequestsOnSuspended = false;
-    }
-}
-#endif
-
 void WebPageProxy::resetState(ResetStateReason resetStateReason)
 {
     m_mainFrame = nullptr;

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (262857 => 262858)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2020-06-10 20:49:59 UTC (rev 262858)
@@ -121,6 +121,7 @@
 #include <wtf/text/WTFString.h>
 
 #if PLATFORM(IOS_FAMILY)
+#include "EndowmentStateTracker.h"
 #include "GestureTypes.h"
 #include "WebAutocorrectionContext.h"
 #endif
@@ -433,7 +434,12 @@
     , public WebCore::PlatformSpeechSynthesisUtteranceClient
     , public WebCore::PlatformSpeechSynthesizerClient
 #endif
-    , public CanMakeWeakPtr<WebPageProxy> {
+#if PLATFORM(IOS_FAMILY)
+    , public EndowmentStateTracker::Client
+#else
+    , public CanMakeWeakPtr<WebPageProxy>
+#endif
+    {
 public:
     static Ref<WebPageProxy> create(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
     virtual ~WebPageProxy();
@@ -1183,6 +1189,8 @@
 #if PLATFORM(IOS_FAMILY)
     void processWillBecomeSuspended();
     void processWillBecomeForeground();
+    void isUserFacingChanged(bool) final;
+    void isVisibleChanged(bool) final;
 #endif
 
 #if HAVE(VISIBILITY_PROPAGATION_VIEW)

Modified: trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (262857 => 262858)


--- trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm	2020-06-10 20:49:59 UTC (rev 262858)
@@ -34,6 +34,7 @@
 #import "DataReference.h"
 #import "DownloadProxy.h"
 #import "DrawingAreaProxy.h"
+#import "EndowmentStateTracker.h"
 #import "FrameInfoData.h"
 #import "InteractionInformationAtPosition.h"
 #import "NativeWebKeyboardEvent.h"
@@ -166,7 +167,7 @@
     pid_t applicationPID = serviceViewController._hostProcessIdentifier;
     ASSERT(applicationPID);
 
-    return isApplicationForeground(applicationPID);
+    return EndowmentStateTracker::isApplicationForeground(applicationPID);
 }
 
 bool PageClientImpl::isViewInWindow()

Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (262857 => 262858)


--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2020-06-10 20:49:59 UTC (rev 262858)
@@ -1600,6 +1600,44 @@
     });
 }
 
+void WebPageProxy::processWillBecomeSuspended()
+{
+    if (!hasRunningProcess())
+        return;
+
+    m_hasNetworkRequestsOnSuspended = m_pageLoadState.networkRequestsInProgress();
+    if (m_hasNetworkRequestsOnSuspended)
+        setNetworkRequestsInProgress(false);
+}
+
+void WebPageProxy::processWillBecomeForeground()
+{
+    if (!hasRunningProcess())
+        return;
+
+    if (m_hasNetworkRequestsOnSuspended) {
+        setNetworkRequestsInProgress(true);
+        m_hasNetworkRequestsOnSuspended = false;
+    }
+}
+
+void WebPageProxy::isUserFacingChanged(bool isUserFacing)
+{
+#if PLATFORM(MACCATALYST)
+    if (!isUserFacing)
+        suspendAllMediaPlayback();
+    else
+        resumeAllMediaPlayback();
+#else
+    UNUSED_PARAM(isUserFacing);
+#endif
+}
+
+void WebPageProxy::isVisibleChanged(bool isVisible)
+{
+    UNUSED_PARAM(isVisible);
+}
+
 #if PLATFORM(IOS)
 void WebPageProxy::grantAccessToAssetServices()
 {

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (262857 => 262858)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2020-06-10 20:49:59 UTC (rev 262858)
@@ -1757,6 +1757,8 @@
 		CDBB49FD240D9A720017C292 /* RemoteAudioSessionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = CDBB49FC240D9A720017C292 /* RemoteAudioSessionConfiguration.h */; };
 		CDC2831D201BD79D00E6E745 /* WKFullscreenStackView.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC2831B201BD79D00E6E745 /* WKFullscreenStackView.h */; };
 		CDCA85C9132ABA4E00E961DF /* WKFullScreenWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCA85C7132ABA4E00E961DF /* WKFullScreenWindowController.h */; };
+		CDCDC99D248FE8DA00A69522 /* EndowmentStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCDC99B248FE8DA00A69522 /* EndowmentStateTracker.h */; };
+		CDCDC99E248FE8DA00A69522 /* EndowmentStateTracker.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDCDC99C248FE8DA00A69522 /* EndowmentStateTracker.mm */; };
 		CDE555322406EB8C008A3DDB /* RemoteLegacyCDMFactoryProxyMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE555292406B896008A3DDB /* RemoteLegacyCDMFactoryProxyMessageReceiver.cpp */; };
 		CDE555332406EB8C008A3DDB /* RemoteLegacyCDMProxyMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE5552A2406B896008A3DDB /* RemoteLegacyCDMProxyMessageReceiver.cpp */; };
 		CDE555342406EB8C008A3DDB /* RemoteLegacyCDMSessionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE5552E2406B897008A3DDB /* RemoteLegacyCDMSessionMessageReceiver.cpp */; };
@@ -5181,6 +5183,8 @@
 		CDCA85C6132ABA4E00E961DF /* WKFullScreenWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKFullScreenWindowController.mm; sourceTree = "<group>"; };
 		CDCA85C7132ABA4E00E961DF /* WKFullScreenWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKFullScreenWindowController.h; sourceTree = "<group>"; };
 		CDCA85D4132AC2B300E961DF /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+		CDCDC99B248FE8DA00A69522 /* EndowmentStateTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EndowmentStateTracker.h; sourceTree = "<group>"; };
+		CDCDC99C248FE8DA00A69522 /* EndowmentStateTracker.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = EndowmentStateTracker.mm; sourceTree = "<group>"; };
 		CDD5356F240DD34300F7B8C4 /* RemoteAudioSession.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = RemoteAudioSession.messages.in; sourceTree = "<group>"; };
 		CDD53570240DD4EF00F7B8C4 /* RemoteAudioSessionProxyManager.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = RemoteAudioSessionProxyManager.messages.in; sourceTree = "<group>"; };
 		CDD53571240DDE0600F7B8C4 /* RemoteAudioSessionProxyMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteAudioSessionProxyMessageReceiver.cpp; sourceTree = "<group>"; };
@@ -6987,6 +6991,8 @@
 				2D5875BD219B53150070B9AA /* EditableImageController.h */,
 				2D5875BB219B28A50070B9AA /* EditableImageController.messages.in */,
 				2D5875BE219B53150070B9AA /* EditableImageController.mm */,
+				CDCDC99B248FE8DA00A69522 /* EndowmentStateTracker.h */,
+				CDCDC99C248FE8DA00A69522 /* EndowmentStateTracker.mm */,
 				2DD45ADC1E5F8972006C355F /* InputViewUpdateDeferrer.h */,
 				2DD45ADD1E5F8972006C355F /* InputViewUpdateDeferrer.mm */,
 				0FCB4E3618BBE044000FCFC9 /* PageClientImplIOS.h */,
@@ -10794,6 +10800,7 @@
 				E105FE5418D7B9DE008F57A8 /* EditingRange.h in Headers */,
 				1AA41AB512C02EC4002BE67B /* EditorState.h in Headers */,
 				BC032DA810F437D10058C15A /* Encoder.h in Headers */,
+				CDCDC99D248FE8DA00A69522 /* EndowmentStateTracker.h in Headers */,
 				51B15A8513843A3900321AD8 /* EnvironmentUtilities.h in Headers */,
 				1AA575FB1496B52600A4EE06 /* EventDispatcher.h in Headers */,
 				57B8264823050C5100B72EB0 /* FidoService.h in Headers */,
@@ -12711,6 +12718,7 @@
 				1A64229912DD029200CAAE2C /* DrawingAreaMessageReceiver.cpp in Sources */,
 				1A64230812DD09EB00CAAE2C /* DrawingAreaProxyMessageReceiver.cpp in Sources */,
 				2D92A780212B6A7100F493FD /* Encoder.cpp in Sources */,
+				CDCDC99E248FE8DA00A69522 /* EndowmentStateTracker.mm in Sources */,
 				1AA576021496B97900A4EE06 /* EventDispatcherMessageReceiver.cpp in Sources */,
 				CDA93DB122F8BCF400490A69 /* FullscreenTouchSecheuristicParameters.cpp in Sources */,
 				2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */,

Modified: trunk/WebKitLibraries/ChangeLog (262857 => 262858)


--- trunk/WebKitLibraries/ChangeLog	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/WebKitLibraries/ChangeLog	2020-06-10 20:49:59 UTC (rev 262858)
@@ -1,3 +1,13 @@
+2020-06-10  Jer Noble  <[email protected]>
+
+        Catalyst WebKit apps continue to play audio after quitting
+        https://bugs.webkit.org/show_bug.cgi?id=212981
+        <rdar://problem/57089471>
+
+        Reviewed by Chris Dumez.
+
+        * WebKitPrivateFrameworkStubs/iOS/13/RunningBoardServices.framework/RunningBoardServices.tbd:
+
 2020-06-04  Jonathan Bedard  <[email protected]>
 
         tvOS: Remove arm64e references in .tbd files

Modified: trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/13/RunningBoardServices.framework/RunningBoardServices.tbd (262857 => 262858)


--- trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/13/RunningBoardServices.framework/RunningBoardServices.tbd	2020-06-10 20:49:16 UTC (rev 262857)
+++ trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/13/RunningBoardServices.framework/RunningBoardServices.tbd	2020-06-10 20:49:59 UTC (rev 262858)
@@ -6,5 +6,5 @@
 exports:
   - archs:           [ x86_64, arm64, arm64e ]
     symbols:         [ _RBSProcessTimeLimitationNone ]
-    objc-classes:    [ RBSAttribute, RBSDomainAttribute, RBSTarget, RBSAssertion, RBSProcessIdentifier, RBSProcessState, RBSProcessHandle ]
+    objc-classes:    [ RBSAttribute, RBSDomainAttribute, RBSTarget, RBSAssertion, RBSProcessIdentifier, RBSProcessState, RBSProcessHandle, RBSProcessStateDescriptor, RBSProcessPredicate, RBSProcessMonitor ]
 ...
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to