Add flag to bluetoothtbd to enable bluetooth on startup

Bluetooth startup takes a few seconds and it can be done in parallel
during the boot up process.

Bug: None
Test: Test on device.
Change-Id: Ia23bdd6907b6f24d1e3eacb011173acf64a583ed
diff --git a/service/daemon.cc b/service/daemon.cc
index 48d098c..7fd9b2b 100644
--- a/service/daemon.cc
+++ b/service/daemon.cc
@@ -25,6 +25,7 @@
 #include "service/hal/bluetooth_interface.h"
 #include "service/ipc/ipc_manager.h"
 #include "service/settings.h"
+#include "service/switches.h"
 
 namespace bluetooth {
 
@@ -33,7 +34,7 @@
 // The global Daemon instance.
 Daemon* g_daemon = nullptr;
 
-class DaemonImpl : public Daemon {
+class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate {
  public:
   DaemonImpl() : initialized_(false) {}
 
@@ -52,6 +53,16 @@
   }
 
  private:
+  // ipc::IPCManager::Delegate implementation:
+  void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override {
+    if (!settings_->EnableOnStart()) return;
+    adapter_->Enable(false /* start_restricted */);
+  }
+
+  void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override {
+    // Do nothing.
+  }
+
   bool StartUpBluetoothInterfaces() {
     if (!hal::BluetoothInterface::Initialize()) goto failed;
 
@@ -82,7 +93,7 @@
     // 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_LINUX, nullptr)) {
+      if (!ipc_manager_->Start(ipc::IPCManager::TYPE_LINUX, this)) {
         LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
         return false;
       }
@@ -90,12 +101,12 @@
     }
 
 #if !defined(OS_GENERIC)
-    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, nullptr)) {
+    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, this)) {
       LOG(ERROR) << "Failed to set up Binder IPCManager";
       return false;
     }
 #else
-    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, nullptr)) {
+    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, this)) {
       LOG(ERROR) << "Failed to set up DBus IPCManager";
       return false;
     }
diff --git a/service/settings.cc b/service/settings.cc
index d4728d7..79ac030 100644
--- a/service/settings.cc
+++ b/service/settings.cc
@@ -24,7 +24,7 @@
 
 namespace bluetooth {
 
-Settings::Settings() : initialized_(false) {}
+Settings::Settings() : initialized_(false), enable_on_start_(false) {}
 
 Settings::~Settings() {}
 
@@ -54,6 +54,16 @@
       }
 
       android_ipc_socket_suffix_ = suffix;
+    } else if (iter.first == switches::kEnableOnStart) {
+      if (iter.second == "true") {
+        enable_on_start_ = true;
+      } else if (iter.second == "false") {
+        enable_on_start_ = false;
+      } else {
+        LOG(ERROR) << "Invalid value for " << switches::kEnableOnStart << ": "
+                   << iter.second << ". Expect 'true' or 'false'";
+        return false;
+      }
     }
     // Check for libbase logging switches. These get processed by
     // logging::InitLogging directly.
diff --git a/service/settings.h b/service/settings.h
index d68bda1..4e7a6b4 100644
--- a/service/settings.h
+++ b/service/settings.h
@@ -60,8 +60,11 @@
            !create_ipc_socket_path().empty();
   }
 
+  bool EnableOnStart() const { return enable_on_start_; }
+
  private:
   bool initialized_;
+  bool enable_on_start_;
   std::string android_ipc_socket_suffix_;
   base::FilePath create_ipc_socket_path_;
 
diff --git a/service/switches.h b/service/switches.h
index af23398..fe6056a 100644
--- a/service/switches.h
+++ b/service/switches.h
@@ -26,6 +26,7 @@
 const char kHelpShort[] = "h";
 const char kAndroidIPCSocketSuffix[] = "android-ipc-socket-suffix";
 const char kCreateIPCSocketPath[] = "create-ipc-socket";
+const char kEnableOnStart[] = "enable-on-start";
 
 const char kHelpMessage[] =
     "\nBluetooth System Service\n"
@@ -36,6 +37,8 @@
     "Mutually exclusive with --create-ipc-socket.\n"
     "\t--create-ipc-socket\t\tSocket path created for Unix domain socket based "
     "IPC. Mutually exclusive with --android-ipc-socket-suffix.\n"
+    "\t--enable-on-start (true|false)\tIf true, enable adapter as soon as the "
+    "daemon starts.\n"
     "\t--v\t\t\t\tLog verbosity level (e.g. -v=1)\n";
 
 }  // namespace switches