• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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