• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "js_application_context_utils.h"
17 
18 #include <map>
19 
20 #include "ability_runtime_error_util.h"
21 #include "application_context.h"
22 #include "hilog_wrapper.h"
23 #include "ipc_skeleton.h"
24 #include "js_context_utils.h"
25 #include "js_data_struct_converter.h"
26 #include "js_resource_manager_utils.h"
27 #include "js_runtime_utils.h"
28 #include "tokenid_kit.h"
29 
30 namespace OHOS {
31 namespace AbilityRuntime {
32 namespace {
33 constexpr char APPLICATION_CONTEXT_NAME[] = "__application_context_ptr__";
34 constexpr size_t ARGC_ZERO = 0;
35 constexpr size_t ARGC_ONE = 1;
36 constexpr size_t ARGC_TWO = 2;
37 constexpr size_t ARGC_THREE = 3;
38 constexpr size_t INDEX_ZERO = 0;
39 constexpr size_t INDEX_ONE = 1;
40 constexpr size_t INDEX_TWO = 2;
41 constexpr int32_t ERROR_CODE_ONE = 1;
42 const char* MD_NAME = "JsApplicationContextUtils";
43 }  // namespace
44 
CreateBundleContext(NativeEngine * engine,NativeCallbackInfo * info)45 NativeValue *JsApplicationContextUtils::CreateBundleContext(NativeEngine *engine, NativeCallbackInfo *info)
46 {
47     JsApplicationContextUtils *me =
48         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
49     return me != nullptr ? me->OnCreateBundleContext(*engine, *info) : nullptr;
50 }
51 
OnCreateBundleContext(NativeEngine & engine,NativeCallbackInfo & info)52 NativeValue *JsApplicationContextUtils::OnCreateBundleContext(NativeEngine &engine, NativeCallbackInfo &info)
53 {
54     if (!CheckCallerIsSystemApp()) {
55         HILOG_ERROR("This application is not system-app, can not use system-api");
56         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
57         return engine.CreateUndefined();
58     }
59 
60     if (info.argc == 0) {
61         HILOG_ERROR("Not enough params");
62         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
63         return engine.CreateUndefined();
64     }
65 
66     auto applicationContext = applicationContext_.lock();
67     if (!applicationContext) {
68         HILOG_WARN("applicationContext is already released");
69         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
70         return engine.CreateUndefined();
71     }
72 
73     std::string bundleName;
74     if (!ConvertFromJsValue(engine, info.argv[0], bundleName)) {
75         HILOG_ERROR("Parse bundleName failed");
76         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
77         return engine.CreateUndefined();
78     }
79 
80     auto bundleContext = applicationContext->CreateBundleContext(bundleName);
81     if (!bundleContext) {
82         HILOG_ERROR("bundleContext is nullptr");
83         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
84         return engine.CreateUndefined();
85     }
86 
87     NativeValue* value = CreateJsBaseContext(engine, bundleContext, true);
88     auto systemModule = JsRuntime::LoadSystemModuleByEngine(&engine, "application.Context", &value, 1);
89     if (systemModule == nullptr) {
90         HILOG_WARN("invalid systemModule.");
91         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
92         return engine.CreateUndefined();
93     }
94     auto contextObj = systemModule->Get();
95     NativeObject *nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
96     if (nativeObj == nullptr) {
97         HILOG_ERROR("Failed to get context native object");
98         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
99         return engine.CreateUndefined();
100     }
101     auto workContext = new (std::nothrow) std::weak_ptr<Context>(bundleContext);
102     nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
103     nativeObj->SetNativePointer(
104         workContext,
105         [](NativeEngine *, void *data, void *) {
106             HILOG_INFO("Finalizer for weak_ptr bundle context is called");
107             delete static_cast<std::weak_ptr<Context> *>(data);
108         },
109         nullptr);
110     return contextObj;
111 }
112 
SwitchArea(NativeEngine * engine,NativeCallbackInfo * info)113 NativeValue *JsApplicationContextUtils::SwitchArea(NativeEngine *engine, NativeCallbackInfo *info)
114 {
115     HILOG_INFO("JsApplicationContextUtils::SwitchArea is called");
116     JsApplicationContextUtils *me =
117         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
118     return me != nullptr ? me->OnSwitchArea(*engine, *info) : nullptr;
119 }
120 
OnSwitchArea(NativeEngine & engine,NativeCallbackInfo & info)121 NativeValue *JsApplicationContextUtils::OnSwitchArea(NativeEngine &engine, NativeCallbackInfo &info)
122 {
123     if (info.argc == 0) {
124         HILOG_ERROR("Not enough params");
125         return engine.CreateUndefined();
126     }
127 
128     auto applicationContext = applicationContext_.lock();
129     if (!applicationContext) {
130         HILOG_WARN("applicationContext is already released");
131         return engine.CreateUndefined();
132     }
133 
134     int mode = 0;
135     if (!ConvertFromJsValue(engine, info.argv[0], mode)) {
136         HILOG_ERROR("Parse mode failed");
137         return engine.CreateUndefined();
138     }
139 
140     applicationContext->SwitchArea(mode);
141 
142     NativeValue *thisVar = info.thisVar;
143     NativeObject *object = ConvertNativeValueTo<NativeObject>(thisVar);
144     if (object == nullptr) {
145         HILOG_ERROR("object is nullptr");
146         return engine.CreateUndefined();
147     }
148     BindNativeProperty(*object, "cacheDir", GetCacheDir);
149     BindNativeProperty(*object, "tempDir", GetTempDir);
150     BindNativeProperty(*object, "filesDir", GetFilesDir);
151     BindNativeProperty(*object, "distributedFilesDir", GetDistributedFilesDir);
152     BindNativeProperty(*object, "databaseDir", GetDatabaseDir);
153     BindNativeProperty(*object, "preferencesDir", GetPreferencesDir);
154     BindNativeProperty(*object, "bundleCodeDir", GetBundleCodeDir);
155     return engine.CreateUndefined();
156 }
157 
158 
CreateModuleContext(NativeEngine * engine,NativeCallbackInfo * info)159 NativeValue* JsApplicationContextUtils::CreateModuleContext(NativeEngine* engine, NativeCallbackInfo* info)
160 {
161     JsApplicationContextUtils *me =
162         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
163     return me != nullptr ? me->OnCreateModuleContext(*engine, *info) : nullptr;
164 }
165 
OnCreateModuleContext(NativeEngine & engine,NativeCallbackInfo & info)166 NativeValue* JsApplicationContextUtils::OnCreateModuleContext(NativeEngine& engine, NativeCallbackInfo& info)
167 {
168     auto applicationContext = applicationContext_.lock();
169     if (!applicationContext) {
170         HILOG_WARN("applicationContext is already released");
171         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
172         return engine.CreateUndefined();
173     }
174 
175     std::string moduleName;
176     std::shared_ptr<Context> moduleContext = nullptr;
177     if (!ConvertFromJsValue(engine, info.argv[1], moduleName)) {
178         HILOG_INFO("Parse inner module name.");
179         if (!ConvertFromJsValue(engine, info.argv[0], moduleName)) {
180             HILOG_ERROR("Parse moduleName failed");
181             AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
182             return engine.CreateUndefined();
183         }
184         moduleContext = applicationContext->CreateModuleContext(moduleName);
185     } else {
186         std::string bundleName;
187         if (!ConvertFromJsValue(engine, info.argv[0], bundleName)) {
188             HILOG_ERROR("Parse bundleName failed");
189             AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
190             return engine.CreateUndefined();
191         }
192         if (!CheckCallerIsSystemApp()) {
193             HILOG_ERROR("This application is not system-app, can not use system-api");
194             AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
195             return engine.CreateUndefined();
196         }
197         HILOG_INFO("Parse outer module name.");
198         moduleContext = applicationContext->CreateModuleContext(bundleName, moduleName);
199     }
200 
201     if (!moduleContext) {
202         HILOG_ERROR("failed to create module context.");
203         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
204         return engine.CreateUndefined();
205     }
206 
207     NativeValue* value = CreateJsBaseContext(engine, moduleContext, true);
208     auto systemModule = JsRuntime::LoadSystemModuleByEngine(&engine, "application.Context", &value, 1);
209     if (systemModule == nullptr) {
210         HILOG_WARN("invalid systemModule.");
211         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
212         return engine.CreateUndefined();
213     }
214     auto contextObj = systemModule->Get();
215     NativeObject *nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
216     if (nativeObj == nullptr) {
217         HILOG_ERROR("OnCreateModuleContext, Failed to get context native object");
218         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
219         return engine.CreateUndefined();
220     }
221     auto workContext = new (std::nothrow) std::weak_ptr<Context>(moduleContext);
222     nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
223     nativeObj->SetNativePointer(
224         workContext,
225         [](NativeEngine *, void *data, void *) {
226             HILOG_INFO("Finalizer for weak_ptr module context is called");
227             delete static_cast<std::weak_ptr<Context> *>(data);
228         },
229         nullptr);
230     return contextObj;
231 }
232 
GetArea(NativeEngine * engine,NativeCallbackInfo * info)233 NativeValue* JsApplicationContextUtils::GetArea(NativeEngine* engine, NativeCallbackInfo* info)
234 {
235     HILOG_INFO("JsApplicationContextUtils::GetArea is called");
236     JsApplicationContextUtils *me =
237         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
238     return me != nullptr ? me->OnGetArea(*engine, *info) : nullptr;
239 }
240 
OnGetArea(NativeEngine & engine,NativeCallbackInfo & info)241 NativeValue* JsApplicationContextUtils::OnGetArea(NativeEngine& engine, NativeCallbackInfo& info)
242 {
243     auto applicationContext = applicationContext_.lock();
244     if (!applicationContext) {
245         HILOG_WARN("applicationContext is already released");
246         return engine.CreateUndefined();
247     }
248     int area = applicationContext->GetArea();
249     return engine.CreateNumber(area);
250 }
251 
GetCacheDir(NativeEngine * engine,NativeCallbackInfo * info)252 NativeValue *JsApplicationContextUtils::GetCacheDir(NativeEngine *engine, NativeCallbackInfo *info)
253 {
254     HILOG_INFO("JsApplicationContextUtils::GetCacheDir is called");
255     JsApplicationContextUtils *me =
256         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
257     return me != nullptr ? me->OnGetCacheDir(*engine, *info) : nullptr;
258 }
259 
OnGetCacheDir(NativeEngine & engine,NativeCallbackInfo & info)260 NativeValue *JsApplicationContextUtils::OnGetCacheDir(NativeEngine &engine, NativeCallbackInfo &info)
261 {
262     auto applicationContext = applicationContext_.lock();
263     if (!applicationContext) {
264         HILOG_WARN("applicationContext is already released");
265         return engine.CreateUndefined();
266     }
267     std::string path = applicationContext->GetCacheDir();
268     return engine.CreateString(path.c_str(), path.length());
269 }
270 
GetTempDir(NativeEngine * engine,NativeCallbackInfo * info)271 NativeValue *JsApplicationContextUtils::GetTempDir(NativeEngine *engine, NativeCallbackInfo *info)
272 {
273     HILOG_INFO("JsApplicationContextUtils::GetTempDir is called");
274     JsApplicationContextUtils *me =
275         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
276     return me != nullptr ? me->OnGetTempDir(*engine, *info) : nullptr;
277 }
278 
OnGetTempDir(NativeEngine & engine,NativeCallbackInfo & info)279 NativeValue *JsApplicationContextUtils::OnGetTempDir(NativeEngine &engine, NativeCallbackInfo &info)
280 {
281     auto applicationContext = applicationContext_.lock();
282     if (!applicationContext) {
283         HILOG_WARN("applicationContext is already released");
284         return engine.CreateUndefined();
285     }
286     std::string path = applicationContext->GetTempDir();
287     return engine.CreateString(path.c_str(), path.length());
288 }
289 
GetFilesDir(NativeEngine * engine,NativeCallbackInfo * info)290 NativeValue *JsApplicationContextUtils::GetFilesDir(NativeEngine *engine, NativeCallbackInfo *info)
291 {
292     HILOG_INFO("JsApplicationContextUtils::GetFilesDir is called");
293     JsApplicationContextUtils *me =
294         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
295     return me != nullptr ? me->OnGetFilesDir(*engine, *info) : nullptr;
296 }
297 
OnGetFilesDir(NativeEngine & engine,NativeCallbackInfo & info)298 NativeValue *JsApplicationContextUtils::OnGetFilesDir(NativeEngine &engine, NativeCallbackInfo &info)
299 {
300     auto applicationContext = applicationContext_.lock();
301     if (!applicationContext) {
302         HILOG_WARN("applicationContext is already released");
303         return engine.CreateUndefined();
304     }
305     std::string path = applicationContext->GetFilesDir();
306     return engine.CreateString(path.c_str(), path.length());
307 }
308 
GetDistributedFilesDir(NativeEngine * engine,NativeCallbackInfo * info)309 NativeValue *JsApplicationContextUtils::GetDistributedFilesDir(NativeEngine *engine, NativeCallbackInfo *info)
310 {
311     HILOG_INFO("JsApplicationContextUtils::GetDistributedFilesDir is called");
312     JsApplicationContextUtils *me =
313         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
314     return me != nullptr ? me->OnGetDistributedFilesDir(*engine, *info) : nullptr;
315 }
316 
OnGetDistributedFilesDir(NativeEngine & engine,NativeCallbackInfo & info)317 NativeValue *JsApplicationContextUtils::OnGetDistributedFilesDir(NativeEngine &engine, NativeCallbackInfo &info)
318 {
319     auto applicationContext = applicationContext_.lock();
320     if (!applicationContext) {
321         HILOG_WARN("applicationContext is already released");
322         return engine.CreateUndefined();
323     }
324     std::string path = applicationContext->GetDistributedFilesDir();
325     return engine.CreateString(path.c_str(), path.length());
326 }
327 
GetDatabaseDir(NativeEngine * engine,NativeCallbackInfo * info)328 NativeValue *JsApplicationContextUtils::GetDatabaseDir(NativeEngine *engine, NativeCallbackInfo *info)
329 {
330     HILOG_INFO("JsApplicationContextUtils::GetDatabaseDir is called");
331     JsApplicationContextUtils *me =
332         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
333     return me != nullptr ? me->OnGetDatabaseDir(*engine, *info) : nullptr;
334 }
335 
OnGetDatabaseDir(NativeEngine & engine,NativeCallbackInfo & info)336 NativeValue *JsApplicationContextUtils::OnGetDatabaseDir(NativeEngine &engine, NativeCallbackInfo &info)
337 {
338     auto applicationContext = applicationContext_.lock();
339     if (!applicationContext) {
340         HILOG_WARN("applicationContext is already released");
341         return engine.CreateUndefined();
342     }
343     std::string path = applicationContext->GetDatabaseDir();
344     return engine.CreateString(path.c_str(), path.length());
345 }
346 
GetPreferencesDir(NativeEngine * engine,NativeCallbackInfo * info)347 NativeValue *JsApplicationContextUtils::GetPreferencesDir(NativeEngine *engine, NativeCallbackInfo *info)
348 {
349     HILOG_INFO("JsApplicationContextUtils::GetPreferencesDir is called");
350     JsApplicationContextUtils *me =
351         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
352     return me != nullptr ? me->OnGetPreferencesDir(*engine, *info) : nullptr;
353 }
354 
GetGroupDir(NativeEngine * engine,NativeCallbackInfo * info)355 NativeValue *JsApplicationContextUtils::GetGroupDir(NativeEngine *engine, NativeCallbackInfo *info)
356 {
357     HILOG_INFO("called");
358     JsApplicationContextUtils *me =
359         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
360     return me != nullptr ? me->OnGetGroupDir(*engine, *info) : nullptr;
361 }
362 
OnGetPreferencesDir(NativeEngine & engine,NativeCallbackInfo & info)363 NativeValue *JsApplicationContextUtils::OnGetPreferencesDir(NativeEngine &engine, NativeCallbackInfo &info)
364 {
365     auto applicationContext = applicationContext_.lock();
366     if (!applicationContext) {
367         HILOG_WARN("applicationContext is already released");
368         return engine.CreateUndefined();
369     }
370     std::string path = applicationContext->GetPreferencesDir();
371     return engine.CreateString(path.c_str(), path.length());
372 }
373 
OnGetGroupDir(NativeEngine & engine,NativeCallbackInfo & info)374 NativeValue *JsApplicationContextUtils::OnGetGroupDir(NativeEngine &engine, NativeCallbackInfo &info)
375 {
376     if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
377         HILOG_ERROR("Not enough params");
378         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
379         return engine.CreateUndefined();
380     }
381 
382     std::string groupId;
383     if (!ConvertFromJsValue(engine, info.argv[0], groupId)) {
384         HILOG_ERROR("Parse groupId failed");
385         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
386         return engine.CreateUndefined();
387     }
388 
389     HILOG_DEBUG("Get Group Dir");
390     auto complete = [applicationContext = applicationContext_, groupId]
391         (NativeEngine& engine, AsyncTask& task, int32_t status) {
392         auto context = applicationContext.lock();
393         if (!context) {
394             task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST,
395                 "applicationContext if already released."));
396             return;
397         }
398         std::string path = context->GetGroupDir(groupId);
399         task.ResolveWithNoError(engine, CreateJsValue(engine, path));
400     };
401 
402     NativeValue* lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
403     NativeValue* result = nullptr;
404     AsyncTask::ScheduleHighQos("JsApplicationContextUtils::OnGetGroupDir",
405         engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
406     return result;
407 }
408 
GetBundleCodeDir(NativeEngine * engine,NativeCallbackInfo * info)409 NativeValue *JsApplicationContextUtils::GetBundleCodeDir(NativeEngine *engine, NativeCallbackInfo *info)
410 {
411     HILOG_INFO("JsApplicationContextUtils::GetBundleCodeDir is called");
412     JsApplicationContextUtils *me =
413         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
414     return me != nullptr ? me->OnGetBundleCodeDir(*engine, *info) : nullptr;
415 }
416 
OnGetBundleCodeDir(NativeEngine & engine,NativeCallbackInfo & info)417 NativeValue *JsApplicationContextUtils::OnGetBundleCodeDir(NativeEngine &engine, NativeCallbackInfo &info)
418 {
419     auto applicationContext = applicationContext_.lock();
420     if (!applicationContext) {
421         HILOG_WARN("applicationContext is already released");
422         return engine.CreateUndefined();
423     }
424     std::string path = applicationContext->GetBundleCodeDir();
425     return engine.CreateString(path.c_str(), path.length());
426 }
427 
KillProcessBySelf(NativeEngine * engine,NativeCallbackInfo * info)428 NativeValue *JsApplicationContextUtils::KillProcessBySelf(NativeEngine *engine, NativeCallbackInfo *info)
429 {
430     JsApplicationContextUtils *me =
431         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
432     return me != nullptr ? me->OnKillProcessBySelf(*engine, *info) : nullptr;
433 }
434 
OnKillProcessBySelf(NativeEngine & engine,NativeCallbackInfo & info)435 NativeValue *JsApplicationContextUtils::OnKillProcessBySelf(NativeEngine &engine, NativeCallbackInfo &info)
436 {
437     // only support 0 or 1 params
438     if (info.argc != ARGC_ZERO && info.argc != ARGC_ONE) {
439         HILOG_ERROR("Not enough params");
440         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
441         return engine.CreateUndefined();
442     }
443     HILOG_DEBUG("kill self process");
444     AsyncTask::CompleteCallback complete =
445         [applicationContext = applicationContext_](NativeEngine& engine, AsyncTask& task, int32_t status) {
446             auto context = applicationContext.lock();
447             if (!context) {
448                 task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST,
449                     "applicationContext if already released."));
450                 return;
451             }
452             context->KillProcessBySelf();
453             task.ResolveWithNoError(engine, engine.CreateUndefined());
454         };
455     NativeValue* lastParam = (info.argc = ARGC_ONE) ? info.argv[INDEX_ZERO] : nullptr;
456     NativeValue* result = nullptr;
457     AsyncTask::ScheduleHighQos("JsApplicationContextUtils::OnkillProcessBySelf",
458         engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
459     return result;
460 }
461 
GetRunningProcessInformation(NativeEngine * engine,NativeCallbackInfo * info)462 NativeValue *JsApplicationContextUtils::GetRunningProcessInformation(NativeEngine *engine, NativeCallbackInfo *info)
463 {
464     JsApplicationContextUtils *me =
465         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
466     return me != nullptr ? me->OnGetRunningProcessInformation(*engine, *info) : nullptr;
467 }
468 
OnGetRunningProcessInformation(NativeEngine & engine,NativeCallbackInfo & info)469 NativeValue *JsApplicationContextUtils::OnGetRunningProcessInformation(NativeEngine &engine, NativeCallbackInfo &info)
470 {
471     // only support 0 or 1 params
472     if (info.argc != ARGC_ZERO && info.argc != ARGC_ONE) {
473         HILOG_ERROR("Not enough params");
474         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
475         return engine.CreateUndefined();
476     }
477     HILOG_DEBUG("Get Process Info");
478     auto complete = [applicationContext = applicationContext_](NativeEngine& engine, AsyncTask& task, int32_t status) {
479         auto context = applicationContext.lock();
480         if (!context) {
481             task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST,
482                 "applicationContext if already released."));
483             return;
484         }
485         AppExecFwk::RunningProcessInfo processInfo;
486         auto ret = context->GetProcessRunningInformation(processInfo);
487         if (ret == 0) {
488             NativeValue* objValue = engine.CreateObject();
489             NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
490             object->SetProperty("processName", CreateJsValue(engine, processInfo.processName_));
491             object->SetProperty("pid", CreateJsValue(engine, processInfo.pid_));
492             object->SetProperty("uid", CreateJsValue(engine, processInfo.uid_));
493             object->SetProperty("bundleNames", CreateNativeArray(engine, processInfo.bundleNames));
494             object->SetProperty(
495                 "state", CreateJsValue(engine, ConvertToJsAppProcessState(processInfo.state_, processInfo.isFocused)));
496             object->SetProperty("isContinuousTask", CreateJsValue(engine, processInfo.isContinuousTask));
497             object->SetProperty("isKeepAlive", CreateJsValue(engine, processInfo.isKeepAlive));
498             object->SetProperty("isFocused", CreateJsValue(engine, processInfo.isFocused));
499             NativeValue* arrayValue = engine.CreateArray(1);
500             NativeArray* array = ConvertNativeValueTo<NativeArray>(arrayValue);
501             if (array == nullptr) {
502                 HILOG_ERROR("Initiate array failed.");
503                 task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR,
504                     "Initiate array failed."));
505             } else {
506                 array->SetElement(0, objValue);
507                 task.ResolveWithNoError(engine, arrayValue);
508             }
509         } else {
510             task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR,
511                 "Get process infos failed."));
512         }
513     };
514 
515     NativeValue* lastParam = (info.argc == ARGC_ONE) ? info.argv[INDEX_ZERO] : nullptr;
516     NativeValue* result = nullptr;
517     AsyncTask::Schedule("JsApplicationContextUtils::OnGetRunningProcessInformation",
518         engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
519     return result;
520 }
521 
Finalizer(NativeEngine * engine,void * data,void * hint)522 void JsApplicationContextUtils::Finalizer(NativeEngine *engine, void *data, void *hint)
523 {
524     HILOG_INFO("JsApplicationContextUtils::Finalizer is called");
525     std::unique_ptr<JsApplicationContextUtils>(static_cast<JsApplicationContextUtils *>(data));
526 }
527 
RegisterAbilityLifecycleCallback(NativeEngine * engine,NativeCallbackInfo * info)528 NativeValue *JsApplicationContextUtils::RegisterAbilityLifecycleCallback(NativeEngine *engine, NativeCallbackInfo *info)
529 {
530     JsApplicationContextUtils *me =
531         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
532     return me != nullptr ? me->OnRegisterAbilityLifecycleCallback(*engine, *info) : nullptr;
533 }
534 
UnregisterAbilityLifecycleCallback(NativeEngine * engine,NativeCallbackInfo * info)535 NativeValue *JsApplicationContextUtils::UnregisterAbilityLifecycleCallback(
536     NativeEngine *engine, NativeCallbackInfo *info)
537 {
538     JsApplicationContextUtils *me =
539         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
540     return me != nullptr ? me->OnUnregisterAbilityLifecycleCallback(*engine, *info) : nullptr;
541 }
542 
OnRegisterAbilityLifecycleCallback(NativeEngine & engine,NativeCallbackInfo & info)543 NativeValue *JsApplicationContextUtils::OnRegisterAbilityLifecycleCallback(
544     NativeEngine &engine, NativeCallbackInfo &info)
545 {
546     HILOG_INFO("OnRegisterAbilityLifecycleCallback is called");
547     // only support one params
548     if (info.argc != ARGC_ONE) {
549         HILOG_ERROR("Not enough params.");
550         return engine.CreateUndefined();
551     }
552 
553     auto applicationContext = applicationContext_.lock();
554     if (applicationContext == nullptr) {
555         HILOG_ERROR("ApplicationContext is nullptr.");
556         return engine.CreateUndefined();
557     }
558     if (callback_ != nullptr) {
559         HILOG_DEBUG("callback_ is not nullptr.");
560         return engine.CreateNumber(callback_->Register(info.argv[0]));
561     }
562     callback_ = std::make_shared<JsAbilityLifecycleCallback>(&engine);
563     int32_t callbackId = callback_->Register(info.argv[INDEX_ZERO]);
564     applicationContext->RegisterAbilityLifecycleCallback(callback_);
565     HILOG_INFO("OnRegisterAbilityLifecycleCallback is end");
566     return engine.CreateNumber(callbackId);
567 }
568 
OnUnregisterAbilityLifecycleCallback(NativeEngine & engine,NativeCallbackInfo & info)569 NativeValue *JsApplicationContextUtils::OnUnregisterAbilityLifecycleCallback(
570     NativeEngine &engine, NativeCallbackInfo &info)
571 {
572     HILOG_INFO("OnUnregisterAbilityLifecycleCallback is called");
573     int32_t errCode = 0;
574     auto applicationContext = applicationContext_.lock();
575     if (applicationContext == nullptr) {
576         HILOG_ERROR("ApplicationContext is nullptr.");
577         errCode = ERROR_CODE_ONE;
578     }
579     int32_t callbackId = -1;
580     if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
581         HILOG_ERROR("OnUnregisterAbilityLifecycleCallback, Not enough params");
582         errCode = ERROR_CODE_ONE;
583     } else {
584         napi_get_value_int32(reinterpret_cast<napi_env>(&engine),
585             reinterpret_cast<napi_value>(info.argv[INDEX_ZERO]), &callbackId);
586         HILOG_DEBUG("callbackId is %{public}d.", callbackId);
587     }
588     std::weak_ptr<JsAbilityLifecycleCallback> callbackWeak(callback_);
589     AsyncTask::CompleteCallback complete = [callbackWeak, callbackId, errCode](
590             NativeEngine &engine, AsyncTask &task, int32_t status) {
591             if (errCode != 0) {
592                 task.Reject(engine, CreateJsError(engine, errCode, "Invalidate params."));
593                 return;
594             }
595             auto callback = callbackWeak.lock();
596             if (callback == nullptr) {
597                 HILOG_ERROR("callback is nullptr");
598                 task.Reject(engine, CreateJsError(engine, ERROR_CODE_ONE, "callback is nullptr"));
599                 return;
600             }
601 
602             HILOG_DEBUG("OnUnregisterAbilityLifecycleCallback begin");
603             if (!callback->UnRegister(callbackId)) {
604                 HILOG_ERROR("call UnRegister failed!");
605                 task.Reject(engine, CreateJsError(engine, ERROR_CODE_ONE, "call UnRegister failed!"));
606                 return;
607             }
608 
609             task.Resolve(engine, engine.CreateUndefined());
610         };
611     NativeValue *lastParam = (info.argc <= ARGC_ONE) ? nullptr : info.argv[INDEX_ONE];
612     NativeValue *result = nullptr;
613     AsyncTask::Schedule("JsApplicationContextUtils::OnUnregisterAbilityLifecycleCallback", engine,
614         CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
615     return result;
616 }
617 
RegisterEnvironmentCallback(NativeEngine * engine,NativeCallbackInfo * info)618 NativeValue *JsApplicationContextUtils::RegisterEnvironmentCallback(NativeEngine *engine, NativeCallbackInfo *info)
619 {
620     JsApplicationContextUtils *me =
621         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
622     return me != nullptr ? me->OnRegisterEnvironmentCallback(*engine, *info) : nullptr;
623 }
624 
UnregisterEnvironmentCallback(NativeEngine * engine,NativeCallbackInfo * info)625 NativeValue *JsApplicationContextUtils::UnregisterEnvironmentCallback(
626     NativeEngine *engine, NativeCallbackInfo *info)
627 {
628     JsApplicationContextUtils *me =
629         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
630     return me != nullptr ? me->OnUnregisterEnvironmentCallback(*engine, *info) : nullptr;
631 }
632 
OnRegisterEnvironmentCallback(NativeEngine & engine,NativeCallbackInfo & info)633 NativeValue *JsApplicationContextUtils::OnRegisterEnvironmentCallback(
634     NativeEngine &engine, NativeCallbackInfo &info)
635 {
636     HILOG_DEBUG("OnRegisterEnvironmentCallback is called");
637     // only support one params
638     if (info.argc != ARGC_ONE) {
639         HILOG_ERROR("Not enough params.");
640         return engine.CreateUndefined();
641     }
642 
643     auto applicationContext = applicationContext_.lock();
644     if (applicationContext == nullptr) {
645         HILOG_ERROR("ApplicationContext is nullptr.");
646         return engine.CreateUndefined();
647     }
648     if (envCallback_ != nullptr) {
649         HILOG_DEBUG("envCallback_ is not nullptr.");
650         return engine.CreateNumber(envCallback_->Register(info.argv[0]));
651     }
652     envCallback_ = std::make_shared<JsEnvironmentCallback>(&engine);
653     int32_t callbackId = envCallback_->Register(info.argv[INDEX_ZERO]);
654     applicationContext->RegisterEnvironmentCallback(envCallback_);
655     HILOG_DEBUG("OnRegisterEnvironmentCallback is end");
656     return engine.CreateNumber(callbackId);
657 }
658 
OnUnregisterEnvironmentCallback(NativeEngine & engine,NativeCallbackInfo & info)659 NativeValue *JsApplicationContextUtils::OnUnregisterEnvironmentCallback(
660     NativeEngine &engine, NativeCallbackInfo &info)
661 {
662     HILOG_DEBUG("OnUnregisterEnvironmentCallback is called");
663     int32_t errCode = 0;
664     auto applicationContext = applicationContext_.lock();
665     if (applicationContext == nullptr) {
666         HILOG_ERROR("ApplicationContext is nullptr.");
667         errCode = ERROR_CODE_ONE;
668     }
669     int32_t callbackId = -1;
670     if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
671         HILOG_ERROR("OnUnregisterEnvironmentCallback, Not enough params");
672         errCode = ERROR_CODE_ONE;
673     } else {
674         napi_get_value_int32(
675             reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[INDEX_ZERO]), &callbackId);
676         HILOG_DEBUG("callbackId is %{public}d.", callbackId);
677     }
678     std::weak_ptr<JsEnvironmentCallback> envCallbackWeak(envCallback_);
679     AsyncTask::CompleteCallback complete = [envCallbackWeak, callbackId, errCode](
680             NativeEngine &engine, AsyncTask &task, int32_t status) {
681             if (errCode != 0) {
682                 task.Reject(engine, CreateJsError(engine, errCode, "Invalidate params."));
683                 return;
684             }
685             auto env_callback = envCallbackWeak.lock();
686             if (env_callback == nullptr) {
687                 HILOG_ERROR("env_callback is nullptr");
688                 task.Reject(engine, CreateJsError(engine, ERROR_CODE_ONE, "env_callback is nullptr"));
689                 return;
690             }
691 
692             HILOG_DEBUG("OnUnregisterEnvironmentCallback begin");
693             if (!env_callback->UnRegister(callbackId)) {
694                 HILOG_ERROR("call UnRegister failed!");
695                 task.Reject(engine, CreateJsError(engine, ERROR_CODE_ONE, "call UnRegister failed!"));
696                 return;
697             }
698 
699             task.Resolve(engine, engine.CreateUndefined());
700         };
701     NativeValue *lastParam = (info.argc <= ARGC_ONE) ? nullptr : info.argv[INDEX_ONE];
702     NativeValue *result = nullptr;
703     AsyncTask::Schedule("JsApplicationContextUtils::OnUnregisterEnvironmentCallback", engine,
704         CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
705     return result;
706 }
707 
On(NativeEngine * engine,NativeCallbackInfo * info)708 NativeValue *JsApplicationContextUtils::On(NativeEngine *engine, NativeCallbackInfo *info)
709 {
710     JsApplicationContextUtils *me =
711         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
712     return me != nullptr ? me->OnOn(*engine, *info) : nullptr;
713 }
714 
Off(NativeEngine * engine,NativeCallbackInfo * info)715 NativeValue *JsApplicationContextUtils::Off(NativeEngine *engine, NativeCallbackInfo *info)
716 {
717     JsApplicationContextUtils *me =
718         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
719     return me != nullptr ? me->OnOff(*engine, *info) : nullptr;
720 }
721 
OnOn(NativeEngine & engine,NativeCallbackInfo & info)722 NativeValue *JsApplicationContextUtils::OnOn(NativeEngine &engine, NativeCallbackInfo &info)
723 {
724     HILOG_INFO("OnOn is called");
725 
726     if (info.argc != ARGC_TWO) {
727         HILOG_ERROR("Not enough params.");
728         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
729         return engine.CreateUndefined();
730     }
731 
732     if (info.argv[0]->TypeOf() != NATIVE_STRING) {
733         HILOG_ERROR("param0 is invalid");
734         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
735         return engine.CreateUndefined();
736     }
737     std::string type;
738     if (!ConvertFromJsValue(engine, info.argv[0], type)) {
739         HILOG_ERROR("convert type failed!");
740         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
741         return engine.CreateUndefined();
742     }
743 
744     if (type == "abilityLifecycle") {
745         return OnOnAbilityLifecycle(engine, info, false);
746     }
747     if (type == "abilityLifecycleEvent") {
748         return OnOnAbilityLifecycle(engine, info, true);
749     }
750     if (type == "environment") {
751         return OnOnEnvironment(engine, info, false);
752     }
753     if (type == "environmentEvent") {
754         return OnOnEnvironment(engine, info, true);
755     }
756     if (type == "applicationStateChange") {
757         return OnOnApplicationStateChange(engine, info);
758     }
759     HILOG_ERROR("on function type not match.");
760     AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
761     return engine.CreateUndefined();
762 }
763 
OnOff(NativeEngine & engine,const NativeCallbackInfo & info)764 NativeValue *JsApplicationContextUtils::OnOff(NativeEngine &engine, const NativeCallbackInfo &info)
765 {
766     HILOG_INFO("OnOff is called");
767     if (info.argc < ARGC_ONE) {
768         HILOG_ERROR("Not enough params");
769         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
770         return engine.CreateUndefined();
771     }
772 
773     if (info.argv[0]->TypeOf() != NATIVE_STRING) {
774         HILOG_ERROR("param0 is invalid");
775         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
776         return engine.CreateUndefined();
777     }
778     std::string type;
779     if (!ConvertFromJsValue(engine, info.argv[0], type)) {
780         HILOG_ERROR("convert type failed!");
781         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
782         return engine.CreateUndefined();
783     }
784 
785     if (type == "applicationStateChange") {
786         return OnOffApplicationStateChange(engine, info);
787     }
788 
789     if (info.argc != ARGC_TWO && info.argc != ARGC_THREE) {
790         HILOG_ERROR("Not enough params");
791         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
792         return engine.CreateUndefined();
793     }
794 
795     int32_t callbackId = -1;
796     if (info.argv[1]->TypeOf() == NATIVE_NUMBER) {
797         napi_get_value_int32(
798             reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[1]), &callbackId);
799         HILOG_DEBUG("callbackId is %{public}d.", callbackId);
800     }
801 
802     if (type == "abilityLifecycle") {
803         return OnOffAbilityLifecycle(engine, info, callbackId);
804     }
805     if (type == "abilityLifecycleEvent") {
806         return OnOffAbilityLifecycleEventSync(engine, info, callbackId);
807     }
808     if (type == "environment") {
809         return OnOffEnvironment(engine, info, callbackId);
810     }
811     if (type == "environmentEvent") {
812         return OnOffEnvironmentEventSync(engine, info, callbackId);
813     }
814     HILOG_ERROR("off function type not match.");
815     AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
816     return engine.CreateUndefined();
817 }
818 
OnOnAbilityLifecycle(NativeEngine & engine,NativeCallbackInfo & info,bool isSync)819 NativeValue *JsApplicationContextUtils::OnOnAbilityLifecycle(
820     NativeEngine &engine, NativeCallbackInfo &info, bool isSync)
821 {
822     HILOG_DEBUG("called");
823 
824     auto applicationContext = applicationContext_.lock();
825     if (applicationContext == nullptr) {
826         HILOG_ERROR("ApplicationContext is nullptr.");
827         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
828         return engine.CreateUndefined();
829     }
830 
831     if (callback_ != nullptr) {
832         HILOG_DEBUG("callback_ is not nullptr.");
833         return engine.CreateNumber(callback_->Register(info.argv[1], isSync));
834     }
835     callback_ = std::make_shared<JsAbilityLifecycleCallback>(&engine);
836     int32_t callbackId = callback_->Register(info.argv[1], isSync);
837     applicationContext->RegisterAbilityLifecycleCallback(callback_);
838     HILOG_INFO("OnOnAbilityLifecycle is end");
839     return engine.CreateNumber(callbackId);
840 }
841 
OnOffAbilityLifecycle(NativeEngine & engine,const NativeCallbackInfo & info,int32_t callbackId)842 NativeValue *JsApplicationContextUtils::OnOffAbilityLifecycle(
843     NativeEngine &engine, const NativeCallbackInfo &info, int32_t callbackId)
844 {
845     HILOG_DEBUG("called");
846 
847     auto applicationContext = applicationContext_.lock();
848     if (applicationContext == nullptr) {
849         HILOG_ERROR("ApplicationContext is nullptr.");
850         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
851         return engine.CreateUndefined();
852     }
853 
854     std::weak_ptr<JsAbilityLifecycleCallback> callbackWeak(callback_);
855     AsyncTask::CompleteCallback complete = [callbackWeak, callbackId](
856             NativeEngine &engine, AsyncTask &task, int32_t status) {
857             auto callback = callbackWeak.lock();
858             if (callback == nullptr) {
859                 HILOG_ERROR("callback is nullptr");
860                 task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
861                     "callback is nullptr"));
862                 return;
863             }
864 
865             HILOG_DEBUG("OnOffAbilityLifecycle begin");
866             if (!callback->UnRegister(callbackId, false)) {
867                 HILOG_ERROR("call UnRegister failed!");
868                 task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
869                     "call UnRegister failed!"));
870                 return;
871             }
872 
873             task.ResolveWithNoError(engine, engine.CreateUndefined());
874         };
875     NativeValue *lastParam = (info.argc <= ARGC_TWO) ? nullptr : info.argv[INDEX_TWO];
876     NativeValue *result = nullptr;
877     AsyncTask::Schedule("JsApplicationContextUtils::OnOffAbilityLifecycle", engine,
878         CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
879     return result;
880 }
881 
OnOffAbilityLifecycleEventSync(NativeEngine & engine,const NativeCallbackInfo & info,int32_t callbackId)882 NativeValue *JsApplicationContextUtils::OnOffAbilityLifecycleEventSync(
883     NativeEngine &engine, const NativeCallbackInfo &info, int32_t callbackId)
884 {
885     HILOG_DEBUG("called");
886 
887     auto applicationContext = applicationContext_.lock();
888     if (applicationContext == nullptr) {
889         HILOG_ERROR("ApplicationContext is nullptr.");
890         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
891         return engine.CreateUndefined();
892     }
893     if (callback_ == nullptr) {
894         HILOG_ERROR("callback is nullptr");
895         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
896         return engine.CreateUndefined();
897     }
898     if (!callback_->UnRegister(callbackId, true)) {
899         HILOG_ERROR("call UnRegister failed!");
900         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
901         return engine.CreateUndefined();
902     }
903     return engine.CreateUndefined();
904 }
905 
OnOnEnvironment(NativeEngine & engine,NativeCallbackInfo & info,bool isSync)906 NativeValue *JsApplicationContextUtils::OnOnEnvironment(
907     NativeEngine &engine, NativeCallbackInfo &info, bool isSync)
908 {
909     HILOG_DEBUG("called");
910 
911     auto applicationContext = applicationContext_.lock();
912     if (applicationContext == nullptr) {
913         HILOG_ERROR("ApplicationContext is nullptr.");
914         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
915         return engine.CreateUndefined();
916     }
917 
918     if (envCallback_ != nullptr) {
919         HILOG_DEBUG("envCallback_ is not nullptr.");
920         return engine.CreateNumber(envCallback_->Register(info.argv[1], isSync));
921     }
922     envCallback_ = std::make_shared<JsEnvironmentCallback>(&engine);
923     int32_t callbackId = envCallback_->Register(info.argv[1], isSync);
924     applicationContext->RegisterEnvironmentCallback(envCallback_);
925     HILOG_DEBUG("OnOnEnvironment is end");
926     return engine.CreateNumber(callbackId);
927 }
928 
OnOffEnvironment(NativeEngine & engine,const NativeCallbackInfo & info,int32_t callbackId)929 NativeValue *JsApplicationContextUtils::OnOffEnvironment(
930     NativeEngine &engine, const NativeCallbackInfo &info, int32_t callbackId)
931 {
932     HILOG_DEBUG("called");
933 
934     auto applicationContext = applicationContext_.lock();
935     if (applicationContext == nullptr) {
936         HILOG_ERROR("ApplicationContext is nullptr.");
937         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
938         return engine.CreateUndefined();
939     }
940 
941     std::weak_ptr<JsEnvironmentCallback> envCallbackWeak(envCallback_);
942     AsyncTask::CompleteCallback complete = [envCallbackWeak, callbackId](
943             NativeEngine &engine, AsyncTask &task, int32_t status) {
944             auto env_callback = envCallbackWeak.lock();
945             if (env_callback == nullptr) {
946                 HILOG_ERROR("env_callback is nullptr");
947                 task.Reject(engine,
948                     CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
949                         "env_callback is nullptr"));
950                 return;
951             }
952 
953             HILOG_DEBUG("OnOffEnvironment begin");
954             if (!env_callback->UnRegister(callbackId, false)) {
955                 HILOG_ERROR("call UnRegister failed!");
956                 task.Reject(engine, CreateJsError(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
957                     "call UnRegister failed!"));
958                 return;
959             }
960 
961             task.ResolveWithNoError(engine, engine.CreateUndefined());
962         };
963     NativeValue *lastParam = (info.argc <= ARGC_TWO) ? nullptr : info.argv[INDEX_TWO];
964     NativeValue *result = nullptr;
965     AsyncTask::Schedule("JsApplicationContextUtils::OnOffEnvironment", engine,
966         CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
967     return result;
968 }
969 
OnOffEnvironmentEventSync(NativeEngine & engine,const NativeCallbackInfo & info,int32_t callbackId)970 NativeValue *JsApplicationContextUtils::OnOffEnvironmentEventSync(
971     NativeEngine &engine, const NativeCallbackInfo &info, int32_t callbackId)
972 {
973     HILOG_DEBUG("called");
974 
975     auto applicationContext = applicationContext_.lock();
976     if (applicationContext == nullptr) {
977         HILOG_ERROR("ApplicationContext is nullptr.");
978         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
979         return engine.CreateUndefined();
980     }
981     if (envCallback_ == nullptr) {
982         HILOG_ERROR("env_callback is nullptr");
983         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
984         return engine.CreateUndefined();
985     }
986     if (!envCallback_->UnRegister(callbackId, true)) {
987         HILOG_ERROR("call UnRegister failed!");
988         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
989         return engine.CreateUndefined();
990     }
991     return engine.CreateUndefined();
992 }
993 
OnOnApplicationStateChange(NativeEngine & engine,NativeCallbackInfo & info)994 NativeValue *JsApplicationContextUtils::OnOnApplicationStateChange(
995     NativeEngine &engine, NativeCallbackInfo &info)
996 {
997     HILOG_DEBUG("called.");
998     auto applicationContext = applicationContext_.lock();
999     if (applicationContext == nullptr) {
1000         HILOG_ERROR("ApplicationContext is nullptr.");
1001         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1002         return engine.CreateUndefined();
1003     }
1004 
1005     std::lock_guard<std::mutex> lock(applicationStateCallbackLock_);
1006     if (applicationStateCallback_ != nullptr) {
1007         applicationStateCallback_->Register(info.argv[INDEX_ONE]);
1008         return engine.CreateUndefined();
1009     }
1010 
1011     applicationStateCallback_ = std::make_shared<JsApplicationStateChangeCallback>(&engine);
1012     applicationStateCallback_->Register(info.argv[INDEX_ONE]);
1013     applicationContext->RegisterApplicationStateChangeCallback(applicationStateCallback_);
1014     return engine.CreateUndefined();
1015 }
1016 
OnOffApplicationStateChange(NativeEngine & engine,const NativeCallbackInfo & info)1017 NativeValue *JsApplicationContextUtils::OnOffApplicationStateChange(
1018     NativeEngine &engine, const NativeCallbackInfo &info)
1019 {
1020     HILOG_DEBUG("called.");
1021     auto applicationContext = applicationContext_.lock();
1022     if (applicationContext == nullptr) {
1023         HILOG_ERROR("ApplicationContext is nullptr.");
1024         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1025         return engine.CreateUndefined();
1026     }
1027 
1028     std::lock_guard<std::mutex> lock(applicationStateCallbackLock_);
1029     if (applicationStateCallback_ == nullptr) {
1030         HILOG_ERROR("ApplicationStateCallback_ is nullptr.");
1031         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1032         return engine.CreateUndefined();
1033     }
1034 
1035     if (info.argc == ARGC_ONE || info.argv[INDEX_ONE]->TypeOf() != NATIVE_OBJECT) {
1036         applicationStateCallback_->UnRegister();
1037     } else if (!applicationStateCallback_->UnRegister(info.argv[INDEX_ONE])) {
1038         HILOG_ERROR("call UnRegister failed!");
1039         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1040         return engine.CreateUndefined();
1041     }
1042 
1043     if (applicationStateCallback_->IsEmpty()) {
1044         applicationStateCallback_.reset();
1045     }
1046     return engine.CreateUndefined();
1047 }
1048 
GetApplicationContext(NativeEngine * engine,NativeCallbackInfo * info)1049 NativeValue* JsApplicationContextUtils::GetApplicationContext(NativeEngine* engine, NativeCallbackInfo* info)
1050 {
1051     JsApplicationContextUtils *me =
1052         CheckParamsAndGetThis<JsApplicationContextUtils>(engine, info, APPLICATION_CONTEXT_NAME);
1053     return me != nullptr ? me->OnGetApplicationContext(*engine, *info) : nullptr;
1054 }
1055 
OnGetApplicationContext(NativeEngine & engine,NativeCallbackInfo & info)1056 NativeValue* JsApplicationContextUtils::OnGetApplicationContext(NativeEngine& engine, NativeCallbackInfo& info)
1057 {
1058     HILOG_INFO("GetApplicationContext start");
1059     auto applicationContext = applicationContext_.lock();
1060     if (!applicationContext) {
1061         HILOG_WARN("applicationContext is already released");
1062         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1063         return engine.CreateUndefined();
1064     }
1065 
1066     NativeValue* value = CreateJsApplicationContext(engine);
1067     auto systemModule = JsRuntime::LoadSystemModuleByEngine(&engine, "application.ApplicationContext", &value, 1);
1068     if (systemModule == nullptr) {
1069         HILOG_WARN("OnGetApplicationContext, invalid systemModule.");
1070         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1071         return engine.CreateUndefined();
1072     }
1073     auto contextObj = systemModule->Get();
1074     NativeObject *nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
1075     if (nativeObj == nullptr) {
1076         HILOG_ERROR("OnGetApplicationContext, Failed to get context native object");
1077         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1078         return engine.CreateUndefined();
1079     }
1080     auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(applicationContext);
1081     nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachApplicationContext,
1082         workContext, nullptr);
1083     nativeObj->SetNativePointer(
1084         workContext,
1085         [](NativeEngine *, void *data, void *) {
1086             HILOG_INFO("Finalizer for weak_ptr application context is called");
1087             delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
1088         },
1089         nullptr);
1090     return contextObj;
1091 }
1092 
CheckCallerIsSystemApp()1093 bool JsApplicationContextUtils::CheckCallerIsSystemApp()
1094 {
1095     auto selfToken = IPCSkeleton::GetSelfTokenID();
1096     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
1097         return false;
1098     }
1099     return true;
1100 }
1101 
CreateJsApplicationContext(NativeEngine & engine)1102 NativeValue* JsApplicationContextUtils::CreateJsApplicationContext(NativeEngine &engine)
1103 {
1104     HILOG_DEBUG("CreateJsApplicationContext start");
1105 
1106     NativeValue* objValue = engine.CreateObject();
1107     NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
1108     if (object == nullptr) {
1109         return objValue;
1110     }
1111 
1112     std::shared_ptr<ApplicationContext> applicationContext = ApplicationContext::GetInstance();
1113     if (applicationContext == nullptr) {
1114         return objValue;
1115     }
1116 
1117     auto jsApplicationContextUtils = std::make_unique<JsApplicationContextUtils>(applicationContext);
1118     SetNamedNativePointer(engine, *object, APPLICATION_CONTEXT_NAME, jsApplicationContextUtils.release(),
1119         JsApplicationContextUtils::Finalizer);
1120 
1121     auto appInfo = applicationContext->GetApplicationInfo();
1122     if (appInfo != nullptr) {
1123         object->SetProperty("applicationInfo", CreateJsApplicationInfo(engine, *appInfo));
1124     }
1125     auto resourceManager = applicationContext->GetResourceManager();
1126     std::shared_ptr<Context> context = std::dynamic_pointer_cast<Context>(applicationContext);
1127     if (resourceManager != nullptr) {
1128         object->SetProperty("resourceManager", CreateJsResourceManager(engine, resourceManager, context));
1129     }
1130 
1131     BindNativeApplicationContext(engine, object);
1132 
1133     return objValue;
1134 }
1135 
BindNativeApplicationContext(NativeEngine & engine,NativeObject * object)1136 void JsApplicationContextUtils::BindNativeApplicationContext(NativeEngine &engine, NativeObject* object)
1137 {
1138     BindNativeProperty(*object, "cacheDir", JsApplicationContextUtils::GetCacheDir);
1139     BindNativeProperty(*object, "tempDir", JsApplicationContextUtils::GetTempDir);
1140     BindNativeProperty(*object, "filesDir", JsApplicationContextUtils::GetFilesDir);
1141     BindNativeProperty(*object, "distributedFilesDir", JsApplicationContextUtils::GetDistributedFilesDir);
1142     BindNativeProperty(*object, "databaseDir", JsApplicationContextUtils::GetDatabaseDir);
1143     BindNativeProperty(*object, "preferencesDir", JsApplicationContextUtils::GetPreferencesDir);
1144     BindNativeProperty(*object, "bundleCodeDir", JsApplicationContextUtils::GetBundleCodeDir);
1145     BindNativeFunction(engine, *object, "registerAbilityLifecycleCallback", MD_NAME,
1146         JsApplicationContextUtils::RegisterAbilityLifecycleCallback);
1147     BindNativeFunction(engine, *object, "unregisterAbilityLifecycleCallback", MD_NAME,
1148         JsApplicationContextUtils::UnregisterAbilityLifecycleCallback);
1149     BindNativeFunction(engine, *object, "registerEnvironmentCallback", MD_NAME,
1150         JsApplicationContextUtils::RegisterEnvironmentCallback);
1151     BindNativeFunction(engine, *object, "unregisterEnvironmentCallback", MD_NAME,
1152         JsApplicationContextUtils::UnregisterEnvironmentCallback);
1153     BindNativeFunction(engine, *object, "createBundleContext", MD_NAME, JsApplicationContextUtils::CreateBundleContext);
1154     BindNativeFunction(engine, *object, "switchArea", MD_NAME, JsApplicationContextUtils::SwitchArea);
1155     BindNativeFunction(engine, *object, "getArea", MD_NAME, JsApplicationContextUtils::GetArea);
1156     BindNativeFunction(engine, *object, "createModuleContext", MD_NAME, JsApplicationContextUtils::CreateModuleContext);
1157     BindNativeFunction(engine, *object, "on", MD_NAME, JsApplicationContextUtils::On);
1158     BindNativeFunction(engine, *object, "off", MD_NAME, JsApplicationContextUtils::Off);
1159     BindNativeFunction(engine, *object, "getApplicationContext", MD_NAME,
1160         JsApplicationContextUtils::GetApplicationContext);
1161     BindNativeFunction(engine, *object, "killAllProcesses", MD_NAME, JsApplicationContextUtils::KillProcessBySelf);
1162     BindNativeFunction(engine, *object, "getProcessRunningInformation", MD_NAME,
1163         JsApplicationContextUtils::GetRunningProcessInformation);
1164     BindNativeFunction(engine, *object, "getRunningProcessInformation", MD_NAME,
1165         JsApplicationContextUtils::GetRunningProcessInformation);
1166     BindNativeFunction(engine, *object, "getGroupDir", MD_NAME,
1167         JsApplicationContextUtils::GetGroupDir);
1168 }
1169 
ConvertToJsAppProcessState(const AppExecFwk::AppProcessState & appProcessState,const bool & isFocused)1170 JsAppProcessState JsApplicationContextUtils::ConvertToJsAppProcessState(
1171     const AppExecFwk::AppProcessState &appProcessState, const bool &isFocused)
1172 {
1173     JsAppProcessState processState;
1174     switch (appProcessState) {
1175         case AppExecFwk::AppProcessState::APP_STATE_CREATE:
1176         case AppExecFwk::AppProcessState::APP_STATE_READY:
1177             processState = STATE_CREATE;
1178             break;
1179         case AppExecFwk::AppProcessState::APP_STATE_FOREGROUND:
1180             processState = isFocused ? STATE_ACTIVE : STATE_FOREGROUND;
1181             break;
1182         case AppExecFwk::AppProcessState::APP_STATE_BACKGROUND:
1183             processState = STATE_BACKGROUND;
1184             break;
1185         case AppExecFwk::AppProcessState::APP_STATE_TERMINATED:
1186         case AppExecFwk::AppProcessState::APP_STATE_END:
1187             processState = STATE_DESTROY;
1188             break;
1189         default:
1190             HILOG_ERROR("Process state is invalid.");
1191             processState = STATE_DESTROY;
1192             break;
1193     }
1194     return processState;
1195 }
1196 }  // namespace AbilityRuntime
1197 }  // namespace OHOS
1198