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