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