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