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 17 #pragma once 18 19 #include <functional> 20 #include <future> 21 #include <map> 22 #include <string> 23 #include <vector> 24 25 #include "common/bind.h" 26 #include "os/handler.h" 27 #include "os/log.h" 28 #include "os/thread.h" 29 30 namespace bluetooth { 31 32 class Module; 33 class ModuleRegistry; 34 35 class ModuleFactory { 36 friend ModuleRegistry; 37 public: 38 ModuleFactory(std::function<Module*()> ctor); 39 40 private: 41 std::function<Module*()> ctor_; 42 }; 43 44 class ModuleList { 45 friend ModuleRegistry; 46 friend Module; 47 public: 48 template <class T> add()49 void add() { 50 list_.push_back(&T::Factory); 51 } 52 53 private: 54 std::vector<const ModuleFactory*> list_; 55 }; 56 57 // Each leaf node module must have a factory like so: 58 // 59 // static const ModuleFactory Factory; 60 // 61 // which will provide a constructor for the module registry to call. 62 // The module registry will also use the factory as the identifier 63 // for that module. 64 class Module { 65 friend ModuleRegistry; 66 public: 67 virtual ~Module() = default; 68 protected: 69 // Populate the provided list with modules that must start before yours 70 virtual void ListDependencies(ModuleList* list) = 0; 71 72 // You can grab your started dependencies during or after this call 73 // using GetDependency(), or access the module registry via GetModuleRegistry() 74 virtual void Start() = 0; 75 76 // Release all resources, you're about to be deleted 77 virtual void Stop() = 0; 78 79 virtual std::string ToString() const; 80 81 ::bluetooth::os::Handler* GetHandler() const; 82 83 const ModuleRegistry* GetModuleRegistry() const; 84 85 template <class T> GetDependency()86 T* GetDependency() const { 87 return static_cast<T*>(GetDependency(&T::Factory)); 88 } 89 90 private: 91 Module* GetDependency(const ModuleFactory* module) const; 92 93 ::bluetooth::os::Handler* handler_ = nullptr; 94 ModuleList dependencies_; 95 const ModuleRegistry* registry_; 96 }; 97 98 class ModuleRegistry { 99 friend Module; 100 friend class StackManager; 101 public: 102 template <class T> IsStarted()103 bool IsStarted() const { 104 return IsStarted(&T::Factory); 105 } 106 107 bool IsStarted(const ModuleFactory* factory) const; 108 109 // Start all the modules on this list and their dependencies 110 // in dependency order 111 void Start(ModuleList* modules, ::bluetooth::os::Thread* thread); 112 113 template <class T> Start(::bluetooth::os::Thread * thread)114 T* Start(::bluetooth::os::Thread* thread) { 115 return static_cast<T*>(Start(&T::Factory, thread)); 116 } 117 118 Module* Start(const ModuleFactory* id, ::bluetooth::os::Thread* thread); 119 120 // Stop all running modules in reverse order of start 121 void StopAll(); 122 123 protected: 124 Module* Get(const ModuleFactory* module) const; 125 126 void set_registry_and_handler(Module* instance, ::bluetooth::os::Thread* thread) const; 127 128 os::Handler* GetModuleHandler(const ModuleFactory* module) const; 129 130 std::map<const ModuleFactory*, Module*> started_modules_; 131 std::vector<const ModuleFactory*> start_order_; 132 }; 133 134 class TestModuleRegistry : public ModuleRegistry { 135 public: InjectTestModule(const ModuleFactory * module,Module * instance)136 void InjectTestModule(const ModuleFactory* module, Module* instance) { 137 start_order_.push_back(module); 138 started_modules_[module] = instance; 139 set_registry_and_handler(instance, &test_thread); 140 } 141 GetModuleUnderTest(const ModuleFactory * module)142 Module* GetModuleUnderTest(const ModuleFactory* module) const { 143 return Get(module); 144 } 145 GetTestModuleHandler(const ModuleFactory * module)146 os::Handler* GetTestModuleHandler(const ModuleFactory* module) const { 147 return GetModuleHandler(module); 148 } 149 GetTestThread()150 os::Thread& GetTestThread() { 151 return test_thread; 152 } 153 SynchronizeModuleHandler(const ModuleFactory * module,std::chrono::milliseconds timeout)154 bool SynchronizeModuleHandler(const ModuleFactory* module, std::chrono::milliseconds timeout) const { 155 std::promise<void> promise; 156 auto future = promise.get_future(); 157 os::Handler* handler = GetTestModuleHandler(module); 158 handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise))); 159 return future.wait_for(timeout) == std::future_status::ready; 160 } 161 162 private: 163 os::Thread test_thread{"test_thread", os::Thread::Priority::NORMAL}; 164 }; 165 166 } // namespace bluetooth 167