Diff
Modified: trunk/Source/WebKit/ChangeLog (244090 => 244091)
--- trunk/Source/WebKit/ChangeLog 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/ChangeLog 2019-04-09 19:37:28 UTC (rev 244091)
@@ -1,3 +1,45 @@
+2019-04-09 Jer Noble <jer.no...@apple.com>
+
+ [Cocoa] Awaken UIProcess if WebContent process is awakened from suspensions unexpectedly.
+ https://bugs.webkit.org/show_bug.cgi?id=196659
+
+ Reviewed by Chris Dumez.
+
+ * Platform/IPC/Connection.h:
+ (IPC::Connection::sendWithAsyncReply):
+ * Platform/spi/ios/AssertionServicesSPI.h:
+ * Shared/Cocoa/ProcessTaskStateObserver.h: Added.
+ (WebKit::ProcessTaskStateObserver::setClient):
+ (WebKit::ProcessTaskStateObserver::client):
+ (WebKit::ProcessTaskStateObserver::taskState const):
+ * Shared/Cocoa/ProcessTaskStateObserver.mm: Added.
+ (-[WKProcessTaskStateObserverDelegate process:taskStateDidChange:]):
+ (WebKit::toProcessTaskStateObserverTaskState):
+ (WebKit::ProcessTaskStateObserver::ProcessTaskStateObserver):
+ (WebKit::ProcessTaskStateObserver::~ProcessTaskStateObserver):
+ (WebKit::ProcessTaskStateObserver::setTaskState):
+ * UIProcess/Cocoa/WebProcessProxyCocoa.mm:
+ (WebKit::WebProcessProxy::processWasUnexpectedlyUnsuspended):
+ * UIProcess/ProcessAssertion.h:
+ * UIProcess/ProcessThrottler.cpp:
+ (WebKit::ProcessThrottler::updateAssertion):
+ * UIProcess/ProcessThrottler.h:
+ (WebKit::ProcessThrottler::shouldBeRunnable const):
+ * UIProcess/WebProcessProxy.h:
+ * UIProcess/WebProcessProxy.messages.in:
+ * UIProcess/ios/ProcessAssertionIOS.mm:
+ (WebKit::reasonForState):
+ (WebKit::toBKSProcessAssertionReason):
+ (WebKit::ProcessAssertion::ProcessAssertion):
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebProcess.cpp:
+ (WebKit::WebProcess::actualPrepareToSuspend):
+ (WebKit::WebProcess::cancelPrepareToSuspend):
+ (WebKit::WebProcess::processDidResume):
+ * WebProcess/WebProcess.h:
+ * WebProcess/cocoa/WebProcessCocoa.mm:
+ (WebKit::WebProcess::processTaskStateDidChange):
+
2019-04-09 Alex Christensen <achristen...@webkit.org>
Clicking "Go Back" from a safe browsing warning from an iframe should navigate the WKWebView back to the previous page
Modified: trunk/Source/WebKit/Platform/IPC/Connection.h (244090 => 244091)
--- trunk/Source/WebKit/Platform/IPC/Connection.h 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/Platform/IPC/Connection.h 2019-04-09 19:37:28 UTC (rev 244091)
@@ -177,7 +177,7 @@
void postConnectionDidCloseOnConnectionWorkQueue();
- template<typename T, typename... Args> void sendWithAsyncReply(T&& message, CompletionHandler<void(Args...)>&& args, uint64_t destinationID = 0);
+ template<typename T, typename C> void sendWithAsyncReply(T&& message, C&& completionHandler, uint64_t destinationID = 0);
template<typename T> bool send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { });
template<typename T> void sendWithReply(T&& message, uint64_t destinationID, FunctionDispatcher& replyDispatcher, Function<void(Optional<typename CodingType<typename T::Reply>::Type>)>&& replyHandler);
template<typename T> bool sendSync(T&& message, typename T::Reply&& reply, uint64_t destinationID, Seconds timeout = Seconds::infinity(), OptionSet<SendSyncOption> sendSyncOptions = { });
@@ -416,8 +416,8 @@
void addAsyncReplyHandler(Connection&, uint64_t, CompletionHandler<void(Decoder*)>&&);
CompletionHandler<void(Decoder*)> takeAsyncReplyHandler(Connection&, uint64_t);
-template<typename T, typename... Args>
-void Connection::sendWithAsyncReply(T&& message, CompletionHandler<void(Args...)>&& completionHandler, uint64_t destinationID)
+template<typename T, typename C>
+void Connection::sendWithAsyncReply(T&& message, C&& completionHandler, uint64_t destinationID)
{
COMPILE_ASSERT(!T::isSync, AsyncMessageExpected);
Modified: trunk/Source/WebKit/Platform/spi/ios/AssertionServicesSPI.h (244090 => 244091)
--- trunk/Source/WebKit/Platform/spi/ios/AssertionServicesSPI.h 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/Platform/spi/ios/AssertionServicesSPI.h 2019-04-09 19:37:28 UTC (rev 244091)
@@ -28,6 +28,7 @@
#if USE(APPLE_INTERNAL_SDK)
#import <AssertionServices/BKSApplicationStateMonitor.h>
+#import <AssertionServices/BKSProcess.h>
#import <AssertionServices/BKSProcessAssertion.h>
#else
@@ -68,6 +69,7 @@
typedef uint32_t BKSProcessAssertionFlags;
enum {
+ BKSProcessAssertionReasonFinishTask = 4,
BKSProcessAssertionReasonExtension = 13,
BKSProcessAssertionReasonFinishTaskUnbounded = 10004,
};
@@ -87,4 +89,27 @@
- (void)invalidate;
@end
+enum {
+ BKSProcessTaskStateNone,
+ BKSProcessTaskStateRunning,
+ BKSProcessTaskStateSuspended,
+};
+typedef uint32_t BKSProcessTaskState;
+
+@class BKSProcess;
+
+@protocol BKSProcessDelegate <NSObject>
+@optional
+- (void)process:(BKSProcess *)process taskStateDidChange:(BKSProcessTaskState)newState;
+@end
+
+@interface BKSProcess : NSObject
+@end
+
+@interface BKSProcess ()
++ (BKSProcess *)currentProcess;
+@property (nonatomic, readwrite, weak) id <BKSProcessDelegate> delegate;
+@property (nonatomic, readonly, assign) BKSProcessTaskState taskState;
+@end
+
#endif
Copied: trunk/Source/WebKit/Shared/Cocoa/ProcessTaskStateObserver.h (from rev 244090, trunk/Source/WebKit/UIProcess/ProcessAssertion.cpp) (0 => 244091)
--- trunk/Source/WebKit/Shared/Cocoa/ProcessTaskStateObserver.h (rev 0)
+++ trunk/Source/WebKit/Shared/Cocoa/ProcessTaskStateObserver.h 2019-04-09 19:37:28 UTC (rev 244091)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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)
+
+#include <wtf/RetainPtr.h>
+
+OBJC_CLASS WKProcessTaskStateObserverDelegate;
+OBJC_CLASS BKSProcess;
+
+namespace WebKit {
+
+class ProcessTaskStateObserver {
+public:
+ class Client;
+
+ ProcessTaskStateObserver();
+ explicit ProcessTaskStateObserver(Client&);
+ ~ProcessTaskStateObserver();
+
+ enum TaskState {
+ None,
+ Running,
+ Suspended,
+ };
+
+ class Client {
+ public:
+ virtual ~Client() = default;
+ virtual void processTaskStateDidChange(TaskState) = 0;
+ };
+
+ void setClient(Client& client) { m_client = &client; }
+ Client* client() { return m_client; }
+
+ TaskState taskState() const { return m_taskState; }
+
+private:
+ void setTaskState(TaskState);
+
+ Client* m_client { nullptr };
+ TaskState m_taskState { None };
+ RetainPtr<BKSProcess> m_process;
+ RetainPtr<WKProcessTaskStateObserverDelegate> m_delegate;
+};
+
+}
+
+#endif // PLATFORM(IOS_FAMILY)
Added: trunk/Source/WebKit/Shared/Cocoa/ProcessTaskStateObserver.mm (0 => 244091)
--- trunk/Source/WebKit/Shared/Cocoa/ProcessTaskStateObserver.mm (rev 0)
+++ trunk/Source/WebKit/Shared/Cocoa/ProcessTaskStateObserver.mm 2019-04-09 19:37:28 UTC (rev 244091)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 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 "ProcessTaskStateObserver.h"
+
+#if PLATFORM(IOS_FAMILY)
+
+#import "AssertionServicesSPI.h"
+#import "Logging.h"
+#import <wtf/Function.h>
+#import <wtf/SoftLinking.h>
+
+SOFT_LINK_PRIVATE_FRAMEWORK(AssertionServices);
+SOFT_LINK_CLASS(AssertionServices, BKSProcess);
+
+typedef void(^TaskStateChangedCallbackType)(BKSProcessTaskState);
+
+@interface WKProcessTaskStateObserverDelegate : NSObject<BKSProcessDelegate>
+@property (copy) TaskStateChangedCallbackType taskStateChangedCallback;
+@end
+
+@implementation WKProcessTaskStateObserverDelegate
+- (void)process:(BKSProcess *)process taskStateDidChange:(BKSProcessTaskState)newState
+{
+ RELEASE_LOG(ProcessSuspension, "%p -[WKProcessTaskStateObserverDelegate process:taskStateDidChange:], process(%p), newState(%d)", self, process, (int)newState);
+
+ if (self.taskStateChangedCallback)
+ self.taskStateChangedCallback(newState);
+}
+@end
+
+namespace WebKit {
+
+static ProcessTaskStateObserver::TaskState toProcessTaskStateObserverTaskState(BKSProcessTaskState state)
+{
+ static_assert(static_cast<uint32_t>(BKSProcessTaskStateNone) == static_cast<uint32_t>(ProcessTaskStateObserver::None), "BKSProcessTaskState != ProcessTaskStateObserver::TaskState");
+ static_assert(static_cast<uint32_t>(BKSProcessTaskStateRunning) == static_cast<uint32_t>(ProcessTaskStateObserver::Running), "BKSProcessTaskState != ProcessTaskStateObserver::TaskState");
+ static_assert(static_cast<uint32_t>(BKSProcessTaskStateSuspended) == static_cast<uint32_t>(ProcessTaskStateObserver::Suspended), "BKSProcessTaskState != ProcessTaskStateObserver::TaskState");
+ return static_cast<ProcessTaskStateObserver::TaskState>(state);
+}
+
+ProcessTaskStateObserver::ProcessTaskStateObserver()
+ : m_process([getBKSProcessClass() currentProcess])
+ , m_delegate(adoptNS([[WKProcessTaskStateObserverDelegate alloc] init]))
+{
+ RELEASE_LOG(ProcessSuspension, "%p - ProcessTaskStateObserver::ProcessTaskStateObserver(), m_process(%p)", this, m_process.get());
+ m_delegate.get().taskStateChangedCallback = [this] (BKSProcessTaskState state) {
+ setTaskState(toProcessTaskStateObserverTaskState(state));
+ };
+ m_process.get().delegate = m_delegate.get();
+}
+
+ProcessTaskStateObserver::ProcessTaskStateObserver(Client& client)
+ : ProcessTaskStateObserver()
+{
+ setClient(client);
+}
+
+ProcessTaskStateObserver::~ProcessTaskStateObserver()
+{
+ m_delegate.get().taskStateChangedCallback = nil;
+}
+
+void ProcessTaskStateObserver::setTaskState(TaskState state)
+{
+ if (m_taskState == state)
+ return;
+
+ m_taskState = state;
+ if (m_client)
+ m_client->processTaskStateDidChange(state);
+}
+
+}
+
+#endif // PLATFORM(IOS_FAMILY)
+
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm 2019-04-09 19:37:28 UTC (rev 244091)
@@ -41,6 +41,8 @@
namespace WebKit {
+static const Seconds unexpectedActivityDuration = 10_s;
+
const HashSet<String>& WebProcessProxy::platformPathsWithAssumedReadAccess()
{
static NeverDestroyed<HashSet<String>> platformPathsWithAssumedReadAccess(std::initializer_list<String> {
@@ -187,4 +189,25 @@
}
#endif
+#if PLATFORM(IOS_FAMILY)
+void WebProcessProxy::processWasUnexpectedlyUnsuspended(CompletionHandler<void()>&& completion)
+{
+ if (m_throttler.shouldBeRunnable()) {
+ // The process becoming unsuspended was not unexpected; it likely was notified of its running state
+ // before receiving a procsessDidResume() message from the UIProcess.
+ completion();
+ return;
+ }
+
+ // The WebProcess was awakened by something other than the UIProcess. Take out an assertion for a
+ // limited duration to allow whatever task needs to be accomplished time to complete.
+ RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::processWasUnexpectedlyUnsuspended()", this);
+ auto backgroundActivityTimeoutHandler = [activityToken = m_throttler.backgroundActivityToken(), weakThis = makeWeakPtr(this)] {
+ RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::processWasUnexpectedlyUnsuspended() - lambda, background activity timed out", weakThis.get());
+ };
+ m_unexpectedActivityTimer = std::make_unique<WebCore::DeferrableOneShotTimer>(WTFMove(backgroundActivityTimeoutHandler), unexpectedActivityDuration);
+ completion();
}
+#endif
+
+}
Modified: trunk/Source/WebKit/UIProcess/ProcessAssertion.cpp (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/ProcessAssertion.cpp 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/ProcessAssertion.cpp 2019-04-09 19:37:28 UTC (rev 244091)
@@ -35,6 +35,11 @@
{
}
+ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState, AssertionReason)
+ : m_assertionState(assertionState)
+{
+}
+
ProcessAssertion::~ProcessAssertion() = default;
void ProcessAssertion::setState(AssertionState assertionState)
Modified: trunk/Source/WebKit/UIProcess/ProcessAssertion.h (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/ProcessAssertion.h 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/ProcessAssertion.h 2019-04-09 19:37:28 UTC (rev 244091)
@@ -45,9 +45,15 @@
Suspended,
Background,
UnboundedNetworking,
- Foreground
+ Foreground,
};
+enum class AssertionReason {
+ Extension,
+ FinishTask,
+ FinishTaskUnbounded,
+};
+
class ProcessAssertion : public CanMakeWeakPtr<ProcessAssertion> {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -58,6 +64,7 @@
};
ProcessAssertion(ProcessID, const String& reason, AssertionState);
+ ProcessAssertion(ProcessID, const String& reason, AssertionState, AssertionReason);
virtual ~ProcessAssertion();
void setClient(Client& client) { m_client = &client; }
Modified: trunk/Source/WebKit/UIProcess/ProcessThrottler.cpp (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/ProcessThrottler.cpp 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/ProcessThrottler.cpp 2019-04-09 19:37:28 UTC (rev 244091)
@@ -68,7 +68,7 @@
void ProcessThrottler::updateAssertion()
{
- bool shouldBeRunnable = m_foregroundCounter.value() || m_backgroundCounter.value();
+ bool shouldBeRunnable = this->shouldBeRunnable();
// If the process is currently runnable but will be suspended then first give it a chance to complete what it was doing
// and clean up - move it to the background and send it a message to notify. Schedule a timeout so it can't stay running
Modified: trunk/Source/WebKit/UIProcess/ProcessThrottler.h (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/ProcessThrottler.h 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/ProcessThrottler.h 2019-04-09 19:37:28 UTC (rev 244091)
@@ -60,6 +60,7 @@
void didConnectToProcess(ProcessID);
void processReadyToSuspend();
void didCancelProcessSuspension();
+ bool shouldBeRunnable() const { return m_foregroundCounter.value() || m_backgroundCounter.value(); }
private:
AssertionState assertionState();
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2019-04-09 19:37:28 UTC (rev 244091)
@@ -57,6 +57,7 @@
}
namespace WebCore {
+class DeferrableOneShotTimer;
class ResourceRequest;
struct PluginInfo;
struct SecurityOriginData;
@@ -301,6 +302,10 @@
LayerHostingContextID contextIDForVisibilityPropagation() { return m_contextIDForVisibilityPropagation; }
#endif
+#if PLATFORM(IOS_FAMILY)
+ void processWasUnexpectedlyUnsuspended(CompletionHandler<void()>&&);
+#endif
+
protected:
static uint64_t generatePageID();
WebProcessProxy(WebProcessPool&, WebsiteDataStore*, IsPrewarmed);
@@ -448,6 +453,7 @@
ForegroundWebProcessToken m_foregroundToken;
BackgroundWebProcessToken m_backgroundToken;
bool m_hasSentMessageToUnblockAccessibilityServer { false };
+ std::unique_ptr<WebCore::DeferrableOneShotTimer> m_unexpectedActivityTimer;
#endif
#if HAVE(VISIBILITY_PROPAGATION_VIEW)
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in 2019-04-09 19:37:28 UTC (rev 244091)
@@ -83,4 +83,8 @@
#if HAVE(VISIBILITY_PROPAGATION_VIEW)
DidCreateContextForVisibilityPropagation(WebKit::LayerHostingContextID contextID);
#endif
+
+#if PLATFORM(IOS_FAMILY)
+ ProcessWasUnexpectedlyUnsuspended() -> () Async
+#endif
}
Modified: trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm (244090 => 244091)
--- trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm 2019-04-09 19:37:28 UTC (rev 244091)
@@ -146,19 +146,36 @@
}
}
-static BKSProcessAssertionReason reasonForState(AssertionState assertionState)
+static AssertionReason reasonForState(AssertionState assertionState)
{
switch (assertionState) {
case AssertionState::UnboundedNetworking:
- return BKSProcessAssertionReasonFinishTaskUnbounded;
+ return AssertionReason::FinishTaskUnbounded;
case AssertionState::Suspended:
case AssertionState::Background:
case AssertionState::Foreground:
+ return AssertionReason::Extension;
+ }
+}
+
+static BKSProcessAssertionReason toBKSProcessAssertionReason(AssertionReason reason)
+{
+ switch (reason) {
+ case AssertionReason::Extension:
return BKSProcessAssertionReasonExtension;
+ case AssertionReason::FinishTask:
+ return BKSProcessAssertionReasonFinishTask;
+ case AssertionReason::FinishTaskUnbounded:
+ return BKSProcessAssertionReasonFinishTaskUnbounded;
}
}
ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState)
+ : ProcessAssertion(pid, name, assertionState, reasonForState(assertionState))
+{
+}
+
+ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState, AssertionReason assertionReason)
: m_assertionState(assertionState)
{
auto weakThis = makeWeakPtr(*this);
@@ -173,7 +190,7 @@
};
RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() PID %d acquiring assertion for process with PID %d, name '%s'", this, getpid(), pid, name.utf8().data());
- m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason:reasonForState(assertionState) name:(NSString *)name withHandler:handler]);
+ m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason:toBKSProcessAssertionReason(assertionReason) name:(NSString *)name withHandler:handler]);
m_assertion.get().invalidationHandler = ^() {
dispatch_async(dispatch_get_main_queue(), ^{
RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() Process assertion for process with PID %d was invalidated", this, pid);
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (244090 => 244091)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-04-09 19:37:28 UTC (rev 244091)
@@ -1561,6 +1561,8 @@
CD0C6831201FD10100A59409 /* WKFullScreenViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = CD0C682F201FD10100A59409 /* WKFullScreenViewController.h */; };
CD19A26E1A13E834008D650E /* WebDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19A26A1A13E821008D650E /* WebDiagnosticLoggingClient.h */; };
CD19D2EA2046406F0017074A /* FullscreenTouchSecheuristic.h in Headers */ = {isa = PBXBuildFile; fileRef = CD19D2E82046406F0017074A /* FullscreenTouchSecheuristic.h */; };
+ CD2865EE2255562000606AC7 /* ProcessTaskStateObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = CD2865EC2255562000606AC7 /* ProcessTaskStateObserver.h */; };
+ CD2865EF2255562000606AC7 /* ProcessTaskStateObserver.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD2865ED2255562000606AC7 /* ProcessTaskStateObserver.mm */; };
CD491B081E70D05F00009066 /* UserMediaCaptureManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CD491B061E70D05F00009066 /* UserMediaCaptureManager.h */; };
CD491B0D1E732E4D00009066 /* UserMediaCaptureManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD491B0B1E732E4D00009066 /* UserMediaCaptureManagerMessageReceiver.cpp */; };
CD491B0E1E732E4D00009066 /* UserMediaCaptureManagerMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = CD491B0C1E732E4D00009066 /* UserMediaCaptureManagerMessages.h */; };
@@ -4417,6 +4419,8 @@
CD19A26A1A13E821008D650E /* WebDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDiagnosticLoggingClient.h; sourceTree = "<group>"; };
CD19D2E82046406F0017074A /* FullscreenTouchSecheuristic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FullscreenTouchSecheuristic.h; path = ios/fullscreen/FullscreenTouchSecheuristic.h; sourceTree = "<group>"; };
CD19D2E92046406F0017074A /* FullscreenTouchSecheuristic.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FullscreenTouchSecheuristic.cpp; path = ios/fullscreen/FullscreenTouchSecheuristic.cpp; sourceTree = "<group>"; };
+ CD2865EC2255562000606AC7 /* ProcessTaskStateObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProcessTaskStateObserver.h; sourceTree = "<group>"; };
+ CD2865ED2255562000606AC7 /* ProcessTaskStateObserver.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ProcessTaskStateObserver.mm; sourceTree = "<group>"; };
CD491B051E70D05F00009066 /* UserMediaCaptureManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaCaptureManager.cpp; sourceTree = "<group>"; };
CD491B061E70D05F00009066 /* UserMediaCaptureManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaCaptureManager.h; sourceTree = "<group>"; };
CD491B0A1E732D1200009066 /* UserMediaCaptureManager.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = UserMediaCaptureManager.messages.in; sourceTree = "<group>"; };
@@ -6313,6 +6317,8 @@
C55F916C1C595E440029E92D /* DataDetectionResult.h */,
C55F916D1C595E440029E92D /* DataDetectionResult.mm */,
2D1087621D2C641B00B85F82 /* LoadParametersCocoa.mm */,
+ CD2865EC2255562000606AC7 /* ProcessTaskStateObserver.h */,
+ CD2865ED2255562000606AC7 /* ProcessTaskStateObserver.mm */,
CD4B4D9A1E765E0000D27092 /* SharedRingBufferStorage.cpp */,
CD4B4D9B1E765E0000D27092 /* SharedRingBufferStorage.h */,
1AB1F78E1D1B34A6007C9BD1 /* WebCoreArgumentCodersCocoa.mm */,
@@ -9397,6 +9403,7 @@
E1CC1B9012D7EADF00625838 /* PrintInfo.h in Headers */,
86F9536518FF58F5001DB2EF /* ProcessAssertion.h in Headers */,
BC1A7C581136E19C00FB7167 /* ProcessLauncher.h in Headers */,
+ CD2865EE2255562000606AC7 /* ProcessTaskStateObserver.h in Headers */,
463FD4821EB94EC000A2982C /* ProcessTerminationReason.h in Headers */,
86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */,
83048AE61ACA45DC0082C832 /* ProcessThrottlerClient.h in Headers */,
@@ -10972,6 +10979,7 @@
BC82844D16B5081C00A278FE /* PluginServiceEntryPoint.mm in Sources */,
2D91344D212CF9F000128AFD /* PluginView.cpp in Sources */,
2D54C31B212F4DA60049C174 /* ProcessLauncher.cpp in Sources */,
+ CD2865EF2255562000606AC7 /* ProcessTaskStateObserver.mm in Sources */,
2D72A1FA212BF46E00517A20 /* RemoteLayerTreeDrawingArea.mm in Sources */,
0FF24A2D1879E4BC003ABF0C /* RemoteLayerTreeDrawingAreaProxyMessageReceiver.cpp in Sources */,
2DC18FB4218A6E9E0025A88D /* RemoteLayerTreeViews.mm in Sources */,
Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (244090 => 244091)
--- trunk/Source/WebKit/WebProcess/WebProcess.cpp 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp 2019-04-09 19:37:28 UTC (rev 244091)
@@ -1450,6 +1450,7 @@
void WebProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
{
SetForScope<bool> suspensionScope(m_isSuspending, true);
+ m_processIsSuspended = true;
#if ENABLE(VIDEO)
suspendAllMediaBuffering();
@@ -1511,6 +1512,9 @@
void WebProcess::cancelPrepareToSuspend()
{
RELEASE_LOG(ProcessSuspension, "%p - WebProcess::cancelPrepareToSuspend()", this);
+
+ m_processIsSuspended = false;
+
unfreezeAllLayerTrees();
#if PLATFORM(IOS_FAMILY)
@@ -1584,6 +1588,8 @@
{
RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processDidResume()", this);
+ m_processIsSuspended = false;
+
cancelMarkAllLayersVolatile();
unfreezeAllLayerTrees();
Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (244090 => 244091)
--- trunk/Source/WebKit/WebProcess/WebProcess.h 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h 2019-04-09 19:37:28 UTC (rev 244091)
@@ -57,6 +57,10 @@
#include <wtf/MachSendRight.h>
#endif
+#if PLATFORM(IOS_FAMILY)
+#include "ProcessTaskStateObserver.h"
+#endif
+
namespace API {
class Object;
}
@@ -116,7 +120,12 @@
class LayerHostingContext;
#endif
-class WebProcess : public AuxiliaryProcess {
+class WebProcess
+ : public AuxiliaryProcess
+#if PLATFORM(IOS_FAMILY)
+ , ProcessTaskStateObserver::Client
+#endif
+{
public:
static WebProcess& singleton();
static constexpr ProcessType processType = ProcessType::WebContent;
@@ -429,6 +438,7 @@
#endif
#if PLATFORM(IOS_FAMILY)
+ void processTaskStateDidChange(ProcessTaskStateObserver::TaskState) final;
bool shouldFreezeOnSuspension() const;
void updateFreezerStatus();
#endif
@@ -494,6 +504,8 @@
bool m_hasRichContentServices { false };
#endif
+ bool m_processIsSuspended { false };
+
HashSet<uint64_t> m_pagesInWindows;
WebCore::Timer m_nonVisibleProcessCleanupTimer;
@@ -501,6 +513,7 @@
#if PLATFORM(IOS_FAMILY)
std::unique_ptr<WebSQLiteDatabaseTracker> m_webSQLiteDatabaseTracker;
+ ProcessTaskStateObserver m_taskStateObserver { *this };
#endif
#if HAVE(VISIBILITY_PROPAGATION_VIEW)
std::unique_ptr<LayerHostingContext> m_contextForVisibilityPropagation;
Modified: trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm (244090 => 244091)
--- trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm 2019-04-09 19:32:08 UTC (rev 244090)
+++ trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm 2019-04-09 19:37:28 UTC (rev 244091)
@@ -31,6 +31,7 @@
#import "LogInitialization.h"
#import "Logging.h"
#import "ObjCObjectGraph.h"
+#import "ProcessAssertion.h"
#import "SandboxExtension.h"
#import "SandboxInitializationParameters.h"
#import "WKAPICast.h"
@@ -287,6 +288,31 @@
#endif // PLATFORM(MAC)
}
+#if PLATFORM(IOS_FAMILY)
+void WebProcess::processTaskStateDidChange(ProcessTaskStateObserver::TaskState taskState)
+{
+ RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processTaskStateDidChange() - taskState(%d)", this, taskState);
+ if (taskState == ProcessTaskStateObserver::None)
+ return;
+
+ if (taskState == ProcessTaskStateObserver::Suspended) {
+ if (m_processIsSuspended)
+ return;
+
+ RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processTaskStateChanged() - unexpectedly entered Suspended state", this);
+ return;
+ }
+
+ if (!m_processIsSuspended)
+ return;
+
+ // We were awakened from suspension unexpectedly. Notify the WebProcessProxy, but take a process assertion on our parent PID
+ // to ensure that it too is awakened.
+ auto uiProcessAssertion = std::make_unique<ProcessAssertion>(parentProcessConnection()->remoteProcessID(), "Unexpectedly resumed", AssertionState::Background, AssertionReason::FinishTask);
+ parentProcessConnection()->sendWithAsyncReply(Messages::WebProcessProxy::ProcessWasUnexpectedlyUnsuspended(), [uiProcessAssertion = WTFMove(uiProcessAssertion)] { });
+}
+#endif
+
static void registerWithAccessibility()
{
#if USE(APPKIT)