• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
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 #define LOG_TAG "BtGdModule"
17 
18 #include "module.h"
19 
20 #include <bluetooth/log.h>
21 #include <com_android_bluetooth_flags.h>
22 
23 using ::bluetooth::os::Handler;
24 using ::bluetooth::os::Thread;
25 
26 namespace bluetooth {
27 
28 constexpr std::chrono::milliseconds kModuleStopTimeout = std::chrono::milliseconds(2000);
29 
ModuleFactory(std::function<Module * ()> ctor)30 ModuleFactory::ModuleFactory(std::function<Module*()> ctor) : ctor_(ctor) {}
31 
GetHandler() const32 Handler* Module::GetHandler() const {
33   log::assert_that(handler_ != nullptr, "Can't get handler when it's not started");
34   return handler_;
35 }
36 
GetModuleRegistry() const37 const ModuleRegistry* Module::GetModuleRegistry() const { return registry_; }
38 
GetDependency(const ModuleFactory * module) const39 Module* Module::GetDependency(const ModuleFactory* module) const {
40   for (auto& dependency : dependencies_.list_) {
41     if (dependency == module) {
42       return registry_->Get(module);
43     }
44   }
45 
46   log::fatal("Module was not listed as a dependency in ListDependencies");
47 }
48 
Get(const ModuleFactory * module) const49 Module* ModuleRegistry::Get(const ModuleFactory* module) const {
50   std::unique_lock<std::mutex> lock(started_modules_guard_, std::defer_lock);
51   if (com::android::bluetooth::flags::fix_started_module_race()) {
52     lock.lock();
53   }
54 
55   auto instance = started_modules_.find(module);
56   log::assert_that(instance != started_modules_.end(),
57                    "Request for module not started up, maybe not in Start(ModuleList)?");
58   return instance->second;
59 }
60 
IsStarted(const ModuleFactory * module) const61 bool ModuleRegistry::IsStarted(const ModuleFactory* module) const {
62   std::unique_lock<std::mutex> lock(started_modules_guard_, std::defer_lock);
63   if (com::android::bluetooth::flags::fix_started_module_race()) {
64     lock.lock();
65   }
66   return started_modules_.find(module) != started_modules_.end();
67 }
68 
Start(ModuleList * modules,Thread * thread,Handler * handler)69 void ModuleRegistry::Start(ModuleList* modules, Thread* thread, Handler* handler) {
70   for (auto it = modules->list_.begin(); it != modules->list_.end(); it++) {
71     Start(*it, thread, handler);
72   }
73 }
74 
set_registry_and_handler(Module * instance,Thread * thread,Handler * handler) const75 void ModuleRegistry::set_registry_and_handler(Module* instance, Thread* thread,
76                                               Handler* handler) const {
77   instance->registry_ = this;
78 
79   if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
80     // Use same handler for all modules initialization.
81     // TODO: remove the dependency on the `thread` when the flag is removed.
82     instance->handler_ = handler;
83   } else {
84     instance->handler_ = new Handler(thread);
85   }
86 }
87 
Start(const ModuleFactory * module,Thread * thread,Handler * handler)88 Module* ModuleRegistry::Start(const ModuleFactory* module, Thread* thread, Handler* handler) {
89   {
90     std::unique_lock<std::mutex> lock(started_modules_guard_, std::defer_lock);
91     if (com::android::bluetooth::flags::fix_started_module_race()) {
92       lock.lock();
93     }
94     auto started_instance = started_modules_.find(module);
95     if (started_instance != started_modules_.end()) {
96       return started_instance->second;
97     }
98   }
99 
100   log::info("Constructing next module");
101   Module* instance = module->ctor_();
102   set_registry_and_handler(instance, thread, handler);
103 
104   log::info("Starting dependencies of {}", instance->ToString());
105   instance->ListDependencies(&instance->dependencies_);
106   Start(&instance->dependencies_, thread, handler);
107 
108   log::info("Finished starting dependencies and calling Start() of {}", instance->ToString());
109 
110   last_instance_ = "starting " + instance->ToString();
111   instance->Start();
112   start_order_.push_back(module);
113   {
114     std::unique_lock<std::mutex> lock(started_modules_guard_, std::defer_lock);
115     if (com::android::bluetooth::flags::fix_started_module_race()) {
116       lock.lock();
117     }
118     started_modules_[module] = instance;
119   }
120   log::info("Started {}", instance->ToString());
121   return instance;
122 }
123 
StopAll()124 void ModuleRegistry::StopAll() {
125   // Since modules were brought up in dependency order, it is safe to tear down by going in reverse
126   // order.
127   for (auto it = start_order_.rbegin(); it != start_order_.rend(); it++) {
128     auto module = Get(*it);
129     last_instance_ = "stopping " + module->ToString();
130 
131     /*
132      * b/393449774 since we have now shifted to a single handler for all modules, we don't need
133      * to clear the handler here, it will be done in the respective teardown.
134      * Since we have a single handler, we need to make sure that the handler instance is deleted
135      * only once, otherwise we will see a crash as a handler can only be cleared once.
136      */
137     if (!com::android::bluetooth::flags::same_handler_for_all_modules()) {
138       // Clear the handler before stopping the module to allow it to shut down gracefully.
139       log::info("Stopping Handler of Module {}", module->ToString());
140       module->handler_->Clear();
141       module->handler_->WaitUntilStopped(kModuleStopTimeout);
142     }
143     log::info("Stopping Module {}", module->ToString());
144     module->Stop();
145   }
146 
147   std::unique_lock<std::mutex> lock(started_modules_guard_, std::defer_lock);
148   if (com::android::bluetooth::flags::fix_started_module_race()) {
149     lock.lock();
150   }
151   for (auto it = start_order_.rbegin(); it != start_order_.rend(); it++) {
152     auto instance = started_modules_.find(*it);
153     log::assert_that(instance != started_modules_.end(),
154                      "assert failed: instance != started_modules_.end()");
155     if (!com::android::bluetooth::flags::same_handler_for_all_modules()) {
156       delete instance->second->handler_;
157     }
158     delete instance->second;
159     started_modules_.erase(instance);
160   }
161 
162   log::assert_that(started_modules_.empty(), "assert failed: started_modules_.empty()");
163   start_order_.clear();
164 }
165 
GetModuleHandler(const ModuleFactory * module) const166 os::Handler* ModuleRegistry::GetModuleHandler(const ModuleFactory* module) const {
167   std::unique_lock<std::mutex> lock(started_modules_guard_, std::defer_lock);
168   if (com::android::bluetooth::flags::fix_started_module_race()) {
169     lock.lock();
170   }
171   auto started_instance = started_modules_.find(module);
172   if (started_instance != started_modules_.end()) {
173     return started_instance->second->GetHandler();
174   }
175   return nullptr;
176 }
177 
178 // Override the StopAll method to use the test thread and handler.
179 // This function will take care of releasing the handler instances.
StopAll()180 void TestModuleRegistry::StopAll() {
181   os::Handler* handler = GetTestHandler();
182   handler->Clear();
183   if (com::android::bluetooth::flags::same_handler_for_all_modules()) {
184     handler->WaitUntilStopped(kHandlerStopTimeout);
185   }
186   ModuleRegistry::StopAll();  // call the base class StopAll
187   delete handler;
188 }
189 }  // namespace bluetooth
190