• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_mgr_interface.h"
22 #include "bundle_mgr_proxy.h"
23 #include "bundle_errors.h"
24 #include "business_error.h"
25 #include "common_func.h"
26 #include "ipc_skeleton.h"
27 #include "napi_arg.h"
28 #include "napi_constants.h"
29 
30 namespace OHOS {
31 namespace AppExecFwk {
32 using namespace OHOS::AAFwk;
33 namespace {
34 const std::string PARAM_TYPE_CHECK_ERROR = "param type check error";
35 const std::string TYPE_WANT = "want";
36 const std::string PERMISSION_DISPOSED_STATUS = "ohos.permission.MANAGE_DISPOSED_APP_STATUS";
37 const std::string SET_DISPOSED_STATUS = "SetDisposedStatus";
38 const std::string GET_DISPOSED_STATUS = "GetDisposedStatus";
39 const std::string DELETE_DISPOSED_STATUS = "DeleteDisposedStatus";
40 const std::string APP_ID = "appId";
41 const std::string DISPOSED_WANT = "disposedWant";
42 }
GetAppControlProxy()43 static OHOS::sptr<OHOS::AppExecFwk::IAppControlMgr> GetAppControlProxy()
44 {
45     auto bundleMgr = CommonFunc::GetBundleMgr();
46     if (bundleMgr == nullptr) {
47         APP_LOGE("CommonFunc::GetBundleMgr failed.");
48         return nullptr;
49     }
50     auto appControlProxy = bundleMgr->GetAppControlProxy();
51     if (appControlProxy == nullptr) {
52         APP_LOGE("GetAppControlProxy failed.");
53         return nullptr;
54     }
55     return appControlProxy;
56 }
57 
InnerGetDisposedStatus(napi_env,const std::string & appId,Want & disposedWant)58 static ErrCode InnerGetDisposedStatus(napi_env, const std::string& appId, Want& disposedWant)
59 {
60     auto appControlProxy = GetAppControlProxy();
61     if (appControlProxy == nullptr) {
62         APP_LOGE("AppControlProxy is null.");
63         return ERROR_SYSTEM_ABILITY_NOT_FOUND;
64     }
65     ErrCode ret = appControlProxy->GetDisposedStatus(appId, disposedWant);
66     return CommonFunc::ConvertErrCode(ret);
67 }
68 
InnerSetDisposedStatus(napi_env,const std::string & appId,Want & disposedWant)69 static ErrCode InnerSetDisposedStatus(napi_env, const std::string& appId, Want& disposedWant)
70 {
71     auto appControlProxy = GetAppControlProxy();
72     if (appControlProxy == nullptr) {
73         APP_LOGE("AppControlProxy is null.");
74         return ERROR_SYSTEM_ABILITY_NOT_FOUND;
75     }
76     ErrCode ret = appControlProxy->SetDisposedStatus(appId, disposedWant);
77     return CommonFunc::ConvertErrCode(ret);
78 }
79 
InnerDeleteDisposedStatus(napi_env,const std::string & appId)80 static ErrCode InnerDeleteDisposedStatus(napi_env, const std::string& appId)
81 {
82     auto appControlProxy = GetAppControlProxy();
83     if (appControlProxy == nullptr) {
84         APP_LOGE("AppControlProxy is null.");
85         return ERROR_SYSTEM_ABILITY_NOT_FOUND;
86     }
87     ErrCode ret = appControlProxy->DeleteDisposedStatus(appId);
88     return CommonFunc::ConvertErrCode(ret);
89 }
90 
SetDisposedStatusExec(napi_env env,void * data)91 void SetDisposedStatusExec(napi_env env, void *data)
92 {
93     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
94     if (asyncCallbackInfo == nullptr) {
95         APP_LOGE("%{public}s, asyncCallbackInfo == nullptr.", __func__);
96         return;
97     }
98     if (asyncCallbackInfo->err == NO_ERROR) {
99         asyncCallbackInfo->err = InnerSetDisposedStatus(env, asyncCallbackInfo->appId,
100             asyncCallbackInfo->want);
101     }
102 }
103 
SetDisposedStatusComplete(napi_env env,napi_status status,void * data)104 void SetDisposedStatusComplete(napi_env env, napi_status status, void *data)
105 {
106     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
107     if (asyncCallbackInfo == nullptr) {
108         APP_LOGE("asyncCallbackInfo is null in %{public}s", __func__);
109         return;
110     }
111     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
112     napi_value result[1] = {0};
113     if (asyncCallbackInfo->err == NO_ERROR) {
114         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
115     } else {
116         APP_LOGE("SetDisposedStatus err = %{public}d", asyncCallbackInfo->err);
117         result[0] = BusinessError::CreateCommonError(
118             env, asyncCallbackInfo->err, SET_DISPOSED_STATUS, PERMISSION_DISPOSED_STATUS);
119     }
120     if (asyncCallbackInfo->deferred) {
121         if (asyncCallbackInfo->err == NO_ERROR) {
122             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[0]));
123         } else {
124             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]));
125         }
126     } else {
127         napi_value callback = nullptr;
128         napi_value placeHolder = nullptr;
129         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback));
130         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback,
131             sizeof(result) / sizeof(result[0]), result, &placeHolder));
132     }
133 }
134 
SetDisposedStatus(napi_env env,napi_callback_info info)135 napi_value SetDisposedStatus(napi_env env, napi_callback_info info)
136 {
137     APP_LOGD("begin to SetDisposedStatus");
138     NapiArg args(env, info);
139     DisposedStatus *asyncCallbackInfo = new (std::nothrow) DisposedStatus(env);
140     if (asyncCallbackInfo == nullptr) {
141         APP_LOGE("asyncCallbackInfo is null.");
142         return nullptr;
143     }
144     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
145     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
146         APP_LOGE("Napi func init failed");
147         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
148         return nullptr;
149     }
150     for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
151         napi_valuetype valueType = napi_undefined;
152         napi_typeof(env, args[i], &valueType);
153         if (i == ARGS_POS_ZERO) {
154             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->appId)) {
155                 APP_LOGE("appId invalid!");
156                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
157                 return nullptr;
158             }
159             asyncCallbackInfo->err = asyncCallbackInfo->appId.size() == 0 ? ERROR_INVALID_APPID : NO_ERROR;
160         } else if (i == ARGS_POS_ONE) {
161             if (!CommonFunc::ParseWantWithoutVerification(env, args[i], asyncCallbackInfo->want)) {
162                 APP_LOGE("disposed want invalid!");
163                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, DISPOSED_WANT, TYPE_WANT);
164                 return nullptr;
165             }
166         } else if (i == ARGS_POS_TWO) {
167             if (valueType == napi_function) {
168                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
169             } else {
170                 APP_LOGD("SetDisposedStatus extra arg ignored");
171             }
172         } else {
173             APP_LOGE("SetDisposedStatus arg err!");
174             BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
175             return nullptr;
176         }
177     }
178     auto promise = CommonFunc::AsyncCallNativeMethod<DisposedStatus>(
179         env, asyncCallbackInfo, "SetDisposedStatus", SetDisposedStatusExec, SetDisposedStatusComplete);
180     callbackPtr.release();
181     APP_LOGD("call SetDisposedStatus done.");
182     return promise;
183 }
184 
DeleteDisposedStatusExec(napi_env env,void * data)185 void DeleteDisposedStatusExec(napi_env env, void *data)
186 {
187     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
188     if (asyncCallbackInfo == nullptr) {
189         APP_LOGE("asyncCallbackInfo is null in %{public}s", __func__);
190         return;
191     }
192     if (asyncCallbackInfo->err == NO_ERROR) {
193         asyncCallbackInfo->err = InnerDeleteDisposedStatus(env, asyncCallbackInfo->appId);
194     }
195 }
196 
DeleteDisposedStatusComplete(napi_env env,napi_status,void * data)197 void DeleteDisposedStatusComplete(napi_env env, napi_status, void *data)
198 {
199     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
200     if (asyncCallbackInfo == nullptr) {
201         APP_LOGE("asyncCallbackInfo is null in %{public}s", __func__);
202         return;
203     }
204     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
205     napi_value result[1] = {0};
206     if (asyncCallbackInfo->err == NO_ERROR) {
207         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
208     } else {
209         APP_LOGE("DeleteDisposedStatus err = %{public}d", asyncCallbackInfo->err);
210         result[0] = BusinessError::CreateCommonError(
211             env, asyncCallbackInfo->err, DELETE_DISPOSED_STATUS, PERMISSION_DISPOSED_STATUS);
212     }
213     if (asyncCallbackInfo->deferred) {
214         if (asyncCallbackInfo->err == NO_ERROR) {
215             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[0]));
216         } else {
217             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]));
218         }
219     } else {
220         napi_value callback = nullptr;
221         napi_value placeHolder = nullptr;
222         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback));
223         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback,
224             sizeof(result) / sizeof(result[0]), result, &placeHolder));
225     }
226 }
227 
DeleteDisposedStatus(napi_env env,napi_callback_info info)228 napi_value DeleteDisposedStatus(napi_env env, napi_callback_info info)
229 {
230     APP_LOGD("begin to DeleteDisposedStatus.");
231     NapiArg args(env, info);
232     DisposedStatus *asyncCallbackInfo = new (std::nothrow) DisposedStatus(env);
233     if (asyncCallbackInfo == nullptr) {
234         APP_LOGE("asyncCallbackInfo is null.");
235         return nullptr;
236     }
237     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
238     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
239         APP_LOGE("param count invalid.");
240         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
241         return nullptr;
242     }
243     for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
244         napi_valuetype valueType = napi_undefined;
245         napi_typeof(env, args[i], &valueType);
246         if (i == ARGS_POS_ZERO) {
247             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->appId)) {
248                 APP_LOGE("appId invalid!");
249                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
250                 return nullptr;
251             }
252             if (asyncCallbackInfo->appId.size() == 0) {
253                 asyncCallbackInfo->err = ERROR_INVALID_APPID;
254             }
255         } else if (i == ARGS_POS_ONE) {
256             if (valueType == napi_function) {
257                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
258             } else {
259                 APP_LOGD("DeleteDisposedStatus extra arg ignored");
260             }
261         } else {
262             APP_LOGE("DeleteDisposedStatus arg err!");
263             BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
264             return nullptr;
265         }
266     }
267     auto promise = CommonFunc::AsyncCallNativeMethod<DisposedStatus>(
268         env, asyncCallbackInfo, "DeleteDisposedStatus", DeleteDisposedStatusExec, DeleteDisposedStatusComplete);
269     callbackPtr.release();
270     APP_LOGD("call DeleteDisposedStatus done.");
271     return promise;
272 }
273 
GetDisposedStatusExec(napi_env env,void * data)274 void GetDisposedStatusExec(napi_env env, void *data)
275 {
276     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
277     if (asyncCallbackInfo == nullptr) {
278         APP_LOGE("asyncCallbackInfo is null in %{public}s", __func__);
279         return;
280     }
281     if (asyncCallbackInfo->err == NO_ERROR) {
282         asyncCallbackInfo->err = InnerGetDisposedStatus(env, asyncCallbackInfo->appId,
283             asyncCallbackInfo->want);
284     }
285 }
286 
GetDisposedStatusComplete(napi_env env,napi_status status,void * data)287 void GetDisposedStatusComplete(napi_env env, napi_status status, void *data)
288 {
289     DisposedStatus *asyncCallbackInfo = reinterpret_cast<DisposedStatus *>(data);
290     if (asyncCallbackInfo == nullptr) {
291         APP_LOGE("asyncCallbackInfo is null in %{public}s", __func__);
292         return;
293     }
294     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
295     napi_value result[2] = {0};
296     if (asyncCallbackInfo->err == NO_ERROR) {
297         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
298         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &result[1]));
299         CommonFunc::ConvertWantInfo(env, result[1], asyncCallbackInfo->want);
300     } else {
301         APP_LOGE("GetDisposedStatus err = %{public}d", asyncCallbackInfo->err);
302         result[0] = BusinessError::CreateCommonError(
303             env, asyncCallbackInfo->err, GET_DISPOSED_STATUS, PERMISSION_DISPOSED_STATUS);
304     }
305     if (asyncCallbackInfo->deferred) {
306         if (asyncCallbackInfo->err == NO_ERROR) {
307             NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[1]));
308         } else {
309             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]));
310         }
311     } else {
312         napi_value callback = nullptr;
313         napi_value placeHolder = nullptr;
314         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback));
315         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback,
316             sizeof(result) / sizeof(result[0]), result, &placeHolder));
317     }
318 }
319 
GetDisposedStatus(napi_env env,napi_callback_info info)320 napi_value GetDisposedStatus(napi_env env, napi_callback_info info)
321 {
322     APP_LOGD("NAPI GetDisposedStatus called");
323     NapiArg args(env, info);
324     DisposedStatus *asyncCallbackInfo = new (std::nothrow) DisposedStatus(env);
325     if (asyncCallbackInfo == nullptr) {
326         APP_LOGE("asyncCallbackInfo is null.");
327         return nullptr;
328     }
329     std::unique_ptr<DisposedStatus> callbackPtr {asyncCallbackInfo};
330     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
331         APP_LOGE("param count invalid.");
332         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
333         return nullptr;
334     }
335     for (size_t i = 0; i < args.GetMaxArgc(); i++) {
336         napi_valuetype valueType = napi_undefined;
337         napi_typeof(env, args[i], &valueType);
338         if (i == ARGS_POS_ZERO) {
339             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->appId)) {
340                 APP_LOGE("appId %{public}s invalid!", asyncCallbackInfo->appId.c_str());
341                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_ID, TYPE_STRING);
342                 return nullptr;
343             }
344             if (asyncCallbackInfo->appId.size() == 0) {
345                 asyncCallbackInfo->err = ERROR_INVALID_APPID;
346             }
347         } else if (i == ARGS_POS_ONE) {
348             if (valueType == napi_function) {
349                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
350             } else {
351                 APP_LOGD("GetDisposedStatus extra arg ignored");
352             }
353         } else {
354             APP_LOGE("GetDisposedStatus arg err!");
355             BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_TYPE_CHECK_ERROR);
356             return nullptr;
357         }
358     }
359     auto promise = CommonFunc::AsyncCallNativeMethod<DisposedStatus>(
360         env, asyncCallbackInfo, "GetDisposedStatus", GetDisposedStatusExec, GetDisposedStatusComplete);
361     callbackPtr.release();
362     APP_LOGD("call GetDisposedStatus done.");
363     return promise;
364 }
365 }
366 }