blob: 439c2c2fab5f559610ee73ddda418a58b3fc037a [file] [log] [blame]
Arman Ugurayfe65fb72015-07-24 19:14:42 -07001//
Jakub Pawlowski5b790fe2017-09-18 09:00:20 -07002// Copyright 2015 Google, Inc.
Arman Ugurayfe65fb72015-07-24 19:14:42 -07003//
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
Arman Ugurayf8881fe2015-08-04 12:56:56 -070019#include <memory>
20
Arman Ugurayfe65fb72015-07-24 19:14:42 -070021#include <base/logging.h>
Hidehiko Abeaeca7aa2017-12-13 18:57:10 +090022#include <base/run_loop.h>
Arman Ugurayfe65fb72015-07-24 19:14:42 -070023
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -070024#include "service/adapter.h"
Bailey Forrest62aa15f2017-01-30 17:38:58 -080025#include "service/hal/bluetooth_av_interface.h"
26#include "service/hal/bluetooth_avrcp_interface.h"
Arman Uguray9ded7b62015-08-31 16:29:07 -070027#include "service/hal/bluetooth_gatt_interface.h"
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -070028#include "service/hal/bluetooth_interface.h"
Arman Ugurayfe65fb72015-07-24 19:14:42 -070029#include "service/ipc/ipc_manager.h"
30#include "service/settings.h"
Bailey Forreste8e6c6b2017-06-07 14:50:08 -070031#include "service/switches.h"
Arman Ugurayfe65fb72015-07-24 19:14:42 -070032
33namespace bluetooth {
34
35namespace {
36
37// The global Daemon instance.
38Daemon* g_daemon = nullptr;
39
Bailey Forreste8e6c6b2017-06-07 14:50:08 -070040class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate {
Arman Ugurayf8881fe2015-08-04 12:56:56 -070041 public:
Myles Watson911d1ae2016-11-28 16:44:40 -080042 DaemonImpl() : initialized_(false) {}
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -070043
44 ~DaemonImpl() override {
Myles Watson911d1ae2016-11-28 16:44:40 -080045 if (!initialized_) return;
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -070046
47 CleanUpBluetoothStack();
48 }
Arman Ugurayf8881fe2015-08-04 12:56:56 -070049
Hidehiko Abeaeca7aa2017-12-13 18:57:10 +090050 void StartMainLoop() override { base::RunLoop().Run(); }
Arman Ugurayf8881fe2015-08-04 12:56:56 -070051
Myles Watson911d1ae2016-11-28 16:44:40 -080052 Settings* GetSettings() const override { return settings_.get(); }
Arman Ugurayf8881fe2015-08-04 12:56:56 -070053
54 base::MessageLoop* GetMessageLoop() const override {
55 return message_loop_.get();
56 }
57
58 private:
Bailey Forreste8e6c6b2017-06-07 14:50:08 -070059 // ipc::IPCManager::Delegate implementation:
60 void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override {
61 if (!settings_->EnableOnStart()) return;
Martin Brabham1a88ace2019-05-10 12:42:15 -070062 adapter_->Enable();
Bailey Forreste8e6c6b2017-06-07 14:50:08 -070063 }
64
65 void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override {
66 // Do nothing.
67 }
68
Arman Uguray9ded7b62015-08-31 16:29:07 -070069 bool StartUpBluetoothInterfaces() {
Myles Watson911d1ae2016-11-28 16:44:40 -080070 if (!hal::BluetoothInterface::Initialize()) goto failed;
Arman Uguray9ded7b62015-08-31 16:29:07 -070071
Myles Watson911d1ae2016-11-28 16:44:40 -080072 if (!hal::BluetoothGattInterface::Initialize()) goto failed;
Arman Uguray9ded7b62015-08-31 16:29:07 -070073
Bailey Forrest62aa15f2017-01-30 17:38:58 -080074 if (!hal::BluetoothAvInterface::Initialize()) goto failed;
75
76 if (!hal::BluetoothAvrcpInterface::Initialize()) goto failed;
77
Arman Uguray9ded7b62015-08-31 16:29:07 -070078 return true;
79
80 failed:
81 ShutDownBluetoothInterfaces();
82 return false;
83 }
84
85 void ShutDownBluetoothInterfaces() {
86 if (hal::BluetoothGattInterface::IsInitialized())
87 hal::BluetoothGattInterface::CleanUp();
88 if (hal::BluetoothInterface::IsInitialized())
89 hal::BluetoothInterface::CleanUp();
Bailey Forrest62aa15f2017-01-30 17:38:58 -080090 if (hal::BluetoothAvInterface::IsInitialized())
91 hal::BluetoothAvInterface::CleanUp();
92 if (hal::BluetoothAvrcpInterface::IsInitialized())
93 hal::BluetoothAvrcpInterface::CleanUp();
Arman Uguray9ded7b62015-08-31 16:29:07 -070094 }
95
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -070096 void CleanUpBluetoothStack() {
97 // The Adapter object needs to be cleaned up before the HAL interfaces.
98 ipc_manager_.reset();
99 adapter_.reset();
Arman Uguray9ded7b62015-08-31 16:29:07 -0700100 ShutDownBluetoothInterfaces();
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -0700101 }
Arman Ugurayf8881fe2015-08-04 12:56:56 -0700102
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -0700103 bool SetUpIPC() {
Arman Ugurayb2286f32015-08-05 21:19:02 -0700104 // If an IPC socket path was given, initialize IPC with it. Otherwise
105 // initialize Binder IPC.
106 if (settings_->UseSocketIPC()) {
Bailey Forreste8e6c6b2017-06-07 14:50:08 -0700107 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_LINUX, this)) {
Arman Ugurayb2286f32015-08-05 21:19:02 -0700108 LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
109 return false;
110 }
Jakub Pawlowski79c2ff92016-10-31 12:56:12 -0700111 return true;
112 }
113
114#if !defined(OS_GENERIC)
Bailey Forreste8e6c6b2017-06-07 14:50:08 -0700115 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, this)) {
Arman Ugurayb2286f32015-08-05 21:19:02 -0700116 LOG(ERROR) << "Failed to set up Binder IPCManager";
Arman Ugurayf8881fe2015-08-04 12:56:56 -0700117 return false;
118 }
Jakub Pawlowski79c2ff92016-10-31 12:56:12 -0700119#else
Bailey Forreste8e6c6b2017-06-07 14:50:08 -0700120 if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, this)) {
Jakub Pawlowski79c2ff92016-10-31 12:56:12 -0700121 LOG(ERROR) << "Failed to set up DBus IPCManager";
122 return false;
123 }
124#endif
Arman Ugurayf8881fe2015-08-04 12:56:56 -0700125
126 return true;
127 }
128
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -0700129 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
Arman Uguray9ded7b62015-08-31 16:29:07 -0700139 if (!StartUpBluetoothInterfaces()) {
140 LOG(ERROR) << "Failed to set up HAL Bluetooth interfaces";
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -0700141 return false;
142 }
143
Arman Uguray0a0d3932015-11-19 15:57:57 -0800144 adapter_ = Adapter::Create();
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -0700145 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_;
Arman Ugurayf8881fe2015-08-04 12:56:56 -0700159 std::unique_ptr<base::MessageLoop> message_loop_;
160 std::unique_ptr<Settings> settings_;
Arman Ugurayd6a4b0c2015-08-13 17:01:07 -0700161 std::unique_ptr<Adapter> adapter_;
Arman Ugurayf8881fe2015-08-04 12:56:56 -0700162 std::unique_ptr<ipc::IPCManager> ipc_manager_;
163
164 DISALLOW_COPY_AND_ASSIGN(DaemonImpl);
165};
166
Arman Ugurayfe65fb72015-07-24 19:14:42 -0700167} // namespace
168
169// static
170bool Daemon::Initialize() {
171 CHECK(!g_daemon);
172
Arman Ugurayf8881fe2015-08-04 12:56:56 -0700173 g_daemon = new DaemonImpl();
Myles Watson911d1ae2016-11-28 16:44:40 -0800174 if (g_daemon->Init()) return true;
Arman Ugurayfe65fb72015-07-24 19:14:42 -0700175
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
185void Daemon::ShutDown() {
186 CHECK(g_daemon);
Arman Ugurayfe65fb72015-07-24 19:14:42 -0700187 delete g_daemon;
Arman Ugurayf8881fe2015-08-04 12:56:56 -0700188 g_daemon = nullptr;
189}
190
191// static
192void Daemon::InitializeForTesting(Daemon* test_daemon) {
193 CHECK(test_daemon);
194 CHECK(!g_daemon);
195
196 g_daemon = test_daemon;
Arman Ugurayfe65fb72015-07-24 19:14:42 -0700197}
198
199// static
200Daemon* Daemon::Get() {
201 CHECK(g_daemon);
202 return g_daemon;
203}
204
Arman Ugurayfe65fb72015-07-24 19:14:42 -0700205} // namespace bluetooth