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