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