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:
DaemonImpl()43 DaemonImpl() : initialized_(false) {}
44
~DaemonImpl()45 ~DaemonImpl() override {
46 if (!initialized_) return;
47
48 CleanUpBluetoothStack();
49 }
50
StartMainLoop()51 void StartMainLoop() override { base::RunLoop().Run(); }
52
GetSettings() const53 Settings* GetSettings() const override { return settings_.get(); }
54
GetMessageLoop() const55 btbase::AbstractMessageLoop* GetMessageLoop() const override {
56 return message_loop_.get();
57 }
58
59 private:
60 // ipc::IPCManager::Delegate implementation:
OnIPCHandlerStarted(ipc::IPCManager::Type)61 void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override {
62 if (!settings_->EnableOnStart()) return;
63 adapter_->Enable();
64 }
65
OnIPCHandlerStopped(ipc::IPCManager::Type)66 void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override {
67 // Do nothing.
68 }
69
StartUpBluetoothInterfaces()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
ShutDownBluetoothInterfaces()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
CleanUpBluetoothStack()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
SetUpIPC()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
Init()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
Initialize()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
ShutDown()186 void Daemon::ShutDown() {
187 CHECK(g_daemon);
188 delete g_daemon;
189 g_daemon = nullptr;
190 }
191
192 // static
InitializeForTesting(Daemon * test_daemon)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
Get()201 Daemon* Daemon::Get() {
202 CHECK(g_daemon);
203 return g_daemon;
204 }
205
206 } // namespace bluetooth
207