1 /*
2 * Copyright (c) 2024 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 FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_JSI_NATIVEMODULE_ARKTS_NATIVE_UTILS_BRIDGE_H
17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_JSI_NATIVEMODULE_ARKTS_NATIVE_UTILS_BRIDGE_H
18
19 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_bridge.h"
20 #include "core/common/task_runner_adapter_factory.h"
21
22 namespace OHOS::Ace::NG {
23 struct NativeWeakRef {
NativeWeakRefNativeWeakRef24 explicit NativeWeakRef(AceType* ptr) : rawPtr(ptr)
25 {
26 weakRef = AceType::WeakClaim(ptr);
27 }
28
InvalidNativeWeakRef29 bool Invalid() const
30 {
31 return weakRef.Invalid();
32 }
33
34 AceType* rawPtr = nullptr;
35 WeakPtr<AceType> weakRef;
36 };
37
38 struct NativeStrongRef {
NativeStrongRefNativeStrongRef39 explicit NativeStrongRef(const RefPtr<AceType>& ref) : strongRef(ref) {}
40
RawPtrNativeStrongRef41 AceType* RawPtr() const
42 {
43 return AceType::RawPtr(strongRef);
44 }
45
46 RefPtr<AceType> strongRef;
47 };
48
49 template<typename T>
DestructorInterceptor(void * env,void * nativePtr,void * data)50 void DestructorInterceptor(void* env, void* nativePtr, void* data)
51 {
52 auto* typePtr = reinterpret_cast<T*>(nativePtr);
53 auto taskExecutor = TaskRunnerAdapterFactory::Create(true, "");
54 if (!taskExecutor) {
55 delete typePtr;
56 return;
57 }
58 taskExecutor->PostTask([taskExecutor, typePtr]() { delete typePtr; }, "DestructorInterceptor");
59 }
60
61 template<typename T>
GetPointerField(ArkUIRuntimeCallInfo * runtimeCallInfo)62 T* GetPointerField(ArkUIRuntimeCallInfo* runtimeCallInfo)
63 {
64 EcmaVM* vm = runtimeCallInfo->GetVM();
65 CHECK_NULL_RETURN(vm, nullptr);
66 Local<JSValueRef> thisRef = runtimeCallInfo->GetThisRef();
67 if (!thisRef->IsObject(vm)) {
68 return nullptr;
69 }
70 Local<panda::ObjectRef> thisObj = thisRef->ToObject(vm);
71 auto* pointer = reinterpret_cast<T*>(thisObj->GetNativePointerField(vm, 0));
72 return pointer;
73 }
74
75 template<typename T>
76 class JsWeak {
77 public:
JsWeak()78 JsWeak() {}
~JsWeak()79 ~JsWeak()
80 {
81 value_.Reset();
82 }
83
JsWeak(const JsWeak<T> & rhs)84 JsWeak(const JsWeak<T>& rhs) : value_(rhs.value_)
85 {
86 value_.SetWeakCallback(this, Reset, nullptr);
87 }
88
JsWeak(JsWeak<T> && rhs)89 JsWeak(JsWeak<T>&& rhs) : value_(std::move(rhs.value_))
90 {
91 value_.SetWeakCallback(this, Reset, nullptr);
92 rhs.value_.Reset();
93 }
94
JsWeak(const T & rhs)95 explicit JsWeak(const T& rhs) : value_(rhs)
96 {
97 value_.SetWeakCallback(this, Reset, nullptr);
98 }
99
100 JsWeak<T>& operator=(const JsWeak<T>& rhs)
101 {
102 value_.Reset();
103 value_ = rhs.value_;
104 value_.SetWeakCallback(this, Reset, nullptr);
105 return *this;
106 }
107
108 JsWeak<T>& operator=(const T& rhs)
109 {
110 value_ = rhs;
111 value_.SetWeakCallback(this, Reset, nullptr);
112 return *this;
113 }
114
115 JsWeak<T>& operator=(JsWeak<T>&& rhs)
116 {
117 value_.Reset();
118 value_ = std::move(rhs.value_);
119 value_.SetWeakCallback(this, Reset, nullptr);
120
121 rhs.value_.Reset();
122 return *this;
123 }
124
IsEmpty()125 bool IsEmpty() const
126 {
127 return value_.IsEmpty();
128 }
129
Reset()130 void Reset()
131 {
132 value_.Reset();
133 }
134
Lock()135 T Lock() const
136 {
137 return T(value_);
138 }
139
Reset(void * ref)140 static void Reset(void* ref)
141 {
142 auto that = reinterpret_cast<JsWeak<T>*>(ref);
143 that->Reset();
144 }
145
146 private:
147 T value_;
148 };
149
150
151 template<typename T>
152 class JSFuncObjRef {
153 public:
~JSFuncObjRef()154 ~JSFuncObjRef()
155 {
156 jsStrongObj.Reset();
157 }
isWeak_(isWeak)158 explicit JSFuncObjRef(const T& jsObject, bool isWeak = false) : isWeak_(isWeak)
159 {
160 if (isWeak) {
161 jsWeakObj = JsWeak(jsObject);
162 } else {
163 jsStrongObj = jsObject;
164 }
165 }
Lock()166 T Lock() const
167 {
168 return isWeak_ ? jsWeakObj.Lock() : jsStrongObj;
169 }
170
171 private:
172 bool isWeak_ = false;
173 JsWeak<T> jsWeakObj;
174 T jsStrongObj;
175 };
176
177 class NativeUtilsBridge {
178 public:
179 static ArkUINativeModuleValue CreateNativeWeakRef(ArkUIRuntimeCallInfo* runtimeCallInfo);
180 static ArkUINativeModuleValue CreateNativeStrongRef(ArkUIRuntimeCallInfo* runtimeCallInfo);
181 static ArkUINativeModuleValue WeakRefInvalid(ArkUIRuntimeCallInfo* runtimeCallInfo);
182 static ArkUINativeModuleValue GetNativeHandleForWeak(ArkUIRuntimeCallInfo* runtimeCallInfo);
183 static ArkUINativeModuleValue GetNativeHandleForStrong(ArkUIRuntimeCallInfo* runtimeCallInfo);
184 static ArkUINativeModuleValue Upgrade(ArkUIRuntimeCallInfo* runtimeCallInfo);
185 static ArkUINativeModuleValue Dispose(ArkUIRuntimeCallInfo* runtimeCallInfo);
186 static ArkUINativeModuleValue CreateStrongRef(EcmaVM* vm, const RefPtr<AceType>& ref);
187 static ArkUINativeModuleValue ParseResourceColor(ArkUIRuntimeCallInfo* runtimeCallInfo);
188 static ArkUINativeModuleValue BlendColor(ArkUIRuntimeCallInfo* runtimeCallInfo);
189 static ArkUINativeModuleValue ResoureToLengthMetrics(ArkUIRuntimeCallInfo* runtimeCallInfo);
190 static ArkUINativeModuleValue CreateWeakRef(EcmaVM* vm, const RefPtr<AceType>& ref);
191 };
192 } // namespace OHOS::Ace::NG
193
194 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_JSI_NATIVEMODULE_ARKTS_NATIVE_UTILS_BRIDGE_H
195