Bug 911242 - [LED] De-couple the control of screen backlight and keyboard backlight. r=dhylands, sr=sicking
authorSean Lin <selin@mozilla.com>
Fri, 30 May 2014 11:11:23 +0800
changeset 205623 3dd59dda51fce8a55862a61061a35dc61307d86e
parent 205622 6ba7959de6825755ad42464968b5a08a1824e617
child 205624 42824338c2e4b0aacff80082cae6c7117c2f08bd
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdhylands, sicking
bugs911242
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 911242 - [LED] De-couple the control of screen backlight and keyboard backlight. r=dhylands, sr=sicking
dom/power/PowerManager.cpp
dom/power/PowerManager.h
dom/power/test/mochitest.ini
dom/power/test/test_power_set_key_light_enabled.html
dom/webidl/MozPowerManager.webidl
hal/Hal.cpp
hal/Hal.h
hal/fallback/FallbackScreenPower.cpp
hal/gonk/GonkHal.cpp
hal/sandbox/PHal.ipdl
hal/sandbox/SandboxHal.cpp
--- a/dom/power/PowerManager.cpp
+++ b/dom/power/PowerManager.cpp
@@ -149,16 +149,28 @@ PowerManager::ScreenEnabled()
 }
 
 void
 PowerManager::SetScreenEnabled(bool aEnabled)
 {
   hal::SetScreenEnabled(aEnabled);
 }
 
+bool
+PowerManager::KeyLightEnabled()
+{
+  return hal::GetKeyLightEnabled();
+}
+
+void
+PowerManager::SetKeyLightEnabled(bool aEnabled)
+{
+  hal::SetKeyLightEnabled(aEnabled);
+}
+
 double
 PowerManager::ScreenBrightness()
 {
   return hal::GetScreenBrightness();
 }
 
 void
 PowerManager::SetScreenBrightness(double aBrightness, ErrorResult& aRv)
--- a/dom/power/PowerManager.h
+++ b/dom/power/PowerManager.h
@@ -48,16 +48,18 @@ public:
   void FactoryReset();
   void PowerOff(ErrorResult& aRv);
   void AddWakeLockListener(nsIDOMMozWakeLockListener* aListener);
   void RemoveWakeLockListener(nsIDOMMozWakeLockListener* aListener);
   void GetWakeLockState(const nsAString& aTopic, nsAString& aState,
                         ErrorResult& aRv);
   bool ScreenEnabled();
   void SetScreenEnabled(bool aEnabled);
+  bool KeyLightEnabled();
+  void SetKeyLightEnabled(bool aEnabled);
   double ScreenBrightness();
   void SetScreenBrightness(double aBrightness, ErrorResult& aRv);
   bool CpuSleepAllowed();
   void SetCpuSleepAllowed(bool aAllowed);
 
 private:
   nsCOMPtr<nsIDOMWindow> mWindow;
   nsTArray<nsCOMPtr<nsIDOMMozWakeLockListener> > mListeners;
--- a/dom/power/test/mochitest.ini
+++ b/dom/power/test/mochitest.ini
@@ -7,8 +7,10 @@ skip-if = e10s
 run-if = appname != "b2g"
 [test_power_basics.html]
 [test_power_set_cpusleepallowed.html]
 skip-if = toolkit != "gonk"
 [test_power_set_screen_brightness.html]
 skip-if = toolkit != "gonk"
 [test_power_set_screen_enabled.html]
 skip-if = toolkit != "gonk"
+[test_power_set_key_light_enabled.html]
+skip-if = toolkit != "gonk"
new file mode 100644
--- /dev/null
+++ b/dom/power/test/test_power_set_key_light_enabled.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test Enabling/Disabling Screen with Power Management API</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+  <script type="application/javascript">
+
+  "use strict";
+
+  function testEnableKeyLight() {
+    try {
+      navigator.mozPower.keyLightEnabled = true;
+      ok(navigator.mozPower.keyLightEnabled === true, "Enabled key backlight.");
+    } catch (e) {
+      ok(false, "Unexpected exception trying to enable key backlight.");
+    }
+  }
+
+  function testDisableKeyLight() {
+    try {
+      navigator.mozPower.keyLightEnabled = false;
+      ok(navigator.mozPower.keyLightEnabled === false, "Disabled key backlight.");
+    } catch (e) {
+      ok(false, "Unexpected exception trying to disable key backlight.");
+    }
+  }
+
+  function startTests() {
+
+    // Make sure we don't suspend
+    navigator.mozPower.cpuSleepAllowed = false;
+
+    testDisableKeyLight();
+    testEnableKeyLight();
+
+    SimpleTest.finish();
+  }
+
+  SimpleTest.waitForExplicitFinish();
+  if (SpecialPowers.hasPermission("power", document)) {
+    // Currently only applicable on FxOS
+    if (navigator.userAgent.indexOf("Mobile") != -1 &&
+        navigator.appVersion.indexOf("Android") == -1) {
+      startTests();
+    } else {
+      ok(true, "mozPower on Firefox OS only.");
+      SimpleTest.finish();
+    }
+  } else {
+    // Add the permission and reload so it's propogated
+    SpecialPowers.addPermission("power", true, document);
+    window.location.reload();
+  }
+  </script>
+</pre>
+</body>
+</html>
--- a/dom/webidl/MozPowerManager.webidl
+++ b/dom/webidl/MozPowerManager.webidl
@@ -45,16 +45,23 @@ interface MozPowerManager
 
     /**
      * Is the device's screen currently enabled?  This attribute controls the
      * device's screen, so setting it to false will turn off the screen.
      */
     attribute boolean screenEnabled;
 
     /**
+     * Is the device's keypad/button backlight enabled? Setting it to false will
+     * turn off the device's keypad/button backlight. And the brightness level
+     * is the same as |screenBrightness|.
+     */
+    attribute boolean keyLightEnabled;
+
+    /**
      * How bright is the screen's backlight, on a scale from 0 (very dim) to 1
      * (full brightness)?  Setting this attribute modifies the screen's
      * brightness.
      *
      * You can read and write this attribute even when the screen is disabled,
      * but the backlight is off while the screen is disabled.
      *
      * If you write a value of X into this attribute, the attribute may not have
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -369,48 +369,60 @@ NotifyBatteryChange(const BatteryInforma
 }
 
 bool GetScreenEnabled()
 {
   AssertMainThread();
   RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled(), false);
 }
 
-void SetScreenEnabled(bool enabled)
+void SetScreenEnabled(bool aEnabled)
 {
   AssertMainThread();
-  PROXY_IF_SANDBOXED(SetScreenEnabled(enabled));
+  PROXY_IF_SANDBOXED(SetScreenEnabled(aEnabled));
+}
+
+bool GetKeyLightEnabled()
+{
+  AssertMainThread();
+  RETURN_PROXY_IF_SANDBOXED(GetKeyLightEnabled(), false);
+}
+
+void SetKeyLightEnabled(bool aEnabled)
+{
+  AssertMainThread();
+  PROXY_IF_SANDBOXED(SetKeyLightEnabled(aEnabled));
 }
 
 bool GetCpuSleepAllowed()
 {
   // Generally for interfaces that are accessible by normal web content
   // we should cache the result and be notified on state changes, like
   // what the battery API does. But since this is only used by
   // privileged interface, the synchronous getter is OK here.
   AssertMainThread();
   RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
 }
 
-void SetCpuSleepAllowed(bool allowed)
+void SetCpuSleepAllowed(bool aAllowed)
 {
   AssertMainThread();
-  PROXY_IF_SANDBOXED(SetCpuSleepAllowed(allowed));
+  PROXY_IF_SANDBOXED(SetCpuSleepAllowed(aAllowed));
 }
 
 double GetScreenBrightness()
 {
   AssertMainThread();
   RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
 }
 
-void SetScreenBrightness(double brightness)
+void SetScreenBrightness(double aBrightness)
 {
   AssertMainThread();
-  PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(brightness, 0.0, 1.0)));
+  PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(aBrightness, 0.0, 1.0)));
 }
 
 bool SetLight(LightType light, const LightConfiguration& aConfig)
 {
   AssertMainThread();
   RETURN_PROXY_IF_SANDBOXED(SetLight(light, aConfig), false);
 }
 
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -119,17 +119,27 @@ void NotifyBatteryChange(const hal::Batt
  */
 bool GetScreenEnabled();
 
 /**
  * Enable or disable the device's screen.
  *
  * Note that it may take a few seconds for the screen to turn on or off.
  */
-void SetScreenEnabled(bool enabled);
+void SetScreenEnabled(bool aEnabled);
+
+/**
+ * Determine whether the device's keypad/button backlight is currently enabled.
+ */
+bool GetKeyLightEnabled();
+
+/**
+ * Enable or disable the device's keypad/button backlight.
+ */
+void SetKeyLightEnabled(bool aEnabled);
 
 /**
  * Get the brightness of the device's screen's backlight, on a scale from 0
  * (very dim) to 1 (full blast).
  *
  * If the display is currently disabled, this returns the brightness the
  * backlight will have when the display is re-enabled.
  */
@@ -140,28 +150,28 @@ double GetScreenBrightness();
  * (very dimm) to 1 (full blast).  Values larger than 1 are treated like 1, and
  * values smaller than 0 are treated like 0.
  *
  * Note that we may reduce the resolution of the given brightness value before
  * sending it to the screen.  Therefore if you call SetScreenBrightness(x)
  * followed by GetScreenBrightness(), the value returned by
  * GetScreenBrightness() may not be exactly x.
  */
-void SetScreenBrightness(double brightness);
+void SetScreenBrightness(double aBrightness);
 
 /**
  * Determine whether the device is allowed to sleep.
  */
 bool GetCpuSleepAllowed();
 
 /**
  * Set whether the device is allowed to suspend automatically after
  * the screen is disabled.
  */
-void SetCpuSleepAllowed(bool allowed);
+void SetCpuSleepAllowed(bool aAllowed);
 
 /**
  * Set the value of a light to a particular color, with a specific flash pattern.
  * light specifices which light.  See Hal.idl for the list of constants
  * mode specifies user set or based on ambient light sensor
  * flash specifies whether or how to flash the light
  * flashOnMS and flashOffMS specify the pattern for XXX flash mode
  * color specifies the color.  If the light doesn't support color, the given color is
--- a/hal/fallback/FallbackScreenPower.cpp
+++ b/hal/fallback/FallbackScreenPower.cpp
@@ -9,23 +9,33 @@ namespace hal_impl {
 
 bool
 GetScreenEnabled()
 {
   return true;
 }
 
 void
-SetScreenEnabled(bool enabled)
+SetScreenEnabled(bool aEnabled)
+{}
+
+bool
+GetKeyLightEnabled()
+{
+  return true;
+}
+
+void
+SetKeyLightEnabled(bool aEnabled)
 {}
 
 double
 GetScreenBrightness()
 {
   return 1;
 }
 
 void
-SetScreenBrightness(double brightness)
+SetScreenBrightness(double aBrightness)
 {}
 
 } // hal_impl
 } // namespace mozilla
--- a/hal/gonk/GonkHal.cpp
+++ b/hal/gonk/GonkHal.cpp
@@ -535,57 +535,92 @@ int32_t sInternalLockCpuCount = 0;
 
 bool
 GetScreenEnabled()
 {
   return sScreenEnabled;
 }
 
 void
-SetScreenEnabled(bool enabled)
+SetScreenEnabled(bool aEnabled)
+{
+  GetGonkDisplay()->SetEnabled(aEnabled);
+  sScreenEnabled = aEnabled;
+}
+
+bool
+GetKeyLightEnabled()
+{
+  hal::LightConfiguration config;
+  hal_impl::GetLight(hal::eHalLightID_Buttons, &config);
+  return (config.color() != 0x00000000);
+}
+
+void
+SetKeyLightEnabled(bool aEnabled)
 {
-  GetGonkDisplay()->SetEnabled(enabled);
-  sScreenEnabled = enabled;
+  hal::LightConfiguration config;
+  config.mode() = hal::eHalLightMode_User;
+  config.flash() = hal::eHalLightFlash_None;
+  config.flashOnMS() = config.flashOffMS() = 0;
+  config.color() = 0x00000000;
+
+  if (aEnabled) {
+    // Convert the value in [0, 1] to an int between 0 and 255 and then convert
+    // it to a color. Note that the high byte is FF, corresponding to the alpha
+    // channel.
+    double brightness = GetScreenBrightness();
+    uint32_t val = static_cast<int>(round(brightness * 255.0));
+    uint32_t color = (0xff<<24) + (val<<16) + (val<<8) + val;
+
+    config.color() = color;
+  }
+
+  hal_impl::SetLight(hal::eHalLightID_Buttons, config);
+  hal_impl::SetLight(hal::eHalLightID_Keyboard, config);
 }
 
 double
 GetScreenBrightness()
 {
-  hal::LightConfiguration aConfig;
+  hal::LightConfiguration config;
   hal::LightType light = hal::eHalLightID_Backlight;
 
-  hal::GetLight(light, &aConfig);
+  hal_impl::GetLight(light, &config);
   // backlight is brightness only, so using one of the RGB elements as value.
-  int brightness = aConfig.color() & 0xFF;
+  int brightness = config.color() & 0xFF;
   return brightness / 255.0;
 }
 
 void
 SetScreenBrightness(double brightness)
 {
   // Don't use De Morgan's law to push the ! into this expression; we want to
   // catch NaN too.
   if (!(0 <= brightness && brightness <= 1)) {
     HAL_LOG(("SetScreenBrightness: Dropping illegal brightness %f.",
              brightness));
     return;
   }
 
   // Convert the value in [0, 1] to an int between 0 and 255 and convert to a color
   // note that the high byte is FF, corresponding to the alpha channel.
-  int val = static_cast<int>(round(brightness * 255));
+  uint32_t val = static_cast<int>(round(brightness * 255.0));
   uint32_t color = (0xff<<24) + (val<<16) + (val<<8) + val;
 
-  hal::LightConfiguration aConfig;
-  aConfig.mode() = hal::eHalLightMode_User;
-  aConfig.flash() = hal::eHalLightFlash_None;
-  aConfig.flashOnMS() = aConfig.flashOffMS() = 0;
-  aConfig.color() = color;
-  hal::SetLight(hal::eHalLightID_Backlight, aConfig);
-  hal::SetLight(hal::eHalLightID_Buttons, aConfig);
+  hal::LightConfiguration config;
+  config.mode() = hal::eHalLightMode_User;
+  config.flash() = hal::eHalLightFlash_None;
+  config.flashOnMS() = config.flashOffMS() = 0;
+  config.color() = color;
+  hal_impl::SetLight(hal::eHalLightID_Backlight, config);
+  if (GetKeyLightEnabled()) {
+    hal_impl::SetLight(hal::eHalLightID_Buttons, config);
+    hal_impl::SetLight(hal::eHalLightID_Keyboard, config);
+  }
 }
 
 static Monitor* sInternalLockCpuMonitor = nullptr;
 
 static void
 UpdateCpuSleepState()
 {
   sInternalLockCpuMonitor->AssertCurrentThreadOwns();
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -122,23 +122,26 @@ parent:
       returns (BatteryInformation aBatteryInfo);
 
     EnableNetworkNotifications();
     DisableNetworkNotifications();
     sync GetCurrentNetworkInformation()
       returns (NetworkInformation aNetworkInfo);
 
     sync GetScreenEnabled() returns (bool enabled);
-    SetScreenEnabled(bool enabled);
+    SetScreenEnabled(bool aEnabled);
+
+    sync GetKeyLightEnabled() returns (bool enabled);
+    SetKeyLightEnabled(bool aEnabled);
 
     sync GetCpuSleepAllowed() returns (bool allowed);
-    SetCpuSleepAllowed(bool allowed);
+    SetCpuSleepAllowed(bool aAllowed);
 
     sync GetScreenBrightness() returns (double brightness);
-    SetScreenBrightness(double brightness);
+    SetScreenBrightness(double aBrightness);
 
     AdjustSystemClock(int64_t aDeltaMilliseconds);
     SetTimezone(nsCString aTimezoneSpec);
     sync GetTimezone()
       returns (nsCString aTimezoneSpec);
     sync GetTimezoneOffset()
       returns (int32_t aTimezoneOffset);
     EnableSystemClockChangeNotifications();
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -138,47 +138,61 @@ bool
 GetScreenEnabled()
 {
   bool enabled = false;
   Hal()->SendGetScreenEnabled(&enabled);
   return enabled;
 }
 
 void
-SetScreenEnabled(bool enabled)
+SetScreenEnabled(bool aEnabled)
+{
+  Hal()->SendSetScreenEnabled(aEnabled);
+}
+
+bool
+GetKeyLightEnabled()
 {
-  Hal()->SendSetScreenEnabled(enabled);
+  bool enabled = false;
+  Hal()->SendGetKeyLightEnabled(&enabled);
+  return enabled;
+}
+
+void
+SetKeyLightEnabled(bool aEnabled)
+{
+  Hal()->SendSetKeyLightEnabled(aEnabled);
 }
 
 bool
 GetCpuSleepAllowed()
 {
   bool allowed = true;
   Hal()->SendGetCpuSleepAllowed(&allowed);
   return allowed;
 }
 
 void
-SetCpuSleepAllowed(bool allowed)
+SetCpuSleepAllowed(bool aAllowed)
 {
-  Hal()->SendSetCpuSleepAllowed(allowed);
+  Hal()->SendSetCpuSleepAllowed(aAllowed);
 }
 
 double
 GetScreenBrightness()
 {
   double brightness = 0;
   Hal()->SendGetScreenBrightness(&brightness);
   return brightness;
 }
 
 void
-SetScreenBrightness(double brightness)
+SetScreenBrightness(double aBrightness)
 {
-  Hal()->SendSetScreenBrightness(brightness);
+  Hal()->SendSetScreenBrightness(aBrightness);
 }
 
 bool
 SetLight(hal::LightType light, const hal::LightConfiguration& aConfig)
 {
   bool status;
   Hal()->SendSetLight(light, aConfig, &status);
   return status;
@@ -586,72 +600,92 @@ public:
     return true;
   }
 
   void Notify(const ScreenConfiguration& aScreenConfiguration) {
     unused << SendNotifyScreenConfigurationChange(aScreenConfiguration);
   }
 
   virtual bool
-  RecvGetScreenEnabled(bool *enabled) MOZ_OVERRIDE
+  RecvGetScreenEnabled(bool* aEnabled) MOZ_OVERRIDE
   {
     if (!AssertAppProcessPermission(this, "power")) {
       return false;
     }
-    *enabled = hal::GetScreenEnabled();
+    *aEnabled = hal::GetScreenEnabled();
     return true;
   }
 
   virtual bool
-  RecvSetScreenEnabled(const bool &enabled) MOZ_OVERRIDE
+  RecvSetScreenEnabled(const bool& aEnabled) MOZ_OVERRIDE
   {
     if (!AssertAppProcessPermission(this, "power")) {
       return false;
     }
-    hal::SetScreenEnabled(enabled);
+    hal::SetScreenEnabled(aEnabled);
     return true;
   }
 
   virtual bool
-  RecvGetCpuSleepAllowed(bool *allowed) MOZ_OVERRIDE
+  RecvGetKeyLightEnabled(bool* aEnabled) MOZ_OVERRIDE
+  {
+    if (!AssertAppProcessPermission(this, "power")) {
+      return false;
+    }
+    *aEnabled = hal::GetKeyLightEnabled();
+    return true;
+  }
+
+  virtual bool
+  RecvSetKeyLightEnabled(const bool& aEnabled) MOZ_OVERRIDE
   {
     if (!AssertAppProcessPermission(this, "power")) {
       return false;
     }
-    *allowed = hal::GetCpuSleepAllowed();
+    hal::SetKeyLightEnabled(aEnabled);
     return true;
   }
 
   virtual bool
-  RecvSetCpuSleepAllowed(const bool &allowed) MOZ_OVERRIDE
+  RecvGetCpuSleepAllowed(bool* aAllowed) MOZ_OVERRIDE
   {
     if (!AssertAppProcessPermission(this, "power")) {
       return false;
     }
-    hal::SetCpuSleepAllowed(allowed);
+    *aAllowed = hal::GetCpuSleepAllowed();
     return true;
   }
 
   virtual bool
-  RecvGetScreenBrightness(double *brightness) MOZ_OVERRIDE
+  RecvSetCpuSleepAllowed(const bool& aAllowed) MOZ_OVERRIDE
   {
     if (!AssertAppProcessPermission(this, "power")) {
       return false;
     }
-    *brightness = hal::GetScreenBrightness();
+    hal::SetCpuSleepAllowed(aAllowed);
     return true;
   }
 
   virtual bool
-  RecvSetScreenBrightness(const double &brightness) MOZ_OVERRIDE
+  RecvGetScreenBrightness(double* aBrightness) MOZ_OVERRIDE
   {
     if (!AssertAppProcessPermission(this, "power")) {
       return false;
     }
-    hal::SetScreenBrightness(brightness);
+    *aBrightness = hal::GetScreenBrightness();
+    return true;
+  }
+
+  virtual bool
+  RecvSetScreenBrightness(const double& aBrightness) MOZ_OVERRIDE
+  {
+    if (!AssertAppProcessPermission(this, "power")) {
+      return false;
+    }
+    hal::SetScreenBrightness(aBrightness);
     return true;
   }
 
   virtual bool
   RecvSetLight(const LightType& aLight,  const hal::LightConfiguration& aConfig, bool *status) MOZ_OVERRIDE
   {
     // XXX currently, the hardware key light and screen backlight are
     // controlled as a unit.  Those are set through the power API, and