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