1 /*
2 * Copyright (c) 2021 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 "abilityms_slite_client.h"
17
18 #include "ability_errors.h"
19 #include "abilityms_log.h"
20 #include "adapter.h"
21 #include "cmsis_os2.h"
22 #include "los_task.h"
23 #include "samgr_lite.h"
24 #include "securec.h"
25 #include "want.h"
26 #include "utils.h"
27
28 namespace OHOS {
29 namespace AbilitySlite {
Initialize() const30 bool AbilityMsClient::Initialize() const
31 {
32 if (amsProxy_ != nullptr) {
33 return true;
34 }
35 int retry = RETRY_TIMES;
36 while (retry--) {
37 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_SLITE_FEATURE);
38 if (iUnknown == nullptr) {
39 HILOG_ERROR(HILOG_MODULE_APP, "iUnknown is null");
40 osDelay(ERROR_SLEEP_TIMES); // sleep 300ms
41 continue;
42 }
43
44 (void)iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&amsProxy_);
45 if (amsProxy_ == nullptr) {
46 HILOG_ERROR(HILOG_MODULE_APP, "ams proxy is null");
47 osDelay(ERROR_SLEEP_TIMES); // sleep 300ms
48 continue;
49 }
50 return true;
51 }
52 return false;
53 }
54
SendRequestToAms(Request & request) const55 int32_t AbilityMsClient::SendRequestToAms(Request &request) const
56 {
57 int32_t retry = RETRY_TIMES;
58 while (retry--) {
59 int32_t ret = SAMGR_SendRequest(identity_, &request, nullptr);
60 if (ret == EC_SUCCESS) {
61 return ERR_OK;
62 }
63 HILOG_WARN(HILOG_MODULE_APP, "SendRequestToAms SAMGR_SendRequest failed with %{public}d", ret);
64 osDelay(ERROR_SLEEP_TIMES); // sleep 300ms
65 }
66 HILOG_ERROR(HILOG_MODULE_APP, "SendRequestToAms failed.");
67 return IPC_REQUEST_ERROR;
68 }
69
StartAbility(const Want * want) const70 int32_t AbilityMsClient::StartAbility(const Want *want) const
71 {
72 if (want == nullptr || want->element == nullptr || !Initialize()) {
73 return PARAM_CHECK_ERROR;
74 }
75
76 if (identity_ == nullptr) {
77 return PARAM_CHECK_ERROR;
78 }
79
80 // The data and info will be freed in the service
81 auto *data = static_cast<StartAbilityData *>(AdapterMalloc(sizeof(StartAbilityData)));
82 if (data == nullptr) {
83 return MEMORY_MALLOC_ERROR;
84 }
85 Want *info = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
86 if (info == nullptr) {
87 return MEMORY_MALLOC_ERROR;
88 }
89 info->element = nullptr;
90 info->data = nullptr;
91 info->dataLength = 0;
92 info->appPath = nullptr;
93 info->mission = want->mission;
94 info->actions = nullptr;
95 info->entities = nullptr;
96 SetWantElement(info, *(want->element));
97 if (want->data != nullptr) {
98 HILOG_INFO(HILOG_MODULE_APP, "start ability with input data");
99 SetWantData(info, want->data, want->dataLength);
100 } else {
101 SetWantData(info, nullptr, 0);
102 HILOG_INFO(HILOG_MODULE_APP, "start ability with no data");
103 }
104 data->want = info;
105 data->curTask = LOS_CurTaskIDGet();
106 Request request = {
107 .msgId = START_ABILITY,
108 .len = sizeof(StartAbilityData),
109 .data = data,
110 .msgValue = 0,
111 };
112 return SendRequestToAms(request);
113 }
114
TerminateAbility(uint64_t token) const115 int32_t AbilityMsClient::TerminateAbility(uint64_t token) const
116 {
117 if (identity_ == nullptr) {
118 return PARAM_CHECK_ERROR;
119 }
120 Request request = {
121 .msgId = TERMINATE_ABILITY,
122 .len = 0,
123 .data = nullptr,
124 .msgValue = static_cast<uint32_t>(token & TRANSACTION_MSG_TOKEN_MASK),
125 };
126 return SendRequestToAms(request);
127 }
128
TerminateMission(uint32_t mission) const129 int32_t AbilityMsClient::TerminateMission(uint32_t mission) const
130 {
131 Request request = {
132 .msgId = TERMINATE_MISSION,
133 .len = 0,
134 .data = nullptr,
135 .msgValue = mission,
136 };
137 return SendRequestToAms(request);
138 }
139
TerminateAll(const char * excludedBundleName) const140 int32_t AbilityMsClient::TerminateAll(const char* excludedBundleName) const
141 {
142 if (identity_ == nullptr) {
143 return PARAM_CHECK_ERROR;
144 }
145 void *data = nullptr;
146 if (excludedBundleName != nullptr) {
147 data = Utils::Strdup(excludedBundleName);
148 }
149 Request request = {
150 .msgId = TERMINATE_ALL,
151 .len = 0,
152 .data = data,
153 .msgValue = 0,
154 };
155 return SendRequestToAms(request);
156 }
157
SchedulerLifecycleDone(uint64_t token,int32_t state) const158 int32_t AbilityMsClient::SchedulerLifecycleDone(uint64_t token, int32_t state) const
159 {
160 if (identity_ == nullptr) {
161 return PARAM_CHECK_ERROR;
162 }
163 Request request = {
164 .msgId = ABILITY_TRANSACTION_DONE,
165 .len = 0,
166 .data = nullptr,
167 .msgValue = static_cast<uint32_t>((token & TRANSACTION_MSG_TOKEN_MASK) |
168 (state << TRANSACTION_MSG_STATE_OFFSET)),
169 };
170 return SendRequestToAms(request);
171 }
172
ForceStopBundle(uint64_t token) const173 int32_t AbilityMsClient::ForceStopBundle(uint64_t token) const
174 {
175 if (identity_ == nullptr) {
176 return PARAM_CHECK_ERROR;
177 }
178 Request request = {
179 .msgId = TERMINATE_APP,
180 .len = 0,
181 .data = nullptr,
182 .msgValue = static_cast<uint32_t>(token & TRANSACTION_MSG_TOKEN_MASK),
183 };
184 return SendRequestToAms(request);
185 }
186
GetTopAbility() const187 ElementName *AbilityMsClient::GetTopAbility() const
188 {
189 if (!Initialize()) {
190 return nullptr;
191 }
192 return amsProxy_->GetTopAbility();
193 }
194
ForceStop(const char * bundleName) const195 int32_t AbilityMsClient::ForceStop(const char *bundleName) const
196 {
197 if (identity_ == nullptr) {
198 return PARAM_CHECK_ERROR;
199 }
200 Want *want = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
201 if (want == nullptr) {
202 return MEMORY_MALLOC_ERROR;
203 }
204 want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
205 if (want->element == nullptr) {
206 return MEMORY_MALLOC_ERROR;
207 }
208 HILOG_INFO(HILOG_MODULE_APP, "ForceStop with bundleName");
209 want->element->deviceId = nullptr;
210 want->element->bundleName = Utils::Strdup(bundleName);
211 want->element->abilityName = nullptr;
212 want->data = nullptr;
213 want->dataLength = 0;
214 want->appPath = nullptr;
215 want->actions = nullptr;
216 want->entities = nullptr;
217 SetWantData(want, nullptr, 0);
218 Request request = {
219 .msgId = TERMINATE_APP_BY_BUNDLENAME,
220 .len = sizeof(Want),
221 .data = want,
222 };
223 return SendRequestToAms(request);
224 }
225
ForceStop(const Want * want) const226 int32_t AbilityMsClient::ForceStop(const Want *want) const
227 {
228 if (identity_ == nullptr) {
229 return PARAM_CHECK_ERROR;
230 }
231 if (want == nullptr || want->element == nullptr || want->element->bundleName == nullptr) {
232 return PARAM_CHECK_ERROR;
233 }
234 Want *info = static_cast<Want *>(AdapterMalloc(sizeof(Want)));
235 if (info == nullptr) {
236 return MEMORY_MALLOC_ERROR;
237 }
238 info->element = nullptr;
239 info->data = nullptr;
240 info->dataLength = 0;
241 info->appPath = nullptr;
242 SetWantElement(info, *(want->element));
243 SetWantData(info, want->data, want->dataLength);
244 if (want->data != nullptr) {
245 HILOG_INFO(HILOG_MODULE_APP, "ForceStop with data");
246 } else {
247 HILOG_INFO(HILOG_MODULE_APP, "ForceStop with no data");
248 }
249 Request request = {
250 .msgId = TERMINATE_APP_BY_BUNDLENAME,
251 .len = sizeof(Want),
252 .data = info,
253 };
254 return SendRequestToAms(request);
255 }
256
AddAbilityRecordObserver(AbilityRecordObserver * observer)257 int32_t AbilityMsClient::AddAbilityRecordObserver(AbilityRecordObserver *observer)
258 {
259 if (identity_ == nullptr) {
260 return PARAM_CHECK_ERROR;
261 }
262 Request request = {
263 .msgId = ADD_ABILITY_RECORD_OBSERVER,
264 .len = 0,
265 .data = nullptr,
266 .msgValue = reinterpret_cast<uint32>(observer),
267 };
268
269 return SendRequestToAms(request);
270 }
271
RemoveAbilityRecordObserver(AbilityRecordObserver * observer)272 int32_t AbilityMsClient::RemoveAbilityRecordObserver(AbilityRecordObserver *observer)
273 {
274 if (identity_ == nullptr) {
275 return PARAM_CHECK_ERROR;
276 }
277 Request request = {
278 .msgId = REMOVE_ABILITY_RECORD_OBSERVER,
279 .len = 0,
280 .data = nullptr,
281 .msgValue = reinterpret_cast<uint32>(observer),
282 };
283
284 return SendRequestToAms(request);
285 }
286
GetMissionInfos(uint32_t maxNum) const287 MissionInfoList *AbilityMsClient::GetMissionInfos(uint32_t maxNum) const
288 {
289 if (!Initialize()) {
290 return nullptr;
291 }
292 return static_cast<MissionInfoList *>(amsProxy_->GetMissionInfos(maxNum));
293 }
294
SetServiceIdentity(const Identity * identity)295 void AbilityMsClient::SetServiceIdentity(const Identity *identity)
296 {
297 identity_ = identity;
298 }
299 } // namespace AbilitySlite
300 } // namespace OHOS
301