• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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