Bug 1173802: Move NFC socket and messaging code into |NfcConsumer|, r=allstars.chh
authorThomas Zimmermann <tdz@users.sourceforge.net>
Fri, 31 Jul 2015 10:07:25 +0200
changeset 287486 d59e98209a18d473c1d831d20c818a433fed324c
parent 287485 7d4dad711118f3b5a381a90c12cf7ab2f652156e
child 287487 d732c4e52cf45c4db3d8f28e6e59ece65faa3f21
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersallstars
bugs1173802
milestone42.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 1173802: Move NFC socket and messaging code into |NfcConsumer|, r=allstars.chh |NfcConsumer| will encapsulates all NFC socket and messaging code. It wil be able to run solely on the NFC worker thread.
dom/nfc/gonk/NfcService.cpp
dom/nfc/gonk/NfcService.h
--- a/dom/nfc/gonk/NfcService.cpp
+++ b/dom/nfc/gonk/NfcService.cpp
@@ -2,27 +2,32 @@
 /* vim: set ts=8 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 "NfcService.h"
 #include <binder/Parcel.h>
 #include <cutils/properties.h>
-#include "mozilla/ModuleUtils.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/NfcOptionsBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/RootedDictionary.h"
+#include "mozilla/ipc/ListenSocket.h"
+#include "mozilla/ipc/ListenSocketConsumer.h"
 #include "mozilla/ipc/NfcConnector.h"
+#include "mozilla/ipc/StreamSocket.h"
+#include "mozilla/ipc/StreamSocketConsumer.h"
+#include "mozilla/ModuleUtils.h"
 #include "mozilla/unused.h"
+#include "NfcMessageHandler.h"
+#include "NfcOptions.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsXULAppAPI.h"
-#include "NfcOptions.h"
 
 #define NS_NFCSERVICE_CID \
   { 0x584c9a21, 0x4e17, 0x43b7, {0xb1, 0x6a, 0x87, 0xa0, 0x42, 0xef, 0xd4, 0x64} }
 #define NS_NFCSERVICE_CONTRACTID "@mozilla.org/nfc/service;1"
 
 using namespace android;
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
@@ -293,16 +298,182 @@ public:
     return NS_OK;
   }
 
 private:
   NfcMessageHandler* mHandler;
   nsAutoPtr<UnixSocketBuffer> mData;
 };
 
+//
+// NfcConsumer
+//
+
+/**
+ * |NfcConsumer| implements the details of the connection to an NFC daemon
+ * as well as the message passing.
+ */
+class NfcConsumer
+  : public ListenSocketConsumer
+  , public StreamSocketConsumer
+{
+public:
+  NfcConsumer(NfcService* aNfcService);
+
+  nsresult Start();
+  void Shutdown();
+
+  bool PostToNfcDaemon(const uint8_t* aData, size_t aSize);
+
+  void SendCommand(const CommandOptions& aCommandOptions);
+
+  // Methods for |StreamSocketConsumer| and |ListenSocketConsumer|
+  //
+
+  void ReceiveSocketData(
+    int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer) override;
+
+  void OnConnectSuccess(int aIndex) override;
+  void OnConnectError(int aIndex) override;
+  void OnDisconnect(int aIndex) override;
+
+private:
+  enum SocketType {
+    LISTEN_SOCKET,
+    STREAM_SOCKET
+  };
+
+  nsRefPtr<NfcService> mNfcService;
+  nsRefPtr<mozilla::ipc::ListenSocket> mListenSocket;
+  nsRefPtr<mozilla::ipc::StreamSocket> mStreamSocket;
+  nsAutoPtr<NfcMessageHandler> mHandler;
+  nsCString mListenSocketName;
+};
+
+NfcConsumer::NfcConsumer(NfcService* aNfcService)
+  : mNfcService(aNfcService)
+{
+  MOZ_ASSERT(mNfcService);
+}
+
+nsresult
+NfcConsumer::Start()
+{
+  static const char BASE_SOCKET_NAME[] = "nfcd";
+
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!mListenSocket);
+
+  // If we could not cleanup properly before and an old
+  // instance of the daemon is still running, we kill it
+  // here.
+  unused << NS_WARN_IF(property_set("ctl.stop", "nfcd") < 0);
+
+  mHandler = new NfcMessageHandler();
+
+  mStreamSocket = new StreamSocket(this, STREAM_SOCKET);
+
+  mListenSocketName = BASE_SOCKET_NAME;
+
+  mListenSocket = new ListenSocket(this, LISTEN_SOCKET);
+  nsresult rv = mListenSocket->Listen(new NfcConnector(mListenSocketName),
+                                      mStreamSocket);
+  if (NS_FAILED(rv)) {
+    mStreamSocket = nullptr;
+    return rv;
+  }
+
+  return NS_OK;
+}
+
+void
+NfcConsumer::Shutdown()
+{
+  mListenSocket->Close();
+  mListenSocket = nullptr;
+  mStreamSocket->Close();
+  mStreamSocket = nullptr;
+
+  mHandler = nullptr;
+}
+
+bool
+NfcConsumer::PostToNfcDaemon(const uint8_t* aData, size_t aSize)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  UnixSocketRawData* raw = new UnixSocketRawData(aData, aSize);
+  nsRefPtr<SendNfcSocketDataTask> task =
+    new SendNfcSocketDataTask(mStreamSocket, raw);
+  NS_DispatchToMainThread(task);
+
+  return true;
+}
+
+void
+NfcConsumer::SendCommand(const CommandOptions& aCommandOptions)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // Dispatch the command to the NFC thread.
+  nsCOMPtr<nsIRunnable> runnable = new NfcCommandRunnable(mHandler, mNfcService,
+                                                          aCommandOptions);
+  mNfcService->GetThread()->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
+}
+
+// |StreamSocketConsumer|, |ListenSocketConsumer|
+
+void
+NfcConsumer::ReceiveSocketData(
+  int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer)
+{
+  MOZ_ASSERT(mHandler);
+  nsCOMPtr<nsIRunnable> runnable =
+    new NfcEventRunnable(mHandler, aBuffer.forget());
+  mNfcService->GetThread()->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
+}
+
+void
+NfcConsumer::OnConnectSuccess(int aIndex)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  switch (aIndex) {
+    case LISTEN_SOCKET: {
+      nsCString value("nfcd:-S -a ");
+      value.Append(mListenSocketName);
+      if (NS_WARN_IF(property_set("ctl.start", value.get()) < 0)) {
+        OnConnectError(STREAM_SOCKET);
+      }
+      break;
+    }
+    case STREAM_SOCKET:
+      /* nothing to do */
+      break;
+  }
+}
+
+void
+NfcConsumer::OnConnectError(int aIndex)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  mNfcService->GetThread()->Shutdown();
+}
+
+void
+NfcConsumer::OnDisconnect(int aIndex)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+}
+
+//
+// NfcService
+//
+
 NfcService::NfcService()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!gNfcService);
 }
 
 NfcService::~NfcService()
 {
@@ -325,102 +496,78 @@ NfcService::FactoryCreate()
 
   nsRefPtr<NfcService> service = gNfcService;
   return service.forget();
 }
 
 NS_IMETHODIMP
 NfcService::Start(nsINfcGonkEventListener* aListener)
 {
-  static const char BASE_SOCKET_NAME[] = "nfcd";
-
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aListener);
   MOZ_ASSERT(!mThread);
-  MOZ_ASSERT(!mListenSocket);
-
-  // If we could not cleanup properly before and an old
-  // instance of the daemon is still running, we kill it
-  // here.
-  unused << NS_WARN_IF(property_set("ctl.stop", "nfcd") < 0);
+  MOZ_ASSERT(!mNfcConsumer);
 
   mListener = aListener;
-  mHandler = new NfcMessageHandler();
-  mStreamSocket = new StreamSocket(this, STREAM_SOCKET);
 
-  mListenSocketName = BASE_SOCKET_NAME;
-
-  mListenSocket = new ListenSocket(this, LISTEN_SOCKET);
-  nsresult rv = mListenSocket->Listen(new NfcConnector(mListenSocketName),
-                                      mStreamSocket);
+  nsresult rv = NS_NewNamedThread("NfcThread", getter_AddRefs(mThread));
   if (NS_FAILED(rv)) {
-    mStreamSocket = nullptr;
+    NS_WARNING("Can't create Nfc worker thread.");
     return rv;
   }
 
-  rv = NS_NewNamedThread("NfcThread", getter_AddRefs(mThread));
+  mNfcConsumer = new NfcConsumer(this);
+
+  rv = mNfcConsumer->Start();
   if (NS_FAILED(rv)) {
-    NS_WARNING("Can't create Nfc worker thread.");
-    mListenSocket->Close();
-    mListenSocket = nullptr;
-    mStreamSocket->Close();
-    mStreamSocket = nullptr;
-    return NS_ERROR_FAILURE;
+    mThread = nullptr;
+    return rv;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 NfcService::Shutdown()
 {
-  MOZ_ASSERT(NS_IsMainThread());
+  if (mNfcConsumer) {
+    mNfcConsumer->Shutdown();
+    mNfcConsumer = nullptr;
+  }
 
   if (mThread) {
     mThread->Shutdown();
     mThread = nullptr;
   }
 
-  mListenSocket->Close();
-  mListenSocket = nullptr;
-  mStreamSocket->Close();
-  mStreamSocket = nullptr;
-
   return NS_OK;
 }
 
 bool
 NfcService::PostToNfcDaemon(const uint8_t* aData, size_t aSize)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
-  UnixSocketRawData* raw = new UnixSocketRawData(aData, aSize);
-  nsRefPtr<SendNfcSocketDataTask> task =
-    new SendNfcSocketDataTask(mStreamSocket, raw);
-  NS_DispatchToMainThread(task);
-  return true;
+  return mNfcConsumer->PostToNfcDaemon(aData, aSize);
 }
 
 NS_IMETHODIMP
 NfcService::SendCommand(JS::HandleValue aOptions, JSContext* aCx)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NfcCommandOptions options;
 
   if (!options.Init(aCx, aOptions)) {
     NS_WARNING("Bad dictionary passed to NfcService::SendCommand");
     return NS_ERROR_FAILURE;
   }
 
-  // Dispatch the command to the NFC thread.
-  CommandOptions commandOptions(options);
-  nsCOMPtr<nsIRunnable> runnable = new NfcCommandRunnable(mHandler, this,
-                                                          commandOptions);
-  mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
+  mNfcConsumer->SendCommand(CommandOptions(options));
+
   return NS_OK;
 }
 
 void
 NfcService::DispatchNfcEvent(const mozilla::dom::NfcEventOptions& aOptions)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -429,62 +576,16 @@ NfcService::DispatchNfcEvent(const mozil
 
   if (!ToJSValue(cx, aOptions, &val)) {
     return;
   }
 
   mListener->OnEvent(val);
 }
 
-// |StreamSocketConsumer|, |ListenSocketConsumer|
-
-void
-NfcService::ReceiveSocketData(
-  int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer)
-{
-  MOZ_ASSERT(mHandler);
-  nsCOMPtr<nsIRunnable> runnable =
-    new NfcEventRunnable(mHandler, aBuffer.forget());
-  mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
-}
-
-void
-NfcService::OnConnectSuccess(int aIndex)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  switch (aIndex) {
-    case LISTEN_SOCKET: {
-        nsCString value("nfcd:-S -a ");
-        value.Append(mListenSocketName);
-        if (NS_WARN_IF(property_set("ctl.start", value.get()) < 0)) {
-          OnConnectError(STREAM_SOCKET);
-        }
-      }
-      break;
-    case STREAM_SOCKET:
-      /* nothing to do */
-      break;
-  }
-}
-
-void
-NfcService::OnConnectError(int aIndex)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  Shutdown();
-}
-
-void
-NfcService::OnDisconnect(int aIndex)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(NfcService,
                                          NfcService::FactoryCreate)
 
 NS_DEFINE_NAMED_CID(NS_NFCSERVICE_CID);
 
 static const mozilla::Module::CIDEntry kNfcServiceCIDs[] = {
   { &kNS_NFCSERVICE_CID, false, nullptr, NfcServiceConstructor },
   { nullptr }
--- a/dom/nfc/gonk/NfcService.h
+++ b/dom/nfc/gonk/NfcService.h
@@ -2,71 +2,48 @@
 /* vim: set ts=8 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/. */
 
 #ifndef NfcService_h
 #define NfcService_h
 
-#include <mozilla/ipc/ListenSocket.h>
-#include "mozilla/ipc/ListenSocketConsumer.h"
-#include <mozilla/ipc/StreamSocket.h>
-#include "mozilla/ipc/StreamSocketConsumer.h"
 #include "nsCOMPtr.h"
 #include "nsINfcService.h"
-#include "NfcMessageHandler.h"
 
 class nsIThread;
 
 namespace mozilla {
 namespace dom {
 class NfcEventOptions;
 } // namespace dom
 
-class NfcService final
-  : public nsINfcService
-  , public mozilla::ipc::StreamSocketConsumer
-  , public mozilla::ipc::ListenSocketConsumer
+class NfcConsumer;
+
+class NfcService final : public nsINfcService
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSINFCSERVICE
 
   static already_AddRefed<NfcService> FactoryCreate();
 
   void DispatchNfcEvent(const mozilla::dom::NfcEventOptions& aOptions);
 
   bool PostToNfcDaemon(const uint8_t* aData, size_t aSize);
 
   nsCOMPtr<nsIThread> GetThread() {
     return mThread;
   }
 
-  // Methods for |StreamSocketConsumer| and |ListenSocketConsumer|
-  //
-
-  void ReceiveSocketData(
-    int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer) override;
-  void OnConnectSuccess(int aIndex) override;
-  void OnConnectError(int aIndex) override;
-  void OnDisconnect(int aIndex) override;
-
 private:
-  enum SocketType {
-    LISTEN_SOCKET,
-    STREAM_SOCKET
-  };
-
   NfcService();
   ~NfcService();
 
   nsCOMPtr<nsIThread> mThread;
   nsCOMPtr<nsINfcGonkEventListener> mListener;
-  nsRefPtr<mozilla::ipc::ListenSocket> mListenSocket;
-  nsRefPtr<mozilla::ipc::StreamSocket> mStreamSocket;
-  nsAutoPtr<NfcMessageHandler> mHandler;
-  nsCString mListenSocketName;
+  nsAutoPtr<NfcConsumer> mNfcConsumer;
 };
 
 } // namespace mozilla
 
 #endif // NfcService_h