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