1 /*
2  * Copyright (c) 2020 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 "ability_mgr_feature.h"
17 
18 #include "ability_callback_utils.h"
19 #include "ability_connect_trans_param.h"
20 #include "ability_errors.h"
21 #include "ability_info.h"
22 #include "ability_message_id.h"
23 #include "ability_mgr_handler.h"
24 #include "ability_service_interface.h"
25 #include "adapter.h"
26 #include "ohos_init.h"
27 #include "iproxy_client.h"
28 #include "rpc_errno.h"
29 #include "samgr_lite.h"
30 #include "securec.h"
31 #include "util/abilityms_helper.h"
32 #include "utils.h"
33 #include "want_utils.h"
34 
35 namespace OHOS {
36 SvcIdentity AbilityMgrFeature::svc_ = {0};
37 IDmsListener* AbilityMgrFeature::myCallback_ = nullptr;
38 
39 AbilityMgrFeatureImpl g_amsImpl = {
40     SERVER_IPROXY_IMPL_BEGIN,
41     .Invoke = AbilityMgrFeature::Invoke,
42     .StartAbility = AbilityMgrFeature::StartAbility,
43     .TerminateAbility = AbilityMgrFeature::TerminateAbility,
44     .ConnectAbility = AbilityMgrFeature::ConnectAbility,
45     .DisconnectAbility = AbilityMgrFeature::DisconnectAbility,
46     .StopAbility = AbilityMgrFeature::StopAbility,
47     IPROXY_END
48 };
49 
50 InvokeFunc AbilityMgrFeature::invokeFuncList[INNER_BEGIN] {
51     AbilityMgrFeature::StartAbilityInvoke,
52     AbilityMgrFeature::TerminateAbilityInvoke,
53     AbilityMgrFeature::AttachBundleInvoke,
54     AbilityMgrFeature::ConnectAbilityInvoke,
55     AbilityMgrFeature::ConnectAbilityDoneInvoke,
56     AbilityMgrFeature::DisconnectAbilityInvoke,
57     AbilityMgrFeature::DisconnectAbilityDoneInvoke,
58     AbilityMgrFeature::AbilityTransactionDoneInvoke,
59     AbilityMgrFeature::StopAbilityInvoke,
60     AbilityMgrFeature::StartAbilityWithCbInvoke,
61 };
62 
Init()63 static void Init()
64 {
65     SamgrLite *samgrLite = SAMGR_GetInstance();
66     CHECK_NULLPTR_RETURN(samgrLite, "AbilityMgrFeature", "get samgr error");
67     BOOL result = samgrLite->RegisterFeature(AMS_SERVICE, AbilityMgrFeature::GetInstance());
68     if (result == FALSE) {
69         PRINTE("AbilityMgrFeature", "ams register feature failure");
70         return;
71     }
72     g_amsImpl.ams = AbilityMgrFeature::GetInstance();
73     auto publicApi = GET_IUNKNOWN(g_amsImpl);
74     CHECK_NULLPTR_RETURN(publicApi, "AbilityMgrFeatureLite", "publicApi is nullptr");
75     BOOL apiResult = samgrLite->RegisterFeatureApi(AMS_SERVICE, AMS_FEATURE, publicApi);
76     PRINTI("AbilityMgrFeature", "ams feature init %{public}s", apiResult ? "success" : "failure");
77 }
78 SYSEX_FEATURE_INIT(Init);
79 
AbilityMgrFeature()80 AbilityMgrFeature::AbilityMgrFeature() : Feature(), identity_()
81 {
82     this->Feature::GetName = AbilityMgrFeature::GetFeatureName;
83     this->Feature::OnInitialize = AbilityMgrFeature::OnFeatureInitialize;
84     this->Feature::OnStop = AbilityMgrFeature::OnFeatureStop;
85     this->Feature::OnMessage = AbilityMgrFeature::OnFeatureMessage;
86 }
87 
Invoke(IServerProxy * iProxy,int funcId,void * origin,IpcIo * req,IpcIo * reply)88 int32 AbilityMgrFeature::Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
89 {
90     PRINTI("AbilityMgrFeature", "ams invoke called");
91     if (req == nullptr) {
92         return EC_INVALID;
93     }
94     if (funcId >= START_ABILITY && funcId < INNER_BEGIN) {
95         return invokeFuncList[funcId](origin, req);
96     }
97     return COMMAND_ERROR;
98 }
99 
GetFeatureName(Feature * feature)100 const char *AbilityMgrFeature::GetFeatureName(Feature *feature)
101 {
102     (void) feature;
103     return AMS_FEATURE;
104 }
105 
OnFeatureInitialize(Feature * feature,Service * parent,Identity identity)106 void AbilityMgrFeature::OnFeatureInitialize(Feature *feature, Service *parent, Identity identity)
107 {
108     CHECK_NULLPTR_RETURN(feature, "AbilityMgrFeature", "initialize fail");
109     (static_cast<AbilityMgrFeature *>(feature))->identity_ = identity;
110     AbilityMgrHandler::GetInstance().Init();
111 }
112 
OnFeatureStop(Feature * feature,Identity identity)113 void AbilityMgrFeature::OnFeatureStop(Feature *feature, Identity identity)
114 {
115     (void) feature;
116     (void) identity;
117     AdapterFree(myCallback_);
118 }
119 
OnFeatureMessage(Feature * feature,Request * request)120 BOOL AbilityMgrFeature::OnFeatureMessage(Feature *feature, Request *request)
121 {
122     if (feature == nullptr || request == nullptr) {
123         return FALSE;
124     }
125 
126     AbilityMgrHandler::GetInstance().ServiceMsgProcess(*request);
127     return TRUE;
128 }
129 
OnRequestCallback(const void * data,int32_t ret)130 void AbilityMgrFeature::OnRequestCallback(const void *data, int32_t ret)
131 {
132     IpcIo io;
133     char ipcData[MAX_IO_SIZE];
134     IpcIo reply;
135     IpcIoInit(&io, ipcData, MAX_IO_SIZE, 0);
136     WriteInt32(&io, static_cast<int32_t>(ret));
137     MessageOption option;
138     MessageOptionInit(&option);
139     option.flags = TF_OP_ASYNC;
140     int32_t transRet = SendRequest(svc_, START_ABILITY_CALLBACK, &io, &reply, option, NULL);
141     if (transRet != ERR_NONE) {
142         HILOG_ERROR(HILOG_MODULE_APP, "AbilityMgrFeature InnerSelfTransact failed %{public}d\n", ret);
143     }
144     ReleaseSvc(svc_);
145 }
146 
StartAbilityInvoke(const void * origin,IpcIo * req)147 int32 AbilityMgrFeature::StartAbilityInvoke(const void *origin, IpcIo *req)
148 {
149     pid_t uid = GetCallingUid();
150     if (uid < 0) {
151         PRINTE("AbilityMgrFeature", "invalid uid argument");
152         return EC_INVALID;
153     }
154     Want want = { nullptr, nullptr, nullptr, 0};
155     if (!DeserializeWant(&want, req)) {
156         return EC_FAILURE;
157     }
158     if (want.element == nullptr) {
159         PRINTE("AbilityMgrFeature", "invalid argument");
160         return EC_INVALID;
161     }
162     const char *deviceId = want.element->deviceId;
163 
164     int32 retVal;
165     if (deviceId != nullptr && *deviceId != '\0') {
166         retVal = StartRemoteAbilityInner(&want, deviceId, uid, nullptr);
167     } else {
168         retVal = StartAbilityInner(&want, uid);
169     }
170     ClearWant(&want);
171     return retVal;
172 }
173 
StartAbilityWithCbInvoke(const void * origin,IpcIo * req)174 int32 AbilityMgrFeature::StartAbilityWithCbInvoke(const void *origin, IpcIo *req)
175 {
176     pid_t uid = GetCallingUid();
177     if (uid < 0) {
178         PRINTE("AbilityMgrFeature", "invalid uid argument");
179         return EC_INVALID;
180     }
181     SvcIdentity svc;
182     bool ret = ReadRemoteObject(req, &svc);
183     if (!ret) {
184         svc_ = {0};
185         return EC_INVALID;
186     }
187     svc_ = svc;
188     Want want = { nullptr, nullptr, nullptr, 0};
189     if (!DeserializeWant(&want, req)) {
190         return EC_FAILURE;
191     }
192     if (want.element == nullptr) {
193         PRINTE("AbilityMgrFeature", "invalid argument");
194         return EC_INVALID;
195     }
196     const char *deviceId = want.element->deviceId;
197 
198     int32 retVal = EC_FAILURE;
199     if (deviceId != nullptr && *deviceId != '\0') {
200         retVal = StartRemoteAbilityInner(&want, deviceId, uid, OnRequestCallback);
201     }
202     ClearWant(&want);
203     return retVal;
204 }
205 
StartAbility(const Want * want)206 int32 AbilityMgrFeature::StartAbility(const Want *want)
207 {
208     return StartAbilityInner(want, -1);
209 }
210 
StartRemoteAbilityInner(const Want * want,const char * deviceId,pid_t uid,OnRequestCallbackFunc callback)211 int32 AbilityMgrFeature::StartRemoteAbilityInner(const Want *want, const char *deviceId,
212     pid_t uid, OnRequestCallbackFunc callback)
213 {
214     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(DISTRIBUTED_SCHEDULE_SERVICE, DMSLITE_FEATURE);
215     DmsProxy *dmsInterface = NULL;
216     if (iUnknown == NULL) {
217         return EC_INVALID;
218     }
219     int32 retVal = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void**) &dmsInterface);
220     if (retVal != EC_SUCCESS) {
221         return EC_INVALID;
222     }
223     CallerInfo callerInfo = {
224         .uid = uid
225     };
226 
227     if (callback != nullptr) {
228         if (myCallback_ == nullptr) {
229             myCallback_ = new IDmsListener();
230         }
231         myCallback_ -> OnResultCallback = callback;
232         retVal = dmsInterface->StartRemoteAbility((Want *)want, &callerInfo, myCallback_);
233     } else {
234         retVal = dmsInterface->StartRemoteAbility((Want *)want, &callerInfo, NULL);
235     }
236     return retVal;
237 }
238 
StartAbilityInner(const Want * want,pid_t callingUid)239 int32 AbilityMgrFeature::StartAbilityInner(const Want *want, pid_t callingUid)
240 {
241     if (want == nullptr || want->element == nullptr) {
242         PRINTE("AbilityMgrFeature", "invalid argument");
243         return EC_INVALID;
244     }
245     Want *data = new Want();
246     if (memset_s(data, sizeof(Want), 0, sizeof(Want)) != EOK) {
247         PRINTE("AbilityMgrFeature", "memory alloc error");
248         delete data;
249         return EC_NOMEMORY;
250     }
251     SetWantElement(data, *(want->element));
252     SetWantData(data, want->data, want->dataLength);
253     if (want->sid != nullptr) {
254         SetWantSvcIdentity(data, *(want->sid));
255     }
256     Request request = {
257         .msgId = AMS_START_ABILITY,
258         .len = 0,
259         .data = reinterpret_cast<void *>(data),
260         .msgValue = static_cast<uint32>(callingUid),
261     };
262     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
263     if (propRet != EC_SUCCESS) {
264         PRINTE("AbilityMgrFeature", "send request failure");
265         ClearWant(data);
266         delete data;
267         return EC_COMMU;
268     }
269     return EC_SUCCESS;
270 }
271 
TerminateAbilityInvoke(const void * origin,IpcIo * req)272 int32 AbilityMgrFeature::TerminateAbilityInvoke(const void *origin, IpcIo *req)
273 {
274     uint64_t token = 0;
275     ReadUint64(req, &token);
276     return TerminateAbility(token);
277 }
278 
TerminateAbility(uint64_t token)279 int32 AbilityMgrFeature::TerminateAbility(uint64_t token)
280 {
281     uint64_t *terminateToken = new uint64_t;
282     *terminateToken = token;
283     Request request = {
284         .msgId = AMS_TERMINATE_ABILITY,
285         .len = 0,
286         .data = reinterpret_cast<void *>(terminateToken),
287     };
288     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
289     if (propRet != EC_SUCCESS) {
290         PRINTE("AbilityMgrFeature", "send request failure");
291         delete terminateToken;
292         return EC_COMMU;
293     }
294     return EC_SUCCESS;
295 }
296 
AbilityTransactionDoneInvoke(const void * origin,IpcIo * req)297 int32 AbilityMgrFeature::AbilityTransactionDoneInvoke(const void *origin, IpcIo *req)
298 {
299     uint64_t token = 0;
300     ReadUint64(req, &token);
301     int32_t ret = 0;
302     ReadInt32(req, &ret);
303     int32 state = static_cast<int32>(ret);
304 
305     TransactionState *transactionState = new TransactionState();
306     transactionState->token = token;
307     transactionState->state = state;
308     Request request = {
309         .msgId = AMS_TRANSACTION_DONE,
310         .len = 0,
311         .data = reinterpret_cast<void *>(transactionState),
312     };
313     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
314     if (propRet != EC_SUCCESS) {
315         PRINTE("AbilityMgrFeature", "send request failure");
316         delete transactionState;
317         return EC_COMMU;
318     }
319     return EC_SUCCESS;
320 }
321 
AttachBundleInvoke(const void * origin,IpcIo * req)322 int32 AbilityMgrFeature::AttachBundleInvoke(const void *origin, IpcIo *req)
323 {
324     uint64_t token = 0;
325     ReadUint64(req, &token);
326     SvcIdentity svc;
327     bool ret = ReadRemoteObject(req, &svc);
328     if (!ret) {
329         return EC_INVALID;
330     }
331 
332 #ifdef __LINUX__
333     uint64_t readData = 0;
334     ReadUint64(req, &readData);
335     pid_t callingPid = static_cast<pid_t>(readData);
336 #else
337     pid_t callingPid = GetCallingPid();
338 #endif
339     if (callingPid < 0) {
340         PRINTE("AbilityMgrFeature", "invalid pid argument");
341         return EC_INVALID;
342     }
343 
344     auto client = new AbilityThreadClient(token, callingPid, svc, &AbilityMgrFeature::AppDeathNotify);
345     Request request = {
346         .msgId = AMS_ATTACH_BUNDLE,
347         .len = 0,
348         .data = reinterpret_cast<void *>(client),
349     };
350     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
351     if (propRet != EC_SUCCESS) {
352         PRINTE("AbilityMgrFeature", "send request failure");
353         delete client;
354         return EC_COMMU;
355     }
356     return EC_SUCCESS;
357 }
358 
ConnectAbilityInvoke(const void * origin,IpcIo * req)359 int32 AbilityMgrFeature::ConnectAbilityInvoke(const void *origin, IpcIo *req)
360 {
361     pid_t uid = GetCallingUid();
362     if (uid < 0) {
363         PRINTE("AbilityMgrFeature", "invalid uid argument");
364         return EC_INVALID;
365     }
366     uint64_t token = 0;
367     ReadUint64(req, &token);
368     SvcIdentity svc;
369     bool ret = ReadRemoteObject(req, &svc);
370     if (!ret) {
371         return EC_INVALID;
372     }
373     Want want = { nullptr, nullptr, nullptr, 0 };
374     if (!DeserializeWant(&want, req)) {
375         return EC_FAILURE;
376     }
377     int32 retVal = ConnectAbilityInner(&want, &svc, token, uid);
378     ClearWant(&want);
379     return retVal;
380 }
381 
ConnectAbility(const Want * want,SvcIdentity * svc,uint64_t token)382 int32 AbilityMgrFeature::ConnectAbility(const Want *want, SvcIdentity *svc, uint64_t token)
383 {
384     return ConnectAbilityInner(want, svc, token, -1);
385 }
386 
ConnectAbilityInner(const Want * want,SvcIdentity * svc,uint64_t token,pid_t callingUid)387 int32 AbilityMgrFeature::ConnectAbilityInner(const Want *want, SvcIdentity *svc, uint64_t token, pid_t callingUid)
388 {
389     if (want == nullptr || want->element == nullptr || svc == nullptr) {
390         return EC_INVALID;
391     }
392     Want *data = new Want();
393     if (memset_s(data, sizeof(Want), 0, sizeof(Want)) != EOK) {
394         delete data;
395         PRINTE("AbilityMgrFeature", "memory alloc error");
396         return EC_NOMEMORY;
397     }
398     SetWantElement(data, *(want->element));
399     SetWantData(data, want->data, want->dataLength);
400     if (want->sid != nullptr) {
401         SetWantSvcIdentity(data, *(want->sid));
402     }
403     auto transParam = new AbilityConnectTransParam(data, *svc, token);
404     transParam->SetCallingUid(callingUid);
405     Request request = {
406         .msgId = AMS_CONNECT_ABILITY,
407         .len = 0,
408         .data = reinterpret_cast<void *>(transParam),
409     };
410     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
411     if (propRet != EC_SUCCESS) {
412         PRINTE("AbilityMgrFeature", "connect ability send request failure");
413         delete transParam;
414         return EC_COMMU;
415     }
416     return EC_SUCCESS;
417 }
418 
DisconnectAbilityInvoke(const void * origin,IpcIo * req)419 int32 AbilityMgrFeature::DisconnectAbilityInvoke(const void *origin, IpcIo *req)
420 {
421     uint64_t token = 0;
422     ReadUint64(req, &token);
423     SvcIdentity svc;
424     bool ret = ReadRemoteObject(req, &svc);
425     if (!ret) {
426         return EC_INVALID;
427     }
428     return DisconnectAbility(&svc, token);
429 }
430 
DisconnectAbility(SvcIdentity * svc,uint64_t token)431 int32 AbilityMgrFeature::DisconnectAbility(SvcIdentity *svc, uint64_t token)
432 {
433     if (svc == nullptr) {
434         return EC_INVALID;
435     }
436     auto transParam = new AbilityConnectTransParam(nullptr, *svc, token);
437     Request request = {
438         .msgId = AMS_DISCONNECT_ABILITY,
439         .len = 0,
440         .data = reinterpret_cast<void *>(transParam),
441     };
442     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
443     if (propRet != EC_SUCCESS) {
444         PRINTE("AbilityMgrFeature", "disconnect ability send request failure");
445         delete transParam;
446         return EC_COMMU;
447     }
448     return EC_SUCCESS;
449 }
450 
ConnectAbilityDoneInvoke(const void * origin,IpcIo * req)451 int32 AbilityMgrFeature::ConnectAbilityDoneInvoke(const void *origin, IpcIo *req)
452 {
453     uint64_t token = 0;
454     ReadUint64(req, &token);
455     SvcIdentity svc;
456     bool ret = ReadRemoteObject(req, &svc);
457     if (!ret) {
458         return EC_INVALID;
459     }
460 
461     auto transParam = new AbilityConnectTransParam(nullptr, svc, token);
462     Request request = {
463         .msgId = AMS_CONNECT_ABILITY_DONE,
464         .len = 0,
465         .data = reinterpret_cast<void *>(transParam),
466     };
467     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
468     if (propRet != EC_SUCCESS) {
469         PRINTE("AbilityMgrFeature", "connect ability done send request failure");
470         delete transParam;
471         return EC_COMMU;
472     }
473     return EC_SUCCESS;
474 }
475 
DisconnectAbilityDoneInvoke(const void * origin,IpcIo * req)476 int32 AbilityMgrFeature::DisconnectAbilityDoneInvoke(const void *origin, IpcIo *req)
477 {
478     uint64_t *disconnectToken = new uint64_t;
479     uint64_t ret = 0;
480     ReadUint64(req, &ret);
481     *disconnectToken = ret;
482     Request request = {
483         .msgId = AMS_DISCONNECT_ABILITY_DONE,
484         .len = 0,
485         .data = reinterpret_cast<void *>(disconnectToken),
486     };
487     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
488     if (propRet != EC_SUCCESS) {
489         PRINTE("AbilityMgrFeature", "disconnect ability done send request failure");
490         delete disconnectToken;
491         return EC_COMMU;
492     }
493     return EC_SUCCESS;
494 }
495 
StopAbilityInvoke(const void * origin,IpcIo * req)496 int32 AbilityMgrFeature::StopAbilityInvoke(const void *origin, IpcIo *req)
497 {
498     pid_t uid = GetCallingUid();
499     if (uid < 0) {
500         PRINTE("AbilityMgrFeature", "invalid uid argument");
501         return EC_INVALID;
502     }
503     Want want = { nullptr, nullptr, nullptr, 0 };
504     if (!DeserializeWant(&want, req)) {
505         return EC_FAILURE;
506     }
507     int retVal = StopAbilityInner(&want, uid);
508     ClearWant(&want);
509     return retVal;
510 }
511 
StopAbility(const Want * want)512 int32 AbilityMgrFeature::StopAbility(const Want *want)
513 {
514     return StopAbilityInner(want, -1);
515 }
516 
StopAbilityInner(const Want * want,pid_t callingUid)517 int32 AbilityMgrFeature::StopAbilityInner(const Want *want, pid_t callingUid)
518 {
519     if (want == nullptr || want->element == nullptr) {
520         PRINTE("AbilityMgrFeature", "invalid argument");
521         return EC_INVALID;
522     }
523     Want *data = new Want();
524     if (memset_s(data, sizeof(Want), 0, sizeof(Want)) != EOK) {
525         PRINTE("AbilityMgrFeature", "memory alloc error");
526         delete data;
527         return EC_NOMEMORY;
528     }
529     SetWantElement(data, *(want->element));
530     SetWantData(data, want->data, want->dataLength);
531     if (want->sid != nullptr) {
532         SetWantSvcIdentity(data, *(want->sid));
533     }
534     Request request = {
535         .msgId = AMS_TERMINATE_SERVICE,
536         .len = 0,
537         .data = reinterpret_cast<void *>(data),
538         .msgValue = static_cast<uint32>(callingUid),
539     };
540     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
541     if (propRet != EC_SUCCESS) {
542         PRINTE("AbilityMgrFeature", "send request failure");
543         ClearWant(data);
544         delete data;
545         return EC_COMMU;
546     }
547     return EC_SUCCESS;
548 }
549 
RestartApp(const char * bundleName)550 int32 AbilityMgrFeature::RestartApp(const char *bundleName)
551 {
552     if (!AbilityMsHelper::IsLegalBundleName(bundleName)) {
553         return EC_INVALID;
554     }
555     char *name = Utils::Strdup(bundleName);
556     if (name == nullptr) {
557         return EC_NOMEMORY;
558     }
559     Request request = {
560         .msgId = AMS_RESTART_APP,
561         .len = 0,
562         .data = reinterpret_cast<void *>(name),
563     };
564     int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr);
565     if (propRet != EC_SUCCESS) {
566         PRINTE("AbilityMgrFeature", "send request failure");
567         AdapterFree(name);
568         return EC_COMMU;
569     }
570     return EC_SUCCESS;
571 }
572 
AppDeathNotify(void * args)573 void AbilityMgrFeature::AppDeathNotify(void *args)
574 {
575     AppInfo *appInfo = reinterpret_cast<AppInfo *>(args);
576     if (appInfo == nullptr) {
577         return;
578     }
579     ReleaseSvc(appInfo->svcIdentity);
580     if (!AbilityMsHelper::IsLegalBundleName(appInfo->bundleName)) {
581         AdapterFree(appInfo->bundleName);
582         delete appInfo;
583         return;
584     }
585     PRINTE("AbilityMgrFeature", "%s AppDeathNotify called", appInfo->bundleName);
586     int32 ret = RestartApp(appInfo->bundleName);
587     if (ret != EC_SUCCESS) {
588         PRINTE("AbilityMgrFeature", "restart app failure");
589     }
590     AdapterFree(appInfo->bundleName);
591     delete appInfo;
592 }
593 } // namespace OHOS
594