1 /*
2 * Copyright 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
22 using ::bluetooth::os::Handler;
23 using ::bluetooth::os::Thread;
24
25 namespace bluetooth {
26
27 constexpr std::chrono::milliseconds kModuleStopTimeout = std::chrono::milliseconds(2000);
28
ModuleFactory(std::function<Module * ()> ctor)29 ModuleFactory::ModuleFactory(std::function<Module*()> ctor) : ctor_(ctor) {}
30
GetHandler() const31 Handler* Module::GetHandler() const {
32 log::assert_that(handler_ != nullptr, "Can't get handler when it's not started");
33 return handler_;
34 }
35
GetModuleRegistry() const36 const ModuleRegistry* Module::GetModuleRegistry() const { return registry_; }
37
GetDependency(const ModuleFactory * module) const38 Module* Module::GetDependency(const ModuleFactory* module) const {
39 for (auto& dependency : dependencies_.list_) {
40 if (dependency == module) {
41 return registry_->Get(module);
42 }
43 }
44
45 log::fatal("Module was not listed as a dependency in ListDependencies");
46 }
47
Get(const ModuleFactory * module) const48 Module* ModuleRegistry::Get(const ModuleFactory* module) const {
49 auto instance = started_modules_.find(module);
50 log::assert_that(instance != started_modules_.end(),
51 "Request for module not started up, maybe not in Start(ModuleList)?");
52 return instance->second;
53 }
54
IsStarted(const ModuleFactory * module) const55 bool ModuleRegistry::IsStarted(const ModuleFactory* module) const {
56 return started_modules_.find(module) != started_modules_.end();
57 }
58
Start(ModuleList * modules,Thread * thread)59 void ModuleRegistry::Start(ModuleList* modules, Thread* thread) {
60 for (auto it = modules->list_.begin(); it != modules->list_.end(); it++) {
61 Start(*it, thread);
62 }
63 }
64
set_registry_and_handler(Module * instance,Thread * thread) const65 void ModuleRegistry::set_registry_and_handler(Module* instance, Thread* thread) const {
66 instance->registry_ = this;
67 instance->handler_ = new Handler(thread);
68 }
69
Start(const ModuleFactory * module,Thread * thread)70 Module* ModuleRegistry::Start(const ModuleFactory* module, Thread* thread) {
71 auto started_instance = started_modules_.find(module);
72 if (started_instance != started_modules_.end()) {
73 return started_instance->second;
74 }
75
76 log::info("Constructing next module");
77 Module* instance = module->ctor_();
78 set_registry_and_handler(instance, thread);
79
80 log::info("Starting dependencies of {}", instance->ToString());
81 instance->ListDependencies(&instance->dependencies_);
82 Start(&instance->dependencies_, thread);
83
84 log::info("Finished starting dependencies and calling Start() of {}", instance->ToString());
85
86 last_instance_ = "starting " + instance->ToString();
87 instance->Start();
88 start_order_.push_back(module);
89 started_modules_[module] = instance;
90 log::info("Started {}", instance->ToString());
91 return instance;
92 }
93
StopAll()94 void ModuleRegistry::StopAll() {
95 // Since modules were brought up in dependency order, it is safe to tear down by going in reverse
96 // order.
97 for (auto it = start_order_.rbegin(); it != start_order_.rend(); it++) {
98 auto instance = started_modules_.find(*it);
99 log::assert_that(instance != started_modules_.end(),
100 "assert failed: instance != started_modules_.end()");
101 last_instance_ = "stopping " + instance->second->ToString();
102
103 // Clear the handler before stopping the module to allow it to shut down gracefully.
104 log::info("Stopping Handler of Module {}", instance->second->ToString());
105 instance->second->handler_->Clear();
106 instance->second->handler_->WaitUntilStopped(kModuleStopTimeout);
107 log::info("Stopping Module {}", instance->second->ToString());
108 instance->second->Stop();
109 }
110 for (auto it = start_order_.rbegin(); it != start_order_.rend(); it++) {
111 auto instance = started_modules_.find(*it);
112 log::assert_that(instance != started_modules_.end(),
113 "assert failed: instance != started_modules_.end()");
114 delete instance->second->handler_;
115 delete instance->second;
116 started_modules_.erase(instance);
117 }
118
119 log::assert_that(started_modules_.empty(), "assert failed: started_modules_.empty()");
120 start_order_.clear();
121 }
122
GetModuleHandler(const ModuleFactory * module) const123 os::Handler* ModuleRegistry::GetModuleHandler(const ModuleFactory* module) const {
124 auto started_instance = started_modules_.find(module);
125 if (started_instance != started_modules_.end()) {
126 return started_instance->second->GetHandler();
127 }
128 return nullptr;
129 }
130
131 } // namespace bluetooth
132