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