• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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