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