service: Add IPCHandlerBinder

This CL integrates Binder IPC into the daemon. This introduces
IPCHandlerBinder and BluetoothBinderServer which is the Binder server
proxy for IBluetooth. A new command-line switch is introduced to
optionally disable Binder on platforms that do not use it.

BluetoothBinderServer currently does not fully implement any of the IPC
calls and consists of stubs.

Bug: 22743677
Change-Id: I3e4ba7a3211898bab0c9c8061f4e4db3854711ed
diff --git a/service/Android.mk b/service/Android.mk
index de963a8..6d4f130 100644
--- a/service/Android.mk
+++ b/service/Android.mk
@@ -32,7 +32,9 @@
 	uuid.cpp
 
 btserviceBinderSrc := \
-	ipc/binder/IBluetooth.cpp
+	ipc/binder/IBluetooth.cpp \
+	ipc/binder/bluetooth_binder_server.cpp \
+	ipc/binder/ipc_handler_binder.cpp
 
 btserviceCommonIncludes := $(LOCAL_PATH)/../
 
@@ -67,6 +69,7 @@
 	test/fake_hal_util.cpp \
 	test/ipc_unix_unittest.cpp \
 	test/settings_unittest.cpp \
+	test/stub_ipc_handler_binder.cpp \
 	test/uuid_unittest.cpp
 LOCAL_C_INCLUDES += $(btserviceCommonIncludes)
 LOCAL_CFLAGS += -std=c++11
diff --git a/service/daemon.cpp b/service/daemon.cpp
index 400bb18..3d0e847 100644
--- a/service/daemon.cpp
+++ b/service/daemon.cpp
@@ -66,11 +66,15 @@
 
     ipc_manager_.reset(new ipc::IPCManager(core_stack_.get()));
 
-    // If an IPC socket path was given, initialize IPC with it.
-    if ((!settings_->create_ipc_socket_path().empty() ||
-         !settings_->android_ipc_socket_suffix().empty()) &&
-        !ipc_manager_->Start(ipc::IPCManager::TYPE_UNIX, nullptr)) {
-      LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
+    // If an IPC socket path was given, initialize IPC with it. Otherwise
+    // initialize Binder IPC.
+    if (settings_->UseSocketIPC()) {
+      if (!ipc_manager_->Start(ipc::IPCManager::TYPE_UNIX, nullptr)) {
+        LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
+        return false;
+      }
+    } else if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, nullptr)) {
+      LOG(ERROR) << "Failed to set up Binder IPCManager";
       return false;
     }
 
diff --git a/service/ipc/binder/bluetooth_binder_server.cpp b/service/ipc/binder/bluetooth_binder_server.cpp
new file mode 100644
index 0000000..15ae741
--- /dev/null
+++ b/service/ipc/binder/bluetooth_binder_server.cpp
@@ -0,0 +1,58 @@
+//
+//  Copyright (C) 2015 Google, Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at:
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  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 "service/ipc/binder/bluetooth_binder_server.h"
+
+#include <base/logging.h>
+
+namespace ipc {
+
+BluetoothBinderServer::BluetoothBinderServer(bluetooth::CoreStack* core_stack)
+    : core_stack_(core_stack) {
+  CHECK(core_stack_);
+}
+
+BluetoothBinderServer::~BluetoothBinderServer() {
+}
+
+// binder::BnBluetooth overrides:
+bool BluetoothBinderServer::IsEnabled() {
+  // TODO(armansito): Implement.
+  VLOG(2) << __func__;
+  return false;
+}
+
+int BluetoothBinderServer::GetState() {
+  // TODO(armansito): Implement.
+  return -1;
+}
+
+bool BluetoothBinderServer::Enable() {
+  // TODO(armansito): Implement.
+  return false;
+}
+
+bool BluetoothBinderServer::EnableNoAutoConnect() {
+  // TODO(armansito): Implement.
+  return false;
+}
+
+bool BluetoothBinderServer::Disable() {
+  // TODO(armansito): Implement.
+  return false;
+}
+
+}  // namespace ipc
diff --git a/service/ipc/binder/bluetooth_binder_server.h b/service/ipc/binder/bluetooth_binder_server.h
new file mode 100644
index 0000000..441aedd
--- /dev/null
+++ b/service/ipc/binder/bluetooth_binder_server.h
@@ -0,0 +1,49 @@
+//
+//  Copyright (C) 2015 Google, Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at:
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  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.
+//
+
+#pragma once
+
+#include <base/macros.h>
+
+#include "service/ipc/binder/IBluetooth.h"
+
+namespace bluetooth {
+class CoreStack;
+}  // namespace bluetooth
+
+namespace ipc {
+
+// Implements the server side of the IBluetooth Binder interface.
+class BluetoothBinderServer : public binder::BnBluetooth {
+ public:
+  explicit BluetoothBinderServer(bluetooth::CoreStack* core_stack);
+  ~BluetoothBinderServer() override;
+
+  // binder::BnBluetooth overrides:
+  bool IsEnabled() override;
+  int GetState() override;
+  bool Enable() override;
+  bool EnableNoAutoConnect() override;
+  bool Disable() override;
+
+ private:
+  // Weak handle on the CoreStack.
+  bluetooth::CoreStack* core_stack_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothBinderServer);
+};
+
+}  // namespace ipc
diff --git a/service/ipc/binder/ipc_handler_binder.cpp b/service/ipc/binder/ipc_handler_binder.cpp
new file mode 100644
index 0000000..d15be08
--- /dev/null
+++ b/service/ipc/binder/ipc_handler_binder.cpp
@@ -0,0 +1,82 @@
+//
+//  Copyright (C) 2015 Google, Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at:
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  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 "service/ipc/binder/ipc_handler_binder.h"
+
+#include <base/bind.h>
+#include <base/logging.h>
+#include <base/message_loop/message_loop.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "service/ipc/binder/bluetooth_binder_server.h"
+
+using android::defaultServiceManager;
+using android::sp;
+using android::status_t;
+using android::String16;
+
+namespace ipc {
+
+IPCHandlerBinder::IPCHandlerBinder(
+    bluetooth::CoreStack* core_stack,
+    IPCManager::Delegate* delegate)
+    : IPCHandler(core_stack, delegate) {
+}
+
+IPCHandlerBinder::~IPCHandlerBinder() {
+}
+
+bool IPCHandlerBinder::Run() {
+  CHECK(core_stack());
+
+  // Register the IBluetooth service with the Android ServiceManager.
+  android::sp<BluetoothBinderServer> bt_server =
+      new BluetoothBinderServer(core_stack());
+  status_t status = defaultServiceManager()->addService(
+      String16(binder::IBluetooth::kBluetoothServiceName),
+      bt_server);
+  if (status != android::NO_ERROR) {
+    LOG(ERROR) << "Failed to register Bluetooth service with ServiceManager";
+    return false;
+  }
+
+  // Notify the delegate. We do this in the message loop to avoid reentrancy.
+  if (delegate()) {
+    base::MessageLoop::current()->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&IPCHandlerBinder::NotifyStarted, this));
+  }
+
+  android::ProcessState::self()->startThreadPool();
+
+  return true;
+}
+
+void IPCHandlerBinder::Stop() {
+  // TODO(armansito): There are several methods in android::IPCThreadState that
+  // are related to shutting down the threadpool, however I haven't been able to
+  // make them shut things down cleanly. Figure out the right way to stop the
+  // Binder IPC here.
+}
+
+void IPCHandlerBinder::NotifyStarted() {
+  if (delegate())
+    delegate()->OnIPCHandlerStarted(IPCManager::TYPE_BINDER);
+}
+
+}  // namespace ipc
diff --git a/service/ipc/binder/ipc_handler_binder.h b/service/ipc/binder/ipc_handler_binder.h
new file mode 100644
index 0000000..f545802
--- /dev/null
+++ b/service/ipc/binder/ipc_handler_binder.h
@@ -0,0 +1,46 @@
+//
+//  Copyright (C) 2015 Google, Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at:
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  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.
+//
+
+#pragma once
+
+#include <base/macros.h>
+
+#include "service/ipc/ipc_handler.h"
+#include "service/ipc/ipc_manager.h"
+
+namespace ipc {
+
+// Implements a Binder based IPCHandler.
+class IPCHandlerBinder : public IPCHandler {
+ public:
+  IPCHandlerBinder(bluetooth::CoreStack* core_stack,
+                   IPCManager::Delegate* delegate);
+  ~IPCHandlerBinder() override;
+
+  // IPCHandler overrides:
+  bool Run() override;
+  void Stop() override;
+
+ private:
+  IPCHandlerBinder() = default;
+
+  // Notify the delegate that IPC has started.
+  void NotifyStarted();
+
+  DISALLOW_COPY_AND_ASSIGN(IPCHandlerBinder);
+};
+
+}  // namespace ipc
diff --git a/service/ipc/ipc_handler_unix.h b/service/ipc/ipc_handler_unix.h
index 0beb852..53e84c1 100644
--- a/service/ipc/ipc_handler_unix.h
+++ b/service/ipc/ipc_handler_unix.h
@@ -30,10 +30,6 @@
 class SingleThreadTaskRunner;
 }  // namespace base
 
-namespace bluetooth {
-class CoreStack;
-}  // namespace bluetooth
-
 namespace ipc {
 
 // Implements a UNIX domain-socket based IPCHandler
diff --git a/service/ipc/ipc_manager.cpp b/service/ipc/ipc_manager.cpp
index 0ff67d5..ad9ae73 100644
--- a/service/ipc/ipc_manager.cpp
+++ b/service/ipc/ipc_manager.cpp
@@ -16,6 +16,7 @@
 
 #include "service/ipc/ipc_manager.h"
 
+#include "service/ipc/binder/ipc_handler_binder.h"
 #include "service/ipc/ipc_handler_unix.h"
 
 namespace ipc {
@@ -37,14 +38,31 @@
 bool IPCManager::Start(Type type, Delegate* delegate) {
   switch (type) {
   case TYPE_UNIX:
+    if (UnixStarted()) {
+      LOG(ERROR) << "IPCManagerUnix already started.";
+      return false;
+    }
+
     unix_handler_ = new IPCHandlerUnix(core_stack_, delegate);
     if (!unix_handler_->Run()) {
       unix_handler_ = nullptr;
       return false;
     }
     return true;
+
   case TYPE_BINDER:
-    // TODO(armansito): Support Binder
+    if (BinderStarted()) {
+      LOG(ERROR) << "IPCManagerBinder already started.";
+      return false;
+    }
+
+    binder_handler_ = new IPCHandlerBinder(core_stack_, delegate);
+    if (!binder_handler_->Run()) {
+      binder_handler_ = nullptr;
+      return false;
+    }
+    return true;
+
   default:
     LOG(ERROR) << "Unsupported IPC type given: " << type;
   }
diff --git a/service/settings.cpp b/service/settings.cpp
index 66235e7..b7e9048 100644
--- a/service/settings.cpp
+++ b/service/settings.cpp
@@ -23,7 +23,8 @@
 
 namespace bluetooth {
 
-Settings::Settings() : initialized_(false) {
+Settings::Settings()
+    : initialized_(false) {
 }
 
 Settings::~Settings() {
diff --git a/service/settings.h b/service/settings.h
index 4747dba..4c4ea4f 100644
--- a/service/settings.h
+++ b/service/settings.h
@@ -53,6 +53,13 @@
     return create_ipc_socket_path_;
   }
 
+  // Returns true if domain-socket based IPC should be used. If false, then
+  // Binder IPC must be used.
+  inline bool UseSocketIPC() const {
+    return !android_ipc_socket_suffix().empty() ||
+        !create_ipc_socket_path().empty();
+  }
+
  private:
   bool initialized_;
   std::string android_ipc_socket_suffix_;
diff --git a/service/switches.h b/service/switches.h
index 755b4d2..6566638 100644
--- a/service/switches.h
+++ b/service/switches.h
@@ -31,11 +31,11 @@
     "\nBluetooth System Service\n"
     "\n"
     "Usage:\n"
-    "\t--help,-h\tShow this help message\n"
+    "\t--help,-h\t\t\tShow this help message\n"
     "\t--android-ipc-socket-suffix\tSuffix of socket created by Android init. "
     "Mutually exclusive with --create-ipc-socket.\n"
-    "\t--create-ipc-socket\tSocket path created for Unix domain socket based "
-    "IPC. Mutually exclusive with --android-ipc-socket-suffix.";
+    "\t--create-ipc-socket\t\tSocket path created for Unix domain socket based "
+    "IPC. Mutually exclusive with --android-ipc-socket-suffix.\n";
 
 }  // namespace switches
 }  // namespace bluetooth
diff --git a/service/test/stub_ipc_handler_binder.cpp b/service/test/stub_ipc_handler_binder.cpp
new file mode 100644
index 0000000..a9c6e64
--- /dev/null
+++ b/service/test/stub_ipc_handler_binder.cpp
@@ -0,0 +1,49 @@
+//
+//  Copyright (C) 2015 Google, Inc.
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at:
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  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 "service/ipc/binder/ipc_handler_binder.h"
+
+// TODO(armansito): This is a crappy workaround to link IPCHandlerBinder into
+// host-native unit tests. We should instead figure out a way to build Binder
+// unit tests for host.
+
+namespace ipc {
+
+IPCHandlerBinder::IPCHandlerBinder(
+    bluetooth::CoreStack* core_stack,
+    IPCManager::Delegate* delegate)
+    : IPCHandler(core_stack, delegate) {
+  // Stub
+}
+
+IPCHandlerBinder::~IPCHandlerBinder() {
+  // Stub
+}
+
+bool IPCHandlerBinder::Run() {
+  // Stub
+  return false;
+}
+
+void IPCHandlerBinder::Stop() {
+  // Stub
+}
+
+void IPCHandlerBinder::NotifyStarted() {
+  // Stub
+}
+
+}  // namespace