1 /*
2 * Copyright (c) 2021-2023 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/jsview/js_utils.h"
17
18 #include "scope_manager/native_scope_manager.h"
19
20 #if !defined(PREVIEW)
21 #include <dlfcn.h>
22 #endif
23 #if !defined(WINDOWS_PLATFORM)
24 #include <regex.h>
25 #endif
26
27 #ifdef PIXEL_MAP_SUPPORTED
28 #include "pixel_map.h"
29 #include "pixel_map_napi.h"
30 #endif
31 #include "napi/native_node_api.h"
32
33 #include "base/image/pixel_map.h"
34 #include "base/log/ace_trace.h"
35 #include "base/want/want_wrap.h"
36 #include "bridge/common/utils/engine_helper.h"
37 #include "bridge/declarative_frontend/engine/js_converter.h"
38 #include "frameworks/bridge/common/utils/engine_helper.h"
39 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
40 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
41 #include "frameworks/bridge/js_frontend/engine/common/js_engine.h"
42
43 namespace OHOS::Ace::Framework {
44 namespace {
45 #if defined(WINDOWS_PLATFORM)
46 constexpr char CHECK_REGEX_VALID[] = "__checkRegexValid__";
47 #endif
48 } // namespace
49
50 #if !defined(PREVIEW)
CreatePixelMapFromNapiValue(JSRef<JSVal> obj)51 RefPtr<PixelMap> CreatePixelMapFromNapiValue(JSRef<JSVal> obj)
52 {
53 if (!obj->IsObject()) {
54 return nullptr;
55 }
56 auto engine = EngineHelper::GetCurrentEngine();
57 if (!engine) {
58 return nullptr;
59 }
60 auto* nativeEngine = engine->GetNativeEngine();
61 if (nativeEngine == nullptr) {
62 return nullptr;
63 }
64 #ifdef USE_ARK_ENGINE
65 panda::Local<JsiValue> value = obj.Get().GetLocalHandle();
66 #endif
67 JSValueWrapper valueWrapper = value;
68
69 ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
70 napi_value napiValue = nativeEngine->ValueToNapiValue(valueWrapper);
71
72 PixelMapNapiEntry pixelMapNapiEntry = JsEngine::GetPixelMapNapiEntry();
73 if (!pixelMapNapiEntry) {
74 return nullptr;
75 }
76
77 void* pixmapPtrAddr = pixelMapNapiEntry(reinterpret_cast<napi_env>(nativeEngine), napiValue);
78 if (pixmapPtrAddr == nullptr) {
79 return nullptr;
80 }
81 return PixelMap::CreatePixelMap(pixmapPtrAddr);
82 }
83
84 namespace {
UnwrapNapiValue(const JSRef<JSVal> & obj)85 void* UnwrapNapiValue(const JSRef<JSVal>& obj)
86 {
87 #ifdef ENABLE_ROSEN_BACKEND
88 if (!obj->IsObject()) {
89 LOGE("info[0] is not an object when try CreateFromNapiValue");
90 return nullptr;
91 }
92 auto engine = EngineHelper::GetCurrentEngine();
93 CHECK_NULL_RETURN(engine, nullptr);
94 auto nativeEngine = engine->GetNativeEngine();
95 CHECK_NULL_RETURN(nativeEngine, nullptr);
96 #ifdef USE_ARK_ENGINE
97 panda::Local<JsiValue> value = obj.Get().GetLocalHandle();
98 #endif
99 JSValueWrapper valueWrapper = value;
100
101 ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
102 napi_value napiValue = nativeEngine->ValueToNapiValue(valueWrapper);
103 auto env = reinterpret_cast<napi_env>(nativeEngine);
104 napi_valuetype valueType = napi_undefined;
105 napi_typeof(env, napiValue, &valueType);
106 if (valueType != napi_object) {
107 LOGE("napiValue is not napi_object");
108 return nullptr;
109 }
110 void* objectNapi = nullptr;
111 napi_unwrap(env, napiValue, &objectNapi);
112 return objectNapi;
113 }
114 } // namespace
115
GetDrawablePixmap(JSRef<JSVal> obj)116 RefPtr<PixelMap> GetDrawablePixmap(JSRef<JSVal> obj)
117 {
118 return PixelMap::GetFromDrawable(UnwrapNapiValue(obj));
119 }
120
CreateRSNodeFromNapiValue(JSRef<JSVal> obj)121 const std::shared_ptr<Rosen::RSNode> CreateRSNodeFromNapiValue(JSRef<JSVal> obj)
122 {
123 auto nodePtr = static_cast<std::shared_ptr<Rosen::RSNode>*>(UnwrapNapiValue(obj));
124 if (nodePtr == nullptr) {
125 return nullptr;
126 }
127 return *nodePtr;
128 #else
129 return nullptr;
130 }
131 #endif
132 } // namespace
133
CreateWantWrapFromNapiValue(JSRef<JSVal> obj)134 RefPtr<OHOS::Ace::WantWrap> CreateWantWrapFromNapiValue(JSRef<JSVal> obj)
135 {
136 if (!obj->IsObject()) {
137 LOGE("invalid object when try CreateWantWrapFromNapiValue");
138 return nullptr;
139 }
140 auto engine = EngineHelper::GetCurrentEngine();
141 CHECK_NULL_RETURN(engine, nullptr);
142
143 NativeEngine* nativeEngine = engine->GetNativeEngine();
144 CHECK_NULL_RETURN(nativeEngine, nullptr);
145
146 #ifdef USE_ARK_ENGINE
147 panda::Local<JsiValue> value = obj.Get().GetLocalHandle();
148 #endif
149 JSValueWrapper valueWrapper = value;
150 ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
151 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
152 return WantWrap::CreateWantWrap(reinterpret_cast<napi_env>(nativeEngine), nativeValue);
153 }
154
155 #endif
156
157 // When the api version >= 10, it is disable event version.
IsDisableEventVersion()158 bool IsDisableEventVersion()
159 {
160 return Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN);
161 }
162
ParseTextShadowFromShadowObject(const JSRef<JSVal> & shadowObject,std::vector<Shadow> & shadows)163 void ParseTextShadowFromShadowObject(const JSRef<JSVal>& shadowObject, std::vector<Shadow>& shadows)
164 {
165 if (!shadowObject->IsNumber() && !shadowObject->IsObject() && !shadowObject->IsArray()) {
166 return;
167 }
168 if (!shadowObject->IsArray()) {
169 Shadow shadow;
170 if (!JSViewAbstract::ParseShadowProps(shadowObject, shadow)) {
171 return;
172 }
173 shadows.push_back(shadow);
174 return;
175 }
176 JSRef<JSArray> params = JSRef<JSArray>::Cast(shadowObject);
177 auto shadowLength = params->Length();
178 for (size_t i = 0; i < shadowLength; ++i) {
179 auto shadowJsVal = params->GetValueAt(i);
180 Shadow shadow;
181 if (!JSViewAbstract::ParseShadowProps(shadowJsVal, shadow)) {
182 continue;
183 }
184 shadows.push_back(shadow);
185 }
186 }
187
188 #ifdef PIXEL_MAP_SUPPORTED
ConvertPixmap(const RefPtr<PixelMap> & pixelMap)189 JSRef<JSVal> ConvertPixmap(const RefPtr<PixelMap>& pixelMap)
190 {
191 auto engine = EngineHelper::GetCurrentEngine();
192 CHECK_NULL_RETURN(engine, {});
193 NativeEngine* nativeEngine = engine->GetNativeEngine();
194 auto* env = reinterpret_cast<napi_env>(nativeEngine);
195 napi_value napiValue = OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelMap->GetPixelMapSharedPtr());
196 return JsConverter::ConvertNapiValueToJsVal(napiValue);
197 }
198 #endif
199
200 #ifdef PIXEL_MAP_SUPPORTED
ConvertPixmapNapi(const RefPtr<PixelMap> & pixelMap)201 napi_value ConvertPixmapNapi(const RefPtr<PixelMap>& pixelMap)
202 {
203 auto engine = EngineHelper::GetCurrentEngine();
204 CHECK_NULL_RETURN(engine, {});
205 NativeEngine* nativeEngine = engine->GetNativeEngine();
206 auto* env = reinterpret_cast<napi_env>(nativeEngine);
207 napi_value napiValue = OHOS::Media::PixelMapNapi::CreatePixelMap(env, pixelMap->GetPixelMapSharedPtr());
208 return napiValue;
209 }
210 #endif
211
IsDrawable(const JSRef<JSVal> & jsValue)212 bool IsDrawable(const JSRef<JSVal>& jsValue)
213 {
214 if (!jsValue->IsObject()) {
215 return false;
216 }
217 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
218 if (jsObj->IsUndefined()) {
219 return false;
220 }
221
222 // if jsObject has function getPixelMap, it's a DrawableDescriptor object
223 JSRef<JSVal> func = jsObj->GetProperty("getPixelMap");
224 return (!func->IsNull() && func->IsFunction());
225 }
226
CheckRegexValid(const std::string & pattern)227 bool CheckRegexValid(const std::string& pattern)
228 {
229 #if !defined(WINDOWS_PLATFORM)
230 regex_t regex;
231 // compile regex
232 const char* patternPtr = pattern.c_str();
233 int32_t ret = regcomp(®ex, patternPtr, REG_EXTENDED);
234 if (ret != 0) {
235 regfree(®ex);
236 return false;
237 }
238 regfree(®ex);
239 return true;
240 #else
241 auto engine = EngineHelper::GetCurrentEngine();
242 CHECK_NULL_RETURN(engine, false);
243 NativeEngine* nativeEngine = engine->GetNativeEngine();
244 CHECK_NULL_RETURN(nativeEngine, false);
245 auto env = reinterpret_cast<napi_env>(nativeEngine);
246 napi_value global;
247 napi_status ret = napi_get_global(env, &global);
248 if (ret != napi_ok) {
249 return false;
250 }
251 napi_value checkRegexValid;
252 ret = napi_get_named_property(env, global, CHECK_REGEX_VALID, &checkRegexValid);
253 if (ret != napi_ok) {
254 return false;
255 }
256 // create napi string
257 napi_value argv[1];
258 napi_create_string_utf8(env, pattern.c_str(), pattern.length(), &argv[0]);
259 napi_value result;
260 napi_call_function(env, nullptr, checkRegexValid, 1, argv, &result);
261 bool isValid = false;
262 napi_get_value_bool(env, result, &isValid);
263 return isValid;
264 #endif
265 }
266 } // namespace OHOS::Ace::Framework
267