Bug 958963 - Headset status from input device didn't be recorded by GonkSwitch. r=dhylands, a=1.3+
authorMarco Chen <mchen@mozilla.com>
Mon, 20 Jan 2014 17:35:24 +0800
changeset 176035 efae13114cd616c023df2d6309fa7be4a482c3ed
parent 176034 1a9216499d538bbb65013ae990e7352a665b9e68
child 176036 27713189accc3ccc485c3d5e5887b0c9745b2ce8
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdhylands, 1
bugs958963
milestone28.0a2
Bug 958963 - Headset status from input device didn't be recorded by GonkSwitch. r=dhylands, a=1.3+
hal/Hal.cpp
hal/Hal.h
hal/fallback/FallbackSwitch.cpp
hal/gonk/GonkSwitch.cpp
hal/sandbox/PHal.ipdl
hal/sandbox/SandboxHal.cpp
widget/gonk/nsAppShell.cpp
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -745,16 +745,21 @@ DisableSwitchNotifications(SwitchDevice 
 }
 
 SwitchState GetCurrentSwitchState(SwitchDevice aDevice)
 {
   AssertMainThread();
   RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice), SWITCH_STATE_UNKNOWN);
 }
 
+void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
+{
+  PROXY_IF_SANDBOXED(NotifySwitchStateFromInputDevice(aDevice, aState));
+}
+
 typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
 
 static SwitchObserverList *sSwitchObserverLists = nullptr;
 
 static SwitchObserverList&
 GetSwitchObserverList(SwitchDevice aDevice) {
   MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE); 
   if (sSwitchObserverLists == nullptr) {
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -433,16 +433,22 @@ void UnregisterSwitchObserver(hal::Switc
 void NotifySwitchChange(const hal::SwitchEvent& aEvent);
 
 /**
  * Get current switch information.
  */
 hal::SwitchState GetCurrentSwitchState(hal::SwitchDevice aDevice);
 
 /**
+ * Notify switch status change from input device.
+ */
+void NotifySwitchStateFromInputDevice(hal::SwitchDevice aDevice,
+                                      hal::SwitchState aState);
+
+/**
  * Register an observer that is notified when a programmed alarm
  * expires.
  *
  * Currently, there can only be 0 or 1 alarm observers.
  */
 bool RegisterTheOneAlarmObserver(hal::AlarmObserver* aObserver);
 
 /**
--- a/hal/fallback/FallbackSwitch.cpp
+++ b/hal/fallback/FallbackSwitch.cpp
@@ -20,10 +20,15 @@ DisableSwitchNotifications(SwitchDevice 
 {
 }
 
 SwitchState
 GetCurrentSwitchState(SwitchDevice aDevice) {
   return SWITCH_STATE_UNKNOWN;
 }
 
+void
+NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
+{
+}
+
 } // namespace hal_impl
 } // namespace mozilla
--- a/hal/gonk/GonkSwitch.cpp
+++ b/hal/gonk/GonkSwitch.cpp
@@ -12,16 +12,17 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #include <android/log.h>
 #include <fcntl.h>
 #include <sysutils/NetlinkEvent.h>
+#include <cutils/properties.h>
 
 #include "base/message_loop.h"
 
 #include "Hal.h"
 #include "mozilla/FileUtils.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/Monitor.h"
 #include "nsPrintfCString.h"
@@ -275,16 +276,30 @@ public:
 
     info.mEvent.status() = currState;
 
     if (info.mEnabled) {
       NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent));
     }
   }
 
+  void Notify(SwitchDevice aDevice, SwitchState aState)
+  {
+    EventInfo& info = mEventInfo[aDevice];
+    if (aState == info.mEvent.status()) {
+      return;
+    }
+
+    info.mEvent.status() = aState;
+
+    if (info.mEnabled) {
+      NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent));
+    }
+  }
+
   SwitchState GetCurrentInformation(SwitchDevice aDevice)
   {
     return mEventInfo[aDevice].mEvent.status();
   }
 
   void NotifyAnEvent(SwitchDevice aDevice)
   {
     EventInfo& info = mEventInfo[aDevice];
@@ -306,17 +321,28 @@ private:
   };
 
   EventInfo mEventInfo[NUM_SWITCH_DEVICE];
   size_t mEnableCount;
   SwitchHandlerArray mHandler;
 
   void Init()
   {
-    mHandler.AppendElement(new SwitchHandlerHeadphone(SWITCH_HEADSET_DEVPATH));
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.moz.devinputjack", value, "0");
+    bool headphonesFromInputDev = !strcmp(value, "1");
+
+    if (!headphonesFromInputDev) {
+      mHandler.AppendElement(new SwitchHandlerHeadphone(SWITCH_HEADSET_DEVPATH));
+    } else {
+      // If headphone status will be notified from input dev then initialize
+      // status to "off" and wait for event notification.
+      mEventInfo[SWITCH_HEADPHONES].mEvent.device() = SWITCH_HEADPHONES;
+      mEventInfo[SWITCH_HEADPHONES].mEvent.status() = SWITCH_STATE_OFF;
+    }
     mHandler.AppendElement(new SwitchHandler(SWITCH_USB_DEVPATH_GB, SWITCH_USB));
     mHandler.AppendElement(new SwitchHandlerUsbIcs(SWITCH_USB_DEVPATH_ICS));
 
     SwitchHandlerArray::index_type handlerIndex;
     SwitchHandlerArray::size_type numHandlers = mHandler.Length();
 
     for (handlerIndex = 0; handlerIndex < numHandlers; handlerIndex++) {
       SwitchState state = mHandler[handlerIndex]->GetState();
@@ -412,10 +438,23 @@ DisableSwitchNotifications(SwitchDevice 
 
 SwitchState
 GetCurrentSwitchState(SwitchDevice aDevice)
 {
   MOZ_ASSERT(sSwitchObserver && sSwitchObserver->GetEnableCount());
   return sSwitchObserver->GetCurrentInformation(aDevice);
 }
 
+static void
+NotifySwitchStateIOThread(SwitchDevice aDevice, SwitchState aState)
+{
+  sSwitchObserver->Notify(aDevice, aState);
+}
+
+void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
+{
+  InitializeResourceIfNeed();
+  XRE_GetIOMessageLoop()->PostTask(
+      FROM_HERE,
+      NewRunnableFunction(NotifySwitchStateIOThread, aDevice, aState));
+}
 } // hal_impl
 } //mozilla
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -166,16 +166,17 @@ parent:
     sync LockScreenOrientation(ScreenOrientation aOrientation)
       returns (bool allowed);
     UnlockScreenOrientation();
  
     EnableSwitchNotifications(SwitchDevice aDevice);
     DisableSwitchNotifications(SwitchDevice aDevice);
     sync GetCurrentSwitchState(SwitchDevice aDevice)
       returns (SwitchState aState);
+    NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState);
 
     FactoryReset();
 
 child:
     NotifySensorChange(SensorData aSensorData);
 
 parent:
     EnableSensorNotifications(SensorType aSensor);
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -322,16 +322,22 @@ DisableSwitchNotifications(SwitchDevice 
 SwitchState
 GetCurrentSwitchState(SwitchDevice aDevice)
 {
   SwitchState state;
   Hal()->SendGetCurrentSwitchState(aDevice, &state);
   return state;
 }
 
+void
+NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
+{
+  Hal()->SendNotifySwitchStateFromInputDevice(aDevice, aState);
+}
+
 bool
 EnableAlarm()
 {
   NS_RUNTIMEABORT("Alarms can't be programmed from sandboxed contexts.  Yet.");
   return false;
 }
 
 void
@@ -811,16 +817,24 @@ public:
   virtual bool
   RecvGetCurrentSwitchState(const SwitchDevice& aDevice, hal::SwitchState *aState) MOZ_OVERRIDE
   {
     // Content has no reason to listen to switch events currently.
     *aState = hal::GetCurrentSwitchState(aDevice);
     return true;
   }
 
+  virtual bool
+  RecvNotifySwitchStateFromInputDevice(const SwitchDevice& aDevice,
+                                       const SwitchState& aState) MOZ_OVERRIDE
+  {
+    hal::NotifySwitchStateFromInputDevice(aDevice, aState);
+    return true;
+  }
+
   void Notify(const int64_t& aClockDeltaMS)
   {
     unused << SendNotifySystemClockChange(aClockDeltaMS);
   }
 
   void Notify(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
   {
     unused << SendNotifySystemTimezoneChange(aSystemTimezoneChangeInfo);
--- a/widget/gonk/nsAppShell.cpp
+++ b/widget/gonk/nsAppShell.cpp
@@ -258,17 +258,18 @@ sendKeyEvent(uint32_t keyCode, int16_t c
 
 class SwitchEventRunnable : public nsRunnable {
 public:
     SwitchEventRunnable(hal::SwitchEvent& aEvent) : mEvent(aEvent)
     {}
 
     NS_IMETHOD Run()
     {
-        hal::NotifySwitchChange(mEvent);
+        hal::NotifySwitchStateFromInputDevice(mEvent.device(),
+          mEvent.status());
         return NS_OK;
     }
 private:
     hal::SwitchEvent mEvent;
 };
 
 static void
 updateHeadphoneSwitch()