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_handler.h"
17 
18 #include "ability_kit_command.h"
19 #include "ability_message_id.h"
20 #include "adapter.h"
21 #include "app_manager.h"
22 #include "bundle_info.h"
23 #include "bundle_manager.h"
24 #ifdef ABILITY_WINDOW_SUPPORT
25 #include "client/wms_client.h"
26 #endif
27 #include "element_name_utils.h"
28 #include "iproxy_client.h"
29 #include "rpc_errno.h"
30 #include "util/abilityms_helper.h"
31 
32 namespace OHOS {
Init()33 void AbilityMgrHandler::Init()
34 {
35     AbilityMsStatus status = bundleMsClient_.Initialize();
36     CHECK_RESULT_LOG(status);
37 }
38 
ServiceMsgProcess(const Request & request)39 void AbilityMgrHandler::ServiceMsgProcess(const Request &request)
40 {
41     switch (request.msgId) {
42         case AMS_SERVICE_INITED: {
43             OnServiceInited();
44             break;
45         }
46         case AMS_START_ABILITY: {
47             Want *want = reinterpret_cast<Want *>(request.data);
48             pid_t uid = request.msgValue;
49             int ret = StartAbility(want, uid);
50             StartAbilityCallback(want, ret);
51             ClearWant(want);
52             delete want;
53             break;
54         }
55         case AMS_TERMINATE_ABILITY: {
56             TerminateAbility(reinterpret_cast<uint64_t *>(request.data));
57             break;
58         }
59         case AMS_ATTACH_BUNDLE: {
60             AttachBundle(reinterpret_cast<AbilityThreadClient *>(request.data));
61             break;
62         }
63         case AMS_TRANSACTION_DONE: {
64             AbilityTransaction(reinterpret_cast<TransactionState *>(request.data));
65             break;
66         }
67         case AMS_CONNECT_ABILITY: {
68             auto transParam = reinterpret_cast<AbilityConnectTransParam *>(request.data);
69             int ret = ConnectAbility(transParam);
70             ConnectAbilityCallback(transParam, ret);
71             delete transParam;
72             break;
73         }
74         case AMS_CONNECT_ABILITY_DONE: {
75             auto transParam = reinterpret_cast<AbilityConnectTransParam *>(request.data);
76             ConnectAbilityDone(transParam);
77             delete transParam;
78             break;
79         }
80         case AMS_DISCONNECT_ABILITY: {
81             auto transParam = reinterpret_cast<AbilityConnectTransParam *>(request.data);
82             DisconnectAbility(transParam);
83             delete transParam;
84             break;
85         }
86         case AMS_DISCONNECT_ABILITY_DONE: {
87             DisconnectAbilityDone(reinterpret_cast<uint64_t *>(request.data));
88             break;
89         }
90         case AMS_TERMINATE_SERVICE: {
91             Want *want = reinterpret_cast<Want *>(request.data);
92             pid_t uid = request.msgValue;
93             TerminateService(want, uid);
94             ClearWant(want);
95             delete want;
96             break;
97         }
98         case AMS_TERMINATE_APP: {
99             char *bundleName = reinterpret_cast<char *>(request.data);
100             TerminateApp(bundleName);
101             AdapterFree(bundleName);
102             break;
103         }
104         case AMS_DUMP_ABILITY: {
105             DumpAbility(reinterpret_cast<AbilityDumpClient *>(request.data));
106             break;
107         }
108         case AMS_RESTART_APP: {
109             char *bundleName = reinterpret_cast<char *>(request.data);
110             RestartApp(bundleName);
111             AdapterFree(bundleName);
112             break;
113         }
114         default: {
115             PRINTI("AbilityMgrHandler", "unknown msgId");
116             break;
117         }
118     }
119 }
120 
OnServiceInited()121 void AbilityMgrHandler::OnServiceInited()
122 {
123     PRINTD("AbilityMgrHandler", "start");
124     StartKeepAliveApps();
125 }
126 
StartKeepAliveApps()127 void AbilityMgrHandler::StartKeepAliveApps()
128 {
129     int32_t len = 0;
130     BundleInfo *bundleInfos = nullptr;
131     AbilityMsStatus status = bundleMsClient_.QueryKeepAliveBundleInfos(&bundleInfos, &len);
132     CHECK_RESULT_LOG(status);
133     CHECK_NULLPTR_RETURN(bundleInfos, "AbilityMgrHandler", "bundleInfos is nullptr");
134 #ifdef ABILITY_WINDOW_SUPPORT
135     if (len > 0) {
136         // Start keep-alive apps until wms is ready.
137         WMSClient::WaitUntilWmsReady();
138     }
139 #endif
140     for (int32_t i = 0; i < len; ++i) {
141         if (AbilityMsHelper::IsLauncherAbility(bundleInfos[i].bundleName)) {
142 #ifdef ABILITY_WINDOW_SUPPORT
143             StartLauncher();
144 #endif
145         } else {
146             StartKeepAliveApp(bundleInfos[i]);
147         }
148     }
149     for (int32_t i = 0; i < len; ++i) {
150         ClearBundleInfo(&(bundleInfos[i]));
151     }
152     AdapterFree(bundleInfos);
153 }
154 
StartKeepAliveApp(const BundleInfo & bundleInfo)155 void AbilityMgrHandler::StartKeepAliveApp(const BundleInfo &bundleInfo)
156 {
157     PRINTD("AbilityMgrHandler", "start");
158     Want want = {};
159     AbilityMsStatus status = AbilityMsHelper::SetKeepAliveWant(bundleInfo, want);
160     CHECK_RESULT_LOG(status);
161     StartAbility(&want, AbilityMsHelper::SYSTEM_UID);
162     ClearWant(&want);
163 }
164 
StartLauncher()165 void AbilityMgrHandler::StartLauncher()
166 {
167     PRINTD("AbilityMgrHandler", "start");
168     // Create Launcher Want,
169     Want want = {};
170     AbilityMsStatus status = AbilityMsHelper::SetLauncherWant(want);
171     CHECK_RESULT_LOG(status);
172 
173     StartAbility(&want, AbilityMsHelper::SYSTEM_UID);
174     ClearWant(&want);
175 }
176 
StartAbility(const Want * want,pid_t callingUid)177 int AbilityMgrHandler::StartAbility(const Want *want, pid_t callingUid)
178 {
179     PRINTD("AbilityMgrHandler", "start");
180     CHECK_NULLPTR_RETURN_CODE(want, "AbilityMgrHandler", "invalid argument", EC_FAILURE);
181     CHECK_NULLPTR_RETURN_CODE(want->element, "AbilityMgrHandler", "invalid argument", EC_FAILURE);
182 
183     // Query BundleInfo note: bundleInfo not need clear
184     BundleInfo bundleInfo = {};
185     AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(want->element->bundleName, &bundleInfo);
186     CHECK_RESULT_LOG_CODE(status, EC_INVALID);
187 
188     // Query AbilityInfo
189     AbilityInfo target = {};
190     status = bundleMsClient_.QueryAbilityInfo(want, &target);
191     CHECK_RESULT_LOG_CODE(status, EC_INVALID);
192 
193     status = abilityWorker_.StartAbility(*want, target, bundleInfo, callingUid);
194     ClearAbilityInfo(&target);
195     CHECK_RESULT_LOG_CODE(status, EC_COMMU);
196 
197     return EC_SUCCESS;
198 }
199 
AttachBundle(AbilityThreadClient * client)200 void AbilityMgrHandler::AttachBundle(AbilityThreadClient *client)
201 {
202     PRINTD("AbilityMgrHandler", "start");
203     CHECK_NULLPTR_RETURN(client, "AbilityMgrHandler", "invalid argument");
204     AbilityMsStatus status = abilityWorker_.AttachBundle(*client);
205     delete client;
206     CHECK_RESULT_LOG(status);
207 }
208 
TerminateAbility(const uint64_t * token)209 void AbilityMgrHandler::TerminateAbility(const uint64_t *token)
210 {
211     PRINTD("AbilityMgrHandler", "start");
212     CHECK_NULLPTR_RETURN(token, "AbilityMgrHandler", "invalid argument");
213     AbilityMsStatus status = abilityWorker_.TerminateAbility(*token);
214     delete token;
215     CHECK_RESULT_LOG(status);
216 }
217 
AbilityTransaction(TransactionState * state)218 void AbilityMgrHandler::AbilityTransaction(TransactionState *state)
219 {
220     PRINTD("AbilityMgrHandler", "start");
221     CHECK_NULLPTR_RETURN(state, "AbilityMgrHandler", "invalid argument");
222     AbilityMsStatus status = abilityWorker_.AbilityTransaction(*state);
223     delete state;
224     if (status.IsNoActiveAbility()) {
225         status.LogStatus();
226         StartLauncher();
227     } else {
228         CHECK_RESULT_LOG(status);
229     }
230 }
231 
TerminateApp(const char * bundleName)232 void AbilityMgrHandler::TerminateApp(const char *bundleName)
233 {
234     PRINTD("AbilityMgrHandler", "start");
235     CHECK_NULLPTR_RETURN(bundleName, "AbilityMgrHandler", "invalid argument");
236     AbilityMsStatus status = abilityWorker_.TerminateApp(bundleName);
237     CHECK_RESULT_LOG(status);
238 }
239 
RestartApp(const char * bundleName)240 void AbilityMgrHandler::RestartApp(const char *bundleName)
241 {
242     PRINTD("AbilityMgrHandler", "start %{public}s", bundleName);
243     CHECK_NULLPTR_RETURN(bundleName, "AbilityMgrHandler", "invalid argument");
244     // Query BundleInfo
245     BundleInfo bundleInfo = {};
246     AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(bundleName, &bundleInfo);
247     if (!status.IsOk()) {
248         status.LogStatus();
249         return;
250     }
251     status = abilityWorker_.RestartApp(bundleInfo);
252     if (status.IsNoActiveAbility()) {
253         status.LogStatus();
254         StartLauncher();
255     }
256     if (!AbilityMsHelper::IsLauncherAbility(bundleInfo.bundleName) && bundleInfo.isSystemApp
257         && bundleInfo.isKeepAlive) {
258         StartKeepAliveApp(bundleInfo);
259     }
260     CHECK_RESULT_LOG(status);
261 }
262 
ConnectAbility(AbilityConnectTransParam * transParam)263 int AbilityMgrHandler::ConnectAbility(AbilityConnectTransParam *transParam)
264 {
265     PRINTD("AbilityMgrHandler", "connect");
266     CHECK_NULLPTR_RETURN_CODE(transParam, "AbilityMgrHandler", "invalid argument", EC_FAILURE);
267     const Want *want = transParam->GetWant();
268     CHECK_NULLPTR_RETURN_CODE(want, "AbilityMgrHandler", "invalid argument", EC_FAILURE);
269     CHECK_NULLPTR_RETURN_CODE(want->element, "AbilityMgrHandler", "invalid argument", EC_FAILURE);
270     // Query BundleInfo note: bundleInfo not need clear
271     BundleInfo bundleInfo = {};
272     AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(want->element->bundleName, &bundleInfo);
273     CHECK_RESULT_LOG_CODE(status, EC_INVALID);
274 
275     // Query AbilityInfo
276     AbilityInfo target = {};
277     status = bundleMsClient_.QueryAbilityInfo(want, &target);
278     CHECK_RESULT_LOG_CODE(status, EC_INVALID);
279 
280     status = abilityWorker_.ConnectAbility(*transParam, target, bundleInfo);
281     ClearAbilityInfo(&target);
282     CHECK_RESULT_LOG_CODE(status, EC_COMMU);
283     return EC_SUCCESS;
284 }
285 
DisconnectAbility(AbilityConnectTransParam * transParam)286 void AbilityMgrHandler::DisconnectAbility(AbilityConnectTransParam *transParam)
287 {
288     PRINTD("AbilityMgrHandler", "disconnect");
289     CHECK_NULLPTR_RETURN(transParam, "AbilityMgrHandler", "invalid argument");
290     const SvcIdentity sid = transParam->GetSvcIdentity();
291     uint64_t token = transParam->GetToken();
292     AbilityMsStatus status = abilityWorker_.DisconnectAbility(sid, token);
293     CHECK_RESULT_LOG(status);
294 }
295 
ConnectAbilityDone(AbilityConnectTransParam * transParam)296 void AbilityMgrHandler::ConnectAbilityDone(AbilityConnectTransParam *transParam)
297 {
298     PRINTD("AbilityMgrHandler", "connectDone");
299     CHECK_NULLPTR_RETURN(transParam, "AbilityMgrHandler", "invalid argument");
300     const SvcIdentity sid = transParam->GetSvcIdentity();
301     uint64_t token = transParam->GetToken();
302     AbilityMsStatus status = abilityWorker_.ConnectAbilityDone(sid, token);
303     CHECK_RESULT_LOG(status);
304 }
305 
DisconnectAbilityDone(const uint64_t * token)306 void AbilityMgrHandler::DisconnectAbilityDone(const uint64_t *token)
307 {
308     PRINTD("AbilityMgrHandler", "disconnectDone");
309     CHECK_NULLPTR_RETURN(token, "AbilityMgrHandler", "invalid argument: token");
310     AbilityMsStatus status = abilityWorker_.DisconnectAbilityDone(*token);
311     delete token;
312     CHECK_RESULT_LOG(status);
313 }
314 
TerminateService(Want * want,pid_t callingUid)315 void AbilityMgrHandler::TerminateService(Want *want, pid_t callingUid)
316 {
317     PRINTD("AbilityMgrHandler", "terminateService");
318     CHECK_NULLPTR_RETURN(want, "AbilityMgrHandler", "invalid argument");
319     CHECK_NULLPTR_RETURN(want->element, "AbilityMgrHandler", "invalid argument");
320 
321     // Query BundleInfo note: bundleInfo not need clear
322     BundleInfo bundleInfo = {};
323     AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(want->element->bundleName, &bundleInfo);
324     CHECK_RESULT_LOG(status);
325 
326     // Query AbilityInfo
327     AbilityInfo target = {};
328     status = bundleMsClient_.QueryAbilityInfo(want, &target);
329     CHECK_RESULT_LOG(status);
330     status = abilityWorker_.TerminateService(target, bundleInfo, callingUid);
331     ClearAbilityInfo(&target);
332     CHECK_RESULT_LOG(status);
333 }
334 
StartAbilityCallback(const Want * want,int code)335 void AbilityMgrHandler::StartAbilityCallback(const Want *want, int code)
336 {
337     if ((want == nullptr) || (want->sid == nullptr) || (code == EC_SUCCESS)) {
338         return;
339     }
340     PRINTI("AbilityMgrHandler", "start ability failed callback");
341     IpcIo io;
342     char data[MAX_IO_SIZE];
343     IpcIoInit(&io, data, MAX_IO_SIZE, 0);
344     if (!SerializeElement(&io, want->element)) {
345         return;
346     }
347     WriteInt32(&io, code);
348     MessageOption option;
349     MessageOptionInit(&option);
350     option.flags = TF_OP_ASYNC;
351     if (SendRequest(*(want->sid), SCHEDULER_APP_INIT, &io, nullptr, option, nullptr) != ERR_NONE) {
352         PRINTE("AbilityMgrHandler", "start ability callback failed, ipc error");
353     }
354 }
355 
DumpAbility(const AbilityDumpClient * client)356 void AbilityMgrHandler::DumpAbility(const AbilityDumpClient *client)
357 {
358     PRINTD("AbilityMgrHandler", "start");
359     CHECK_NULLPTR_RETURN(client, "AbilityMgrHandler", "invalid argument");
360     AbilityMsStatus status = abilityWorker_.DumpAbility(*client);
361     ReleaseSvc(*(client->GetWant().sid));
362     delete client;
363     CHECK_RESULT_LOG(status);
364 }
365 
ConnectAbilityCallback(AbilityConnectTransParam * transParam,int code)366 void AbilityMgrHandler::ConnectAbilityCallback(AbilityConnectTransParam *transParam, int code)
367 {
368     if (transParam == nullptr || code == EC_SUCCESS) {
369         return;
370     }
371     PRINTI("AbilityMgrHandler", "connect ability failed");
372     MessageOption option;
373     MessageOptionInit(&option);
374     option.flags = TF_OP_ASYNC;
375     if (SendRequest(transParam->GetSvcIdentity(), SCHEDULER_ABILITY_CONNECT_FAIL, nullptr, nullptr,
376         option, nullptr) != ERR_NONE) {
377         PRINTE("AbilityMgrHandler", "connect ability callback failed, ipc error");
378     }
379     ReleaseSvc(transParam->GetSvcIdentity());
380 }
381 }  // namespace OHOS
382