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