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