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