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