• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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/quickjs/modules/qjs_module_manager.h"
17 
18 #include "base/log/log.h"
19 #include "bridge/declarative_frontend/engine/quickjs/modules/qjs_curves_module.h"
20 #include "bridge/declarative_frontend/engine/quickjs/modules/qjs_matrix4_module.h"
21 #include "bridge/declarative_frontend/engine/quickjs/modules/qjs_router_module.h"
22 #include "bridge/declarative_frontend/engine/quickjs/qjs_declarative_engine.h"
23 #include "bridge/js_frontend/engine/common/js_constants.h"
24 #include "bridge/js_frontend/engine/quickjs/qjs_utils.h"
25 #include "core/common/container.h"
26 
27 namespace OHOS::Ace::Framework {
28 namespace {
29 constexpr int32_t CUSTOM_FULL_WINDOW_LENGTH = 3;
30 constexpr int32_t ARGS_FULL_WINDOW_LENGTH = 2;
31 } // namespace
32 
GetInstance()33 ModuleManager* ModuleManager::GetInstance()
34 {
35     static ModuleManager instance;
36     return &instance;
37 }
38 
AppGetInfo(JSContext * ctx,JSValue value,int32_t argc,JSValueConst * argv)39 JSValue AppGetInfo(JSContext* ctx, JSValue value, int32_t argc, JSValueConst* argv)
40 {
41     auto* instance = static_cast<QJSDeclarativeEngineInstance*>(JS_GetContextOpaque(ctx));
42     if (instance == nullptr) {
43         LOGE("Can not cast Context to QJSDeclarativeEngineInstance object.");
44         return JS_NULL;
45     }
46     auto delegate = instance->GetDelegate();
47     if (!delegate) {
48         LOGE("get frontend delegate failed");
49         return JS_NULL;
50     }
51     JSValue appInfo = JS_NewObject(ctx);
52     auto appId = delegate->GetAppID();
53     auto appName = delegate->GetAppName();
54     auto versionName = delegate->GetVersionName();
55     auto versionCode = delegate->GetVersionCode();
56     JS_SetPropertyStr(ctx, appInfo, "appID", JS_NewString(ctx, appId.c_str()));
57     JS_SetPropertyStr(ctx, appInfo, "appName", JS_NewString(ctx, appName.c_str()));
58     JS_SetPropertyStr(ctx, appInfo, "versionName", JS_NewString(ctx, versionName.c_str()));
59     JS_SetPropertyStr(ctx, appInfo, "versionCode", JS_NewInt32(ctx, versionCode));
60     return appInfo;
61 }
62 
AppTerminate(JSContext * ctx,JSValue value,int32_t argc,JSValueConst * argv)63 JSValue AppTerminate(JSContext* ctx, JSValue value, int32_t argc, JSValueConst* argv)
64 {
65     auto* instance = static_cast<QJSDeclarativeEngineInstance*>(JS_GetContextOpaque(ctx));
66     if (instance == nullptr) {
67         LOGE("Can not cast Context to QJSDeclarativeEngineInstance object.");
68         return JS_NULL;
69     }
70     auto delegate = instance->GetDelegate();
71     if (!delegate) {
72         LOGE("get frontend delegate failed");
73         return JS_NULL;
74     }
75     auto pipelineContext = instance->GetPipelineContext(ctx);
76     if (!pipelineContext) {
77         LOGE("get frontend pipelineContext failed");
78         return JS_NULL;
79     }
80     auto uiTaskExecutor = delegate->GetUiTask();
81     WeakPtr<PipelineBase> pipelineContextWeak(pipelineContext);
82     uiTaskExecutor.PostTask([pipelineContextWeak]() mutable {
83         auto pipelineContext = pipelineContextWeak.Upgrade();
84         if (pipelineContext) {
85             pipelineContext->Finish();
86         }
87     });
88     return JS_NULL;
89 }
90 
ParseFullWindowParams(JSContext * ctx,JSValue params,std::string & duration)91 void ParseFullWindowParams(JSContext* ctx, JSValue params, std::string& duration)
92 {
93     JSPropertyEnum* tab = nullptr;
94     uint32_t paramLen = 0;
95     if (JS_IsObject(params)) {
96         JS_GetOwnPropertyNames(ctx, &tab, &paramLen, params, JS_GPN_STRING_MASK);
97         const char* jsDurationKey = JS_AtomToCString(ctx, tab[0].atom);
98         if (jsDurationKey == nullptr) {
99             JS_FreeAtom(ctx, tab[0].atom);
100             js_free(ctx, tab);
101             LOGE("jsDurationKey is null.");
102             return;
103         }
104         if (std::strcmp(jsDurationKey, "duration") == 0) {
105             JSValue valObject = JS_GetProperty(ctx, params, tab[0].atom);
106             if (JS_IsString(valObject) || JS_IsNumber(valObject)) {
107                 ScopedString styleVal(ctx, valObject);
108                 const char* valDuration = styleVal.get();
109                 duration = valDuration;
110             }
111             JS_FreeValue(ctx, valObject);
112         }
113         JS_FreeAtom(ctx, tab[0].atom);
114         JS_FreeCString(ctx, jsDurationKey);
115     }
116     js_free(ctx, tab);
117 }
118 
AppRequestFullWindow(JSContext * ctx,JSValue value,int32_t argc,JSValueConst * argv)119 JSValue AppRequestFullWindow(JSContext* ctx, JSValue value, int32_t argc, JSValueConst* argv)
120 {
121     JSPropertyEnum* pTab = nullptr;
122     uint32_t len = 0;
123     int32_t duration = -1;
124     if (JS_IsObject(value) && JS_IsArray(ctx, value)) {
125         JS_GetOwnPropertyNames(ctx, &pTab, &len, value, JS_GPN_STRING_MASK);
126         if (len < ARGS_FULL_WINDOW_LENGTH) {
127             LOGW("RequestFullWindow: invalid callback value");
128             js_free(ctx, pTab);
129             return JS_NULL;
130         }
131         if (len == CUSTOM_FULL_WINDOW_LENGTH) {
132             JSValue jsDuration = JS_GetProperty(ctx, value, pTab[0].atom);
133             std::string valDuration;
134             ParseFullWindowParams(ctx, jsDuration, valDuration);
135             if (!valDuration.empty()) {
136                 duration = StringToInt(valDuration);
137             }
138             if (duration < 0) {
139                 duration = -1;
140             }
141             JS_FreeValue(ctx, jsDuration);
142         }
143         js_free(ctx, pTab);
144     }
145     auto instance = static_cast<QJSDeclarativeEngineInstance*>(JS_GetContextOpaque(ctx));
146     WeakPtr<PipelineBase> pipelineContextWeak = instance->GetDelegate()->GetPipelineContext();
147     auto uiTaskExecutor = instance->GetDelegate()->GetUiTask();
148     uiTaskExecutor.PostTask([pipelineContextWeak, duration]() mutable {
149         auto pipelineContext = pipelineContextWeak.Upgrade();
150         if (pipelineContext) {
151             pipelineContext->RequestFullWindow(duration);
152         }
153     });
154     return JS_NULL;
155 }
156 
AppSetImageCacheCount(JSContext * ctx,JSValue value,int32_t argc,JSValueConst * argv)157 JSValue AppSetImageCacheCount(JSContext* ctx, JSValue value, int32_t argc, JSValueConst* argv)
158 {
159     auto container = Container::Current();
160     if (!container) {
161         LOGE("current container is null");
162         return JS_NULL;
163     }
164     auto pipelineContext = container->GetPipelineContext();
165     if (!pipelineContext) {
166         LOGE("get pipelineContext failed");
167         return JS_NULL;
168     }
169     auto taskExecutor = pipelineContext->GetTaskExecutor();
170     if (!taskExecutor) {
171         LOGE("taskExecutor is null.");
172         return JS_NULL;
173     }
174     WeakPtr<PipelineBase> pipelineContextWeak(pipelineContext);
175     int32_t size;
176     JS_ToInt32(ctx, &size, argv[0]);
177     size = size > 0 ? size : 0;
178     taskExecutor->PostTask([pipelineContextWeak, size]() mutable {
179         auto pipelineContext = pipelineContextWeak.Upgrade();
180         if (pipelineContext) {
181             auto imageCache = pipelineContext->GetImageCache();
182             if (imageCache) {
183                 imageCache->SetCapacity(size);
184             } else {
185                 LOGW("image cache is null");
186             }
187         }
188     }, TaskExecutor::TaskType::UI);
189     return JS_NULL;
190 }
191 
AppSetImageRawDataCacheSize(JSContext * ctx,JSValue value,int32_t argc,JSValueConst * argv)192 JSValue AppSetImageRawDataCacheSize(JSContext* ctx, JSValue value, int32_t argc, JSValueConst* argv)
193 {
194     auto container = Container::Current();
195     if (!container) {
196         LOGE("current container is null");
197         return JS_NULL;
198     }
199     auto pipelineContext = container->GetPipelineContext();
200     if (!pipelineContext) {
201         LOGE("get pipelineContext failed");
202         return JS_NULL;
203     }
204     auto taskExecutor = pipelineContext->GetTaskExecutor();
205     if (!taskExecutor) {
206         LOGE("taskExecutor is null.");
207         return JS_NULL;
208     }
209     WeakPtr<PipelineBase> pipelineContextWeak(pipelineContext);
210     int32_t size;
211     JS_ToInt32(ctx, &size, argv[0]);
212     size = size > 0 ? size : 0;
213     taskExecutor->PostTask([pipelineContextWeak, size]() mutable {
214         auto pipelineContext = pipelineContextWeak.Upgrade();
215         if (pipelineContext) {
216             auto imageCache = pipelineContext->GetImageCache();
217             if (imageCache) {
218                 imageCache->SetCapacity(size);
219             } else {
220                 LOGW("image cache is null");
221             }
222         }
223     }, TaskExecutor::TaskType::UI);
224     return JS_NULL;
225 }
226 
AppSetImageFileCacheSize(JSContext * ctx,JSValue value,int32_t argc,JSValueConst * argv)227 JSValue AppSetImageFileCacheSize(JSContext* ctx, JSValue value, int32_t argc, JSValueConst* argv)
228 {
229     auto container = Container::Current();
230     if (!container) {
231         LOGE("current container is null");
232         return JS_NULL;
233     }
234     auto pipelineContext = container->GetPipelineContext();
235     if (!pipelineContext) {
236         LOGE("get pipelineContext failed");
237         return JS_NULL;
238     }
239     auto taskExecutor = pipelineContext->GetTaskExecutor();
240     if (!taskExecutor) {
241         LOGE("taskExecutor is null.");
242         return JS_NULL;
243     }
244     WeakPtr<PipelineBase> pipelineContextWeak(pipelineContext);
245     int32_t size;
246     JS_ToInt32(ctx, &size, argv[0]);
247     size = size > 0 ? size : 0;
248     taskExecutor->PostTask([pipelineContextWeak, size]() mutable {
249         auto pipelineContext = pipelineContextWeak.Upgrade();
250         if (pipelineContext) {
251             auto imageCache = pipelineContext->GetImageCache();
252             if (imageCache) {
253                 imageCache->SetCacheFileLimit(size);
254             } else {
255                 LOGW("image cache is null");
256             }
257         }
258     }, TaskExecutor::TaskType::UI);
259     return JS_NULL;
260 }
261 
InitAppModule(JSContext * ctx,JSValue & moduleObj)262 void InitAppModule(JSContext* ctx, JSValue& moduleObj)
263 {
264     JS_SetPropertyStr(ctx, moduleObj, APP_GET_INFO, JS_NewCFunction(ctx, AppGetInfo, APP_GET_INFO, 0));
265     JS_SetPropertyStr(ctx, moduleObj, APP_TERMINATE, JS_NewCFunction(ctx, AppTerminate, APP_TERMINATE, 0));
266     JS_SetPropertyStr(ctx, moduleObj, APP_REQUEST_FULL_WINDOW,
267         JS_NewCFunction(ctx, AppRequestFullWindow, APP_REQUEST_FULL_WINDOW, 1));
268     JS_SetPropertyStr(ctx, moduleObj, APP_SET_IMAGE_CACHE_COUNT,
269         JS_NewCFunction(ctx, AppSetImageCacheCount, APP_SET_IMAGE_CACHE_COUNT, 1));
270     JS_SetPropertyStr(ctx, moduleObj, APP_SET_IMAGE_RAWDATA_CACHE_SIZE,
271         JS_NewCFunction(ctx, AppSetImageRawDataCacheSize, APP_SET_IMAGE_RAWDATA_CACHE_SIZE, 1));
272     JS_SetPropertyStr(ctx, moduleObj, APP_SET_IMAGE_FILE_CACHE_SIZE,
273         JS_NewCFunction(ctx, AppSetImageFileCacheSize, APP_SET_IMAGE_FILE_CACHE_SIZE, 1));
274 }
275 
InitModule(JSContext * ctx,const std::string & moduleName,JSValue & jsObject)276 bool ModuleManager::InitModule(JSContext* ctx, const std::string& moduleName, JSValue& jsObject)
277 {
278     static const std::unordered_map<std::string, void (*)(JSContext * ctx, JSValue & jsObject)> MODULE_LIST = {
279         { "system.router", [](JSContext* ctx, JSValue& jsObject) { InitRouterModule(ctx, jsObject); } },
280         { "ohos.router", [](JSContext* ctx, JSValue& jsObject) { InitRouterModule(ctx, jsObject); } },
281         { "system.curves", [](JSContext* ctx, JSValue& jsObject) { InitCurvesModule(ctx, jsObject); } },
282         { "ohos.curves", [](JSContext* ctx, JSValue& jsObject) { InitCurvesModule(ctx, jsObject); } },
283         { "system.matrix4", [](JSContext* ctx, JSValue& jsObject) { InitMatrix4Module(ctx, jsObject); } },
284         { "ohos.matrix4", [](JSContext* ctx, JSValue& jsObject) { InitMatrix4Module(ctx, jsObject); } },
285         { "system.app", [](JSContext* ctx, JSValue& jsObject) { InitAppModule(ctx, jsObject); } },
286         { "ohos.app", [](JSContext* ctx, JSValue& jsObject) { InitAppModule(ctx, jsObject); } },
287     };
288     auto iter = MODULE_LIST.find(moduleName);
289     if (iter != MODULE_LIST.end()) {
290         iter->second(ctx, jsObject);
291         LOGD("ModuleManager InitModule is %{private}s", moduleName.c_str());
292         return true;
293     } else {
294         LOGE("register module is not found");
295         return false;
296     }
297 }
298 
SetTimeout(JSContext * ctx,JSValueConst value,int32_t argc,JSValueConst * argv)299 JSValue SetTimeout(JSContext* ctx, JSValueConst value, int32_t argc, JSValueConst* argv)
300 {
301     return ModuleManager::GetInstance()->SetWaitTimer(ctx, argc, argv, false);
302 }
303 
SetInterval(JSContext * ctx,JSValueConst value,int32_t argc,JSValueConst * argv)304 JSValue SetInterval(JSContext* ctx, JSValueConst value, int32_t argc, JSValueConst* argv)
305 {
306     return ModuleManager::GetInstance()->SetWaitTimer(ctx, argc, argv, true);
307 }
308 
ClearTimeout(JSContext * ctx,JSValueConst value,int32_t argc,JSValueConst * argv)309 JSValue ClearTimeout(JSContext* ctx, JSValueConst value, int32_t argc, JSValueConst* argv)
310 {
311     return ModuleManager::GetInstance()->ClearWaitTimer(ctx, argc, argv, false);
312 }
313 
ClearInterval(JSContext * ctx,JSValueConst value,int32_t argc,JSValueConst * argv)314 JSValue ClearInterval(JSContext* ctx, JSValueConst value, int32_t argc, JSValueConst* argv)
315 {
316     return ModuleManager::GetInstance()->ClearWaitTimer(ctx, argc, argv, true);
317 }
318 
CanIUse(JSContext * ctx,JSValueConst value,int32_t argc,JSValueConst * argv)319 JSValue CanIUse(JSContext* ctx, JSValueConst value, int32_t argc, JSValueConst* argv)
320 {
321     LOGD("CanIUse argc is %d", argc);
322 
323     if (argc != 1) {
324         LOGE("CanIUse: invalid value");
325         return JS_NULL;
326     }
327 
328     QJSContext::Scope scp(ctx);
329     if (!JS_IsString(argv[0])) {
330         LOGE("CanIUse: invalid input");
331         return JS_NULL;
332     }
333 
334     ScopedString targetString(ctx, argv[0]);
335     std::string syscapString = targetString.get();
336 
337     bool ret = Ace::SystemProperties::IsSyscapExist(syscapString.c_str());
338 
339     return JS_NewBool(ctx, ret);
340 }
341 
SetWaitTimer(JSContext * ctx,int32_t argc,JSValueConst * argv,bool isInterval)342 JSValue ModuleManager::SetWaitTimer(JSContext* ctx, int32_t argc, JSValueConst* argv, bool isInterval)
343 {
344     LOGD("SetWaitTimer argc is %d", argc);
345 
346     auto instance = static_cast<QJSDeclarativeEngineInstance*>(JS_GetContextOpaque(ctx));
347     if (instance == nullptr) {
348         LOGE("Can not cast Context to QJSDeclarativeEngineInstance object.");
349         return JS_NULL;
350     }
351 
352     if (argc < 1) {
353         LOGW("JsSetTimer: invalid callback value");
354         return JS_NULL;
355     }
356 
357     JSValue jsFunc = JS_DupValue(ctx, argv[0]);
358     if (!JS_IsFunction(ctx, jsFunc)) {
359         LOGW("argv[0] is not function");
360         return JS_NULL;
361     }
362 
363     uint32_t delay = 0;
364     std::vector<JSValue> callbackArray;
365     if (argc < 2 || !JS_IsNumber(argv[1])) {
366         uint32_t callbackId = ModuleManager::GetInstance()->AddCallback(jsFunc, callbackArray, isInterval);
367         instance->GetDelegate()->WaitTimer(std::to_string(callbackId), std::to_string(delay), isInterval, true);
368         return JS_NULL;
369     }
370 
371     JS_ToUint32(ctx, &delay, argv[1]);
372     for (int index = 2; index < argc; ++index) {
373         callbackArray.emplace_back(JS_DupValue(ctx, argv[index]));
374     }
375 
376     uint32_t callbackId = ModuleManager::GetInstance()->AddCallback(jsFunc, callbackArray, isInterval);
377     instance->GetDelegate()->WaitTimer(std::to_string(callbackId), std::to_string(delay), isInterval, true);
378 
379     return JS_NewInt32(ctx, callbackId);
380 }
381 
AddCallback(JSValue callbackFunc,std::vector<JSValue> callbackArray,bool isInterval)382 uint32_t ModuleManager::AddCallback(JSValue callbackFunc, std::vector<JSValue> callbackArray, bool isInterval)
383 {
384     if (isInterval) {
385         return AddCallback(intervalCallbackFuncMap_, intervalCallbackArrayMap_, callbackFunc, callbackArray);
386     } else {
387         return AddCallback(callbackFuncMap_, callbackArrayMap_, callbackFunc, callbackArray);
388     }
389 }
390 
AddCallback(std::unordered_map<uint32_t,JSValue> & callbackFuncMap,std::unordered_map<uint32_t,std::vector<JSValue>> & callbackArrayMap,JSValue callbackFunc,std::vector<JSValue> callbackArray)391 uint32_t ModuleManager::AddCallback(std::unordered_map<uint32_t, JSValue>& callbackFuncMap,
392     std::unordered_map<uint32_t, std::vector<JSValue>>& callbackArrayMap, JSValue callbackFunc,
393     std::vector<JSValue> callbackArray)
394 {
395     ++callbackId_;
396     callbackFuncMap[callbackId_] = callbackFunc;
397     if (!callbackArray.empty()) {
398         callbackArrayMap[callbackId_] = callbackArray;
399     }
400     return callbackId_;
401 }
402 
GetCallbackFunc(uint32_t callbackId,bool isInterval)403 JSValue ModuleManager::GetCallbackFunc(uint32_t callbackId, bool isInterval)
404 {
405     if (isInterval) {
406         return intervalCallbackFuncMap_[callbackId];
407     } else {
408         return callbackFuncMap_[callbackId];
409     }
410 }
411 
GetCallbackArray(uint32_t callbackId,bool isInterval)412 std::vector<JSValue> ModuleManager::GetCallbackArray(uint32_t callbackId, bool isInterval)
413 {
414     if (isInterval) {
415         return GetCallbackArray(intervalCallbackArrayMap_, callbackId);
416     } else {
417         return GetCallbackArray(callbackArrayMap_, callbackId);
418     }
419 }
420 
GetCallbackArray(std::unordered_map<uint32_t,std::vector<JSValue>> & callbackArrayMap,uint32_t callbackId)421 std::vector<JSValue> ModuleManager::GetCallbackArray(
422     std::unordered_map<uint32_t, std::vector<JSValue>>& callbackArrayMap, uint32_t callbackId)
423 {
424     if (callbackArrayMap.find(callbackId) != callbackArrayMap.end()) {
425         return callbackArrayMap[callbackId];
426     }
427     std::vector<JSValue> emptyRet;
428     return emptyRet;
429 }
430 
ClearWaitTimer(JSContext * ctx,int32_t argc,JSValueConst * argv,bool isInterval)431 JSValue ModuleManager::ClearWaitTimer(JSContext* ctx, int32_t argc, JSValueConst* argv, bool isInterval)
432 {
433     if (argc < 0 || !JS_IsNumber(argv[0])) {
434         LOGE("args[0] is not number");
435         return JS_NULL;
436     }
437 
438     uint32_t callbackId;
439     JS_ToUint32(ctx, &callbackId, argv[0]);
440     ModuleManager::GetInstance()->RemoveCallbackFunc(ctx, callbackId, isInterval);
441     auto instance = static_cast<QJSDeclarativeEngineInstance*>(JS_GetContextOpaque(ctx));
442     if (instance == nullptr) {
443         LOGE("Can not cast Context to QJSDeclarativeEngineInstance object.");
444         return JS_NULL;
445     }
446     instance->GetDelegate()->ClearTimer(std::to_string(callbackId));
447     return JS_NULL;
448 }
449 
RemoveCallbackFunc(JSContext * ctx,uint32_t callbackId,bool isInterval)450 void ModuleManager::RemoveCallbackFunc(JSContext* ctx, uint32_t callbackId, bool isInterval)
451 {
452     if (isInterval) {
453         RemoveCallbackFunc(ctx, intervalCallbackFuncMap_, intervalCallbackArrayMap_, callbackId);
454     } else {
455         RemoveCallbackFunc(ctx, callbackFuncMap_, callbackArrayMap_, callbackId);
456     }
457 }
458 
RemoveCallbackFunc(JSContext * ctx,std::unordered_map<uint32_t,JSValue> & callbackFuncMap,std::unordered_map<uint32_t,std::vector<JSValue>> & callbackArrayMap,uint32_t callbackId)459 void ModuleManager::RemoveCallbackFunc(JSContext* ctx, std::unordered_map<uint32_t, JSValue>& callbackFuncMap,
460     std::unordered_map<uint32_t, std::vector<JSValue>>& callbackArrayMap, uint32_t callbackId)
461 {
462     JS_FreeValue(ctx, callbackFuncMap[callbackId]);
463     callbackFuncMap.erase(callbackId);
464 
465     if (callbackArrayMap.find(callbackId) != callbackArrayMap.end()) {
466         uint32_t index = 0;
467         while (index < callbackArrayMap[callbackId].size()) {
468             JS_FreeValue(ctx, callbackArrayMap[callbackId][index]);
469             ++index;
470         }
471         callbackArrayMap.erase(callbackId);
472     }
473 }
474 
InitTimerModule(JSContext * ctx)475 void ModuleManager::InitTimerModule(JSContext* ctx)
476 {
477     JSValue globalObj = JS_GetGlobalObject(ctx);
478     JS_SetPropertyStr(ctx, globalObj, SET_TIMEOUT, JS_NewCFunction(ctx, SetTimeout, SET_TIMEOUT, 2));
479     JS_SetPropertyStr(ctx, globalObj, SET_INTERVAL, JS_NewCFunction(ctx, SetInterval, SET_INTERVAL, 2));
480     JS_SetPropertyStr(ctx, globalObj, CLEAR_TIMEOUT, JS_NewCFunction(ctx, ClearTimeout, CLEAR_TIMEOUT, 1));
481     JS_SetPropertyStr(ctx, globalObj, CLEAR_INTERVAL, JS_NewCFunction(ctx, ClearInterval, CLEAR_INTERVAL, 1));
482     JS_FreeValue(ctx, globalObj);
483 }
484 
InitSyscapModule(JSContext * ctx)485 void ModuleManager::InitSyscapModule(JSContext* ctx)
486 {
487     JSValue globalObj = JS_GetGlobalObject(ctx);
488     JS_SetPropertyStr(ctx, globalObj, CAN_IUSE, JS_NewCFunction(ctx, CanIUse, CAN_IUSE, 1));
489     JS_FreeValue(ctx, globalObj);
490 }
491 
492 } // namespace OHOS::Ace::Framework
493