1600cc4afSopenharmony_ci/* 2600cc4afSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3600cc4afSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4600cc4afSopenharmony_ci * you may not use this file except in compliance with the License. 5600cc4afSopenharmony_ci * You may obtain a copy of the License at 6600cc4afSopenharmony_ci * 7600cc4afSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8600cc4afSopenharmony_ci * 9600cc4afSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10600cc4afSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11600cc4afSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12600cc4afSopenharmony_ci * See the License for the specific language governing permissions and 13600cc4afSopenharmony_ci * limitations under the License. 14600cc4afSopenharmony_ci */ 15600cc4afSopenharmony_ci#include "package.h" 16600cc4afSopenharmony_ci#include <string> 17600cc4afSopenharmony_ci 18600cc4afSopenharmony_ci#include "app_log_wrapper.h" 19600cc4afSopenharmony_ci#include "bundle_constants.h" 20600cc4afSopenharmony_ci#include "bundle_mgr_host.h" 21600cc4afSopenharmony_ci#include "bundle_mgr_interface.h" 22600cc4afSopenharmony_ci#include "if_system_ability_manager.h" 23600cc4afSopenharmony_ci#include "ipc_skeleton.h" 24600cc4afSopenharmony_ci#include "iservice_registry.h" 25600cc4afSopenharmony_ci#include "napi/native_api.h" 26600cc4afSopenharmony_ci#include "napi/native_node_api.h" 27600cc4afSopenharmony_ci 28600cc4afSopenharmony_ci#include "securec.h" 29600cc4afSopenharmony_ci#include "system_ability_definition.h" 30600cc4afSopenharmony_ci 31600cc4afSopenharmony_cinamespace OHOS { 32600cc4afSopenharmony_cinamespace AppExecFwk { 33600cc4afSopenharmony_ciusing namespace OHOS; 34600cc4afSopenharmony_ciusing namespace OHOS::AAFwk; 35600cc4afSopenharmony_ciusing namespace OHOS::AppExecFwk; 36600cc4afSopenharmony_cinamespace { 37600cc4afSopenharmony_ciconstexpr int32_t NAPI_RETURN_ZERO = 0; 38600cc4afSopenharmony_ciconstexpr size_t ARGS_SIZE_ONE = 1; 39600cc4afSopenharmony_ciconstexpr size_t ARGS_SIZE_TWO = 2; 40600cc4afSopenharmony_ciconstexpr int32_t PARAM0 = 0; 41600cc4afSopenharmony_ciconstexpr int32_t PARAM1 = 1; 42600cc4afSopenharmony_ciconstexpr int32_t NAPI_RETURN_ONE = 1; 43600cc4afSopenharmony_ciconstexpr int32_t INVALID_PARAM = 2; 44600cc4afSopenharmony_ciconstexpr int32_t INVALID_NUMBER = 202; 45600cc4afSopenharmony_ciconstexpr const char* BUNDLE_NAME = "bundleName"; 46600cc4afSopenharmony_ciconstexpr const char* COMPLETE = "complete"; 47600cc4afSopenharmony_ciconstexpr const char* FAIL = "fail"; 48600cc4afSopenharmony_ciconstexpr const char* SUCCESS = "success"; 49600cc4afSopenharmony_ci} 50600cc4afSopenharmony_ci 51600cc4afSopenharmony_ciCheckPackageHasInstalledOptions::~CheckPackageHasInstalledOptions() 52600cc4afSopenharmony_ci{ 53600cc4afSopenharmony_ci if (successRef) { 54600cc4afSopenharmony_ci APP_LOGD("CheckPackageHasInstalledOptions::~CheckPackageHasInstalledOptions delete successRef"); 55600cc4afSopenharmony_ci napi_delete_reference(env, successRef); 56600cc4afSopenharmony_ci successRef = nullptr; 57600cc4afSopenharmony_ci } 58600cc4afSopenharmony_ci if (failRef) { 59600cc4afSopenharmony_ci APP_LOGD("CheckPackageHasInstalledOptions::~CheckPackageHasInstalledOptions delete failRef"); 60600cc4afSopenharmony_ci napi_delete_reference(env, failRef); 61600cc4afSopenharmony_ci failRef = nullptr; 62600cc4afSopenharmony_ci } 63600cc4afSopenharmony_ci if (completeRef) { 64600cc4afSopenharmony_ci APP_LOGD("CheckPackageHasInstalledOptions::~CheckPackageHasInstalledOptions delete completeRef"); 65600cc4afSopenharmony_ci napi_delete_reference(env, completeRef); 66600cc4afSopenharmony_ci completeRef = nullptr; 67600cc4afSopenharmony_ci } 68600cc4afSopenharmony_ci if (asyncWork) { 69600cc4afSopenharmony_ci APP_LOGD("CheckPackageHasInstalledOptions::~CheckPackageHasInstalledOptions delete callbackRef"); 70600cc4afSopenharmony_ci napi_delete_async_work(env, asyncWork); 71600cc4afSopenharmony_ci asyncWork = nullptr; 72600cc4afSopenharmony_ci } 73600cc4afSopenharmony_ci} 74600cc4afSopenharmony_ci 75600cc4afSopenharmony_cistatic OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> GetBundleMgr() 76600cc4afSopenharmony_ci{ 77600cc4afSopenharmony_ci auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 78600cc4afSopenharmony_ci if (systemAbilityManager == nullptr) { 79600cc4afSopenharmony_ci APP_LOGE("GetBundleMgr GetSystemAbilityManager is null"); 80600cc4afSopenharmony_ci return nullptr; 81600cc4afSopenharmony_ci } 82600cc4afSopenharmony_ci auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 83600cc4afSopenharmony_ci if (bundleMgrSa == nullptr) { 84600cc4afSopenharmony_ci APP_LOGE("GetBundleMgr GetSystemAbility is null"); 85600cc4afSopenharmony_ci return nullptr; 86600cc4afSopenharmony_ci } 87600cc4afSopenharmony_ci auto bundleMgr = OHOS::iface_cast<IBundleMgr>(bundleMgrSa); 88600cc4afSopenharmony_ci if (bundleMgr == nullptr) { 89600cc4afSopenharmony_ci APP_LOGE("GetBundleMgr iface_cast get null"); 90600cc4afSopenharmony_ci } 91600cc4afSopenharmony_ci return bundleMgr; 92600cc4afSopenharmony_ci} 93600cc4afSopenharmony_ci 94600cc4afSopenharmony_cistatic std::string GetStringFromNAPI(napi_env env, napi_value value) 95600cc4afSopenharmony_ci{ 96600cc4afSopenharmony_ci std::string result; 97600cc4afSopenharmony_ci size_t size = 0; 98600cc4afSopenharmony_ci 99600cc4afSopenharmony_ci if (napi_get_value_string_utf8(env, value, nullptr, NAPI_RETURN_ZERO, &size) != napi_ok) { 100600cc4afSopenharmony_ci APP_LOGE("can not get string size"); 101600cc4afSopenharmony_ci return ""; 102600cc4afSopenharmony_ci } 103600cc4afSopenharmony_ci result.reserve(size + NAPI_RETURN_ONE); 104600cc4afSopenharmony_ci result.resize(size); 105600cc4afSopenharmony_ci if (napi_get_value_string_utf8(env, value, result.data(), (size + NAPI_RETURN_ONE), &size) != napi_ok) { 106600cc4afSopenharmony_ci APP_LOGE("can not get string value"); 107600cc4afSopenharmony_ci return ""; 108600cc4afSopenharmony_ci } 109600cc4afSopenharmony_ci return result; 110600cc4afSopenharmony_ci} 111600cc4afSopenharmony_ci 112600cc4afSopenharmony_cistatic void ParseCheckPackageHasInstalledOptions(napi_env env, napi_value param, 113600cc4afSopenharmony_ci OHOS::AppExecFwk::CheckPackageHasInstalledOptions *hasInstalledOptions) 114600cc4afSopenharmony_ci{ 115600cc4afSopenharmony_ci if (hasInstalledOptions == nullptr) { 116600cc4afSopenharmony_ci APP_LOGW("hasInstalledOptions is nullptr"); 117600cc4afSopenharmony_ci return; 118600cc4afSopenharmony_ci } 119600cc4afSopenharmony_ci napi_valuetype valueType; 120600cc4afSopenharmony_ci napi_value prop = nullptr; 121600cc4afSopenharmony_ci // parse bundleName 122600cc4afSopenharmony_ci napi_get_named_property(env, param, BUNDLE_NAME, &prop); 123600cc4afSopenharmony_ci napi_typeof(env, prop, &valueType); 124600cc4afSopenharmony_ci hasInstalledOptions->isString = false; 125600cc4afSopenharmony_ci if (valueType == napi_string) { 126600cc4afSopenharmony_ci hasInstalledOptions->bundleName = GetStringFromNAPI(env, prop); 127600cc4afSopenharmony_ci hasInstalledOptions->isString = true; 128600cc4afSopenharmony_ci } 129600cc4afSopenharmony_ci // parse success function 130600cc4afSopenharmony_ci napi_value jsFunc = nullptr; 131600cc4afSopenharmony_ci napi_ref jsFuncRef = nullptr; 132600cc4afSopenharmony_ci napi_get_named_property(env, param, SUCCESS, &jsFunc); 133600cc4afSopenharmony_ci napi_typeof(env, jsFunc, &valueType); 134600cc4afSopenharmony_ci if (valueType == napi_function) { 135600cc4afSopenharmony_ci napi_create_reference(env, jsFunc, NAPI_RETURN_ONE, &jsFuncRef); 136600cc4afSopenharmony_ci hasInstalledOptions->successRef = jsFuncRef; 137600cc4afSopenharmony_ci } 138600cc4afSopenharmony_ci // parse fail function 139600cc4afSopenharmony_ci napi_get_named_property(env, param, FAIL, &jsFunc); 140600cc4afSopenharmony_ci napi_typeof(env, jsFunc, &valueType); 141600cc4afSopenharmony_ci if (valueType == napi_function) { 142600cc4afSopenharmony_ci napi_create_reference(env, jsFunc, NAPI_RETURN_ONE, &jsFuncRef); 143600cc4afSopenharmony_ci hasInstalledOptions->failRef = jsFuncRef; 144600cc4afSopenharmony_ci } 145600cc4afSopenharmony_ci // parse complete function 146600cc4afSopenharmony_ci napi_get_named_property(env, param, COMPLETE, &jsFunc); 147600cc4afSopenharmony_ci napi_typeof(env, jsFunc, &valueType); 148600cc4afSopenharmony_ci if (valueType == napi_function) { 149600cc4afSopenharmony_ci napi_create_reference(env, jsFunc, NAPI_RETURN_ONE, &jsFuncRef); 150600cc4afSopenharmony_ci hasInstalledOptions->completeRef = jsFuncRef; 151600cc4afSopenharmony_ci } 152600cc4afSopenharmony_ci} 153600cc4afSopenharmony_ci 154600cc4afSopenharmony_cistatic bool InnerHasInstalled(std::string bundleName) 155600cc4afSopenharmony_ci{ 156600cc4afSopenharmony_ci if (bundleName.empty()) { 157600cc4afSopenharmony_ci APP_LOGE("bundleName is invalid param"); 158600cc4afSopenharmony_ci return false; 159600cc4afSopenharmony_ci } 160600cc4afSopenharmony_ci auto iBundleMgr = GetBundleMgr(); 161600cc4afSopenharmony_ci if (iBundleMgr == nullptr) { 162600cc4afSopenharmony_ci APP_LOGE("can not get iBundleMgr"); 163600cc4afSopenharmony_ci return false; 164600cc4afSopenharmony_ci } 165600cc4afSopenharmony_ci BundleInfo bundleInfo; 166600cc4afSopenharmony_ci bool ret = iBundleMgr->GetBundleInfo(bundleName, 0, bundleInfo); 167600cc4afSopenharmony_ci if (!ret) { 168600cc4afSopenharmony_ci APP_LOGE("bundleInfo is not find, bundleName=%{public}s", bundleName.c_str()); 169600cc4afSopenharmony_ci } 170600cc4afSopenharmony_ci return ret; 171600cc4afSopenharmony_ci} 172600cc4afSopenharmony_ci 173600cc4afSopenharmony_cistatic void ConvertCheckPackageHasInstalledResponse(napi_env env, napi_value hasInstalledResponseObj, 174600cc4afSopenharmony_ci const OHOS::AppExecFwk::CheckPackageHasInstalledResponse &response) 175600cc4afSopenharmony_ci{ 176600cc4afSopenharmony_ci APP_LOGD("convert CheckPackageHasInstalledResponse start"); 177600cc4afSopenharmony_ci napi_value nResult; 178600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, response.result, &nResult)); 179600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, hasInstalledResponseObj, "result", nResult)); 180600cc4afSopenharmony_ci} 181600cc4afSopenharmony_ci 182600cc4afSopenharmony_cistatic void HasInstalledExecute(napi_env env, void *data) 183600cc4afSopenharmony_ci{ 184600cc4afSopenharmony_ci APP_LOGD("NAPI_HasInstalled, worker pool thread execute"); 185600cc4afSopenharmony_ci CheckPackageHasInstalledOptions *asyncCallbackInfo = static_cast<CheckPackageHasInstalledOptions *>(data); 186600cc4afSopenharmony_ci if (asyncCallbackInfo == nullptr) { 187600cc4afSopenharmony_ci APP_LOGW("NAPI_HasInstalled, asyncCallbackInfo == nullptr"); 188600cc4afSopenharmony_ci return; 189600cc4afSopenharmony_ci } 190600cc4afSopenharmony_ci if (!asyncCallbackInfo->errCode && asyncCallbackInfo->isString && asyncCallbackInfo->successRef) { 191600cc4afSopenharmony_ci asyncCallbackInfo->response.result = InnerHasInstalled(asyncCallbackInfo->bundleName); 192600cc4afSopenharmony_ci } 193600cc4afSopenharmony_ci APP_LOGD("NAPI_HasInstalled, worker pool thread execute end"); 194600cc4afSopenharmony_ci} 195600cc4afSopenharmony_ci 196600cc4afSopenharmony_cistatic void HasInstalledAsyncComplete(napi_env env, napi_status status, void *data) 197600cc4afSopenharmony_ci{ 198600cc4afSopenharmony_ci APP_LOGD("NAPI_HasInstalled, main event thread complete"); 199600cc4afSopenharmony_ci CheckPackageHasInstalledOptions *asyncCallbackInfo = static_cast<CheckPackageHasInstalledOptions *>(data); 200600cc4afSopenharmony_ci std::unique_ptr<CheckPackageHasInstalledOptions> callbackPtr {asyncCallbackInfo}; 201600cc4afSopenharmony_ci if (asyncCallbackInfo == nullptr) { 202600cc4afSopenharmony_ci APP_LOGW("NAPI_HasInstalled, asyncCallbackInfo == nullptr"); 203600cc4afSopenharmony_ci return; 204600cc4afSopenharmony_ci } 205600cc4afSopenharmony_ci napi_value callback = nullptr; 206600cc4afSopenharmony_ci napi_value placeHolder = nullptr; 207600cc4afSopenharmony_ci if (!asyncCallbackInfo->isString) { 208600cc4afSopenharmony_ci if (asyncCallbackInfo->failRef) { 209600cc4afSopenharmony_ci napi_value result[ARGS_SIZE_TWO] = { 0 }; 210600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, "value is not an available number", 211600cc4afSopenharmony_ci NAPI_AUTO_LENGTH, &result[PARAM0])); 212600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, INVALID_NUMBER, &result[PARAM1])); 213600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->failRef, &callback)); 214600cc4afSopenharmony_ci napi_call_function(env, nullptr, callback, ARGS_SIZE_TWO, result, &placeHolder); 215600cc4afSopenharmony_ci } 216600cc4afSopenharmony_ci } else { 217600cc4afSopenharmony_ci if (asyncCallbackInfo->successRef) { 218600cc4afSopenharmony_ci napi_value result[ARGS_SIZE_ONE] = { 0 }; 219600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &result[PARAM0])); 220600cc4afSopenharmony_ci ConvertCheckPackageHasInstalledResponse(env, result[PARAM0], asyncCallbackInfo->response); 221600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->successRef, &callback)); 222600cc4afSopenharmony_ci napi_call_function(env, nullptr, callback, ARGS_SIZE_ONE, result, &placeHolder); 223600cc4afSopenharmony_ci } 224600cc4afSopenharmony_ci } 225600cc4afSopenharmony_ci if (asyncCallbackInfo->completeRef) { 226600cc4afSopenharmony_ci NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->completeRef, &callback)); 227600cc4afSopenharmony_ci napi_call_function(env, nullptr, callback, 0, nullptr, &placeHolder); 228600cc4afSopenharmony_ci } 229600cc4afSopenharmony_ci APP_LOGD("NAPI_HasInstalled, main event thread complete end"); 230600cc4afSopenharmony_ci} 231600cc4afSopenharmony_ci 232600cc4afSopenharmony_cinapi_value HasInstalled(napi_env env, napi_callback_info info) 233600cc4afSopenharmony_ci{ 234600cc4afSopenharmony_ci APP_LOGD("asyncCallback"); 235600cc4afSopenharmony_ci size_t requireArgc = ARGS_SIZE_ONE; 236600cc4afSopenharmony_ci size_t argc = ARGS_SIZE_TWO; 237600cc4afSopenharmony_ci napi_value argv[ARGS_SIZE_TWO] = { 0 }; 238600cc4afSopenharmony_ci napi_value thisArg = nullptr; 239600cc4afSopenharmony_ci void *data = nullptr; 240600cc4afSopenharmony_ci 241600cc4afSopenharmony_ci NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data)); 242600cc4afSopenharmony_ci if (argc != requireArgc) { 243600cc4afSopenharmony_ci APP_LOGW("requires 1 parameter"); 244600cc4afSopenharmony_ci return nullptr; 245600cc4afSopenharmony_ci } 246600cc4afSopenharmony_ci 247600cc4afSopenharmony_ci CheckPackageHasInstalledOptions *asyncCallbackInfo = new (std::nothrow) CheckPackageHasInstalledOptions(); 248600cc4afSopenharmony_ci if (asyncCallbackInfo == nullptr) { 249600cc4afSopenharmony_ci return nullptr; 250600cc4afSopenharmony_ci } 251600cc4afSopenharmony_ci std::unique_ptr<CheckPackageHasInstalledOptions> callbackPtr {asyncCallbackInfo}; 252600cc4afSopenharmony_ci asyncCallbackInfo->env = env; 253600cc4afSopenharmony_ci napi_valuetype valueType = napi_undefined; 254600cc4afSopenharmony_ci NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valueType)); 255600cc4afSopenharmony_ci if (valueType == napi_object) { 256600cc4afSopenharmony_ci ParseCheckPackageHasInstalledOptions(env, argv[PARAM0], asyncCallbackInfo); 257600cc4afSopenharmony_ci } else { 258600cc4afSopenharmony_ci asyncCallbackInfo->errCode = INVALID_PARAM; 259600cc4afSopenharmony_ci } 260600cc4afSopenharmony_ci 261600cc4afSopenharmony_ci napi_value resource = nullptr; 262600cc4afSopenharmony_ci NAPI_CALL(env, napi_create_string_utf8(env, "JSHasInstalled", NAPI_AUTO_LENGTH, &resource)); 263600cc4afSopenharmony_ci NAPI_CALL(env, napi_create_async_work(env, nullptr, resource, HasInstalledExecute, 264600cc4afSopenharmony_ci HasInstalledAsyncComplete, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork)); 265600cc4afSopenharmony_ci NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); 266600cc4afSopenharmony_ci callbackPtr.release(); 267600cc4afSopenharmony_ci return nullptr; 268600cc4afSopenharmony_ci} 269600cc4afSopenharmony_ci} // namespace AppExecFwk 270600cc4afSopenharmony_ci} // namespace OHOS 271