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