1// 2// Copyright (C) 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 23#include "service/adapter.h" 24#include "service/hal/bluetooth_gatt_interface.h" 25#include "service/hal/bluetooth_interface.h" 26#include "service/ipc/ipc_manager.h" 27#include "service/settings.h" 28#include "service/switches.h" 29 30namespace bluetooth { 31 32namespace { 33 34// The global Daemon instance. 35Daemon* g_daemon = nullptr; 36 37class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate { 38 public: 39 DaemonImpl() : initialized_(false) {} 40 41 ~DaemonImpl() override { 42 if (!initialized_) return; 43 44 CleanUpBluetoothStack(); 45 } 46 47 void StartMainLoop() override { message_loop_->Run(); } 48 49 Settings* GetSettings() const override { return settings_.get(); } 50 51 base::MessageLoop* GetMessageLoop() const override { 52 return message_loop_.get(); 53 } 54 55 private: 56 // ipc::IPCManager::Delegate implementation: 57 void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override { 58 if (!settings_->EnableOnStart()) return; 59 adapter_->Enable(false /* start_restricted */); 60 } 61 62 void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override { 63 // Do nothing. 64 } 65 66 bool StartUpBluetoothInterfaces() { 67 if (!hal::BluetoothInterface::Initialize()) goto failed; 68 69 if (!hal::BluetoothGattInterface::Initialize()) goto failed; 70 71 return true; 72 73 failed: 74 ShutDownBluetoothInterfaces(); 75 return false; 76 } 77 78 void ShutDownBluetoothInterfaces() { 79 if (hal::BluetoothGattInterface::IsInitialized()) 80 hal::BluetoothGattInterface::CleanUp(); 81 if (hal::BluetoothInterface::IsInitialized()) 82 hal::BluetoothInterface::CleanUp(); 83 } 84 85 void CleanUpBluetoothStack() { 86 // The Adapter object needs to be cleaned up before the HAL interfaces. 87 ipc_manager_.reset(); 88 adapter_.reset(); 89 ShutDownBluetoothInterfaces(); 90 } 91 92 bool SetUpIPC() { 93 // If an IPC socket path was given, initialize IPC with it. Otherwise 94 // initialize Binder IPC. 95 if (settings_->UseSocketIPC()) { 96 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_LINUX, this)) { 97 LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager"; 98 return false; 99 } 100 return true; 101 } 102 103#if !defined(OS_GENERIC) 104 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, this)) { 105 LOG(ERROR) << "Failed to set up Binder IPCManager"; 106 return false; 107 } 108#else 109 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, this)) { 110 LOG(ERROR) << "Failed to set up DBus IPCManager"; 111 return false; 112 } 113#endif 114 115 return true; 116 } 117 118 bool Init() override { 119 CHECK(!initialized_); 120 message_loop_.reset(new base::MessageLoop()); 121 122 settings_.reset(new Settings()); 123 if (!settings_->Init()) { 124 LOG(ERROR) << "Failed to set up Settings"; 125 return false; 126 } 127 128 if (!StartUpBluetoothInterfaces()) { 129 LOG(ERROR) << "Failed to set up HAL Bluetooth interfaces"; 130 return false; 131 } 132 133 adapter_ = Adapter::Create(); 134 ipc_manager_.reset(new ipc::IPCManager(adapter_.get())); 135 136 if (!SetUpIPC()) { 137 CleanUpBluetoothStack(); 138 return false; 139 } 140 141 initialized_ = true; 142 LOG(INFO) << "Daemon initialized"; 143 144 return true; 145 } 146 147 bool initialized_; 148 std::unique_ptr<base::MessageLoop> message_loop_; 149 std::unique_ptr<Settings> settings_; 150 std::unique_ptr<Adapter> adapter_; 151 std::unique_ptr<ipc::IPCManager> ipc_manager_; 152 153 DISALLOW_COPY_AND_ASSIGN(DaemonImpl); 154}; 155 156} // namespace 157 158// static 159bool Daemon::Initialize() { 160 CHECK(!g_daemon); 161 162 g_daemon = new DaemonImpl(); 163 if (g_daemon->Init()) return true; 164 165 LOG(ERROR) << "Failed to initialize the Daemon object"; 166 167 delete g_daemon; 168 g_daemon = nullptr; 169 170 return false; 171} 172 173// static 174void Daemon::ShutDown() { 175 CHECK(g_daemon); 176 delete g_daemon; 177 g_daemon = nullptr; 178} 179 180// static 181void Daemon::InitializeForTesting(Daemon* test_daemon) { 182 CHECK(test_daemon); 183 CHECK(!g_daemon); 184 185 g_daemon = test_daemon; 186} 187 188// static 189Daemon* Daemon::Get() { 190 CHECK(g_daemon); 191 return g_daemon; 192} 193 194} // namespace bluetooth 195