1/* 2 * Copyright (c) 2022-2024 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 "free_install_manager.h" 17 18#include "ability_manager_service.h" 19#include "ability_util.h" 20#include "atomic_service_status_callback.h" 21#include "distributed_client.h" 22#include "hitrace_meter.h" 23#include "insight_intent_execute_manager.h" 24#include "insight_intent_utils.h" 25#include "permission_constants.h" 26#include "utils/app_mgr_util.h" 27#include "uri_utils.h" 28 29namespace OHOS { 30namespace AAFwk { 31const std::u16string DMS_FREE_INSTALL_CALLBACK_TOKEN = u"ohos.DistributedSchedule.IDmsFreeInstallCallback"; 32const std::string DMS_MISSION_ID = "dmsMissionId"; 33const std::string PARAM_FREEINSTALL_APPID = "ohos.freeinstall.params.callingAppId"; 34const std::string PARAM_FREEINSTALL_BUNDLENAMES = "ohos.freeinstall.params.callingBundleNames"; 35const std::string PARAM_FREEINSTALL_UID = "ohos.freeinstall.params.callingUid"; 36constexpr uint32_t IDMS_CALLBACK_ON_FREE_INSTALL_DONE = 0; 37constexpr uint32_t UPDATE_ATOMOIC_SERVICE_TASK_TIMER = 24 * 60 * 60 * 1000; /* 24h */ 38constexpr const char* KEY_IS_APP_RUNNING = "com.ohos.param.isAppRunning"; 39 40FreeInstallManager::FreeInstallManager(const std::weak_ptr<AbilityManagerService> &server) 41 : server_(server) 42{ 43} 44 45bool FreeInstallManager::IsTopAbility(const sptr<IRemoteObject> &callerToken) 46{ 47 auto server = server_.lock(); 48 CHECK_POINTER_AND_RETURN_LOG(server, false, "Get server failed!"); 49 AppExecFwk::ElementName elementName = IN_PROCESS_CALL(server->GetTopAbility()); 50 if (elementName.GetBundleName().empty() || elementName.GetAbilityName().empty()) { 51 TAG_LOGE(AAFwkTag::FREE_INSTALL, "GetBundleName or GetAbilityName empty"); 52 return false; 53 } 54 55 auto caller = Token::GetAbilityRecordByToken(callerToken); 56 if (caller == nullptr) { 57 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null caller"); 58 return false; 59 } 60 61 auto type = caller->GetAbilityInfo().type; 62 if (type == AppExecFwk::AbilityType::SERVICE || type == AppExecFwk::AbilityType::EXTENSION) { 63 TAG_LOGE(AAFwkTag::FREE_INSTALL, "service or extension"); 64 return true; 65 } 66 67 AppExecFwk::ElementName callerElementName = caller->GetElementName(); 68 std::string callerBundleName = callerElementName.GetBundleName(); 69 std::string callerAbilityName = callerElementName.GetAbilityName(); 70 std::string callerModuleName = callerElementName.GetModuleName(); 71 if (elementName.GetBundleName().compare(callerBundleName) == 0 && 72 elementName.GetAbilityName().compare(callerAbilityName) == 0 && 73 elementName.GetModuleName().compare(callerModuleName) == 0) { 74 TAG_LOGI(AAFwkTag::FREE_INSTALL, "top ability"); 75 return true; 76 } 77 78 return false; 79} 80 81int FreeInstallManager::StartFreeInstall(const Want &want, int32_t userId, int requestCode, 82 const sptr<IRemoteObject> &callerToken, bool isAsync, uint32_t specifyTokenId, bool isOpenAtomicServiceShortUrl, 83 std::shared_ptr<Want> originalWant) 84{ 85 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 86 if (!VerifyStartFreeInstallPermission(callerToken)) { 87 return NOT_TOP_ABILITY; 88 } 89 FreeInstallInfo info = BuildFreeInstallInfo(want, userId, requestCode, callerToken, 90 isAsync, specifyTokenId, isOpenAtomicServiceShortUrl, originalWant); 91 { 92 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 93 freeInstallList_.push_back(info); 94 } 95 int32_t recordId = GetRecordIdByToken(callerToken); 96 sptr<AtomicServiceStatusCallback> callback = new AtomicServiceStatusCallback(weak_from_this(), isAsync, recordId); 97 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper(); 98 CHECK_POINTER_AND_RETURN(bundleMgrHelper, GET_ABILITY_SERVICE_FAILED); 99 AppExecFwk::AbilityInfo abilityInfo = {}; 100 constexpr auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION; 101 info.want.SetParam(PARAM_FREEINSTALL_UID, IPCSkeleton::GetCallingUid()); 102 103 int result = SetAppRunningState(info.want); 104 if (result != ERR_OK) { 105 TAG_LOGE(AAFwkTag::FREE_INSTALL, "setAppRunningState failed"); 106 return result; 107 } 108 109 if (IN_PROCESS_CALL(bundleMgrHelper->QueryAbilityInfo(info.want, flag, info.userId, abilityInfo, callback))) { 110 TAG_LOGI(AAFwkTag::FREE_INSTALL, "app installed"); 111 } 112 std::string callingAppId = info.want.GetStringParam(PARAM_FREEINSTALL_APPID); 113 std::vector<std::string> callingBundleNames = info.want.GetStringArrayParam(PARAM_FREEINSTALL_BUNDLENAMES); 114 if (callingAppId.empty() && callingBundleNames.empty()) { 115 TAG_LOGI(AAFwkTag::FREE_INSTALL, "callingAppId and callingBundleNames empty"); 116 } 117 info.want.RemoveParam(PARAM_FREEINSTALL_APPID); 118 info.want.RemoveParam(PARAM_FREEINSTALL_BUNDLENAMES); 119 120 if (isAsync) { 121 return ERR_OK; 122 } else { 123 auto future = info.promise->get_future(); 124 std::future_status status = future.wait_for(std::chrono::milliseconds(DELAY_LOCAL_FREE_INSTALL_TIMEOUT)); 125 if (status == std::future_status::timeout) { 126 RemoveFreeInstallInfo(info.want.GetElement().GetBundleName(), info.want.GetElement().GetAbilityName(), 127 info.want.GetStringParam(Want::PARAM_RESV_START_TIME)); 128 return FREE_INSTALL_TIMEOUT; 129 } 130 return future.get(); 131 } 132} 133 134int FreeInstallManager::RemoteFreeInstall(const Want &want, int32_t userId, int requestCode, 135 const sptr<IRemoteObject> &callerToken) 136{ 137 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 138 bool isFromRemote = want.GetBoolParam(FROM_REMOTE_KEY, false); 139 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall(); 140 if (!isSaCall && !isFromRemote && !IsTopAbility(callerToken)) { 141 return NOT_TOP_ABILITY; 142 } 143 FreeInstallInfo info = BuildFreeInstallInfo(want, userId, requestCode, callerToken, false); 144 { 145 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 146 freeInstallList_.push_back(info); 147 } 148 int32_t recordId = GetRecordIdByToken(callerToken); 149 sptr<AtomicServiceStatusCallback> callback = new AtomicServiceStatusCallback(weak_from_this(), false, recordId); 150 int32_t callerUid = IPCSkeleton::GetCallingUid(); 151 uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 152 UriUtils::GetInstance().FilterUriWithPermissionDms(info.want, accessToken); 153 DistributedClient dmsClient; 154 auto result = dmsClient.StartRemoteFreeInstall(info.want, callerUid, info.requestCode, accessToken, callback); 155 if (result != ERR_NONE) { 156 return result; 157 } 158 auto remoteFuture = info.promise->get_future(); 159 std::future_status remoteStatus = remoteFuture.wait_for(std::chrono::milliseconds( 160 DELAY_REMOTE_FREE_INSTALL_TIMEOUT)); 161 if (remoteStatus == std::future_status::timeout) { 162 return FREE_INSTALL_TIMEOUT; 163 } 164 return remoteFuture.get(); 165} 166 167FreeInstallInfo FreeInstallManager::BuildFreeInstallInfo(const Want &want, int32_t userId, int requestCode, 168 const sptr<IRemoteObject> &callerToken, bool isAsync, uint32_t specifyTokenId, bool isOpenAtomicServiceShortUrl, 169 std::shared_ptr<Want> originalWant) 170{ 171 FreeInstallInfo info = { 172 .want = want, 173 .userId = userId, 174 .requestCode = requestCode, 175 .callerToken = callerToken, 176 .specifyTokenId = specifyTokenId, 177 .isOpenAtomicServiceShortUrl = isOpenAtomicServiceShortUrl, 178 .originalWant = originalWant 179 }; 180 if (!isAsync) { 181 auto promise = std::make_shared<std::promise<int32_t>>(); 182 info.promise = promise; 183 } 184 auto identity = IPCSkeleton::ResetCallingIdentity(); 185 info.identity = identity; 186 IPCSkeleton::SetCallingIdentity(identity); 187 return info; 188} 189 190int FreeInstallManager::StartRemoteFreeInstall(const Want &want, int requestCode, int32_t validUserId, 191 const sptr<IRemoteObject> &callerToken) 192{ 193 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 194 if (!want.GetBoolParam(Want::PARAM_RESV_FOR_RESULT, false)) { 195 TAG_LOGI(AAFwkTag::FREE_INSTALL, "StartAbility freeInstall"); 196 return RemoteFreeInstall(want, validUserId, requestCode, callerToken); 197 } 198 int32_t missionId = DelayedSingleton<AbilityManagerService>::GetInstance()-> 199 GetMissionIdByAbilityToken(callerToken); 200 if (missionId < 0) { 201 return ERR_INVALID_VALUE; 202 } 203 Want* newWant = const_cast<Want*>(&want); 204 newWant->SetParam(DMS_MISSION_ID, missionId); 205 return RemoteFreeInstall(*newWant, validUserId, requestCode, callerToken); 206} 207 208int FreeInstallManager::NotifyDmsCallback(const Want &want, int resultCode) 209{ 210 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 211 std::lock_guard<ffrt::mutex> autoLock(distributedFreeInstallLock_); 212 if (dmsFreeInstallCbs_.empty()) { 213 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null dms callback"); 214 return ERR_INVALID_VALUE; 215 } 216 217 MessageParcel reply; 218 MessageOption option; 219 220 for (auto it = dmsFreeInstallCbs_.begin(); it != dmsFreeInstallCbs_.end();) { 221 std::string abilityName = (*it).want.GetElement().GetAbilityName(); 222 if (want.GetElement().GetAbilityName().compare(abilityName) == 0) { 223 TAG_LOGI(AAFwkTag::FREE_INSTALL, "Handle DMS"); 224 MessageParcel data; 225 if (!data.WriteInterfaceToken(DMS_FREE_INSTALL_CALLBACK_TOKEN)) { 226 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write interface token failed"); 227 return ERR_INVALID_VALUE; 228 } 229 230 if (!data.WriteInt32(resultCode)) { 231 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write resultCode error"); 232 return ERR_INVALID_VALUE; 233 } 234 235 if (!data.WriteParcelable(&((*it).want))) { 236 TAG_LOGE(AAFwkTag::FREE_INSTALL, "want write failed"); 237 return INNER_ERR; 238 } 239 240 if (!data.WriteInt32((*it).requestCode)) { 241 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write resultCode error"); 242 return ERR_INVALID_VALUE; 243 } 244 245 (*it).dmsCallback->SendRequest(IDMS_CALLBACK_ON_FREE_INSTALL_DONE, data, reply, option); 246 it = dmsFreeInstallCbs_.erase(it); 247 } else { 248 it++; 249 } 250 } 251 252 return reply.ReadInt32(); 253} 254 255void FreeInstallManager::NotifyFreeInstallResult(int32_t recordId, const Want &want, int resultCode, bool isAsync) 256{ 257 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 258 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 259 if (freeInstallList_.empty()) { 260 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null app callback"); 261 return; 262 } 263 264 bool isFromRemote = want.GetBoolParam(FROM_REMOTE_KEY, false); 265 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 266 FreeInstallInfo &freeInstallInfo = *it; 267 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName(); 268 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName(); 269 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME); 270 std::string url = freeInstallInfo.want.GetUriString(); 271 if (want.GetElement().GetBundleName().compare(bundleName) != 0 || 272 want.GetElement().GetAbilityName().compare(abilityName) != 0 || 273 want.GetStringParam(Want::PARAM_RESV_START_TIME).compare(startTime) != 0 || 274 want.GetUriString().compare(url) != 0) { 275 it++; 276 continue; 277 } 278 279 if (!isAsync && freeInstallInfo.promise == nullptr) { 280 it++; 281 continue; 282 } 283 freeInstallInfo.isFreeInstallFinished = true; 284 freeInstallInfo.resultCode = resultCode; 285 HandleFreeInstallResult(recordId, freeInstallInfo, resultCode, isAsync); 286 it = freeInstallList_.erase(it); 287 } 288} 289 290void FreeInstallManager::HandleOnFreeInstallSuccess(int32_t recordId, FreeInstallInfo &freeInstallInfo, bool isAsync) 291{ 292 TAG_LOGI(AAFwkTag::FREE_INSTALL, "install success"); 293 freeInstallInfo.isInstalled = true; 294 295 if (isAsync) { 296 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME); 297 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName(); 298 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName(); 299 if (freeInstallInfo.isPreStartMissionCalled) { 300 StartAbilityByPreInstall(recordId, freeInstallInfo, bundleName, abilityName, startTime); 301 return; 302 } 303 if (freeInstallInfo.isOpenAtomicServiceShortUrl) { 304 StartAbilityByConvertedWant(freeInstallInfo, startTime); 305 return; 306 } 307 StartAbilityByFreeInstall(freeInstallInfo, bundleName, abilityName, startTime); 308 return; 309 } 310 freeInstallInfo.promise->set_value(ERR_OK); 311} 312 313void FreeInstallManager::HandleOnFreeInstallFail(int32_t recordId, FreeInstallInfo &freeInstallInfo, int resultCode, 314 bool isAsync) 315{ 316 TAG_LOGI(AAFwkTag::FREE_INSTALL, "install failed"); 317 freeInstallInfo.isInstalled = false; 318 319 if (isAsync) { 320 if (freeInstallInfo.isPreStartMissionCalled && 321 freeInstallInfo.want.HasParameter(KEY_SESSION_ID) && 322 !freeInstallInfo.want.GetStringParam(KEY_SESSION_ID).empty() && 323 freeInstallInfo.isStartUIAbilityBySCBCalled) { 324 DelayedSingleton<AbilityManagerService>::GetInstance()->NotifySCBToHandleAtomicServiceException( 325 freeInstallInfo.want.GetStringParam(KEY_SESSION_ID), 326 resultCode, "free install failed"); 327 } 328 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME); 329 if (freeInstallInfo.isOpenAtomicServiceShortUrl 330 && resultCode != CONCURRENT_TASKS_WAITING_FOR_RETRY) { 331 StartAbilityByOriginalWant(freeInstallInfo, startTime); 332 return; 333 } 334 335 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName(); 336 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName(); 337 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished( 338 recordId, bundleName, abilityName, startTime, resultCode); 339 return; 340 } 341 freeInstallInfo.promise->set_value(resultCode); 342} 343 344void FreeInstallManager::HandleFreeInstallResult(int32_t recordId, FreeInstallInfo &freeInstallInfo, int resultCode, 345 bool isAsync) 346{ 347 if (resultCode == ERR_OK) { 348 HandleOnFreeInstallSuccess(recordId, freeInstallInfo, isAsync); 349 return; 350 } 351 HandleOnFreeInstallFail(recordId, freeInstallInfo, resultCode, isAsync); 352} 353 354void FreeInstallManager::StartAbilityByFreeInstall(FreeInstallInfo &info, std::string &bundleName, 355 std::string &abilityName, std::string &startTime) 356{ 357 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND); 358 auto identity = IPCSkeleton::ResetCallingIdentity(); 359 IPCSkeleton::SetCallingIdentity(info.identity); 360 int32_t result = ERR_OK; 361 if (info.want.GetElement().GetAbilityName().empty()) { 362 result = UpdateElementName(info.want, info.userId); 363 } 364 if (result == ERR_OK) { 365 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbilityByFreeInstall(info.want, 366 info.callerToken, info.userId, info.requestCode); 367 } 368 IPCSkeleton::SetCallingIdentity(identity); 369 int32_t recordId = GetRecordIdByToken(info.callerToken); 370 TAG_LOGI(AAFwkTag::FREE_INSTALL, "result: %{public}d", result); 371 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished( 372 recordId, bundleName, abilityName, startTime, result); 373} 374 375void FreeInstallManager::StartAbilityByPreInstall(int32_t recordId, FreeInstallInfo &info, std::string &bundleName, 376 std::string &abilityName, std::string &startTime) 377{ 378 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND); 379 auto identity = IPCSkeleton::ResetCallingIdentity(); 380 IPCSkeleton::SetCallingIdentity(info.identity); 381 int32_t result = ERR_OK; 382 if (info.want.GetElement().GetAbilityName().empty()) { 383 result = UpdateElementName(info.want, info.userId); 384 } 385 if (result == ERR_OK) { 386 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartUIAbilityByPreInstall(info); 387 } 388 if (result != ERR_OK && info.isStartUIAbilityBySCBCalled) { 389 DelayedSingleton<AbilityManagerService>::GetInstance()->NotifySCBToHandleAtomicServiceException( 390 info.want.GetStringParam(KEY_SESSION_ID), 391 result, "start ability failed"); 392 } 393 IPCSkeleton::SetCallingIdentity(identity); 394 TAG_LOGI(AAFwkTag::FREE_INSTALL, "preInstall result: %{public}d", result); 395 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished( 396 recordId, bundleName, abilityName, startTime, result); 397} 398 399void FreeInstallManager::StartAbilityByConvertedWant(FreeInstallInfo &info, const std::string &startTime) 400{ 401 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND); 402 auto identity = IPCSkeleton::ResetCallingIdentity(); 403 IPCSkeleton::SetCallingIdentity(info.identity); 404 int32_t result = ERR_OK; 405 if (info.want.GetElement().GetAbilityName().empty()) { 406 result = UpdateElementName(info.want, info.userId); 407 } 408 if (result == ERR_OK) { 409 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(info.want, 410 info.callerToken, info.userId, info.requestCode); 411 } 412 IPCSkeleton::SetCallingIdentity(identity); 413 auto url = info.want.GetUriString(); 414 int32_t recordId = GetRecordIdByToken(info.callerToken); 415 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId, 416 startTime, url, result); 417} 418 419void FreeInstallManager::StartAbilityByOriginalWant(FreeInstallInfo &info, const std::string &startTime) 420{ 421 auto identity = IPCSkeleton::ResetCallingIdentity(); 422 IPCSkeleton::SetCallingIdentity(info.identity); 423 int result = ERR_INVALID_VALUE; 424 if (info.originalWant) { 425 TAG_LOGI(AAFwkTag::FREE_INSTALL, "StartAbility by originalWant"); 426 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(*(info.originalWant), 427 info.callerToken, info.userId, info.requestCode); 428 } else { 429 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null original want"); 430 } 431 IPCSkeleton::SetCallingIdentity(identity); 432 TAG_LOGI(AAFwkTag::FREE_INSTALL, "startAbility result: %{public}d", result); 433 auto url = info.want.GetUriString(); 434 int32_t recordId = GetRecordIdByToken(info.callerToken); 435 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId, 436 startTime, url, result); 437} 438 439int32_t FreeInstallManager::UpdateElementName(Want &want, int32_t userId) const 440{ 441 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper(); 442 CHECK_POINTER_AND_RETURN(bundleMgrHelper, ERR_INVALID_VALUE); 443 Want launchWant; 444 auto errCode = IN_PROCESS_CALL(bundleMgrHelper->GetLaunchWantForBundle(want.GetBundle(), launchWant, userId)); 445 if (errCode != ERR_OK) { 446 return errCode; 447 } 448 want.SetElement(launchWant.GetElement()); 449 return ERR_OK; 450} 451 452int FreeInstallManager::FreeInstallAbilityFromRemote(const Want &want, const sptr<IRemoteObject> &callback, 453 int32_t userId, int requestCode) 454{ 455 if (callback == nullptr) { 456 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null callback"); 457 return ERR_INVALID_VALUE; 458 } 459 460 FreeInstallInfo info = { 461 .want = want, 462 .userId = userId, 463 .requestCode = requestCode, 464 .dmsCallback = callback 465 }; 466 467 { 468 std::lock_guard<ffrt::mutex> autoLock(distributedFreeInstallLock_); 469 dmsFreeInstallCbs_.push_back(info); 470 } 471 472 auto result = StartFreeInstall(info.want, info.userId, info.requestCode, nullptr); 473 if (result != ERR_OK) { 474 TAG_LOGE(AAFwkTag::FREE_INSTALL, "StartFreeInstall code: %{public}d", result); 475 NotifyDmsCallback(info.want, result); 476 } 477 return result; 478} 479 480int FreeInstallManager::ConnectFreeInstall(const Want &want, int32_t userId, 481 const sptr<IRemoteObject> &callerToken, const std::string& localDeviceId) 482{ 483 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper(); 484 CHECK_POINTER_AND_RETURN(bundleMgrHelper, GET_ABILITY_SERVICE_FAILED); 485 std::string wantDeviceId = want.GetElement().GetDeviceID(); 486 if (!(localDeviceId == wantDeviceId || wantDeviceId.empty())) { 487 TAG_LOGE(AAFwkTag::FREE_INSTALL, "deviceID empty"); 488 return INVALID_PARAMETERS_ERR; 489 } 490 491 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall(); 492 if (!isSaCall) { 493 std::string wantAbilityName = want.GetElement().GetAbilityName(); 494 std::string wantBundleName = want.GetElement().GetBundleName(); 495 if (wantBundleName.empty() || wantAbilityName.empty()) { 496 TAG_LOGE(AAFwkTag::FREE_INSTALL, "wantBundleName or wantAbilityName empty."); 497 return INVALID_PARAMETERS_ERR; 498 } 499 int callerUid = IPCSkeleton::GetCallingUid(); 500 std::string localBundleName; 501 auto res = IN_PROCESS_CALL(bundleMgrHelper->GetNameForUid(callerUid, localBundleName)); 502 if (res != ERR_OK || localBundleName != wantBundleName) { 503 TAG_LOGE(AAFwkTag::FREE_INSTALL, "not local BundleName"); 504 return INVALID_PARAMETERS_ERR; 505 } 506 } 507 508 AppExecFwk::AbilityInfo abilityInfo; 509 std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos; 510 if (!IN_PROCESS_CALL(bundleMgrHelper->QueryAbilityInfo( 511 want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, abilityInfo)) && 512 !IN_PROCESS_CALL(bundleMgrHelper->QueryExtensionAbilityInfos( 513 want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, extensionInfos))) { 514 TAG_LOGI(AAFwkTag::FREE_INSTALL, "try to StartFreeInstall"); 515 int result = StartFreeInstall(want, userId, DEFAULT_INVAL_VALUE, callerToken); 516 if (result) { 517 TAG_LOGE(AAFwkTag::FREE_INSTALL, "startFreeInstall error"); 518 return result; 519 } 520 } 521 return ERR_OK; 522} 523 524std::time_t FreeInstallManager::GetTimeStamp() 525{ 526 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp = 527 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()); 528 std::time_t timestamp = tp.time_since_epoch().count(); 529 return timestamp; 530} 531 532void FreeInstallManager::OnInstallFinished(int32_t recordId, int resultCode, const Want &want, 533 int32_t userId, bool isAsync) 534{ 535 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 536 TAG_LOGI(AAFwkTag::FREE_INSTALL, "resultCode: %{public}d", resultCode); 537 538 if (!InsightIntentExecuteParam::IsInsightIntentExecute(want)) { 539 NotifyDmsCallback(want, resultCode); 540 NotifyFreeInstallResult(recordId, want, resultCode, isAsync); 541 } else { 542 NotifyInsightIntentFreeInstallResult(want, resultCode); 543 } 544 545 PostUpgradeAtomicServiceTask(resultCode, want, userId); 546} 547 548void FreeInstallManager::PostUpgradeAtomicServiceTask(int resultCode, const Want &want, int32_t userId) 549{ 550 TAG_LOGI(AAFwkTag::FREE_INSTALL, "called"); 551 std::weak_ptr<FreeInstallManager> thisWptr(shared_from_this()); 552 if (resultCode == ERR_OK) { 553 auto updateAtmoicServiceTask = [want, userId, thisWptr, &timeStampMap = timeStampMap_]() { 554 auto sptr = thisWptr.lock(); 555 TAG_LOGD(AAFwkTag::FREE_INSTALL, 556 "bundleName: %{public}s, moduleName: %{public}s", want.GetElement().GetBundleName().c_str(), 557 want.GetElement().GetModuleName().c_str()); 558 std::string nameKey = want.GetElement().GetBundleName() + want.GetElement().GetModuleName(); 559 if (timeStampMap.find(nameKey) == timeStampMap.end() || 560 sptr->GetTimeStamp() - timeStampMap[nameKey] > UPDATE_ATOMOIC_SERVICE_TASK_TIMER) { 561 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper(); 562 CHECK_POINTER(bundleMgrHelper); 563 bundleMgrHelper->UpgradeAtomicService(want, userId); 564 timeStampMap.emplace(nameKey, sptr->GetTimeStamp()); 565 } 566 }; 567 568 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler(); 569 CHECK_POINTER_LOG(handler, "Fail to get Ability task handler."); 570 handler->SubmitTask(updateAtmoicServiceTask, "UpdateAtmoicServiceTask"); 571 } 572} 573 574void FreeInstallManager::OnRemoteInstallFinished(int32_t recordId, int resultCode, const Want &want, int32_t userId) 575{ 576 TAG_LOGI(AAFwkTag::FREE_INSTALL, "finished resultCode:%{public}d", resultCode); 577 NotifyFreeInstallResult(recordId, want, resultCode); 578} 579 580int FreeInstallManager::AddFreeInstallObserver(const sptr<IRemoteObject> &callerToken, 581 const sptr<AbilityRuntime::IFreeInstallObserver> &observer) 582{ 583 TAG_LOGI(AAFwkTag::FREE_INSTALL, "called"); 584 auto abilityRecord = Token::GetAbilityRecordByToken(callerToken); 585 if (abilityRecord != nullptr) { 586 return DelayedSingleton<FreeInstallObserverManager>::GetInstance()->AddObserver(abilityRecord->GetRecordId(), 587 observer); 588 } 589 if (AAFwk::PermissionVerification::GetInstance()->IsSACall()) { 590 return DelayedSingleton<FreeInstallObserverManager>::GetInstance()->AddObserver(-1, observer); 591 } 592 return CHECK_PERMISSION_FAILED; 593} 594 595void FreeInstallManager::RemoveFreeInstallInfo(const std::string &bundleName, const std::string &abilityName, 596 const std::string &startTime) 597{ 598 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 599 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 600 if ((*it).want.GetElement().GetBundleName() == bundleName && 601 (*it).want.GetElement().GetAbilityName() == abilityName && 602 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { 603 it = freeInstallList_.erase(it); 604 } else { 605 it++; 606 } 607 } 608} 609 610int32_t FreeInstallManager::GetRecordIdByToken(const sptr<IRemoteObject> &callerToken) 611{ 612 auto abilityRecord = Token::GetAbilityRecordByToken(callerToken); 613 int recordId = -1; 614 if (abilityRecord != nullptr) { 615 recordId = abilityRecord->GetRecordId(); 616 } 617 return recordId; 618} 619 620bool FreeInstallManager::VerifyStartFreeInstallPermission(const sptr<IRemoteObject> &callerToken) 621{ 622 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall(); 623 if (isSaCall || IsTopAbility(callerToken)) { 624 return true; 625 } 626 627 if (AAFwk::PermissionVerification::GetInstance()->VerifyCallingPermission( 628 PermissionConstants::PERMISSION_START_ABILITIES_FROM_BACKGROUND)) { 629 return true; 630 } 631 632 return false; 633} 634 635int FreeInstallManager::SetAppRunningState(Want &want) 636{ 637 auto appMgr = AppMgrUtil::GetAppMgr(); 638 if (appMgr == nullptr) { 639 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null appMgr"); 640 return ERR_INVALID_VALUE; 641 } 642 643 bool isAppRunning = appMgr->GetAppRunningStateByBundleName(want.GetElement().GetBundleName()); 644 TAG_LOGI(AAFwkTag::FREE_INSTALL, "isAppRunning:%{public}d", static_cast<int>(isAppRunning)); 645 want.SetParam(KEY_IS_APP_RUNNING, isAppRunning); 646 return ERR_OK; 647} 648 649bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& bundleName, const std::string& abilityName, 650 const std::string& startTime, FreeInstallInfo& taskInfo) 651{ 652 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 653 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 654 if ((*it).want.GetElement().GetBundleName() == bundleName && 655 (*it).want.GetElement().GetAbilityName() == abilityName && 656 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { 657 taskInfo = *it; 658 return true; 659 } 660 it++; 661 } 662 return false; 663} 664 665bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& sessionId, FreeInstallInfo& taskInfo) 666{ 667 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 668 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 669 if ((*it).want.GetStringParam(KEY_SESSION_ID) == sessionId) { 670 taskInfo = *it; 671 return true; 672 } 673 it++; 674 } 675 return false; 676} 677 678void FreeInstallManager::SetSCBCallStatus(const std::string& bundleName, const std::string& abilityName, 679 const std::string& startTime, bool scbCallStatus) 680{ 681 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 682 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 683 if ((*it).want.GetElement().GetBundleName() == bundleName && 684 (*it).want.GetElement().GetAbilityName() == abilityName && 685 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { 686 (*it).isStartUIAbilityBySCBCalled = scbCallStatus; 687 return; 688 } 689 it++; 690 } 691} 692 693void FreeInstallManager::SetPreStartMissionCallStatus(const std::string& bundleName, const std::string& abilityName, 694 const std::string& startTime, bool preStartMissionCallStatus) 695{ 696 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 697 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 698 if ((*it).want.GetElement().GetBundleName() == bundleName && 699 (*it).want.GetElement().GetAbilityName() == abilityName && 700 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { 701 (*it).isPreStartMissionCalled = preStartMissionCallStatus; 702 return; 703 } 704 it++; 705 } 706} 707 708void FreeInstallManager::SetFreeInstallTaskSessionId(const std::string& bundleName, const std::string& abilityName, 709 const std::string& startTime, const std::string& sessionId) 710{ 711 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 712 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 713 if ((*it).want.GetElement().GetBundleName() == bundleName && 714 (*it).want.GetElement().GetAbilityName() == abilityName && 715 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) { 716 (*it).want.SetParam(KEY_SESSION_ID, sessionId); 717 return; 718 } 719 it++; 720 } 721} 722 723void FreeInstallManager::NotifyInsightIntentFreeInstallResult(const Want &want, int resultCode) 724{ 725 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 726 TAG_LOGI(AAFwkTag::FREE_INSTALL, "insight install result:%{public}d", resultCode); 727 if (resultCode != ERR_OK) { 728 RemoveFreeInstallInfo(want.GetElement().GetBundleName(), want.GetElement().GetAbilityName(), 729 want.GetStringParam(Want::PARAM_RESV_START_TIME)); 730 NotifyInsightIntentExecuteDone(want, ERR_INVALID_VALUE); 731 return; 732 } 733 734 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_); 735 if (freeInstallList_.empty()) { 736 TAG_LOGI(AAFwkTag::FREE_INSTALL, "list empty"); 737 return; 738 } 739 740 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) { 741 std::string bundleName = (*it).want.GetElement().GetBundleName(); 742 std::string abilityName = (*it).want.GetElement().GetAbilityName(); 743 std::string startTime = (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME); 744 if (want.GetElement().GetBundleName().compare(bundleName) != 0 || 745 want.GetElement().GetAbilityName().compare(abilityName) != 0 || 746 want.GetStringParam(Want::PARAM_RESV_START_TIME).compare(startTime) != 0) { 747 it++; 748 continue; 749 } 750 751 auto moduleName = (*it).want.GetElement().GetModuleName(); 752 auto insightIntentName = (*it).want.GetStringParam(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_NAME); 753 auto executeMode = static_cast<AppExecFwk::ExecuteMode>( 754 it->want.GetIntParam(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_MODE, 0)); 755 std::string srcEntry; 756 auto ret = AbilityRuntime::InsightIntentUtils::GetSrcEntry(it->want.GetElement(), insightIntentName, 757 executeMode, srcEntry); 758 if (ret != ERR_OK || srcEntry.empty()) { 759 TAG_LOGE(AAFwkTag::FREE_INSTALL, "failed. bundleName: %{public}s, " 760 "moduleName: %{public}s, insightIntentName: %{public}s", bundleName.c_str(), moduleName.c_str(), 761 insightIntentName.c_str()); 762 NotifyInsightIntentExecuteDone(want, ERR_INVALID_VALUE); 763 } else { 764 (*it).want.SetParam(AppExecFwk::INSIGHT_INTENT_SRC_ENTRY, srcEntry); 765 StartAbilityByFreeInstall(*it, bundleName, abilityName, startTime); 766 } 767 768 it = freeInstallList_.erase(it); 769 } 770} 771 772void FreeInstallManager::NotifyInsightIntentExecuteDone(const Want &want, int resultCode) 773{ 774 InsightIntentExecuteParam executeParam; 775 InsightIntentExecuteParam::GenerateFromWant(want, executeParam); 776 AppExecFwk::InsightIntentExecuteResult result; 777 auto ret = DelayedSingleton<InsightIntentExecuteManager>::GetInstance()->ExecuteIntentDone( 778 executeParam.insightIntentId_, resultCode, result); 779 if (ret != ERR_OK) { 780 TAG_LOGE(AAFwkTag::FREE_INSTALL, "failed with %{public}d", ret); 781 } 782} 783} // namespace AAFwk 784} // namespace OHOS 785