1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef OHOS_ABILITY_RUNTIME_BINDABLE_H 17 #define OHOS_ABILITY_RUNTIME_BINDABLE_H 18 19 #include <memory> 20 #include <mutex> 21 22 class NativeReference; 23 typedef class __ani_ref *ani_ref; 24 namespace OHOS { 25 namespace AbilityRuntime { 26 class Runtime; 27 28 class BindingObject final { 29 public: 30 BindingObject() = default; 31 ~BindingObject() = default; 32 33 template<class T> Bind(Runtime & runtime,T * object)34 void Bind(Runtime& runtime, T* object) 35 { 36 static_assert(IsValidType<T>(), "T must be ani_ref or NativeReference"); 37 const std::string typeName = GetTypeString<T>(); 38 std::lock_guard guard(objectsMutex_); 39 std::unique_ptr<void, void (*)(void*)> obj(object, SimpleRelease<T>); 40 objects_.emplace(typeName, std::move(obj)); 41 } 42 43 template<class T> Bind(T * object)44 void Bind(T* object) 45 { 46 static_assert(IsValidType<T>(), "T must be ani_ref or NativeReference"); 47 const std::string typeName = GetTypeString<T>(); 48 std::lock_guard guard(objectsMutex_); 49 std::unique_ptr<void, void (*)(void*)> obj(object, SimpleRelease<T>); 50 objects_.emplace(typeName, std::move(obj)); 51 } 52 53 template<class T> Get()54 T* Get() 55 { 56 const std::string typeName = GetTypeString<T>(); 57 std::lock_guard guard(objectsMutex_); 58 const auto& iter = objects_.find(typeName); 59 if (iter == objects_.end()) { 60 return nullptr; 61 } 62 return static_cast<T*>(iter->second.get()); 63 } 64 Unbind()65 void Unbind() 66 { 67 // Consistency with previous behavior 68 Unbind<NativeReference>(); 69 } 70 71 template<class T> Unbind()72 void Unbind() 73 { 74 const std::string typeName = GetTypeString<T>(); 75 std::lock_guard guard(objectsMutex_); 76 const auto& iter = objects_.find(typeName); 77 if (iter == objects_.end()) { 78 return; 79 } 80 iter->second.release(); 81 } 82 83 BindingObject(const BindingObject&) = delete; 84 BindingObject& operator=(const BindingObject&) = delete; 85 BindingObject(BindingObject&&) = delete; 86 BindingObject& operator=(BindingObject&&) = delete; 87 88 private: 89 template<class T> SimpleRelease(void * ptr)90 static void SimpleRelease(void* ptr) 91 { 92 delete static_cast<T*>(ptr); 93 } 94 95 template<class T> IsValidType()96 static constexpr bool IsValidType() 97 { 98 if (std::is_same_v<T, ani_ref> || std::is_same_v<T, NativeReference>) { 99 return true; 100 } 101 return false; 102 } 103 104 template<class T> GetTypeString()105 static std::string GetTypeString() 106 { 107 if (std::is_same_v<T, ani_ref>) { 108 return "ani_ref"; 109 } else { 110 return "NativeReference"; 111 } 112 } 113 114 std::map<std::string, std::unique_ptr<void, void (*)(void*)>> objects_; 115 std::mutex objectsMutex_; 116 }; 117 118 class BindingObjectSubThread { 119 public: 120 BindingObjectSubThread() = default; 121 virtual ~BindingObjectSubThread() = default; 122 123 virtual void BindSubThreadObject(void* napiEnv, void* object); 124 virtual void* GetSubThreadObject(void* napiEnv); 125 virtual void RemoveSubThreadObject(void* napiEnv); 126 virtual void RemoveAllObject(); 127 128 private: 129 BindingObjectSubThread(const BindingObjectSubThread&) = delete; 130 BindingObjectSubThread(BindingObjectSubThread&&) = delete; 131 BindingObjectSubThread& operator=(const BindingObjectSubThread&) = delete; 132 BindingObjectSubThread& operator=(BindingObjectSubThread&&) = delete; 133 }; 134 135 class Bindable { 136 public: 137 virtual ~Bindable() = default; 138 139 template<class T> Bind(Runtime & runtime,T * object)140 void Bind(Runtime& runtime, T* object) 141 { 142 if (object_) { 143 object_->Bind(runtime, object); 144 } 145 } 146 147 template<class T> Bind(T * object)148 void Bind(T* object) 149 { 150 if (object_) { 151 object_->Bind(object); 152 } 153 } 154 Unbind()155 void Unbind() const 156 { 157 if (object_) { 158 object_->Unbind(); 159 } 160 161 if (subThreadObject_) { 162 subThreadObject_->RemoveAllObject(); 163 } 164 } 165 166 template<class T> Unbind()167 void Unbind() const 168 { 169 if (object_) { 170 object_->Unbind<T>(); 171 } 172 173 if (subThreadObject_) { 174 subThreadObject_->RemoveAllObject(); 175 } 176 } 177 GetBindingObject()178 const std::unique_ptr<BindingObject>& GetBindingObject() const 179 { 180 return object_; 181 } 182 BindSubThreadObject(void * napiEnv,void * object)183 void BindSubThreadObject(void* napiEnv, void* object) 184 { 185 if (subThreadObject_) { 186 subThreadObject_->BindSubThreadObject(napiEnv, object); 187 } 188 } 189 GetSubThreadObject(void * napiEnv)190 void* GetSubThreadObject(void* napiEnv) 191 { 192 if (subThreadObject_) { 193 return subThreadObject_->GetSubThreadObject(napiEnv); 194 } 195 return nullptr; 196 } 197 198 protected: 199 Bindable() = default; 200 std::unique_ptr<BindingObjectSubThread> subThreadObject_ = nullptr; 201 202 private: 203 std::unique_ptr<BindingObject> object_ = std::make_unique<BindingObject>(); 204 }; 205 } // namespace AbilityRuntime 206 } // namespace OHOS 207 #endif // OHOS_ABILITY_RUNTIME_BINDABLE_H 208