Take additional process assertion while downloading.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Feb 2019 01:27:23 +0000 (01:27 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Feb 2019 01:27:23 +0000 (01:27 +0000)
<rdar://problem/47741356> and https://bugs.webkit.org/show_bug.cgi?id=194239

Reviewed by Chris Dumez.

When the first download starts, grab this new assertion.
When the last download ends, release it.

* Configurations/Network-iOS.entitlements:

* NetworkProcess/Downloads/DownloadManager.cpp:
(WebKit::DownloadManager::dataTaskBecameDownloadTask):
(WebKit::DownloadManager::downloadFinished):
* NetworkProcess/Downloads/DownloadManager.h:

* Platform/spi/ios/AssertionServicesSPI.h:

* UIProcess/ProcessAssertion.cpp:
(WebKit::ProcessAssertion::ProcessAssertion):
* UIProcess/ProcessAssertion.h:
(WebKit::ProcessAssertion::ProcessAssertion):

* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::didSetAssertionState):

* UIProcess/ios/ProcessAssertionIOS.mm:
(WebKit::flagsForState):
(WebKit::reasonForState):
(WebKit::ProcessAssertion::ProcessAssertion):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240954 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/Configurations/Network-iOS.entitlements
Source/WebKit/NetworkProcess/Downloads/DownloadManager.cpp
Source/WebKit/NetworkProcess/Downloads/DownloadManager.h
Source/WebKit/Platform/spi/ios/AssertionServicesSPI.h
Source/WebKit/UIProcess/ProcessAssertion.cpp
Source/WebKit/UIProcess/ProcessAssertion.h
Source/WebKit/UIProcess/WebProcessProxy.cpp
Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm

index 8c3f6f8..23fe1d3 100644 (file)
@@ -1,3 +1,35 @@
+2019-02-04  Brady Eidson  <beidson@apple.com>
+
+        Take additional process assertion while downloading.
+        <rdar://problem/47741356> and https://bugs.webkit.org/show_bug.cgi?id=194239
+
+        Reviewed by Chris Dumez.
+
+        When the first download starts, grab this new assertion.
+        When the last download ends, release it.
+
+        * Configurations/Network-iOS.entitlements:
+
+        * NetworkProcess/Downloads/DownloadManager.cpp:
+        (WebKit::DownloadManager::dataTaskBecameDownloadTask):
+        (WebKit::DownloadManager::downloadFinished):
+        * NetworkProcess/Downloads/DownloadManager.h:
+
+        * Platform/spi/ios/AssertionServicesSPI.h:
+
+        * UIProcess/ProcessAssertion.cpp:
+        (WebKit::ProcessAssertion::ProcessAssertion):
+        * UIProcess/ProcessAssertion.h:
+        (WebKit::ProcessAssertion::ProcessAssertion):
+
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::didSetAssertionState):
+
+        * UIProcess/ios/ProcessAssertionIOS.mm:
+        (WebKit::flagsForState):
+        (WebKit::reasonForState):
+        (WebKit::ProcessAssertion::ProcessAssertion):
+
 2019-02-04  Said Abou-Hallawa  <said@apple.com>
 
         [CG] Enable setAdditionalSupportedImageTypes for WK1
index cc96c82..5f74903 100644 (file)
@@ -16,6 +16,8 @@
        <array>
                <string>com.apple.WebKit.Networking</string>
        </array>
+       <key>com.apple.multitasking.systemappassertions</key>
+       <true/>
        <key>com.apple.private.memorystatus</key>
        <true/>
 </dict>
index 41cec37..da377b8 100644 (file)
@@ -71,6 +71,13 @@ void DownloadManager::dataTaskBecameDownloadTask(DownloadID downloadID, std::uni
     ASSERT(!m_downloads.contains(downloadID));
     m_downloadsAfterDestinationDecided.remove(downloadID);
     m_downloads.add(downloadID, WTFMove(download));
+
+#if ENABLE(TAKE_DOWNLOAD_ASSERTION)
+    if (m_downloads.size() == 1) {
+        ASSERT(!m_downloadAssertion);
+        m_downloadAssertion = std::make_unique<ProcessAssertion>(getpid(), "WebKit downloads"_s, AssertionState::Download);
+    }
+#endif
 }
 
 void DownloadManager::continueWillSendRequest(DownloadID downloadID, WebCore::ResourceRequest&& request)
@@ -172,6 +179,13 @@ void DownloadManager::downloadFinished(Download* download)
 {
     ASSERT(m_downloads.contains(download->downloadID()));
     m_downloads.remove(download->downloadID());
+    
+#if ENABLE(TAKE_DOWNLOAD_ASSERTION)
+    if (m_downloads.isEmpty()) {
+        ASSERT(m_downloadAssertion);
+        m_downloadAssertion = nullptr;
+    }
+#endif
 }
 
 void DownloadManager::didCreateDownload()
index 8a0ed49..ffe1ad0 100644 (file)
@@ -28,6 +28,7 @@
 #include "DownloadID.h"
 #include "NetworkDataTask.h"
 #include "PendingDownload.h"
+#include "ProcessAssertion.h"
 #include "SandboxExtension.h"
 #include <WebCore/NotImplemented.h>
 #include <wtf/Forward.h>
@@ -113,6 +114,10 @@ private:
     HashMap<DownloadID, std::pair<RefPtr<NetworkDataTask>, ResponseCompletionHandler>> m_downloadsWaitingForDestination;
     HashMap<DownloadID, RefPtr<NetworkDataTask>> m_downloadsAfterDestinationDecided;
     HashMap<DownloadID, std::unique_ptr<Download>> m_downloads;
+
+#if ENABLE(TAKE_DOWNLOAD_ASSERTION)
+    std::unique_ptr<ProcessAssertion> m_downloadAssertion;
+#endif
 };
 
 } // namespace WebKit
index e2fcea0..fae2a11 100644 (file)
@@ -69,6 +69,7 @@ typedef uint32_t BKSProcessAssertionFlags;
 
 enum {
     BKSProcessAssertionReasonExtension = 13,
+    BKSProcessAssertionReasonFinishTaskUnbounded = 10004,
 };
 typedef uint32_t BKSProcessAssertionReason;
 
index 54c12dd..a25df2b 100644 (file)
@@ -35,6 +35,11 @@ ProcessAssertion::ProcessAssertion(ProcessID, AssertionState assertionState, Fun
 {
 }
 
+ProcessAssertion::ProcessAssertion(ProcessID, const String&, AssertionState assertionState, Function<void()>&&)
+    : m_assertionState(assertionState)
+{
+}
+
 ProcessAssertion::~ProcessAssertion()
 {
 }
index b9b1e16..e9b13c4 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <wtf/Function.h>
 #include <wtf/ProcessID.h>
+#include <wtf/text/WTFString.h>
 
 #if !OS(WINDOWS)
 #include <unistd.h>
@@ -44,6 +45,7 @@ namespace WebKit {
 enum class AssertionState {
     Suspended,
     Background,
+    Download,
     Foreground
 };
 
@@ -60,6 +62,7 @@ class ProcessAssertion
 {
 public:
     ProcessAssertion(ProcessID, AssertionState, Function<void()>&& invalidationCallback = { });
+    ProcessAssertion(ProcessID, const String& reason, AssertionState, Function<void()>&& invalidationCallback = { });
     virtual ~ProcessAssertion();
 
     virtual void setClient(ProcessAssertionClient& client) { m_client = &client; }
index 86d56b4..b2da3bb 100644 (file)
@@ -1077,6 +1077,9 @@ void WebProcessProxy::didSetAssertionState(AssertionState state)
         for (auto& page : m_pageMap.values())
             page->processWillBecomeForeground();
         break;
+    
+    case AssertionState::Download:
+        ASSERT_NOT_REACHED();
     }
 
     ASSERT(!m_backgroundToken || !m_foregroundToken);
index 70d7429..408995d 100644 (file)
@@ -153,20 +153,38 @@ static BKSProcessAssertionFlags flagsForState(AssertionState assertionState)
     case AssertionState::Suspended:
         return suspendedTabFlags;
     case AssertionState::Background:
+    case AssertionState::Download:
         return backgroundTabFlags;
     case AssertionState::Foreground:
         return foregroundTabFlags;
     }
 }
 
+static BKSProcessAssertionReason reasonForState(AssertionState assertionState)
+{
+    switch (assertionState) {
+    case AssertionState::Download:
+        return BKSProcessAssertionReasonFinishTaskUnbounded;
+    case AssertionState::Suspended:
+    case AssertionState::Background:
+    case AssertionState::Foreground:
+        return BKSProcessAssertionReasonExtension;
+    }
+}
+
 ProcessAssertion::ProcessAssertion(pid_t pid, AssertionState assertionState, Function<void()>&& invalidationCallback)
+    : ProcessAssertion(pid, "Web content visibility"_s, assertionState, WTFMove(invalidationCallback))
+{
+}
+
+ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState, Function<void()>&& invalidationCallback)
     : m_invalidationCallback(WTFMove(invalidationCallback))
     , m_assertionState(assertionState)
 {
     auto weakThis = makeWeakPtr(*this);
     BKSProcessAssertionAcquisitionHandler handler = ^(BOOL acquired) {
         if (!acquired) {
-            RELEASE_LOG_ERROR(ProcessSuspension, " %p - ProcessAssertion() Unable to acquire assertion for process with PID %d", this, pid);
+            RELEASE_LOG_ERROR(ProcessSuspension, " %p - ProcessAssertion() PID %d Unable to acquire assertion for process with PID %d", this, getpid(), pid);
             ASSERT_NOT_REACHED();
             dispatch_async(dispatch_get_main_queue(), ^{
                 if (weakThis)
@@ -174,8 +192,9 @@ ProcessAssertion::ProcessAssertion(pid_t pid, AssertionState assertionState, Fun
             });
         }
     };
-    RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() Acquiring assertion for process with PID %d", this, pid);
-    m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason:BKSProcessAssertionReasonExtension name:@"Web content visibility" withHandler:handler]);
+    RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() PID %d acquiring assertion for process with PID %d", this, getpid(), pid);
+    
+    m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason:reasonForState(assertionState) 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);