1 // 2 // Copyright 2015 Google, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "service/daemon.h" 18 19 #include <memory> 20 21 #include <base/logging.h> 22 #include <base/run_loop.h> 23 24 #include "abstract_message_loop.h" 25 #include "service/adapter.h" 26 #include "service/hal/bluetooth_av_interface.h" 27 #include "service/hal/bluetooth_avrcp_interface.h" 28 #include "service/hal/bluetooth_gatt_interface.h" 29 #include "service/hal/bluetooth_interface.h" 30 #include "service/ipc/ipc_manager.h" 31 #include "service/settings.h" 32 #include "service/switches.h" 33 34 namespace bluetooth { 35 36 namespace { 37 38 // The global Daemon instance. 39 Daemon* g_daemon = nullptr; 40 41 class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate { 42 public: 43 DaemonImpl() : initialized_(false) {} 44 45 ~DaemonImpl() override { 46 if (!initialized_) return; 47 48 CleanUpBluetoothStack(); 49 } 50 51 void StartMainLoop() override { base::RunLoop().Run(); } 52 53 Settings* GetSettings() const override { return settings_.get(); } 54 55 btbase::AbstractMessageLoop* GetMessageLoop() const override { 56 return message_loop_.get(); 57 } 58 59 private: 60 // ipc::IPCManager::Delegate implementation: 61 void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override { 62 if (!settings_->EnableOnStart()) return; 63 adapter_->Enable(); 64 } 65 66 void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override { 67 // Do nothing. 68 } 69 70 bool StartUpBluetoothInterfaces() { 71 if (!hal::BluetoothInterface::Initialize()) goto failed; 72 73 if (!hal::BluetoothGattInterface::Initialize()) goto failed; 74 75 if (!hal::BluetoothAvInterface::Initialize()) goto failed; 76 77 if (!hal::BluetoothAvrcpInterface::Initialize()) goto failed; 78 79 return true; 80 81 failed: 82 ShutDownBluetoothInterfaces(); 83 return false; 84 } 85 86 void ShutDownBluetoothInterfaces() { 87 if (hal::BluetoothGattInterface::IsInitialized()) 88 hal::BluetoothGattInterface::CleanUp(); 89 if (hal::BluetoothInterface::IsInitialized()) 90 hal::BluetoothInterface::CleanUp(); 91 if (hal::BluetoothAvInterface::IsInitialized()) 92 hal::BluetoothAvInterface::CleanUp(); 93 if (hal::BluetoothAvrcpInterface::IsInitialized()) 94 hal::BluetoothAvrcpInterface::CleanUp(); 95 } 96 97 void CleanUpBluetoothStack() { 98 // The Adapter object needs to be cleaned up before the HAL interfaces. 99 ipc_manager_.reset(); 100 adapter_.reset(); 101 ShutDownBluetoothInterfaces(); 102 } 103 104 bool SetUpIPC() { 105 // If an IPC socket path was given, initialize IPC with it. Otherwise 106 // initialize Binder IPC. 107 if (settings_->UseSocketIPC()) { 108 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_LINUX, this)) { 109 LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager"; 110 return false; 111 } 112 return true; 113 } 114 115 #if !defined(OS_GENERIC) 116 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, this)) { 117 LOG(ERROR) << "Failed to set up Binder IPCManager"; 118 return false; 119 } 120 #else 121 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, this)) { 122 LOG(ERROR) << "Failed to set up DBus IPCManager"; 123 return false; 124 } 125 #endif 126 127 return true; 128 } 129 130 bool Init() override { 131 CHECK(!initialized_); 132 message_loop_.reset(new btbase::AbstractMessageLoop()); 133 134 settings_.reset(new Settings()); 135 if (!settings_->Init()) { 136 LOG(ERROR) << "Failed to set up Settings"; 137 return false; 138 } 139 140 if (!StartUpBluetoothInterfaces()) { 141 LOG(ERROR) << "Failed to set up HAL Bluetooth interfaces"; 142 return false; 143 } 144 145 adapter_ = Adapter::Create(); 146 ipc_manager_.reset(new ipc::IPCManager(adapter_.get())); 147 148 if (!SetUpIPC()) { 149 CleanUpBluetoothStack(); 150 return false; 151 } 152 153 initialized_ = true; 154 LOG(INFO) << "Daemon initialized"; 155 156 return true; 157 } 158 159 bool initialized_; 160 std::unique_ptr<btbase::AbstractMessageLoop> message_loop_; 161 std::unique_ptr<Settings> settings_; 162 std::unique_ptr<Adapter> adapter_; 163 std::unique_ptr<ipc::IPCManager> ipc_manager_; 164 165 DISALLOW_COPY_AND_ASSIGN(DaemonImpl); 166 }; 167 168 } // namespace 169 170 // static 171 bool Daemon::Initialize() { 172 CHECK(!g_daemon); 173 174 g_daemon = new DaemonImpl(); 175 if (g_daemon->Init()) return true; 176 177 LOG(ERROR) << "Failed to initialize the Daemon object"; 178 179 delete g_daemon; 180 g_daemon = nullptr; 181 182 return false; 183 } 184 185 // static 186 void Daemon::ShutDown() { 187 CHECK(g_daemon); 188 delete g_daemon; 189 g_daemon = nullptr; 190 } 191 192 // static 193 void Daemon::InitializeForTesting(Daemon* test_daemon) { 194 CHECK(test_daemon); 195 CHECK(!g_daemon); 196 197 g_daemon = test_daemon; 198 } 199 200 // static 201 Daemon* Daemon::Get() { 202 CHECK(g_daemon); 203 return g_daemon; 204 } 205 206 } // namespace bluetooth 207