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 "client/ability_thread_client.h"
17
18 #define __STDC_FORMAT_MACROS
19 #include <cinttypes>
20
21 #include "ability_kit_command.h"
22 #include "adapter.h"
23 #include "app_manager.h"
24 #include "app_record.h"
25 #include "client/bundlems_client.h"
26 #include "element_name_utils.h"
27 #include "liteipc_adapter.h"
28 #include "securec.h"
29 #include "serializer.h"
30 #include "util/abilityms_helper.h"
31 #include "utils.h"
32 #include "want_utils.h"
33
34 namespace OHOS {
35 const int MAX_MODULE_SIZE = 16;
AbilityThreadClient(uint64_t token,pid_t pid,const SvcIdentity & svcIdentity,IpcMsgHandler handler)36 AbilityThreadClient::AbilityThreadClient(uint64_t token, pid_t pid, const SvcIdentity &svcIdentity,
37 IpcMsgHandler handler) : token_(token), pid_(pid), svcIdentity_(svcIdentity), deathHandler_(handler)
38 {
39 }
40
AbilityThreadClient(const AbilityThreadClient & client)41 AbilityThreadClient::AbilityThreadClient(const AbilityThreadClient &client)
42 : token_(client.token_), pid_(client.pid_), svcIdentity_(client.svcIdentity_), deathHandler_(client.deathHandler_)
43 {
44 }
45
~AbilityThreadClient()46 AbilityThreadClient::~AbilityThreadClient()
47 {
48 UnregisterDeathCallback(svcIdentity_, cbid_);
49 }
50
Initialize(const char * bundleName)51 AbilityMsStatus AbilityThreadClient::Initialize(const char *bundleName)
52 {
53 if (bundleName == nullptr) {
54 return AbilityMsStatus::AppTransanctStatus("bundleName is null");
55 }
56 AppInfo *appInfo = new AppInfo();
57 appInfo->bundleName = Utils::Strdup(bundleName);
58 if (appInfo->bundleName == nullptr) {
59 delete appInfo;
60 return AbilityMsStatus::AppTransanctStatus("memory alloc fail");
61 }
62 appInfo->svcIdentity = svcIdentity_;
63 if (RegisterDeathCallback(nullptr, svcIdentity_, deathHandler_, appInfo, &cbid_) != LITEIPC_OK) {
64 AdapterFree(appInfo->bundleName);
65 delete appInfo;
66 return AbilityMsStatus::AppTransanctStatus("register death callback ipc error");
67 }
68 PRINTD("AbilityThreadClient", "token(%{private}" PRIu64 ") bundleName(%{public}s) success",
69 token_, appInfo->bundleName);
70 return AbilityMsStatus::Ok();
71 }
72
GetToken() const73 uint64_t AbilityThreadClient::GetToken() const
74 {
75 return token_;
76 }
77
GetPid() const78 pid_t AbilityThreadClient::GetPid() const
79 {
80 return pid_;
81 }
82
GetSvcIdentity() const83 const SvcIdentity& AbilityThreadClient::GetSvcIdentity() const
84 {
85 return svcIdentity_;
86 }
87
AbilityTransaction(const TransactionState & state,const Want & want,AbilityType abilityType) const88 AbilityMsStatus AbilityThreadClient::AbilityTransaction(const TransactionState &state,
89 const Want &want, AbilityType abilityType) const
90 {
91 PRINTD("AbilityThreadClient", "start");
92 IpcIo req;
93 char data[IPC_IO_DATA_MAX];
94 IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS);
95 IpcIoPushInt32(&req, state.state);
96 IpcIoPushUint64(&req, state.token);
97 IpcIoPushInt32(&req, abilityType);
98 if (!SerializeWant(&req, &want)) {
99 return AbilityMsStatus::AppTransanctStatus("SerializeWant failed");
100 }
101 int32_t ret = Transact(nullptr, svcIdentity_, SCHEDULER_ABILITY_LIFECYCLE, &req,
102 nullptr, LITEIPC_FLAG_ONEWAY, nullptr);
103 if (ret != LITEIPC_OK) {
104 return AbilityMsStatus::AppTransanctStatus("lifecycle ipc error");
105 }
106 return AbilityMsStatus::Ok();
107 }
108
AppInitTransaction(const BundleInfo & bundleInfo)109 AbilityMsStatus AbilityThreadClient::AppInitTransaction(const BundleInfo &bundleInfo)
110 {
111 PRINTD("AbilityThreadClient", "start");
112 if (bundleInfo.bundleName == nullptr || bundleInfo.codePath == nullptr ||
113 bundleInfo.numOfModule > MAX_MODULE_SIZE) {
114 return AbilityMsStatus::AppTransanctStatus("app init invalid argument");
115 }
116 IpcIo req;
117 char data[IPC_IO_DATA_MAX];
118 IpcIoInit(&req, data, IPC_IO_DATA_MAX, 0);
119 IpcIoPushString(&req, bundleInfo.bundleName);
120 IpcIoPushString(&req, bundleInfo.codePath);
121 IpcIoPushString(&req, bundleInfo.dataPath);
122 IpcIoPushBool(&req, bundleInfo.isNativeApp);
123 // transact moduleName
124 IpcIoPushInt32(&req, bundleInfo.numOfModule);
125 for (int i = 0; i < bundleInfo.numOfModule; i++) {
126 if (bundleInfo.moduleInfos[i].moduleName != nullptr) {
127 IpcIoPushString(&req, bundleInfo.moduleInfos[i].moduleName);
128 }
129 }
130 IpcIo reply;
131 uintptr_t ptr;
132 if (Transact(nullptr, svcIdentity_, SCHEDULER_APP_INIT, &req,
133 &reply, LITEIPC_FLAG_DEFAULT, &ptr) != LITEIPC_OK) {
134 return AbilityMsStatus::AppTransanctStatus("app init ipc error");
135 }
136 FreeBuffer(nullptr, reinterpret_cast<void *>(ptr));
137 return AbilityMsStatus::Ok();
138 }
139
AppExitTransaction()140 AbilityMsStatus AbilityThreadClient::AppExitTransaction()
141 {
142 PRINTD("AbilityThreadClient", "start");
143 if (Transact(nullptr, svcIdentity_, SCHEDULER_APP_EXIT, nullptr,
144 nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) {
145 return AbilityMsStatus::AppTransanctStatus("app exit ipc error");
146 }
147 return AbilityMsStatus::Ok();
148 }
149
ConnectAbility(const Want & want,uint64_t token) const150 AbilityMsStatus AbilityThreadClient::ConnectAbility(const Want &want, uint64_t token) const
151 {
152 PRINTD("AbilityThreadClient", "connect");
153 IpcIo req;
154 char data[IPC_IO_DATA_MAX];
155 IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS);
156 IpcIoPushUint64(&req, token);
157 if (!SerializeWant(&req, &want)) {
158 return AbilityMsStatus::TaskStatus("connectAbility", "SerializeWant failed");
159 }
160 if (Transact(nullptr, svcIdentity_, SCHEDULER_ABILITY_CONNECT, &req,
161 nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) {
162 return AbilityMsStatus::TaskStatus("connectAbility", "connectAbility exit ipc error");
163 }
164 return AbilityMsStatus::Ok();
165 }
166
DisconnectAbility(const Want & want,uint64_t token) const167 AbilityMsStatus AbilityThreadClient::DisconnectAbility(const Want &want, uint64_t token) const
168 {
169 PRINTD("AbilityThreadClient", "disconnect");
170 IpcIo req;
171 char data[IPC_IO_DATA_MAX];
172 IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS);
173 IpcIoPushUint64(&req, token);
174 if (!SerializeWant(&req, &want)) {
175 return AbilityMsStatus::TaskStatus("disconnectAbility", "SerializeWant failed");
176 }
177 if (Transact(nullptr, svcIdentity_, SCHEDULER_ABILITY_DISCONNECT, &req, nullptr,
178 LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) {
179 return AbilityMsStatus::TaskStatus("disconnectAbility", "disconnectAbility exit ipc error");
180 }
181 return AbilityMsStatus::Ok();
182 }
183
ConnectAbilityDone(const Want & want,const SvcIdentity & serviceSid,const SvcIdentity & connectSid) const184 AbilityMsStatus AbilityThreadClient::ConnectAbilityDone(const Want &want, const SvcIdentity &serviceSid,
185 const SvcIdentity &connectSid) const
186 {
187 PRINTD("AbilityThreadClient", "connectDone");
188 IpcIo req;
189 char data[IPC_IO_DATA_MAX];
190 IpcIoInit(&req, data, IPC_IO_DATA_MAX, 1);
191 IpcIoPushSvc(&req, &serviceSid);
192 if (!SerializeElement(&req, want.element)) {
193 return AbilityMsStatus::TaskStatus("connectAbilityDone", "SerializeElement failed");
194 }
195
196 if (Transact(nullptr, connectSid, SCHEDULER_ABILITY_CONNECT, &req, nullptr,
197 LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) {
198 return AbilityMsStatus::TaskStatus("connectAbilityDone", "connectAbilityDone ipc error");
199 }
200 return AbilityMsStatus::Ok();
201 }
202
DisconnectAbilityDone(const Want & want,const SvcIdentity & connectSid) const203 AbilityMsStatus AbilityThreadClient::DisconnectAbilityDone(const Want &want, const SvcIdentity &connectSid) const
204 {
205 PRINTD("AbilityThreadClient", "disconnectDone");
206 IpcIo req;
207 char data[IPC_IO_DATA_MAX];
208 IpcIoInit(&req, data, IPC_IO_DATA_MAX, 0);
209 if (!SerializeElement(&req, want.element)) {
210 return AbilityMsStatus::TaskStatus("DisconnectAbilityDone", "SerializeElement failed");
211 }
212
213 if (Transact(nullptr, connectSid, SCHEDULER_ABILITY_DISCONNECT, &req,
214 nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) {
215 #ifdef __LINUX__
216 BinderRelease(connectSid.ipcContext, connectSid.handle);
217 #endif
218 return AbilityMsStatus::TaskStatus("disconnectAbilityDone", "disconnectAbilityDone ipc error");
219 }
220 #ifdef __LINUX__
221 BinderRelease(connectSid.ipcContext, connectSid.handle);
222 #endif
223 return AbilityMsStatus::Ok();
224 }
225
DumpAbilityTransaction(const Want & want,uint64_t token)226 AbilityMsStatus AbilityThreadClient::DumpAbilityTransaction(const Want &want, uint64_t token)
227 {
228 PRINTD("AbilityThreadClient", "start");
229 IpcIo req;
230 char data[IPC_IO_DATA_MAX];
231 IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS);
232 if (!SerializeWant(&req, &want)) {
233 return AbilityMsStatus::TaskStatus("dumpAbility", "SerializeWant failed");
234 }
235 IpcIoPushUint64(&req, token);
236 if (Transact(nullptr, svcIdentity_, SCHEDULER_DUMP_ABILITY, &req,
237 nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) {
238 return AbilityMsStatus::AppTransanctStatus("dump ability ipc error");
239 }
240 return AbilityMsStatus::Ok();
241 }
242 }
243