Bug 1194721: Add registry interface and module for Gonk sensors, r=gsvelto
authorThomas Zimmermann <tdz@users.sourceforge.net>
Thu, 04 Feb 2016 12:35:13 +0100
changeset 308815 8dd47c4c4cd663c086b8e162c720fe930283abb1
parent 308814 67a40851409d512802f7fca7bb89013674dba6a8
child 308816 dd570dc405ce3297eac2b8158fbe74010adeeab1
push idunknown
push userunknown
push dateunknown
reviewersgsvelto
bugs1194721
milestone47.0a1
Bug 1194721: Add registry interface and module for Gonk sensors, r=gsvelto A system daemon can contain several services. One of them is the registry service that manages all other services. This patch adds support for this service in the Gonk sensors daemon.
hal/gonk/GonkSensorsRegistryInterface.cpp
hal/gonk/GonkSensorsRegistryInterface.h
hal/moz.build
new file mode 100644
--- /dev/null
+++ b/hal/gonk/GonkSensorsRegistryInterface.cpp
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GonkSensorsRegistryInterface.h"
+#include "GonkSensorsHelpers.h"
+#include "HalLog.h"
+
+namespace mozilla {
+namespace hal {
+
+using namespace mozilla::ipc;
+
+//
+// GonkSensorsRegistryResultHandler
+//
+
+void
+GonkSensorsRegistryResultHandler::OnError(SensorsError aError)
+{
+  HAL_ERR("Received error code %d", static_cast<int>(aError));
+}
+
+void
+GonkSensorsRegistryResultHandler::RegisterModule(uint32_t aProtocolVersion)
+{ }
+
+void
+GonkSensorsRegistryResultHandler::UnregisterModule()
+{ }
+
+GonkSensorsRegistryResultHandler::~GonkSensorsRegistryResultHandler()
+{ }
+
+//
+// GonkSensorsRegistryModule
+//
+
+GonkSensorsRegistryModule::~GonkSensorsRegistryModule()
+{ }
+
+void
+GonkSensorsRegistryModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
+                                     DaemonSocketPDU& aPDU,
+                                     DaemonSocketResultHandler* aRes)
+{
+  static void (GonkSensorsRegistryModule::* const HandleRsp[])(
+    const DaemonSocketPDUHeader&,
+    DaemonSocketPDU&,
+    GonkSensorsRegistryResultHandler*) = {
+    [OPCODE_ERROR] = &GonkSensorsRegistryModule::ErrorRsp,
+    [OPCODE_REGISTER_MODULE] = &GonkSensorsRegistryModule::RegisterModuleRsp,
+    [OPCODE_UNREGISTER_MODULE] = &GonkSensorsRegistryModule::UnregisterModuleRsp
+  };
+
+  if ((aHeader.mOpcode >= MOZ_ARRAY_LENGTH(HandleRsp)) ||
+      !HandleRsp[aHeader.mOpcode]) {
+    HAL_ERR("Sensors registry response opcode %d unknown", aHeader.mOpcode);
+    return;
+  }
+
+  RefPtr<GonkSensorsRegistryResultHandler> res =
+    static_cast<GonkSensorsRegistryResultHandler*>(aRes);
+
+  if (!res) {
+    return; // Return early if no result handler has been set
+  }
+
+  (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
+}
+
+// Commands
+//
+
+nsresult
+GonkSensorsRegistryModule::RegisterModuleCmd(
+  uint8_t aId, GonkSensorsRegistryResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_REGISTER_MODULE, 0));
+
+  nsresult rv = PackPDU(aId, *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  Unused << pdu.forget();
+  return NS_OK;
+}
+
+nsresult
+GonkSensorsRegistryModule::UnregisterModuleCmd(
+  uint8_t aId, GonkSensorsRegistryResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_UNREGISTER_MODULE, 0));
+
+  nsresult rv = PackPDU(aId, *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  Unused << pdu.forget();
+  return NS_OK;
+}
+
+// Responses
+//
+
+void
+GonkSensorsRegistryModule::ErrorRsp(
+  const DaemonSocketPDUHeader& aHeader,
+  DaemonSocketPDU& aPDU, GonkSensorsRegistryResultHandler* aRes)
+{
+  ErrorRunnable::Dispatch(
+    aRes, &GonkSensorsRegistryResultHandler::OnError, UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsRegistryModule::RegisterModuleRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  GonkSensorsRegistryResultHandler* aRes)
+{
+  Uint32ResultRunnable::Dispatch(
+    aRes,
+    &GonkSensorsRegistryResultHandler::RegisterModule,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsRegistryModule::UnregisterModuleRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  GonkSensorsRegistryResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes,
+    &GonkSensorsRegistryResultHandler::UnregisterModule,
+    UnpackPDUInitOp(aPDU));
+}
+
+//
+// GonkSensorsRegistryInterface
+//
+
+GonkSensorsRegistryInterface::GonkSensorsRegistryInterface(
+  GonkSensorsRegistryModule* aModule)
+  : mModule(aModule)
+{ }
+
+GonkSensorsRegistryInterface::~GonkSensorsRegistryInterface()
+{ }
+
+void
+GonkSensorsRegistryInterface::RegisterModule(
+  uint8_t aId, GonkSensorsRegistryResultHandler* aRes)
+{
+  MOZ_ASSERT(mModule);
+
+  nsresult rv = mModule->RegisterModuleCmd(aId, aRes);
+  if (NS_FAILED(rv)) {
+    DispatchError(aRes, rv);
+  }
+}
+
+void
+GonkSensorsRegistryInterface::UnregisterModule(
+  uint8_t aId, GonkSensorsRegistryResultHandler* aRes)
+{
+  MOZ_ASSERT(mModule);
+
+  nsresult rv = mModule->UnregisterModuleCmd(aId, aRes);
+  if (NS_FAILED(rv)) {
+    DispatchError(aRes, rv);
+  }
+}
+
+void
+GonkSensorsRegistryInterface::DispatchError(
+  GonkSensorsRegistryResultHandler* aRes, SensorsError aError)
+{
+  DaemonResultRunnable1<GonkSensorsRegistryResultHandler, void,
+                        SensorsError, SensorsError>::Dispatch(
+    aRes, &GonkSensorsRegistryResultHandler::OnError,
+    ConstantInitOp1<SensorsError>(aError));
+}
+
+void
+GonkSensorsRegistryInterface::DispatchError(
+  GonkSensorsRegistryResultHandler* aRes, nsresult aRv)
+{
+  SensorsError error;
+
+  if (NS_FAILED(Convert(aRv, error))) {
+    error = SENSORS_ERROR_FAIL;
+  }
+  DispatchError(aRes, error);
+}
+
+} // namespace hal
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/hal/gonk/GonkSensorsRegistryInterface.h
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * The registry interface gives yo access to the Sensors daemon's Registry
+ * service. The purpose of the service is to register and setup all other
+ * services, and make them available.
+ *
+ * All public methods and callback methods run on the main thread.
+ */
+
+#ifndef hal_gonk_GonkSensorsRegistryInterface_h
+#define hal_gonk_GonkSensorsRegistryInterface_h
+
+#include <mozilla/ipc/DaemonRunnables.h>
+#include <mozilla/ipc/DaemonSocketMessageHandlers.h>
+#include "SensorsTypes.h"
+
+namespace mozilla {
+namespace ipc {
+
+class DaemonSocketPDU;
+class DaemonSocketPDUHeader;
+
+}
+}
+
+namespace mozilla {
+namespace hal {
+
+class SensorsInterface;
+
+using mozilla::ipc::DaemonSocketPDU;
+using mozilla::ipc::DaemonSocketPDUHeader;
+using mozilla::ipc::DaemonSocketResultHandler;
+
+/**
+ * This class is the result-handler interface for the Sensors
+ * Registry interface. Methods always run on the main thread.
+ */
+class GonkSensorsRegistryResultHandler : public DaemonSocketResultHandler
+{
+public:
+
+  /**
+   * Called if a registry command failed.
+   *
+   * @param aError The error code.
+   */
+  virtual void OnError(SensorsError aError);
+
+  /**
+   * The callback method for |GonkSensorsRegistryInterface::RegisterModule|.
+   *
+   * @param aProtocolVersion The daemon's protocol version. Make sure it's
+   *                         compatible with Gecko's implementation.
+   */
+  virtual void RegisterModule(uint32_t aProtocolVersion);
+
+  /**
+   * The callback method for |SensorsRegsitryInterface::UnregisterModule|.
+   */
+  virtual void UnregisterModule();
+
+protected:
+  virtual ~GonkSensorsRegistryResultHandler();
+};
+
+/**
+ * This is the module class for the Sensors registry component. It handles
+ * PDU packing and unpacking. Methods are either executed on the main thread
+ * or the I/O thread.
+ *
+ * This is an internal class, use |GonkSensorsRegistryInterface| instead.
+ */
+class GonkSensorsRegistryModule
+{
+public:
+  enum {
+    SERVICE_ID = 0x00
+  };
+
+  enum {
+    OPCODE_ERROR = 0x00,
+    OPCODE_REGISTER_MODULE = 0x01,
+    OPCODE_UNREGISTER_MODULE = 0x02
+  };
+
+  virtual nsresult Send(DaemonSocketPDU* aPDU,
+                        DaemonSocketResultHandler* aRes) = 0;
+
+  //
+  // Commands
+  //
+
+  nsresult RegisterModuleCmd(uint8_t aId,
+                             GonkSensorsRegistryResultHandler* aRes);
+
+  nsresult UnregisterModuleCmd(uint8_t aId,
+                               GonkSensorsRegistryResultHandler* aRes);
+
+protected:
+  virtual ~GonkSensorsRegistryModule();
+
+  void HandleSvc(const DaemonSocketPDUHeader& aHeader,
+                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+
+  //
+  // Responses
+  //
+
+  typedef mozilla::ipc::DaemonResultRunnable0<
+    GonkSensorsRegistryResultHandler, void>
+    ResultRunnable;
+
+  typedef mozilla::ipc::DaemonResultRunnable1<
+    GonkSensorsRegistryResultHandler, void, uint32_t, uint32_t>
+    Uint32ResultRunnable;
+
+  typedef mozilla::ipc::DaemonResultRunnable1<
+    GonkSensorsRegistryResultHandler, void, SensorsError, SensorsError>
+    ErrorRunnable;
+
+  void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
+                DaemonSocketPDU& aPDU,
+                GonkSensorsRegistryResultHandler* aRes);
+
+  void RegisterModuleRsp(const DaemonSocketPDUHeader& aHeader,
+                         DaemonSocketPDU& aPDU,
+                         GonkSensorsRegistryResultHandler* aRes);
+
+  void UnregisterModuleRsp(const DaemonSocketPDUHeader& aHeader,
+                           DaemonSocketPDU& aPDU,
+                           GonkSensorsRegistryResultHandler* aRes);
+};
+
+/**
+ * This class implements the public interface to the Sensors Registry
+ * component. Use |SensorsInterface::GetRegistryInterface| to retrieve
+ * an instance. All methods run on the main thread.
+ */
+class GonkSensorsRegistryInterface final
+{
+public:
+  friend class GonkSensorsInterface;
+
+  /**
+   * Sends a RegisterModule command to the Sensors daemon. When the
+   * result handler's |RegisterModule| method gets called, the service
+   * has been registered successfully and can be used.
+   *
+   * @param aId The id of the service that is to be registered.
+   * @param aRes The result handler.
+   */
+  void RegisterModule(uint8_t aId, GonkSensorsRegistryResultHandler* aRes);
+
+  /**
+   * Sends an UnregisterModule command to the Sensors daemon. The service
+   * should not be used afterwards until it has been registered again.
+   *
+   * @param aId The id of the service that is to be unregistered.
+   * @param aRes The result handler.
+   */
+  void UnregisterModule(uint8_t aId, GonkSensorsRegistryResultHandler* aRes);
+
+  ~GonkSensorsRegistryInterface();
+
+private:
+  GonkSensorsRegistryInterface(GonkSensorsRegistryModule* aModule);
+
+  void DispatchError(GonkSensorsRegistryResultHandler* aRes,
+                     SensorsError aError);
+  void DispatchError(GonkSensorsRegistryResultHandler* aRes,
+                     nsresult aRv);
+
+  GonkSensorsRegistryModule* mModule;
+};
+
+} // namespace hal
+} // namespace mozilla
+
+#endif // hal_gonk_GonkSensorsRegistryInterface_h
--- a/hal/moz.build
+++ b/hal/moz.build
@@ -47,16 +47,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
         'android/AndroidHal.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     UNIFIED_SOURCES += [
         'gonk/GonkDiskSpaceWatcher.cpp',
         'gonk/GonkFMRadio.cpp',
         'gonk/GonkSensor.cpp',
         'gonk/GonkSensorsHelpers.cpp',
+        'gonk/GonkSensorsRegistryInterface.cpp',
         'gonk/GonkSwitch.cpp',
         'gonk/SystemService.cpp',
         'gonk/UeventPoller.cpp',
         'linux/LinuxMemory.cpp',
         'linux/LinuxPower.cpp',
     ]
     # GonkHal.cpp cannot be built in unified mode because it relies on HalImpl.h.
     SOURCES += [