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