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