1 /******************************************************************************
2  *
3  *  Copyright 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #define LOG_TAG "bt_stack_manager"
20 
21 #include "stack_manager.h"
22 
23 #include <hardware/bluetooth.h>
24 
25 #include "btcore/include/module.h"
26 #include "btcore/include/osi_module.h"
27 #include "btif_api.h"
28 #include "btif_common.h"
29 #include "common/message_loop_thread.h"
30 #include "device/include/controller.h"
31 #include "main/shim/shim.h"
32 #include "osi/include/log.h"
33 #include "osi/include/osi.h"
34 #include "osi/include/semaphore.h"
35 
36 // Temp includes
37 #include "bt_utils.h"
38 #include "btif_config.h"
39 #include "btif_profile_queue.h"
40 
41 using bluetooth::common::MessageLoopThread;
42 
43 static MessageLoopThread management_thread("bt_stack_manager_thread");
44 
45 // If initialized, any of the bluetooth API functions can be called.
46 // (e.g. turning logging on and off, enabling/disabling the stack, etc)
47 static bool stack_is_initialized;
48 // If running, the stack is fully up and able to bluetooth.
49 static bool stack_is_running;
50 
51 static void event_init_stack(void* context);
52 static void event_start_up_stack(void* context);
53 static void event_shut_down_stack(void* context);
54 static void event_clean_up_stack(void* context);
55 
56 static void event_signal_stack_up(void* context);
57 static void event_signal_stack_down(void* context);
58 
59 // Unvetted includes/imports, etc which should be removed or vetted in the
60 // future
61 static future_t* hack_future;
62 // End unvetted section
63 
64 // Interface functions
65 
init_stack()66 static void init_stack() {
67   // This is a synchronous process. Post it to the thread though, so
68   // state modification only happens there. Using the thread to perform
69   // all stack operations ensures that the operations are done serially
70   // and do not overlap.
71   semaphore_t* semaphore = semaphore_new(0);
72   management_thread.DoInThread(FROM_HERE,
73                                base::Bind(event_init_stack, semaphore));
74   semaphore_wait(semaphore);
75   semaphore_free(semaphore);
76 }
77 
start_up_stack_async()78 static void start_up_stack_async() {
79   management_thread.DoInThread(FROM_HERE,
80                                base::Bind(event_start_up_stack, nullptr));
81 }
82 
shut_down_stack_async()83 static void shut_down_stack_async() {
84   management_thread.DoInThread(FROM_HERE,
85                                base::Bind(event_shut_down_stack, nullptr));
86 }
87 
clean_up_stack()88 static void clean_up_stack() {
89   // This is a synchronous process. Post it to the thread though, so
90   // state modification only happens there.
91   semaphore_t* semaphore = semaphore_new(0);
92   management_thread.DoInThread(FROM_HERE,
93                                base::Bind(event_clean_up_stack, semaphore));
94   semaphore_wait(semaphore);
95   semaphore_free(semaphore);
96   management_thread.ShutDown();
97 }
98 
get_stack_is_running()99 static bool get_stack_is_running() { return stack_is_running; }
100 
101 // Internal functions
102 
103 // Synchronous function to initialize the stack
event_init_stack(void * context)104 static void event_init_stack(void* context) {
105   semaphore_t* semaphore = (semaphore_t*)context;
106 
107   LOG_INFO("%s is initializing the stack", __func__);
108 
109   if (stack_is_initialized) {
110     LOG_INFO("%s found the stack already in initialized state", __func__);
111   } else {
112     module_management_start();
113 
114     module_init(get_module(OSI_MODULE));
115     module_init(get_module(BT_UTILS_MODULE));
116     if (bluetooth::shim::is_gd_shim_enabled()) {
117       module_start_up(get_module(GD_IDLE_MODULE));
118     }
119     module_init(get_module(BTIF_CONFIG_MODULE));
120     btif_init_bluetooth();
121 
122     // stack init is synchronous, so no waiting necessary here
123     stack_is_initialized = true;
124   }
125 
126   LOG_INFO("%s finished", __func__);
127 
128   if (semaphore) semaphore_post(semaphore);
129 }
130 
ensure_stack_is_initialized()131 static void ensure_stack_is_initialized() {
132   if (!stack_is_initialized) {
133     LOG_WARN("%s found the stack was uninitialized. Initializing now.",
134              __func__);
135     // No semaphore needed since we are calling it directly
136     event_init_stack(nullptr);
137   }
138 }
139 
140 // Synchronous function to start up the stack
event_start_up_stack(UNUSED_ATTR void * context)141 static void event_start_up_stack(UNUSED_ATTR void* context) {
142   if (stack_is_running) {
143     LOG_INFO("%s stack already brought up", __func__);
144     return;
145   }
146 
147   ensure_stack_is_initialized();
148 
149   LOG_INFO("%s is bringing up the stack", __func__);
150   future_t* local_hack_future = future_new();
151   hack_future = local_hack_future;
152 
153   // Include this for now to put btif config into a shutdown-able state
154   bte_main_enable();
155 
156   if (future_await(local_hack_future) != FUTURE_SUCCESS) {
157     LOG_ERROR("%s failed to start up the stack", __func__);
158     stack_is_running = true;  // So stack shutdown actually happens
159     event_shut_down_stack(nullptr);
160     return;
161   }
162 
163   stack_is_running = true;
164   LOG_INFO("%s finished", __func__);
165   do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_up, nullptr));
166 }
167 
168 // Synchronous function to shut down the stack
event_shut_down_stack(UNUSED_ATTR void * context)169 static void event_shut_down_stack(UNUSED_ATTR void* context) {
170   if (!stack_is_running) {
171     LOG_INFO("%s stack is already brought down", __func__);
172     return;
173   }
174 
175   LOG_INFO("%s is bringing down the stack", __func__);
176   future_t* local_hack_future = future_new();
177   hack_future = local_hack_future;
178   stack_is_running = false;
179 
180   btif_disable_bluetooth();
181   module_shut_down(get_module(BTIF_CONFIG_MODULE));
182 
183   future_await(local_hack_future);
184   module_shut_down(get_module(CONTROLLER_MODULE));  // Doesn't do any work, just
185                                                     // puts it in a restartable
186                                                     // state
187 
188   hack_future = future_new();
189   do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_down, nullptr));
190   future_await(hack_future);
191   LOG_INFO("%s finished", __func__);
192 }
193 
ensure_stack_is_not_running()194 static void ensure_stack_is_not_running() {
195   if (stack_is_running) {
196     LOG_WARN("%s found the stack was still running. Bringing it down now.",
197              __func__);
198     event_shut_down_stack(nullptr);
199   }
200 }
201 
202 // Synchronous function to clean up the stack
event_clean_up_stack(void * context)203 static void event_clean_up_stack(void* context) {
204   if (!stack_is_initialized) {
205     LOG_INFO("%s found the stack already in a clean state", __func__);
206     goto cleanup;
207   }
208 
209   ensure_stack_is_not_running();
210 
211   LOG_INFO("%s is cleaning up the stack", __func__);
212   stack_is_initialized = false;
213 
214   btif_cleanup_bluetooth();
215   module_clean_up(get_module(BTIF_CONFIG_MODULE));
216   module_clean_up(get_module(BT_UTILS_MODULE));
217   module_clean_up(get_module(OSI_MODULE));
218   module_shut_down(get_module(GD_IDLE_MODULE));
219   module_management_stop();
220   LOG_INFO("%s finished", __func__);
221 
222 cleanup:;
223   semaphore_t* semaphore = (semaphore_t*)context;
224   if (semaphore) semaphore_post(semaphore);
225 }
226 
event_signal_stack_up(UNUSED_ATTR void * context)227 static void event_signal_stack_up(UNUSED_ATTR void* context) {
228   // Notify BTIF connect queue that we've brought up the stack. It's
229   // now time to dispatch all the pending profile connect requests.
230   btif_queue_connect_next();
231   HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
232 }
233 
event_signal_stack_down(UNUSED_ATTR void * context)234 static void event_signal_stack_down(UNUSED_ATTR void* context) {
235   HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
236   future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
237 }
238 
ensure_manager_initialized()239 static void ensure_manager_initialized() {
240   if (management_thread.IsRunning()) return;
241 
242   management_thread.StartUp();
243   if (!management_thread.IsRunning()) {
244     LOG_ERROR("%s unable to start stack management thread", __func__);
245     return;
246   }
247 }
248 
249 static const stack_manager_t interface = {init_stack, start_up_stack_async,
250                                           shut_down_stack_async, clean_up_stack,
251                                           get_stack_is_running};
252 
stack_manager_get_interface()253 const stack_manager_t* stack_manager_get_interface() {
254   ensure_manager_initialized();
255   return &interface;
256 }
257 
stack_manager_get_hack_future()258 future_t* stack_manager_get_hack_future() { return hack_future; }
259