Bug 1373888 - part4 : request non-display wake lock for audio playing. draft
authorAlastor Wu <alwu@mozilla.com>
Tue, 29 Aug 2017 15:25:34 +0800
changeset 654753 c60c73749a84f65e1729db8fef2c37f0168949fa
parent 654647 70fd76bbef317ab3e502377db33832ab705c30d4
child 654754 0e9ddbb58cbab18e4d54b2f5de89359f8b37c6ce
push id76666
push useralwu@mozilla.com
push dateTue, 29 Aug 2017 07:28:48 +0000
bugs1373888
milestone57.0a1
Bug 1373888 - part4 : request non-display wake lock for audio playing. According to [1], kIOPMAssertionTypeNoDisplaySleep prevents display sleep and kIOPMAssertionTypeNoIdleSleep prevents idle sleep. We should use kIOPMAssertionTypeNoIdleSleep for audio playing, because it won't need to block the display. [1] https://developer.apple.com/library/content/qa/qa1340/_index.html --- On Windows, ES_DISPLAY_REQUIRED forces display on, and ES_SYSTEM_REQUIRED forces system on working state [2]. [2] https://msdn.microsoft.com/zh-tw/library/windows/desktop/aa373208(v=vs.85).aspx MozReview-Commit-ID: Izs29PdzQOW
widget/cocoa/nsAppShell.mm
widget/windows/nsAppShell.cpp
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -52,47 +52,56 @@ using namespace mozilla::widget;
 
 class MacWakeLockListener final : public nsIDOMMozWakeLockListener {
 public:
   NS_DECL_ISUPPORTS;
 
 private:
   ~MacWakeLockListener() {}
 
-  IOPMAssertionID mAssertionID = kIOPMNullAssertionID;
+  IOPMAssertionID mAssertionNoDisplaySleepID = kIOPMNullAssertionID;
+  IOPMAssertionID mAssertionNoIdleSleepID = kIOPMNullAssertionID;
 
   NS_IMETHOD Callback(const nsAString& aTopic, const nsAString& aState) override {
     if (!aTopic.EqualsASCII("screen") &&
         !aTopic.EqualsASCII("audio-playing") &&
         !aTopic.EqualsASCII("video-playing")) {
       return NS_OK;
     }
+
+    bool shouldKeepDisplayOn = aTopic.EqualsASCII("screen") ||
+                               aTopic.EqualsASCII("video-playing");
+    CFStringRef assertionType = shouldKeepDisplayOn ?
+      kIOPMAssertionTypeNoDisplaySleep : kIOPMAssertionTypeNoIdleSleep;
+    IOPMAssertionID& assertionId = shouldKeepDisplayOn ?
+      mAssertionNoDisplaySleepID : mAssertionNoIdleSleepID;
+
     // Note the wake lock code ensures that we're not sent duplicate
     // "locked-foreground" notifications when multiple wake locks are held.
     if (aState.EqualsASCII("locked-foreground")) {
       // Prevent screen saver.
       CFStringRef cf_topic =
         ::CFStringCreateWithCharacters(kCFAllocatorDefault,
                                        reinterpret_cast<const UniChar*>
                                          (aTopic.Data()),
                                        aTopic.Length());
       IOReturn success =
-        ::IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
+        ::IOPMAssertionCreateWithName(assertionType,
                                       kIOPMAssertionLevelOn,
                                       cf_topic,
-                                      &mAssertionID);
+                                      &assertionId);
       CFRelease(cf_topic);
       if (success != kIOReturnSuccess) {
         NS_WARNING("failed to disable screensaver");
       }
     } else {
       // Re-enable screen saver.
       NS_WARNING("Releasing screensaver");
-      if (mAssertionID != kIOPMNullAssertionID) {
-        IOReturn result = ::IOPMAssertionRelease(mAssertionID);
+      if (assertionId != kIOPMNullAssertionID) {
+        IOReturn result = ::IOPMAssertionRelease(assertionId);
         if (result != kIOReturnSuccess) {
           NS_WARNING("failed to release screensaver");
         }
       }
     }
     return NS_OK;
   }
 }; // MacWakeLockListener
--- a/widget/windows/nsAppShell.cpp
+++ b/widget/windows/nsAppShell.cpp
@@ -51,22 +51,28 @@ private:
   ~WinWakeLockListener() {}
 
   NS_IMETHOD Callback(const nsAString& aTopic, const nsAString& aState) {
     if (!aTopic.EqualsASCII("screen") &&
         !aTopic.EqualsASCII("audio-playing") &&
         !aTopic.EqualsASCII("video-playing")) {
       return NS_OK;
     }
+    bool shouldKeepDisplayOn = aTopic.EqualsASCII("screen") ||
+                               aTopic.EqualsASCII("video-playing");
     // Note the wake lock code ensures that we're not sent duplicate
     // "locked-foreground" notifications when multiple wake locks are held.
     if (aState.EqualsASCII("locked-foreground")) {
       WAKE_LOCK_LOG("WinWakeLock: Blocking screen saver");
-      // Prevent the display turning off and block the screen saver.
-      SetThreadExecutionState(ES_DISPLAY_REQUIRED|ES_CONTINUOUS);
+      if (shouldKeepDisplayOn) {
+        // Prevent the display turning off and block the screen saver.
+        SetThreadExecutionState(ES_DISPLAY_REQUIRED|ES_CONTINUOUS);
+      } else {
+        SetThreadExecutionState(ES_SYSTEM_REQUIRED|ES_CONTINUOUS);
+      }
     } else {
       WAKE_LOCK_LOG("WinWakeLock: Unblocking screen saver");
       // Unblock display/screen saver turning off.
       SetThreadExecutionState(ES_CONTINUOUS);
     }
     return NS_OK;
   }
 };