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 186405 3dd59dda51fce8a55862a61061a35dc61307d86e
parent 186404 6ba7959de6825755ad42464968b5a08a1824e617
child 186406 42824338c2e4b0aacff80082cae6c7117c2f08bd
push id7119
push userryanvm@gmail.com
push dateTue, 03 Jun 2014 21:50:47 +0000
treeherderfx-team@e7f2825aed54 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdhylands, sicking
bugs911242
milestone32.0a1
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