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