Modified: trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm (259609 => 259610)
--- trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm 2020-04-06 23:17:38 UTC (rev 259609)
+++ trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm 2020-04-06 23:25:58 UTC (rev 259610)
@@ -265,8 +265,51 @@
@end
+typedef void(^RBSAssertionInvalidationCallbackType)();
+
+@interface WKRBSAssertionDelegate : NSObject<RBSAssertionObserving>
+@property (copy) RBSAssertionInvalidationCallbackType invalidationCallback;
+@end
+
+@implementation WKRBSAssertionDelegate
+- (void)assertionWillInvalidate:(RBSAssertion *)assertion
+{
+ RELEASE_LOG(ProcessSuspension, "%p - WKRBSAssertionDelegate: assertionWillInvalidate", self);
+}
+
+- (void)assertion:(RBSAssertion *)assertion didInvalidateWithError:(NSError *)error
+{
+ RELEASE_LOG(ProcessSuspension, "%p - WKRBSAssertionDelegate: assertion was invalidated, error: %{public}@", error, self);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (_invalidationCallback)
+ _invalidationCallback();
+ });
+}
+@end
+
namespace WebKit {
+static NSString *runningBoardNameForAssertionType(ProcessAssertionType assertionType)
+{
+#if HAVE(RUNNINGBOARD_WEBKIT_ASSERTIONS)
+ switch (assertionType) {
+ case ProcessAssertionType::Suspended:
+ return @"Suspended";
+ case ProcessAssertionType::Background:
+ return @"Background";
+ case ProcessAssertionType::UnboundedNetworking:
+ return @"UnboundedNetworking";
+ case ProcessAssertionType::Foreground:
+ return @"Foreground";
+ case ProcessAssertionType::MediaPlayback:
+ return nil; // FIXME: Name to be defined in <rdar://problem/61263147>.
+ }
+#else
+ UNUSED_PARAM(assertionType);
+ return nil;
+#endif
+}
+
const BKSProcessAssertionFlags suspendedTabFlags = (BKSProcessAssertionAllowIdleSleep);
const BKSProcessAssertionFlags backgroundTabFlags = (BKSProcessAssertionPreventTaskSuspend);
const BKSProcessAssertionFlags foregroundTabFlags = (BKSProcessAssertionPreventTaskSuspend | BKSProcessAssertionWantsForegroundResourcePriority | BKSProcessAssertionPreventTaskThrottleDown);
@@ -301,43 +344,75 @@
ProcessAssertion::ProcessAssertion(pid_t pid, ASCIILiteral reason, ProcessAssertionType assertionType)
: m_assertionType(assertionType)
+ , m_pid(pid)
{
auto weakThis = makeWeakPtr(*this);
- BKSProcessAssertionAcquisitionHandler handler = ^(BOOL acquired) {
- if (!acquired) {
- RELEASE_LOG_ERROR(ProcessSuspension, " %p - ProcessAssertion() PID %d Unable to acquire assertion for process with PID %d", this, getpid(), pid);
+ NSString *nsReason = [NSString stringWithCString:reason.characters() encoding:NSASCIIStringEncoding];
+ NSString *runningBoardAssertionName = runningBoardNameForAssertionType(assertionType);
+ if (runningBoardAssertionName) {
+ RBSTarget *target = [RBSTarget targetWithPid:pid];
+ RBSDomainAttribute *domainAttribute = [RBSDomainAttribute attributeWithDomain:@"com.apple.webkit" name:runningBoardAssertionName];
+ m_rbsAssertion = adoptNS([[RBSAssertion alloc] initWithExplanation:nsReason target:target attributes:@[domainAttribute]]);
+
+ m_delegate = adoptNS([[WKRBSAssertionDelegate alloc] init]);
+ [m_rbsAssertion addObserver:m_delegate.get()];
+ m_delegate.get().invalidationCallback = ^{
+ RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() RBS %{public}@ assertion for process with PID %d was invalidated", this, runningBoardAssertionName, pid);
+ processAssertionWasInvalidated();
+ };
+
+ NSError *acquisitionError = nil;
+ if (![m_rbsAssertion acquireWithError:&acquisitionError]) {
+ RELEASE_LOG_ERROR(ProcessSuspension, "%p - ProcessAssertion: Failed to acquire RBS %{public}@ assertion '%{public}s' for process with PID %d, error: %{public}@", this, runningBoardAssertionName, reason.characters(), pid, acquisitionError);
dispatch_async(dispatch_get_main_queue(), ^{
if (weakThis)
processAssertionWasInvalidated();
});
- }
- };
- RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() PID %d acquiring assertion for process with PID %d, name '%s'", this, getpid(), pid, reason.characters());
-
- NSString *nsReason = [NSString stringWithCString:reason.characters() encoding:NSASCIIStringEncoding];
- m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForAssertionType(assertionType) reason:toBKSProcessAssertionReason(assertionType) name:nsReason withHandler:handler]);
+ } else
+ RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion: Successfully took RBS %{public}@ assertion '%{public}s' for process with PID %d", this, runningBoardAssertionName, reason.characters(), pid);
+ } else {
+ // Legacy code path.
+ BKSProcessAssertionAcquisitionHandler handler = ^(BOOL acquired) {
+ if (!acquired) {
+ RELEASE_LOG_ERROR(ProcessSuspension, " %p - ProcessAssertion() PID %d Unable to acquire BKS assertion for process with PID %d", this, getpid(), pid);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (weakThis)
+ processAssertionWasInvalidated();
+ });
+ }
+ };
+ RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() PID %d acquiring BKS assertion for process with PID %d, name '%s'", this, getpid(), pid, reason.characters());
- 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);
- if (weakThis)
- processAssertionWasInvalidated();
- });
- };
+ m_bksAssertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForAssertionType(assertionType) reason:toBKSProcessAssertionReason(assertionType) name:nsReason withHandler:handler]);
+
+ m_bksAssertion.get().invalidationHandler = ^() {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() BKS Process assertion for process with PID %d was invalidated", this, pid);
+ if (weakThis)
+ processAssertionWasInvalidated();
+ });
+ };
+ }
+ ASSERT(m_rbsAssertion || m_bksAssertion);
}
ProcessAssertion::~ProcessAssertion()
{
- m_assertion.get().invalidationHandler = nil;
+ RELEASE_LOG(ProcessSuspension, "%p - ~ProcessAssertion() Releasing process assertion for process with PID %d", this, m_pid);
- RELEASE_LOG(ProcessSuspension, "%p - ~ProcessAssertion() Releasing process assertion", this);
- [m_assertion invalidate];
+ if (m_rbsAssertion) {
+ [m_rbsAssertion removeObserver:m_delegate.get()];
+ [m_rbsAssertion invalidate];
+ } else {
+ m_bksAssertion.get().invalidationHandler = nil;
+ [m_bksAssertion invalidate];
+ }
}
void ProcessAssertion::processAssertionWasInvalidated()
{
ASSERT(RunLoop::isMain());
- RELEASE_LOG_ERROR(ProcessSuspension, "%p - ProcessAssertion::processAssertionWasInvalidated()", this);
+ RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion::processAssertionWasInvalidated() PID: %d", this, m_pid);
m_validity = Validity::No;
}