• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_utils_bridge.h"
17 
18 #include "jsnapi_expo.h"
19 
20 #include "base/geometry/calc_dimension.h"
21 #include "base/geometry/dimension.h"
22 #include "base/memory/ace_type.h"
23 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
24 
25 namespace OHOS::Ace::NG {
26 constexpr uint32_t MAX_COLOR_ARRAY_COUNT = 4;
27 constexpr uint32_t ARRAY_INDEX_RED = 0;
28 constexpr uint32_t ARRAY_INDEX_GREEN = 1;
29 constexpr uint32_t ARRAY_INDEX_BLUE = 2;
30 constexpr uint32_t ARRAY_INDEX_ALPHA = 3;
31 constexpr uint32_t ARRAY_INDEX_RESOURCE_ID = 4;
32 constexpr uint32_t MAX_COLOR_ARRAY_COUNT_WITH_RESOURCE_ID = 5;
33 constexpr uint32_t ARRAY_SIZE = 2;
34 
CreateNativeWeakRef(ArkUIRuntimeCallInfo * runtimeCallInfo)35 ArkUINativeModuleValue NativeUtilsBridge::CreateNativeWeakRef(ArkUIRuntimeCallInfo* runtimeCallInfo)
36 {
37     EcmaVM* vm = runtimeCallInfo->GetVM();
38     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
39     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
40     if (firstArg.IsEmpty() || !firstArg->IsNativePointer(vm)) {
41         return panda::JSValueRef::Undefined(vm);
42     }
43     auto refPtr = AceType::Claim(reinterpret_cast<AceType*>(firstArg->ToNativePointer(vm)->Value()));
44     return NativeUtilsBridge::CreateWeakRef(vm, refPtr);
45 }
46 
CreateWeakRef(EcmaVM * vm,const RefPtr<AceType> & ref)47 ArkUINativeModuleValue NativeUtilsBridge::CreateWeakRef(EcmaVM* vm, const RefPtr<AceType>& ref)
48 {
49     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
50     CHECK_NULL_RETURN(ref, panda::JSValueRef::Undefined(vm));
51     auto* weak = new NativeWeakRef(AceType::RawPtr(ref));
52     auto nativeWeakRef = panda::ObjectRef::New(vm);
53     nativeWeakRef->SetNativePointerFieldCount(vm, 1);
54     nativeWeakRef->SetConcurrentNativePointerField(vm, 0, weak, &DestructorInterceptor<NativeWeakRef>);
55     nativeWeakRef->Set(vm, panda::StringRef::NewFromUtf8(vm, "invalid"),
56         panda::FunctionRef::New(const_cast<panda::EcmaVM*>(vm), NativeUtilsBridge::WeakRefInvalid));
57     nativeWeakRef->Set(vm, panda::StringRef::NewFromUtf8(vm, "getNativeHandle"),
58         panda::FunctionRef::New(const_cast<panda::EcmaVM*>(vm), NativeUtilsBridge::GetNativeHandleForWeak));
59     nativeWeakRef->Set(vm, panda::StringRef::NewFromUtf8(vm, "upgrade"),
60         panda::FunctionRef::New(const_cast<panda::EcmaVM*>(vm), NativeUtilsBridge::Upgrade));
61     return nativeWeakRef;
62 }
63 
CreateStrongRef(EcmaVM * vm,const RefPtr<AceType> & ref)64 ArkUINativeModuleValue NativeUtilsBridge::CreateStrongRef(EcmaVM* vm, const RefPtr<AceType>& ref)
65 {
66     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
67     CHECK_NULL_RETURN(ref, panda::JSValueRef::Undefined(vm));
68     auto* nativeRef = new NativeStrongRef(ref);
69     auto nativeStrongRef = panda::ObjectRef::New(vm);
70     nativeStrongRef->SetNativePointerFieldCount(vm, 1);
71     nativeStrongRef->SetConcurrentNativePointerField(vm, 0, nativeRef, &DestructorInterceptor<NativeStrongRef>);
72     nativeStrongRef->Set(vm, panda::StringRef::NewFromUtf8(vm, "getNativeHandle"),
73         panda::FunctionRef::New(const_cast<panda::EcmaVM*>(vm), NativeUtilsBridge::GetNativeHandleForStrong));
74     nativeStrongRef->Set(vm, panda::StringRef::NewFromUtf8(vm, "dispose"),
75         panda::FunctionRef::New(const_cast<panda::EcmaVM*>(vm), NativeUtilsBridge::Dispose));
76     return nativeStrongRef;
77 }
78 
CreateNativeStrongRef(ArkUIRuntimeCallInfo * runtimeCallInfo)79 ArkUINativeModuleValue NativeUtilsBridge::CreateNativeStrongRef(ArkUIRuntimeCallInfo* runtimeCallInfo)
80 {
81     EcmaVM* vm = runtimeCallInfo->GetVM();
82     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
83     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
84     if (firstArg.IsEmpty() || !firstArg->IsNativePointer(vm)) {
85         return panda::JSValueRef::Undefined(vm);
86     }
87     auto refPtr = AceType::Claim(reinterpret_cast<AceType*>(firstArg->ToNativePointer(vm)->Value()));
88     return NativeUtilsBridge::CreateStrongRef(vm, refPtr);
89 }
90 
WeakRefInvalid(ArkUIRuntimeCallInfo * runtimeCallInfo)91 ArkUINativeModuleValue NativeUtilsBridge::WeakRefInvalid(ArkUIRuntimeCallInfo* runtimeCallInfo)
92 {
93     EcmaVM* vm = runtimeCallInfo->GetVM();
94     CHECK_NULL_RETURN(vm, panda::BooleanRef::New(vm, true));
95     auto* weak = GetPointerField<NativeWeakRef>(runtimeCallInfo);
96     if (weak != nullptr) {
97         return panda::BooleanRef::New(vm, weak->Invalid());
98     }
99     return panda::BooleanRef::New(vm, true);
100 }
101 
GetNativeHandleForStrong(ArkUIRuntimeCallInfo * runtimeCallInfo)102 ArkUINativeModuleValue NativeUtilsBridge::GetNativeHandleForStrong(ArkUIRuntimeCallInfo* runtimeCallInfo)
103 {
104     EcmaVM* vm = runtimeCallInfo->GetVM();
105     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
106     auto* strong = GetPointerField<NativeStrongRef>(runtimeCallInfo);
107     if (strong != nullptr && strong->strongRef) {
108         return panda::NativePointerRef::New(vm, strong->RawPtr());
109     }
110     return panda::JSValueRef::Undefined(vm);
111 }
112 
GetNativeHandleForWeak(ArkUIRuntimeCallInfo * runtimeCallInfo)113 ArkUINativeModuleValue NativeUtilsBridge::GetNativeHandleForWeak(ArkUIRuntimeCallInfo* runtimeCallInfo)
114 {
115     EcmaVM* vm = runtimeCallInfo->GetVM();
116     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
117     auto* weak = GetPointerField<NativeWeakRef>(runtimeCallInfo);
118     if (weak != nullptr && !weak->Invalid()) {
119         return panda::NativePointerRef::New(vm, weak->rawPtr);
120     }
121     return panda::JSValueRef::Undefined(vm);
122 }
123 
Upgrade(ArkUIRuntimeCallInfo * runtimeCallInfo)124 ArkUINativeModuleValue NativeUtilsBridge::Upgrade(ArkUIRuntimeCallInfo* runtimeCallInfo)
125 {
126     EcmaVM* vm = runtimeCallInfo->GetVM();
127     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
128     auto* weak = GetPointerField<NativeWeakRef>(runtimeCallInfo);
129     if (weak != nullptr) {
130         auto ref = weak->weakRef.Upgrade();
131         return NativeUtilsBridge::CreateStrongRef(vm, ref);
132     }
133     return panda::JSValueRef::Undefined(vm);
134 }
135 
Dispose(ArkUIRuntimeCallInfo * runtimeCallInfo)136 ArkUINativeModuleValue NativeUtilsBridge::Dispose(ArkUIRuntimeCallInfo* runtimeCallInfo)
137 {
138     EcmaVM* vm = runtimeCallInfo->GetVM();
139     auto* ptr = GetPointerField<NativeStrongRef>(runtimeCallInfo);
140     if (ptr != nullptr) {
141         ptr->strongRef.Reset();
142         return panda::JSValueRef::Undefined(vm);
143     }
144     return panda::JSValueRef::Undefined(vm);
145 }
146 
ParseResourceColor(ArkUIRuntimeCallInfo * runtimeCallInfo)147 ArkUINativeModuleValue NativeUtilsBridge::ParseResourceColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
148 {
149     EcmaVM* vm = runtimeCallInfo->GetVM();
150     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
151     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
152     if (firstArg.IsEmpty() || !firstArg->IsObject(vm)) {
153         return panda::JSValueRef::Undefined(vm);
154     }
155     Color color;
156     if (!ArkTSUtils::ParseJsColorFromResource(vm, firstArg, color)) {
157         return panda::JSValueRef::Undefined(vm);
158     }
159     Local<panda::ArrayRef> chanels = panda::ArrayRef::New(vm, MAX_COLOR_ARRAY_COUNT_WITH_RESOURCE_ID);
160     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_RED, panda::NumberRef::New(vm, color.GetRed()));
161     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_GREEN, panda::NumberRef::New(vm, color.GetGreen()));
162     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_BLUE, panda::NumberRef::New(vm, color.GetBlue()));
163     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_ALPHA, panda::NumberRef::New(vm, color.GetAlpha()));
164     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_RESOURCE_ID, panda::NumberRef::New(vm, color.GetResourceId()));
165     return chanels;
166 }
167 
BlendColor(ArkUIRuntimeCallInfo * runtimeCallInfo)168 ArkUINativeModuleValue NativeUtilsBridge::BlendColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
169 {
170     EcmaVM* vm = runtimeCallInfo->GetVM();
171     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
172     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
173     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
174 
175     if (firstArg.IsEmpty() || !firstArg->IsNumber() || secondArg.IsEmpty() || !secondArg->IsNumber()) {
176         return panda::JSValueRef::Undefined(vm);
177     }
178     Color color;
179     Color overlayColor;
180     if (!ArkTSUtils::ParseJsColor(vm, firstArg, color) || !ArkTSUtils::ParseJsColor(vm, secondArg, overlayColor)) {
181         return panda::JSValueRef::Undefined(vm);
182     }
183     auto blendColor = color.BlendColor(overlayColor);
184     Local<panda::ArrayRef> chanels = panda::ArrayRef::New(vm, MAX_COLOR_ARRAY_COUNT);
185     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_RED, panda::NumberRef::New(vm, blendColor.GetRed()));
186     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_GREEN, panda::NumberRef::New(vm, blendColor.GetGreen()));
187     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_BLUE, panda::NumberRef::New(vm, blendColor.GetBlue()));
188     panda::ArrayRef::SetValueAt(vm, chanels, ARRAY_INDEX_ALPHA, panda::NumberRef::New(vm, blendColor.GetAlpha()));
189     return chanels;
190 }
191 
ResoureToLengthMetrics(ArkUIRuntimeCallInfo * runtimeCallInfo)192 ArkUINativeModuleValue NativeUtilsBridge::ResoureToLengthMetrics(ArkUIRuntimeCallInfo* runtimeCallInfo)
193 {
194     EcmaVM* vm = runtimeCallInfo->GetVM();
195     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
196     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
197     if (!firstArg->IsObject(vm)) {
198         return panda::JSValueRef::Undefined(vm);
199     }
200     CalcDimension result;
201     ArkTSUtils::ParseJsDimensionFromResourceNG(vm, firstArg, DimensionUnit::VP, result);
202     Local<panda::ArrayRef> length = panda::ArrayRef::New(vm, ARRAY_SIZE);
203     panda::ArrayRef::SetValueAt(vm, length, 0, panda::NumberRef::New(vm, result.Value()));
204     panda::ArrayRef::SetValueAt(vm, length, 1, panda::NumberRef::New(vm, static_cast<int32_t>(result.Unit())));
205     return length;
206 }
207 } // namespace OHOS::Ace::NG
208