1 /*
2  * Copyright (c) 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 #include "js_app_control.h"
16 
17 #include <string>
18 
19 #include "app_log_wrapper.h"
20 #include "app_control_interface.h"
21 #include "bundle_constants.h"
22 #include "bundle_mgr_interface.h"
23 #include "bundle_mgr_proxy.h"
24 #include "bundle_errors.h"
25 #include "business_error.h"
26 #include "common_func.h"
27 #include "disposed_rule.h"
28 #include "ipc_skeleton.h"
29 #include "napi_arg.h"
30 #include "napi_common_want.h"
31 #include "napi_constants.h"
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 using namespace OHOS::AAFwk;
36 namespace {
37 const char* PARAM_TYPE_CHECK_ERROR = "param type check error";
38 const char* TYPE_WANT = "want";
39 const char* PERMISSION_DISPOSED_STATUS = "ohos.permission.MANAGE_DISPOSED_APP_STATUS";
40 const char* SET_DISPOSED_STATUS = "SetDisposedStatus";
41 const char* GET_DISPOSED_STATUS = "GetDisposedStatus";
42 const char* DELETE_DISPOSED_STATUS = "DeleteDisposedStatus";
43 const char* SET_DISPOSED_STATUS_SYNC = "SetDisposedStatusSync";
44 const char* DELETE_DISPOSED_STATUS_SYNC = "DeleteDisposedStatusSync";
45 const char* GET_DISPOSED_STATUS_SYNC = "GetDisposedStatusSync";
46 const char* APP_ID = "appId";
47 const char* DISPOSED_WANT = "disposedWant";
48 const char* DISPOSED_RULE = "disposedRule";
49 const char* DISPOSED_RULE_TYPE = "DisposedRule";
50 }
GetAppControlProxy()51 static OHOS::sptr<OHOS::AppExecFwk::IAppControlMgr> GetAppControlProxy()
52 {
53     auto bundleMgr = CommonFunc::GetBundleMgr();
54     if (bundleMgr == nullptr) {
55         APP_LOGE("CommonFunc::GetBundleMgr failed");
56         return nullptr;
57     }
58     auto appControlProxy = bundleMgr->GetAppControlProxy();
59     if (appControlProxy == nullptr) {
60         APP_LOGE("GetAppControlProxy failed");
61         return nullptr;
62     }
63     return appControlProxy;
64 }
65 
InnerGetDisposedStatus(napi_env,const std::string & appId,Want & disposedWant)66 static ErrCode InnerGetDisposedStatus(napi_env, const std::string& appId, Want& disposedWant)
67 {
68     auto appControlProxy = GetAppControlProxy();
69     if (appControlProxy == nullptr) {
70         APP_LOGE("AppControlProxy is null");
71         return ERROR_SYSTEM_ABILITY_NOT_FOUND;
72     }
73     ErrCode ret = appControlProxy->GetDisposedStatus(appId, disposedWant);
74     return CommonFunc::ConvertErrCode(ret);
75 }
76 
InnerSetDisposedStatus(napi_env,const std::string & appId,Want & disposedWant)77 static ErrCode InnerSetDisposedStatus(napi_env, const std::string& appId, Want& disposedWant)
78 {
79     auto appControlProxy = GetAppControlProxy();
80     if (appControlProxy == nullptr) {
81         APP_LOGE("AppControlProxy is null");
82         return ERROR_SYSTEM_ABILITY_NOT_FOUND;
83     }
84     ErrCode ret = appControlProxy->SetDisposedStatus(appId, disposedWant);
85     return CommonFunc::ConvertErrCode(ret);
86 }
87 
InnerDeleteDisposedStatus(napi_env,const std::string & appId)88 static ErrCode InnerDeleteDisposedStatus(napi_env, const std::string& appId)
89 {
90     auto appControlProxy = GetAppControlProxy();
91     if (appControlProxy == nullptr) {
92         APP_LOGE("AppControlProxy is null");
93         return ERROR_SYSTEM_ABILITY_NOT_FOUND;
94     }
95     ErrCode ret = appControlProxy->DeleteDisposedStatus(appId);
96     return CommonFunc::ConvertErrCode(ret);
97 }
98 
SetDisposedStatusExec(napi_env env,void * data)99 void SetDisposedStatusExec(napi_env env, void *data)
100 {
101     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
102     if (asyncCallbackInfo == nullptr) {
103         APP_LOGE("asyncCallbackInfo == nullptr");
104         return;
105     }
106     if (asyncCallbackInfo->err == NO_ERROR) {
107         asyncCallbackInfo->err = InnerSetDisposedStatus(env, asyncCallbackInfo->appId,
108             asyncCallbackInfo->want);
109     }
110 }
111 
SetDisposedStatusComplete(napi_env env,napi_status status,void * data)112 void SetDisposedStatusComplete(napi_env env, napi_status status, void *data)
113 {
114     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
115     if (asyncCallbackInfo == nullptr) {
116         APP_LOGE("asyncCallbackInfo is null");
117         return;
118     }
119     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
120     napi_value result[1] = {0};
121     if (asyncCallbackInfo->err == NO_ERROR) {
122         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
123     } else {
124         APP_LOGE("SetDisposedStatus err = %{public}d", asyncCallbackInfo->err);
125         result[0] = BusinessError::CreateCommonError(
126             env, asyncCallbackInfo->err, SET_DISPOSED_STATUS, PERMISSION_DISPOSED_STATUS);
127     }
128     CommonFunc::NapiReturnDeferred<DisposedStatus>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
129 }
130 
SetDisposedStatus(napi_env env,napi_callback_info info)131 napi_value SetDisposedStatus(napi_env env, napi_callback_info info)
132 {
133     APP_LOGD("begin to SetDisposedStatus");
134     NapiArg args(env, info);
135     DisposedStatus *asyncCallbackInfo = new (std::nothrow) DisposedStatus(env);
136     if (asyncCallbackInfo == nullptr) {
137         APP_LOGE("asyncCallbackInfo is null");
138         return nullptr;
139     }
140     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
141     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
142         APP_LOGE("Napi func init failed");
143         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
144         return nullptr;
145     }
146     for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
147         napi_valuetype valueType = napi_undefined;
148         napi_typeof(env, args[i], &valueType);
149         if (i == ARGS_POS_ZERO) {
150             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->appId)) {
151                 APP_LOGE("appId invalid");
152                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
153                 return nullptr;
154             }
155             asyncCallbackInfo->err = asyncCallbackInfo->appId.size() == 0 ? ERROR_INVALID_APPID : NO_ERROR;
156         } else if (i == ARGS_POS_ONE) {
157             if (!CommonFunc::ParseWantWithoutVerification(env, args[i], asyncCallbackInfo->want)) {
158                 APP_LOGE("disposed want invalid");
159                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, DISPOSED_WANT, TYPE_WANT);
160                 return nullptr;
161             }
162         } else if (i == ARGS_POS_TWO) {
163             if (valueType == napi_function) {
164                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
165             } else {
166                 APP_LOGD("SetDisposedStatus extra arg ignored");
167             }
168         } else {
169             APP_LOGE("SetDisposedStatus arg err");
170             BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
171             return nullptr;
172         }
173     }
174     auto promise = CommonFunc::AsyncCallNativeMethod<DisposedStatus>(
175         env, asyncCallbackInfo, "SetDisposedStatus", SetDisposedStatusExec, SetDisposedStatusComplete);
176     callbackPtr.release();
177     APP_LOGD("call SetDisposedStatus done");
178     return promise;
179 }
180 
SetDisposedStatusSync(napi_env env,napi_callback_info info)181 napi_value SetDisposedStatusSync(napi_env env, napi_callback_info info)
182 {
183     APP_LOGD("begin to SetDisposedStatusSync");
184     NapiArg args(env, info);
185     napi_value nRet;
186     napi_get_undefined(env, &nRet);
187     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_TWO)) {
188         APP_LOGE("Napi func init failed");
189         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
190         return nRet;
191     }
192     std::string appId;
193     if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], appId)) {
194         APP_LOGE("appId %{public}s invalid", appId.c_str());
195         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
196         return nRet;
197     }
198     if (appId.size() == 0) {
199         napi_value businessError = BusinessError::CreateCommonError(
200             env, ERROR_INVALID_APPID, SET_DISPOSED_STATUS_SYNC);
201         napi_throw(env, businessError);
202         return nullptr;
203     }
204     OHOS::AAFwk::Want want;
205     if (!CommonFunc::ParseWantWithoutVerification(env, args[ARGS_POS_ONE], want)) {
206         APP_LOGE("want invalid");
207         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, DISPOSED_WANT, TYPE_WANT);
208         return nRet;
209     }
210     auto appControlProxy = GetAppControlProxy();
211     if (appControlProxy == nullptr) {
212         APP_LOGE("AppControlProxy is null");
213         napi_value error = BusinessError::CreateCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
214             SET_DISPOSED_STATUS_SYNC);
215         napi_throw(env, error);
216         return nRet;
217     }
218     ErrCode ret = appControlProxy->SetDisposedStatus(appId, want);
219     ret = CommonFunc::ConvertErrCode(ret);
220     if (ret != NO_ERROR) {
221         APP_LOGE("SetDisposedStatusSync err = %{public}d", ret);
222         napi_value businessError = BusinessError::CreateCommonError(
223             env, ret, SET_DISPOSED_STATUS_SYNC, PERMISSION_DISPOSED_STATUS);
224         napi_throw(env, businessError);
225     }
226     APP_LOGD("call SetDisposedStatusSync done");
227     return nRet;
228 }
229 
DeleteDisposedStatusExec(napi_env env,void * data)230 void DeleteDisposedStatusExec(napi_env env, void *data)
231 {
232     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
233     if (asyncCallbackInfo == nullptr) {
234         APP_LOGE("asyncCallbackInfo is null");
235         return;
236     }
237     if (asyncCallbackInfo->err == NO_ERROR) {
238         asyncCallbackInfo->err = InnerDeleteDisposedStatus(env, asyncCallbackInfo->appId);
239     }
240 }
241 
DeleteDisposedStatusComplete(napi_env env,napi_status,void * data)242 void DeleteDisposedStatusComplete(napi_env env, napi_status, void *data)
243 {
244     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
245     if (asyncCallbackInfo == nullptr) {
246         APP_LOGE("asyncCallbackInfo is null");
247         return;
248     }
249     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
250     napi_value result[1] = {0};
251     if (asyncCallbackInfo->err == NO_ERROR) {
252         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
253     } else {
254         APP_LOGE("DeleteDisposedStatus err = %{public}d", asyncCallbackInfo->err);
255         result[0] = BusinessError::CreateCommonError(
256             env, asyncCallbackInfo->err, DELETE_DISPOSED_STATUS, PERMISSION_DISPOSED_STATUS);
257     }
258     CommonFunc::NapiReturnDeferred<DisposedStatus>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
259 }
260 
DeleteDisposedStatus(napi_env env,napi_callback_info info)261 napi_value DeleteDisposedStatus(napi_env env, napi_callback_info info)
262 {
263     APP_LOGD("begin to DeleteDisposedStatus");
264     NapiArg args(env, info);
265     DisposedStatus *asyncCallbackInfo = new (std::nothrow) DisposedStatus(env);
266     if (asyncCallbackInfo == nullptr) {
267         APP_LOGE("asyncCallbackInfo is null");
268         return nullptr;
269     }
270     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
271     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
272         APP_LOGE("param count invalid");
273         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
274         return nullptr;
275     }
276     for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
277         napi_valuetype valueType = napi_undefined;
278         napi_typeof(env, args[i], &valueType);
279         if (i == ARGS_POS_ZERO) {
280             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->appId)) {
281                 APP_LOGE("appId invalid");
282                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
283                 return nullptr;
284             }
285             if (asyncCallbackInfo->appId.size() == 0) {
286                 asyncCallbackInfo->err = ERROR_INVALID_APPID;
287             }
288         } else if (i == ARGS_POS_ONE) {
289             if (valueType == napi_function) {
290                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
291             } else {
292                 APP_LOGD("DeleteDisposedStatus extra arg ignored");
293             }
294         } else {
295             APP_LOGE("DeleteDisposedStatus arg err");
296             BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
297             return nullptr;
298         }
299     }
300     auto promise = CommonFunc::AsyncCallNativeMethod<DisposedStatus>(
301         env, asyncCallbackInfo, "DeleteDisposedStatus", DeleteDisposedStatusExec, DeleteDisposedStatusComplete);
302     callbackPtr.release();
303     APP_LOGD("call DeleteDisposedStatus done");
304     return promise;
305 }
306 
InnerDeleteDisposedStatusSync(napi_env env,std::string & appId,int32_t appIndex)307 static napi_value InnerDeleteDisposedStatusSync(napi_env env, std::string &appId, int32_t appIndex)
308 {
309     napi_value nRet;
310     napi_get_undefined(env, &nRet);
311     if (appId.size() == 0) {
312         napi_value businessError = BusinessError::CreateCommonError(
313             env, ERROR_INVALID_APPID, DELETE_DISPOSED_STATUS_SYNC);
314         napi_throw(env, businessError);
315         return nullptr;
316     }
317     auto appControlProxy = GetAppControlProxy();
318     if (appControlProxy == nullptr) {
319         APP_LOGE("AppControlProxy is null");
320         napi_value error = BusinessError::CreateCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
321             DELETE_DISPOSED_STATUS_SYNC);
322         napi_throw(env, error);
323         return nullptr;
324     }
325     ErrCode ret = ERR_OK;
326     if (appIndex == Constants::MAIN_APP_INDEX) {
327         ret = appControlProxy->DeleteDisposedStatus(appId);
328     } else {
329         ret = appControlProxy->DeleteDisposedRuleForCloneApp(appId, appIndex);
330     }
331     ret = CommonFunc::ConvertErrCode(ret);
332     if (ret != ERR_OK) {
333         APP_LOGE("DeleteDisposedStatusSync failed");
334         napi_value businessError = BusinessError::CreateCommonError(
335             env, ret, DELETE_DISPOSED_STATUS_SYNC, PERMISSION_DISPOSED_STATUS);
336         napi_throw(env, businessError);
337         return nullptr;
338     }
339     return nRet;
340 }
341 
DeleteDisposedStatusSync(napi_env env,napi_callback_info info)342 napi_value DeleteDisposedStatusSync(napi_env env, napi_callback_info info)
343 {
344     APP_LOGD("begin to DeleteDisposedStatusSync");
345     NapiArg args(env, info);
346     napi_value nRet;
347     napi_get_undefined(env, &nRet);
348     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
349         APP_LOGE("param count invalid");
350         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
351         return nRet;
352     }
353     std::string appId;
354     if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], appId)) {
355         APP_LOGE("appId %{public}s invalid", appId.c_str());
356         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
357         return nRet;
358     }
359     int32_t appIndex = Constants::MAIN_APP_INDEX;
360     if (args.GetMaxArgc() == ARGS_SIZE_ONE) {
361         return InnerDeleteDisposedStatusSync(env, appId, appIndex);
362     }
363     if (args.GetMaxArgc() == ARGS_SIZE_TWO) {
364         if (!CommonFunc::ParseInt(env, args[ARGS_POS_ONE], appIndex)) {
365             APP_LOGW("parse appIndex falied");
366         }
367         return InnerDeleteDisposedStatusSync(env, appId, appIndex);
368     }
369     APP_LOGE("parameter is invalid");
370     BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
371     return nRet;
372 }
373 
GetDisposedStatusExec(napi_env env,void * data)374 void GetDisposedStatusExec(napi_env env, void *data)
375 {
376     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
377     if (asyncCallbackInfo == nullptr) {
378         APP_LOGE("asyncCallbackInfo is null");
379         return;
380     }
381     if (asyncCallbackInfo->err == NO_ERROR) {
382         asyncCallbackInfo->err = InnerGetDisposedStatus(env, asyncCallbackInfo->appId,
383             asyncCallbackInfo->want);
384     }
385 }
386 
GetDisposedStatusComplete(napi_env env,napi_status status,void * data)387 void GetDisposedStatusComplete(napi_env env, napi_status status, void *data)
388 {
389     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
390     if (asyncCallbackInfo == nullptr) {
391         APP_LOGE("asyncCallbackInfo is null");
392         return;
393     }
394     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
395     napi_value result[2] = {0};
396     if (asyncCallbackInfo->err == NO_ERROR) {
397         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
398         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &result[1]));
399         CommonFunc::ConvertWantInfo(env, result[1], asyncCallbackInfo->want);
400     } else {
401         APP_LOGE("GetDisposedStatus err = %{public}d", asyncCallbackInfo->err);
402         result[0] = BusinessError::CreateCommonError(
403             env, asyncCallbackInfo->err, GET_DISPOSED_STATUS, PERMISSION_DISPOSED_STATUS);
404     }
405     CommonFunc::NapiReturnDeferred<DisposedStatus>(env, asyncCallbackInfo, result, ARGS_SIZE_TWO);
406 }
407 
GetDisposedStatus(napi_env env,napi_callback_info info)408 napi_value GetDisposedStatus(napi_env env, napi_callback_info info)
409 {
410     APP_LOGD("NAPI GetDisposedStatus called");
411     NapiArg args(env, info);
412     DisposedStatus *asyncCallbackInfo = new (std::nothrow) DisposedStatus(env);
413     if (asyncCallbackInfo == nullptr) {
414         APP_LOGE("asyncCallbackInfo is null");
415         return nullptr;
416     }
417     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
418     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
419         APP_LOGE("param count invalid");
420         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
421         return nullptr;
422     }
423     for (size_t i = 0; i < args.GetMaxArgc(); i++) {
424         napi_valuetype valueType = napi_undefined;
425         napi_typeof(env, args[i], &valueType);
426         if (i == ARGS_POS_ZERO) {
427             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->appId)) {
428                 APP_LOGE("appId %{public}s invalid", asyncCallbackInfo->appId.c_str());
429                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
430                 return nullptr;
431             }
432             if (asyncCallbackInfo->appId.size() == 0) {
433                 asyncCallbackInfo->err = ERROR_INVALID_APPID;
434             }
435         } else if (i == ARGS_POS_ONE) {
436             if (valueType == napi_function) {
437                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
438             } else {
439                 APP_LOGD("GetDisposedStatus extra arg ignored");
440             }
441         } else {
442             APP_LOGE("GetDisposedStatus arg err");
443             BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
444             return nullptr;
445         }
446     }
447     auto promise = CommonFunc::AsyncCallNativeMethod<DisposedStatus>(
448         env, asyncCallbackInfo, "GetDisposedStatus", GetDisposedStatusExec, GetDisposedStatusComplete);
449     callbackPtr.release();
450     APP_LOGD("call GetDisposedStatus done");
451     return promise;
452 }
453 
GetDisposedStatusSync(napi_env env,napi_callback_info info)454 napi_value GetDisposedStatusSync(napi_env env, napi_callback_info info)
455 {
456     APP_LOGD("NAPI GetDisposedStatusSync called");
457     NapiArg args(env, info);
458     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_ONE)) {
459         APP_LOGE("param count invalid");
460         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
461         return nullptr;
462     }
463     std::string appId;
464     if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], appId)) {
465         APP_LOGE("appId %{public}s invalid", appId.c_str());
466         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
467         return nullptr;
468     }
469     if (appId.size() == 0) {
470         napi_value businessError = BusinessError::CreateCommonError(
471             env, ERROR_INVALID_APPID, GET_DISPOSED_STATUS_SYNC);
472         napi_throw(env, businessError);
473         return nullptr;
474     }
475     auto appControlProxy = GetAppControlProxy();
476     if (appControlProxy == nullptr) {
477         APP_LOGE("AppControlProxy is null");
478         napi_value error = BusinessError::CreateCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
479             GET_DISPOSED_STATUS_SYNC);
480         napi_throw(env, error);
481         return nullptr;
482     }
483     OHOS::AAFwk::Want disposedWant;
484     ErrCode ret = appControlProxy->GetDisposedStatus(appId, disposedWant);
485     ret = CommonFunc::ConvertErrCode(ret);
486     if (ret != ERR_OK) {
487         APP_LOGE("GetDisposedStatusSync failed");
488         napi_value businessError = BusinessError::CreateCommonError(
489             env, ret, GET_DISPOSED_STATUS_SYNC, PERMISSION_DISPOSED_STATUS);
490         napi_throw(env, businessError);
491         return nullptr;
492     }
493     napi_value nWant = nullptr;
494     NAPI_CALL(env, napi_create_object(env, &nWant));
495     CommonFunc::ConvertWantInfo(env, nWant, disposedWant);
496     APP_LOGD("call GetDisposedStatusSync done");
497     return nWant;
498 }
499 
ConvertRuleInfo(napi_env env,napi_value nRule,const DisposedRule & rule)500 void ConvertRuleInfo(napi_env env, napi_value nRule, const DisposedRule &rule)
501 {
502     napi_value nWant = nullptr;
503     if (rule.want != nullptr) {
504         nWant = CreateJsWant(env, *rule.want);
505     } else {
506         napi_create_object(env, &nWant);
507     }
508     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, nRule, "want", nWant));
509     napi_value nComponentType;
510     NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, static_cast<int32_t>(rule.componentType), &nComponentType));
511     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, nRule, "componentType", nComponentType));
512     napi_value nDisposedType;
513     NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, static_cast<int32_t>(rule.disposedType), &nDisposedType));
514     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, nRule, "disposedType", nDisposedType));
515     napi_value nControlType;
516     NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, static_cast<int32_t>(rule.controlType), &nControlType));
517     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, nRule, "controlType", nControlType));
518 
519     napi_value nElementList;
520     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &nElementList));
521     for (size_t idx = 0; idx < rule.elementList.size(); idx++) {
522         napi_value nElementName;
523         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &nElementName));
524         CommonFunc::ConvertElementName(env, nElementName, rule.elementList[idx]);
525         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, nElementList, idx, nElementName));
526     }
527     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, nRule, "elementList", nElementList));
528     napi_value nPriority;
529     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, rule.priority, &nPriority));
530     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, nRule, "priority", nPriority));
531 }
532 
ParseDiposedRule(napi_env env,napi_value nRule,DisposedRule & rule)533 bool ParseDiposedRule(napi_env env, napi_value nRule, DisposedRule &rule)
534 {
535     napi_valuetype valueType;
536     NAPI_CALL_BASE(env, napi_typeof(env, nRule, &valueType), false);
537     if (valueType != napi_object) {
538         APP_LOGW("nRule not object type");
539         return false;
540     }
541     napi_value prop = nullptr;
542     napi_get_named_property(env, nRule, TYPE_WANT, &prop);
543     AAFwk::Want want;
544     if (!UnwrapWant(env, prop, want)) {
545         APP_LOGW("parse want failed");
546         return false;
547     }
548     rule.want = std::make_shared<AAFwk::Want>(want);
549     napi_get_named_property(env, nRule, "componentType", &prop);
550     int32_t componentType;
551     if (!CommonFunc::ParseInt(env, prop, componentType)) {
552         APP_LOGW("componentType parseInt failed");
553         return false;
554     }
555     if (componentType > static_cast<int32_t>(ComponentType::UI_EXTENSION) ||
556         componentType < static_cast<int32_t>(ComponentType::UI_ABILITY)) {
557         APP_LOGW("componentType not valid");
558         return false;
559     }
560     rule.componentType = static_cast<ComponentType>(componentType);
561     napi_get_named_property(env, nRule, "disposedType", &prop);
562     int32_t disposedType;
563     if (!CommonFunc::ParseInt(env, prop, disposedType)) {
564         APP_LOGW("disposedType parseInt failed");
565         return false;
566     }
567     if (disposedType > static_cast<int32_t>(DisposedType::NON_BLOCK) ||
568         disposedType < static_cast<int32_t>(DisposedType::BLOCK_APPLICATION)) {
569         APP_LOGW("disposedType not valid");
570         return false;
571     }
572     rule.disposedType = static_cast<DisposedType>(disposedType);
573     napi_get_named_property(env, nRule, "controlType", &prop);
574     int32_t controlType;
575     if (!CommonFunc::ParseInt(env, prop, controlType)) {
576         APP_LOGW("disposedType parseInt failed");
577         return false;
578     }
579     if (controlType > static_cast<int32_t>(ControlType::DISALLOWED_LIST) ||
580         controlType < static_cast<int32_t>(ControlType::ALLOWED_LIST)) {
581         APP_LOGW("ControlType not valid");
582         return false;
583     }
584     rule.controlType = static_cast<ControlType>(controlType);
585 
586     napi_value nElementList = nullptr;
587     napi_get_named_property(env, nRule, "elementList", &nElementList);
588     bool isArray = false;
589     NAPI_CALL_BASE(env, napi_is_array(env, nElementList, &isArray), false);
590     if (!isArray) {
591         APP_LOGW("nElementList not array");
592         return false;
593     }
594     uint32_t arrayLength = 0;
595     NAPI_CALL_BASE(env, napi_get_array_length(env, nElementList, &arrayLength), false);
596     for (uint32_t j = 0; j < arrayLength; j++) {
597         napi_value value = nullptr;
598         NAPI_CALL_BASE(env, napi_get_element(env, nElementList, j, &value), false);
599         ElementName name;
600         if (!CommonFunc::ParseElementName(env, value, name)) {
601             APP_LOGW("parse element name failed");
602             return false;
603         }
604         rule.elementList.push_back(name);
605     }
606     napi_get_named_property(env, nRule, "priority", &prop);
607     if (!CommonFunc::ParseInt(env, prop, rule.priority)) {
608         APP_LOGW("priority parseInt failed");
609         return false;
610     }
611     return true;
612 }
613 
InnerGetDisposedRule(napi_env env,std::string & appId,int32_t appIndex)614 static napi_value InnerGetDisposedRule(napi_env env, std::string &appId, int32_t appIndex)
615 {
616     if (appId.size() == 0) {
617         napi_value businessError = BusinessError::CreateCommonError(
618             env, ERROR_INVALID_APPID, GET_DISPOSED_STATUS_SYNC);
619         napi_throw(env, businessError);
620         return nullptr;
621     }
622     auto appControlProxy = GetAppControlProxy();
623     if (appControlProxy == nullptr) {
624         APP_LOGE("AppControlProxy is null");
625         napi_value error = BusinessError::CreateCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
626             GET_DISPOSED_STATUS_SYNC);
627         napi_throw(env, error);
628         return nullptr;
629     }
630     DisposedRule disposedRule;
631     ErrCode ret = ERR_OK;
632     if (appIndex == Constants::MAIN_APP_INDEX) {
633         ret = appControlProxy->GetDisposedRule(appId, disposedRule);
634     } else {
635         ret = appControlProxy->GetDisposedRuleForCloneApp(appId, disposedRule, appIndex);
636     }
637     ret = CommonFunc::ConvertErrCode(ret);
638     if (ret != ERR_OK) {
639         APP_LOGE("GetDisposedStatusSync failed");
640         napi_value businessError = BusinessError::CreateCommonError(
641             env, ret, GET_DISPOSED_STATUS_SYNC, PERMISSION_DISPOSED_STATUS);
642         napi_throw(env, businessError);
643         return nullptr;
644     }
645     napi_value nRule = nullptr;
646     NAPI_CALL(env, napi_create_object(env, &nRule));
647     ConvertRuleInfo(env, nRule, disposedRule);
648     return nRule;
649 }
650 
GetDisposedRule(napi_env env,napi_callback_info info)651 napi_value GetDisposedRule(napi_env env, napi_callback_info info)
652 {
653     APP_LOGD("NAPI GetDisposedRule called");
654     NapiArg args(env, info);
655     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
656         APP_LOGE("param count invalid");
657         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
658         return nullptr;
659     }
660     std::string appId;
661     if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], appId)) {
662         APP_LOGE("appId %{public}s invalid", appId.c_str());
663         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
664         return nullptr;
665     }
666     int32_t appIndex = Constants::MAIN_APP_INDEX;
667     if (args.GetMaxArgc() == ARGS_SIZE_ONE) {
668         return InnerGetDisposedRule(env, appId, appIndex);
669     }
670     if (args.GetMaxArgc() == ARGS_SIZE_TWO) {
671         if (!CommonFunc::ParseInt(env, args[ARGS_POS_ONE], appIndex)) {
672             APP_LOGW("parse appIndex falied");
673         }
674         return InnerGetDisposedRule(env, appId, appIndex);
675     }
676     APP_LOGE("parameter is invalid");
677     BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
678     return nullptr;
679 }
680 
InnerSetDisposedRule(napi_env env,std::string & appId,DisposedRule & rule,int32_t appIndex)681 static napi_value InnerSetDisposedRule(napi_env env, std::string &appId, DisposedRule &rule, int32_t appIndex)
682 {
683     napi_value nRet;
684     napi_get_undefined(env, &nRet);
685     auto appControlProxy = GetAppControlProxy();
686     if (appControlProxy == nullptr) {
687         APP_LOGE("AppControlProxy is null.");
688         napi_value error = BusinessError::CreateCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND,
689             SET_DISPOSED_STATUS_SYNC);
690         napi_throw(env, error);
691         return nRet;
692     }
693     ErrCode ret = ERR_OK;
694     if (appIndex == Constants::MAIN_APP_INDEX) {
695         ret = appControlProxy->SetDisposedRule(appId, rule);
696     } else {
697         ret = appControlProxy->SetDisposedRuleForCloneApp(appId, rule, appIndex);
698     }
699     ret = CommonFunc::ConvertErrCode(ret);
700     if (ret != NO_ERROR) {
701         APP_LOGE("SetDisposedStatusSync err = %{public}d", ret);
702         napi_value businessError = BusinessError::CreateCommonError(
703             env, ret, SET_DISPOSED_STATUS_SYNC, PERMISSION_DISPOSED_STATUS);
704         napi_throw(env, businessError);
705         return nullptr;
706     }
707     return nRet;
708 }
709 
SetDisposedRule(napi_env env,napi_callback_info info)710 napi_value SetDisposedRule(napi_env env, napi_callback_info info)
711 {
712     NapiArg args(env, info);
713     napi_value nRet;
714     napi_get_undefined(env, &nRet);
715     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
716         APP_LOGE("Napi func init failed");
717         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
718         return nRet;
719     }
720     std::string appId;
721     if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], appId)) {
722         APP_LOGE("appId %{public}s invalid!", appId.c_str());
723         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
724         return nRet;
725     }
726     if (appId.size() == 0) {
727         napi_value businessError = BusinessError::CreateCommonError(
728             env, ERROR_INVALID_APPID, SET_DISPOSED_STATUS_SYNC);
729         napi_throw(env, businessError);
730         return nullptr;
731     }
732     DisposedRule rule;
733     if (!ParseDiposedRule(env, args[ARGS_POS_ONE], rule)) {
734         APP_LOGE("rule invalid!");
735         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, DISPOSED_RULE, DISPOSED_RULE_TYPE);
736         return nRet;
737     }
738     int32_t appIndex = Constants::MAIN_APP_INDEX;
739     if (args.GetMaxArgc() == ARGS_SIZE_TWO) {
740         return InnerSetDisposedRule(env, appId, rule, appIndex);
741     }
742     if (args.GetMaxArgc() == ARGS_SIZE_THREE) {
743         if (!CommonFunc::ParseInt(env, args[ARGS_POS_TWO], appIndex)) {
744             APP_LOGW("parse appIndex falied");
745         }
746         return InnerSetDisposedRule(env, appId, rule, appIndex);
747     }
748     APP_LOGE("parameter is invalid");
749     BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
750     return nRet;
751 }
752 
CreateComponentType(napi_env env,napi_value value)753 void CreateComponentType(napi_env env, napi_value value)
754 {
755     napi_value nUiAbilityType;
756     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ComponentType::UI_ABILITY),
757         &nUiAbilityType));
758     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "UI_ABILITY",
759         nUiAbilityType));
760     napi_value nExtensionAbilityType;
761     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ComponentType::UI_EXTENSION),
762         &nExtensionAbilityType));
763     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "UI_EXTENSION",
764         nExtensionAbilityType));
765 }
766 
CreateDisposedType(napi_env env,napi_value value)767 void CreateDisposedType(napi_env env, napi_value value)
768 {
769     napi_value nBlockApplication;
770     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(DisposedType::BLOCK_APPLICATION),
771         &nBlockApplication));
772     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "BLOCK_APPLICATION",
773         nBlockApplication));
774     napi_value nBlockAbility;
775     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(DisposedType::BLOCK_ABILITY),
776         &nBlockAbility));
777     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "BLOCK_ABILITY",
778         nBlockApplication));
779     napi_value nNonBlock;
780     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(DisposedType::NON_BLOCK),
781         &nNonBlock));
782     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "NON_BLOCK",
783         nNonBlock));
784 }
785 
CreateControlType(napi_env env,napi_value value)786 void CreateControlType(napi_env env, napi_value value)
787 {
788     napi_value nAllowedList;
789     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ControlType::ALLOWED_LIST),
790         &nAllowedList));
791     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "ALLOWED_LIST",
792         nAllowedList));
793     napi_value nDisAllowedList;
794     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ControlType::DISALLOWED_LIST),
795         &nDisAllowedList));
796     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "DISALLOWED_LIST",
797         nDisAllowedList));
798 }
799 }
800 }