1 /*
2 * Copyright (c) 2024 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 "cj_ability_context_object.h"
17
18 #include <regex>
19
20 #include "ability_business_error.h"
21 #include "accesstoken_kit.h"
22 #include "cj_ability_connect_callback_object.h"
23 #include "cj_ability_context.h"
24 #include "cj_common_ffi.h"
25 #include "cj_lambda.h"
26 #include "cj_utils_ffi.h"
27 #include "ffi_remote_data.h"
28 #include "hilog_tag_wrapper.h"
29 #include "js_ability_context.h"
30 #include "js_native_api.h"
31 #include "js_runtime_utils.h"
32 #include "napi_common_start_options.h"
33 #include "napi_common_util.h"
34 #include "open_link_options.h"
35 #include "pixel_map.h"
36 #include "process_options.h"
37 #include "uri.h"
38
39 using namespace OHOS::FFI;
40
41 namespace OHOS {
42 namespace AbilityRuntime {
43 namespace {
44 constexpr int64_t NOT_SUPPORT = 1;
45 // max request code is (1 << 49) - 1
46 constexpr int64_t MAX_REQUEST_CODE = 562949953421311;
47 constexpr size_t MAX_REQUEST_CODE_LENGTH = 15;
48 constexpr int32_t BASE_REQUEST_CODE_NUM = 10;
49 // g_cjAbilityCallbacks is used to save cangjie functions.
50 // It is assigned by the global variable REGISTER_ABILITY_CONTEXT_CALLBACK on the cangjie side which invokes
51 // RegisterCJAbilityCallbacks. And it is never released.
52 CJAbilityCallbacks* g_cjAbilityCallbacks = nullptr;
53 const std::string ATOMIC_SERVICE_PREFIX = "com.atomicservice.";
54 const std::string APP_LINKING_ONLY = "appLinkingOnly";
55
56 const char* CJ_ABILITY_LIBNAME = "libcj_ability_ffi.z.so";
57 const char* FUNC_CONVERT_CONFIGURATION = "OHOS_ConvertConfiguration";
58 const char* CJ_BUNDLE_MGR_LIBNAME = "libcj_bundle_manager_ffi.z.so";
59 const char* FUNC_CONVERT_ABILITY_INFO = "OHOS_ConvertAbilityInfoV2";
60 const char* FUNC_CONVERT_HAP_INFO = "OHOS_ConvertHapInfoV2";
61 } // namespace
62
RequestCodeFromStringToInt64(const std::string & requestCode)63 int64_t RequestCodeFromStringToInt64(const std::string& requestCode)
64 {
65 if (requestCode.size() > MAX_REQUEST_CODE_LENGTH) {
66 TAG_LOGW(AAFwkTag::CONTEXT, "requestCode too long: %{public}s", requestCode.c_str());
67 return 0;
68 }
69 std::regex formatRegex("^[1-9]\\d*|0$");
70 std::smatch sm;
71 if (!std::regex_match(requestCode, sm, formatRegex)) {
72 TAG_LOGW(AAFwkTag::CONTEXT, "requestCode match failed: %{public}s", requestCode.c_str());
73 return 0;
74 }
75 int64_t parsedRequestCode = 0;
76 parsedRequestCode = strtoll(requestCode.c_str(), nullptr, BASE_REQUEST_CODE_NUM);
77 if (parsedRequestCode > MAX_REQUEST_CODE) {
78 TAG_LOGW(AAFwkTag::CONTEXT, "requestCode too large: %{public}s", requestCode.c_str());
79 return 0;
80 }
81 return parsedRequestCode;
82 }
83
UnWrapStartOption(CJStartOptions * source,AAFwk::StartOptions & target)84 void UnWrapStartOption(CJStartOptions* source, AAFwk::StartOptions& target)
85 {
86 if (source == nullptr) {
87 TAG_LOGE(AAFwkTag::CONTEXT, "null source");
88 return;
89 }
90 target.SetWindowMode(source->windowMode);
91 target.SetDisplayID(source->displayId);
92 }
93
UnWrapStartOptions(CJNewStartOptions source,AAFwk::StartOptions & target)94 void UnWrapStartOptions(CJNewStartOptions source, AAFwk::StartOptions& target)
95 {
96 target.SetWindowMode(source.windowMode);
97 target.SetDisplayID(source.displayId);
98 target.SetWithAnimation(source.withAnimation);
99 target.SetWindowLeft(source.windowLeft);
100 target.SetWindowTop(source.windowTop);
101 target.SetWindowWidth(source.windowWidth);
102 target.SetWindowHeight(source.windowHeight);
103 }
104
UnWrapProcessOptions(CJNewStartOptions source,std::shared_ptr<AAFwk::ProcessOptions> & processOptions)105 void UnWrapProcessOptions(CJNewStartOptions source, std::shared_ptr<AAFwk::ProcessOptions> &processOptions)
106 {
107 auto option = std::make_shared<AAFwk::ProcessOptions>();
108 option->processMode = AAFwk::ProcessOptions::ConvertInt32ToProcessMode(source.processMode);
109 option->startupVisibility = AAFwk::ProcessOptions::ConvertInt32ToStartupVisibility(source.startupVisibility);
110 processOptions = option;
111 }
112
WrapCJAbilityResultTask(int64_t lambdaId)113 std::function<void(int32_t, CJAbilityResult*)> WrapCJAbilityResultTask(int64_t lambdaId)
114 {
115 auto cjTask = [lambdaId](int32_t error, CJAbilityResult* abilityResult) {
116 if (g_cjAbilityCallbacks == nullptr) {
117 TAG_LOGE(AAFwkTag::CONTEXT, "null g_cjAbilityCallbacks");
118 return;
119 }
120 g_cjAbilityCallbacks->invokeAbilityResultCallback(lambdaId, error, abilityResult);
121 TAG_LOGD(AAFwkTag::CONTEXT, "error: %{public}d", error);
122 };
123 return cjTask;
124 }
125
WrapRuntimeTask(std::function<void (int32_t,CJAbilityResult *)> cjTask,int32_t error)126 RuntimeTask WrapRuntimeTask(std::function<void(int32_t, CJAbilityResult*)> cjTask, int32_t error)
127 {
128 RuntimeTask task = [cjTask, error](int32_t resultCode, const AAFwk::Want& want, bool isInner) {
129 WantHandle wantHandle = const_cast<AAFwk::Want*>(&want);
130 CJAbilityResult abilityResult = { resultCode, wantHandle };
131 cjTask(error, &abilityResult);
132 TAG_LOGD(AAFwkTag::CONTEXT, "error: %{public}d", error);
133 };
134 return task;
135 }
136
CheckUrl(std::string & urlValue)137 static bool CheckUrl(std::string& urlValue)
138 {
139 if (urlValue.empty()) {
140 return false;
141 }
142 Uri uri = Uri(urlValue);
143 if (uri.GetScheme().empty() || uri.GetHost().empty()) {
144 return false;
145 }
146
147 return true;
148 }
149
150 extern "C" {
RegisterCJAbilityCallbacks(void (* registerFunc)(CJAbilityCallbacks *))151 void RegisterCJAbilityCallbacks(void (*registerFunc)(CJAbilityCallbacks*))
152 {
153 if (g_cjAbilityCallbacks != nullptr) {
154 TAG_LOGE(AAFwkTag::CONTEXT, "null g_cjAbilityCallbacks");
155 return;
156 }
157
158 if (registerFunc == nullptr) {
159 TAG_LOGE(AAFwkTag::CONTEXT, "null registerFunc");
160 return;
161 }
162
163 g_cjAbilityCallbacks = new CJAbilityCallbacks();
164 registerFunc(g_cjAbilityCallbacks);
165 }
166
FFIAbilityContextIsAbilityContextExisted(int64_t id)167 bool FFIAbilityContextIsAbilityContextExisted(int64_t id)
168 {
169 return FFIData::GetData<CJAbilityContext>(id) != nullptr;
170 }
171
FFIAbilityContextGetSizeOfStartOptions()172 int64_t FFIAbilityContextGetSizeOfStartOptions()
173 {
174 return sizeof(CJStartOptions);
175 }
176
FFIAbilityContextGetAbilityInfo(int64_t id)177 int64_t FFIAbilityContextGetAbilityInfo(int64_t id)
178 {
179 auto context = FFIData::GetData<CJAbilityContext>(id);
180 if (context == nullptr) {
181 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
182 return INVALID_DATA_ID;
183 }
184 return NOT_SUPPORT;
185 }
186
FFIAbilityContextGetHapModuleInfo(int64_t id)187 int64_t FFIAbilityContextGetHapModuleInfo(int64_t id)
188 {
189 auto context = FFIData::GetData<CJAbilityContext>(id);
190 if (context == nullptr) {
191 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
192 return INVALID_DATA_ID;
193 }
194 auto hapModuleInfo = context->GetHapModuleInfo();
195 return NOT_SUPPORT;
196 }
197
FFIAbilityContextGetConfiguration(int64_t id)198 int64_t FFIAbilityContextGetConfiguration(int64_t id)
199 {
200 auto context = FFIData::GetData<CJAbilityContext>(id);
201 if (context == nullptr) {
202 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
203 return INVALID_DATA_ID;
204 }
205 auto configuration = context->GetConfiguration();
206 return NOT_SUPPORT;
207 }
208
FFIAbilityContextStartAbility(int64_t id,WantHandle want)209 int32_t FFIAbilityContextStartAbility(int64_t id, WantHandle want)
210 {
211 auto context = FFIData::GetData<CJAbilityContext>(id);
212 if (context == nullptr) {
213 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
214 return ERR_INVALID_INSTANCE_CODE;
215 }
216
217 auto actualWant = reinterpret_cast<Want*>(want);
218 context->InheritWindowMode(*actualWant);
219 return context->StartAbility(*actualWant);
220 }
221
FFIAbilityContextStartAbilityWithOption(int64_t id,WantHandle want,CJStartOptions * startOption)222 int32_t FFIAbilityContextStartAbilityWithOption(int64_t id, WantHandle want, CJStartOptions* startOption)
223 {
224 auto context = FFIData::GetData<CJAbilityContext>(id);
225 if (context == nullptr) {
226 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
227 return ERR_INVALID_INSTANCE_CODE;
228 }
229 auto actualWant = reinterpret_cast<Want*>(want);
230 context->InheritWindowMode(*actualWant);
231 AAFwk::StartOptions option;
232 UnWrapStartOption(startOption, option);
233 return context->StartAbility(*actualWant, option);
234 }
235
FFIAbilityContextStartAbilityWithOptions(int64_t id,WantHandle want,CJNewStartOptions startOption)236 int32_t FFIAbilityContextStartAbilityWithOptions(int64_t id, WantHandle want, CJNewStartOptions startOption)
237 {
238 auto context = FFIData::GetData<CJAbilityContext>(id);
239 if (context == nullptr) {
240 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
241 return ERR_INVALID_INSTANCE_CODE;
242 }
243 auto actualWant = reinterpret_cast<Want*>(want);
244 context->InheritWindowMode(*actualWant);
245 AAFwk::StartOptions option;
246 UnWrapStartOptions(startOption, option);
247 UnWrapProcessOptions(startOption, option.processOptions);
248 return context->StartAbility(*actualWant, option);
249 }
250
FFIAbilityContextStartAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId)251 int32_t FFIAbilityContextStartAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId)
252 {
253 auto context = FFIData::GetData<CJAbilityContext>(id);
254 if (context == nullptr) {
255 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
256 return ERR_INVALID_INSTANCE_CODE;
257 }
258 auto actualWant = reinterpret_cast<Want*>(want);
259 context->InheritWindowMode(*actualWant);
260 return context->StartAbilityWithAccount(*actualWant, accountId);
261 }
262
FFIAbilityContextStartAbilityWithAccountAndOption(int64_t id,WantHandle want,int32_t accountId,CJStartOptions * startOption)263 int32_t FFIAbilityContextStartAbilityWithAccountAndOption(
264 int64_t id, WantHandle want, int32_t accountId, CJStartOptions* startOption)
265 {
266 auto context = FFIData::GetData<CJAbilityContext>(id);
267 if (context == nullptr) {
268 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
269 return ERR_INVALID_INSTANCE_CODE;
270 }
271 auto actualWant = reinterpret_cast<Want*>(want);
272 context->InheritWindowMode(*actualWant);
273 AAFwk::StartOptions option;
274 UnWrapStartOption(startOption, option);
275 return context->StartAbilityWithAccount(*actualWant, accountId, option);
276 }
277
FFIAbilityContextStartServiceExtensionAbility(int64_t id,WantHandle want)278 int32_t FFIAbilityContextStartServiceExtensionAbility(int64_t id, WantHandle want)
279 {
280 auto context = FFIData::GetData<CJAbilityContext>(id);
281 if (context == nullptr) {
282 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
283 return ERR_INVALID_INSTANCE_CODE;
284 }
285 auto actualWant = reinterpret_cast<Want*>(want);
286 return context->StartServiceExtensionAbility(*actualWant);
287 }
288
FFIAbilityContextStartServiceExtensionAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId)289 int32_t FFIAbilityContextStartServiceExtensionAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId)
290 {
291 auto context = FFIData::GetData<CJAbilityContext>(id);
292 if (context == nullptr) {
293 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
294 return ERR_INVALID_INSTANCE_CODE;
295 }
296 auto actualWant = reinterpret_cast<Want*>(want);
297 return context->StartServiceExtensionAbilityWithAccount(*actualWant, accountId);
298 }
299
FFIAbilityContextStopServiceExtensionAbility(int64_t id,WantHandle want)300 int32_t FFIAbilityContextStopServiceExtensionAbility(int64_t id, WantHandle want)
301 {
302 auto context = FFIData::GetData<CJAbilityContext>(id);
303 if (context == nullptr) {
304 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
305 return ERR_INVALID_INSTANCE_CODE;
306 }
307 auto actualWant = reinterpret_cast<Want*>(want);
308 return context->StopServiceExtensionAbility(*actualWant);
309 }
310
FFIAbilityContextStopServiceExtensionAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId)311 int32_t FFIAbilityContextStopServiceExtensionAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId)
312 {
313 auto context = FFIData::GetData<CJAbilityContext>(id);
314 if (context == nullptr) {
315 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
316 return ERR_INVALID_INSTANCE_CODE;
317 }
318 auto actualWant = reinterpret_cast<Want*>(want);
319 return context->StopServiceExtensionAbilityWithAccount(*actualWant, accountId);
320 }
321
FFIAbilityContextTerminateSelf(int64_t id)322 int32_t FFIAbilityContextTerminateSelf(int64_t id)
323 {
324 auto context = FFIData::GetData<CJAbilityContext>(id);
325 if (context == nullptr) {
326 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
327 return ERR_INVALID_INSTANCE_CODE;
328 }
329 return context->TerminateSelf();
330 }
331
FFIAbilityContextTerminateSelfWithResult(int64_t id,WantHandle want,int32_t resultCode)332 int32_t FFIAbilityContextTerminateSelfWithResult(int64_t id, WantHandle want, int32_t resultCode)
333 {
334 auto context = FFIData::GetData<CJAbilityContext>(id);
335 if (context == nullptr) {
336 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
337 return ERR_INVALID_INSTANCE_CODE;
338 }
339 auto actualWant = reinterpret_cast<Want*>(want);
340 return context->TerminateSelfWithResult(*actualWant, resultCode);
341 }
342
FFIAbilityContextIsTerminating(int64_t id)343 RetDataBool FFIAbilityContextIsTerminating(int64_t id)
344 {
345 RetDataBool res = { ERR_INVALID_INSTANCE_CODE, false };
346 auto context = FFIData::GetData<CJAbilityContext>(id);
347 if (context == nullptr) {
348 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
349 return res;
350 }
351
352 auto [code, data] = context->IsTerminating();
353 res.code = code;
354 res.data = data;
355 return res;
356 }
357
FFIAbilityContextConnectAbility(int64_t id,WantHandle want,int64_t connection)358 int32_t FFIAbilityContextConnectAbility(int64_t id, WantHandle want, int64_t connection)
359 {
360 auto context = FFIData::GetData<CJAbilityContext>(id);
361 if (context == nullptr) {
362 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
363 return ERR_INVALID_INSTANCE_CODE;
364 }
365 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
366 auto res = context->ConnectAbility(*actualWant, connection);
367 return res ? SUCCESS_CODE : static_cast<int32_t>(GetJsErrorCodeByNativeError(res));
368 }
369
FFIAbilityContextConnectAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId,int64_t connection)370 int32_t FFIAbilityContextConnectAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId, int64_t connection)
371 {
372 auto context = FFIData::GetData<CJAbilityContext>(id);
373 if (context == nullptr) {
374 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
375 return ERR_INVALID_INSTANCE_CODE;
376 }
377 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
378 auto res = context->ConnectAbilityWithAccount(*actualWant, accountId, connection);
379 return res ? SUCCESS_CODE : ERR_INVALID_INSTANCE_CODE;
380 }
381
FFIAbilityContextDisconnectAbility(int64_t id,WantHandle want,int64_t connection)382 int32_t FFIAbilityContextDisconnectAbility(int64_t id, WantHandle want, int64_t connection)
383 {
384 auto context = FFIData::GetData<CJAbilityContext>(id);
385 if (context == nullptr) {
386 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
387 return ERR_INVALID_INSTANCE_CODE;
388 }
389 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
390 context->DisconnectAbility(*actualWant, connection);
391 return SUCCESS_CODE;
392 }
393
FFIAbilityContextStartAbilityForResult(int64_t id,WantHandle want,int32_t requestCode,int64_t lambdaId)394 int32_t FFIAbilityContextStartAbilityForResult(int64_t id, WantHandle want, int32_t requestCode, int64_t lambdaId)
395 {
396 auto cjTask = WrapCJAbilityResultTask(lambdaId);
397 RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
398
399 auto context = FFIData::GetData<CJAbilityContext>(id);
400 if (context == nullptr) {
401 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
402 cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
403 return ERR_INVALID_INSTANCE_CODE;
404 }
405
406 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
407 context->InheritWindowMode(*actualWant);
408 return context->StartAbilityForResult(*actualWant, requestCode, std::move(task));
409 }
410
FFIAbilityContextStartAbilityForResultWithOption(int64_t id,WantHandle want,CJStartOptions * startOption,int32_t requestCode,int64_t lambdaId)411 int32_t FFIAbilityContextStartAbilityForResultWithOption(
412 int64_t id, WantHandle want, CJStartOptions* startOption, int32_t requestCode, int64_t lambdaId)
413 {
414 auto cjTask = WrapCJAbilityResultTask(lambdaId);
415 RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
416
417 auto context = FFIData::GetData<CJAbilityContext>(id);
418 if (context == nullptr) {
419 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
420 cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
421 return ERR_INVALID_INSTANCE_CODE;
422 }
423
424 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
425 context->InheritWindowMode(*actualWant);
426 AAFwk::StartOptions option;
427 UnWrapStartOption(startOption, option);
428 return context->StartAbilityForResult(*actualWant, option, requestCode, std::move(task));
429 }
430
FFIAbilityContextStartAbilityForResultWithAccount(int64_t id,WantHandle want,int32_t accountId,int32_t requestCode,int64_t lambdaId)431 int32_t FFIAbilityContextStartAbilityForResultWithAccount(
432 int64_t id, WantHandle want, int32_t accountId, int32_t requestCode, int64_t lambdaId)
433 {
434 auto cjTask = WrapCJAbilityResultTask(lambdaId);
435 RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
436
437 auto context = FFIData::GetData<CJAbilityContext>(id);
438 if (context == nullptr) {
439 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
440 cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
441 return ERR_INVALID_INSTANCE_CODE;
442 }
443
444 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
445 context->InheritWindowMode(*actualWant);
446 return context->StartAbilityForResultWithAccount(*actualWant, accountId, requestCode, std::move(task));
447 }
448
FFIAbilityContextStartAbilityForResultWithAccountAndOption(int64_t id,WantHandle want,int32_t accountId,CJStartOptions * startOption,int32_t requestCode,int64_t lambdaId)449 int32_t FFIAbilityContextStartAbilityForResultWithAccountAndOption(
450 int64_t id, WantHandle want, int32_t accountId, CJStartOptions* startOption, int32_t requestCode, int64_t lambdaId)
451 {
452 auto cjTask = WrapCJAbilityResultTask(lambdaId);
453 RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
454
455 auto context = FFIData::GetData<CJAbilityContext>(id);
456 if (context == nullptr) {
457 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
458 cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
459 return ERR_INVALID_INSTANCE_CODE;
460 }
461
462 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
463 context->InheritWindowMode(*actualWant);
464 AAFwk::StartOptions option;
465 UnWrapStartOption(startOption, option);
466 return context->StartAbilityForResultWithAccount(*actualWant, accountId, option, requestCode, std::move(task));
467 }
468
FFIAbilityContextRequestPermissionsFromUser(int64_t id,VectorStringHandle permissions,int32_t requestCode,int64_t lambdaId)469 int32_t FFIAbilityContextRequestPermissionsFromUser(
470 int64_t id, VectorStringHandle permissions, int32_t requestCode, int64_t lambdaId)
471 {
472 auto cjTask = [lambdaId](int32_t error, CJPermissionRequestResult* cjPermissionRequestResult) {
473 if (g_cjAbilityCallbacks == nullptr) {
474 TAG_LOGE(AAFwkTag::CONTEXT, "null g_cjAbilityCallbacks");
475 return;
476 }
477 g_cjAbilityCallbacks->invokePermissionRequestResultCallback(lambdaId, error, cjPermissionRequestResult);
478 TAG_LOGD(AAFwkTag::CONTEXT, "invoke, error is %{public}d", error);
479 };
480 PermissionRequestTask task = [cjTask](const std::vector<std::string>& permissions,
481 const std::vector<int>& grantResults) {
482 VectorStringHandle permissionList = const_cast<std::vector<std::string>*>(&permissions);
483 VectorInt32Handle result = const_cast<std::vector<int>*>(&grantResults);
484 CJPermissionRequestResult cjPermissionRequestResult = { permissionList, result };
485 cjTask(SUCCESS_CODE, &cjPermissionRequestResult);
486 };
487
488 auto context = FFIData::GetData<CJAbilityContext>(id);
489 if (context == nullptr) {
490 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
491 cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
492 return ERR_INVALID_INSTANCE_CODE;
493 }
494
495 auto actualPermissions = reinterpret_cast<std::vector<std::string>*>(permissions);
496 if (actualPermissions->empty()) {
497 TAG_LOGE(AAFwkTag::CONTEXT, "empty permissions");
498 cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
499 return ERR_INVALID_INSTANCE_CODE;
500 }
501 return true;
502 }
503
504 #ifdef SUPPORT_GRAPHICS
FFIAbilityContextSetMissionLabel(int64_t id,const char * label)505 int32_t FFIAbilityContextSetMissionLabel(int64_t id, const char* label)
506 {
507 auto context = FFIData::GetData<CJAbilityContext>(id);
508 if (context == nullptr) {
509 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
510 return ERR_INVALID_INSTANCE_CODE;
511 }
512 return context->SetMissionLabel(label);
513 }
514
FFIAbilityContextSetMissionIcon(int64_t id,int64_t pixelMapId)515 int32_t FFIAbilityContextSetMissionIcon(int64_t id, int64_t pixelMapId)
516 {
517 auto context = FFIData::GetData<CJAbilityContext>(id);
518 if (context == nullptr) {
519 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
520 return ERR_INVALID_INSTANCE_CODE;
521 }
522 return 0;
523 }
524 #endif
525
FFIAbilityContextRequestDialogService(int64_t id,WantHandle want,int64_t lambdaId)526 int32_t FFIAbilityContextRequestDialogService(int64_t id, WantHandle want, int64_t lambdaId)
527 {
528 auto context = FFIData::GetData<CJAbilityContext>(id);
529 if (context == nullptr) {
530 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
531 return ERR_INVALID_INSTANCE_CODE;
532 }
533 RequestDialogResultTask task = [lambdaId](int32_t resultCode, const AAFwk::Want& resultWant) {
534 if (g_cjAbilityCallbacks == nullptr) {
535 TAG_LOGE(AAFwkTag::CONTEXT, "null g_cjAbilityCallbacks");
536 return;
537 }
538 CJDialogRequestResult dialogRequestResult = { .resultCode = resultCode, .wantHandle = (WantHandle)&resultWant };
539 g_cjAbilityCallbacks->invokeDialogRequestResultCallback(lambdaId, resultCode, &dialogRequestResult);
540 TAG_LOGD(AAFwkTag::CONTEXT, "invoke, resultCode is %{public}d", resultCode);
541 };
542 auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
543 return context->RequestDialogService(*actualWant, std::move(task));
544 }
545
FFIAbilityContextSetRestoreEnabled(int64_t id,bool enabled)546 int32_t FFIAbilityContextSetRestoreEnabled(int64_t id, bool enabled)
547 {
548 auto context = FFIData::GetData<CJAbilityContext>(id);
549 if (context == nullptr) {
550 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
551 return ERR_INVALID_INSTANCE_CODE;
552 }
553 return context->SetRestoreEnabled(enabled);
554 }
555
FFIAbilityContextBackToCallerAbilityWithResult(int64_t id,CJAbilityResult abilityResult,char * requestCode)556 int32_t FFIAbilityContextBackToCallerAbilityWithResult(int64_t id, CJAbilityResult abilityResult, char* requestCode)
557 {
558 auto context = FFIData::GetData<CJAbilityContext>(id);
559 if (context == nullptr) {
560 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
561 return ERR_INVALID_INSTANCE_CODE;
562 }
563 AAFwk::Want* want = reinterpret_cast<AAFwk::Want*>(abilityResult.wantHandle);
564 if (want == nullptr) {
565 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
566 return ERR_INVALID_INSTANCE_CODE;
567 }
568 int32_t resultCode = abilityResult.resultCode;
569 std::string requestCodeStr = std::string(requestCode);
570 auto requestCodeInt64 = RequestCodeFromStringToInt64(requestCodeStr);
571 auto innerErrCod = context->BackToCallerAbilityWithResult(*want, resultCode, requestCodeInt64);
572 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
573 }
574
FFIAbilityContextSetMissionContinueState(int64_t id,int32_t intState)575 int32_t FFIAbilityContextSetMissionContinueState(int64_t id, int32_t intState)
576 {
577 auto context = FFIData::GetData<CJAbilityContext>(id);
578 if (context == nullptr) {
579 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
580 return ERR_INVALID_INSTANCE_CODE;
581 }
582 AAFwk::ContinueState state = static_cast<AAFwk::ContinueState>(intState);
583 if (state <= AAFwk::ContinueState::CONTINUESTATE_UNKNOWN || state >= AAFwk::ContinueState::CONTINUESTATE_MAX) {
584 TAG_LOGE(AAFwkTag::CONTEXT, "invalid params, state: %{public}d", state);
585 return static_cast<int>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
586 }
587 auto innerErrCod = context->SetMissionContinueState(state);
588 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
589 }
590
CallConvertConfig(std::shared_ptr<AppExecFwk::Configuration> configuration)591 CConfiguration CallConvertConfig(std::shared_ptr<AppExecFwk::Configuration> configuration)
592 {
593 CConfiguration cCfg = {};
594 void* handle = dlopen(CJ_ABILITY_LIBNAME, RTLD_LAZY);
595 if (handle == nullptr) {
596 TAG_LOGE(AAFwkTag::CONTEXT, "null handle");
597 return cCfg;
598 }
599 using ConvertConfigFunc = CConfiguration (*)(void*);
600 auto func = reinterpret_cast<ConvertConfigFunc>(dlsym(handle, FUNC_CONVERT_CONFIGURATION));
601 if (func == nullptr) {
602 TAG_LOGE(AAFwkTag::CONTEXT, "null func");
603 dlclose(handle);
604 return cCfg;
605 }
606 cCfg = func(configuration.get());
607 dlclose(handle);
608 return cCfg;
609 }
610
FFIAbilityContextPropConfiguration(int64_t id,int32_t * errCode)611 CConfiguration FFIAbilityContextPropConfiguration(int64_t id, int32_t* errCode)
612 {
613 CConfiguration cCfg = {};
614 auto context = FFIData::GetData<CJAbilityContext>(id);
615 if (context == nullptr) {
616 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
617 *errCode = ERR_INVALID_INSTANCE_CODE;
618 return cCfg;
619 }
620 auto configuration = context->GetConfiguration();
621 if (configuration == nullptr) {
622 *errCode = static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
623 return cCfg;
624 }
625 *errCode = SUCCESS_CODE;
626 return CallConvertConfig(configuration);
627 }
628
CallConvertAbilityInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)629 RetAbilityInfoV2 CallConvertAbilityInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
630 {
631 RetAbilityInfoV2 retInfo = {};
632 void* handle = dlopen(CJ_BUNDLE_MGR_LIBNAME, RTLD_LAZY);
633 if (handle == nullptr) {
634 TAG_LOGE(AAFwkTag::CONTEXT, "null handle");
635 return retInfo;
636 }
637 using ConvertAbilityInfoFunc = RetAbilityInfoV2 (*)(void*);
638 auto func = reinterpret_cast<ConvertAbilityInfoFunc>(dlsym(handle, FUNC_CONVERT_ABILITY_INFO));
639 if (func == nullptr) {
640 TAG_LOGE(AAFwkTag::CONTEXT, "null func");
641 dlclose(handle);
642 return retInfo;
643 }
644 retInfo = func(abilityInfo.get());
645 dlclose(handle);
646 return retInfo;
647 }
648
FFIAbilityContextPropAbilityInfo(int64_t id,int32_t * errCode)649 RetAbilityInfoV2 FFIAbilityContextPropAbilityInfo(int64_t id, int32_t* errCode)
650 {
651 RetAbilityInfoV2 ret = {};
652 auto context = FFIData::GetData<CJAbilityContext>(id);
653 if (context == nullptr) {
654 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
655 *errCode = ERR_INVALID_INSTANCE_CODE;
656 return ret;
657 }
658 auto abilityInfo = context->GetAbilityInfo();
659 if (abilityInfo == nullptr) {
660 *errCode = static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
661 return ret;
662 }
663 *errCode = SUCCESS_CODE;
664 return CallConvertAbilityInfo(abilityInfo);
665 }
666
CallConvertHapInfo(std::shared_ptr<AppExecFwk::HapModuleInfo> hapInfo)667 RetHapModuleInfoV2 CallConvertHapInfo(std::shared_ptr<AppExecFwk::HapModuleInfo> hapInfo)
668 {
669 RetHapModuleInfoV2 retInfo = {};
670 void* handle = dlopen(CJ_BUNDLE_MGR_LIBNAME, RTLD_LAZY);
671 if (handle == nullptr) {
672 TAG_LOGE(AAFwkTag::CONTEXT, "null handle");
673 return retInfo;
674 }
675 using ConvertHapInfoFunc = RetHapModuleInfoV2 (*)(void*);
676 auto func = reinterpret_cast<ConvertHapInfoFunc>(dlsym(handle, FUNC_CONVERT_HAP_INFO));
677 if (func == nullptr) {
678 TAG_LOGE(AAFwkTag::CONTEXT, "null func");
679 dlclose(handle);
680 return retInfo;
681 }
682 retInfo = func(hapInfo.get());
683 dlclose(handle);
684 return retInfo;
685 }
686
FFIAbilityContextPropCurrentHapModuleInfo(int64_t id,int32_t * errCode)687 RetHapModuleInfoV2 FFIAbilityContextPropCurrentHapModuleInfo(int64_t id, int32_t* errCode)
688 {
689 RetHapModuleInfoV2 ret = {};
690 auto context = FFIData::GetData<CJAbilityContext>(id);
691 if (context == nullptr) {
692 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
693 *errCode = ERR_INVALID_INSTANCE_CODE;
694 return ret;
695 }
696 auto hapModuleInfo = context->GetHapModuleInfo();
697 if (hapModuleInfo == nullptr) {
698 *errCode = static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
699 return ret;
700 }
701 *errCode = SUCCESS_CODE;
702 return CallConvertHapInfo(hapModuleInfo);
703 }
704
FFIAbilityContextStartAbilityByType(int64_t id,char * cType,char * cWantParams,void (* onError)(int32_t,char *,char *),void (* onResult)(CJAbilityResult))705 int32_t FFIAbilityContextStartAbilityByType(int64_t id, char* cType, char* cWantParams,
706 void (*onError)(int32_t, char*, char*), void (*onResult)(CJAbilityResult))
707 {
708 auto innerErrCod = SUCCESS_CODE;
709 auto context = FFIData::GetData<CJAbilityContext>(id);
710 if (context == nullptr) {
711 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
712 return ERR_INVALID_INSTANCE_CODE;
713 }
714 auto type = std::string(cType);
715 auto wantParm = OHOS::AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(cWantParams);
716 std::shared_ptr<CjUIExtensionCallback> callback = std::make_shared<CjUIExtensionCallback>();
717 callback->SetCjCallbackOnResult(CJLambda::Create(onResult));
718 callback->SetCjCallbackOnError(CJLambda::Create(onError));
719 #ifdef SUPPORT_SCREEN
720 innerErrCod = context->StartAbilityByType(type, wantParm, callback);
721 #endif
722 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
723 }
724
FFIAbilityContextMoveAbilityToBackground(int64_t id)725 int32_t FFIAbilityContextMoveAbilityToBackground(int64_t id)
726 {
727 auto context = FFIData::GetData<CJAbilityContext>(id);
728 if (context == nullptr) {
729 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
730 return ERR_INVALID_INSTANCE_CODE;
731 }
732 auto innerErrCod = context->MoveUIAbilityToBackground();
733 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
734 }
735
FFIAbilityContextReportDrawnCompleted(int64_t id)736 int32_t FFIAbilityContextReportDrawnCompleted(int64_t id)
737 {
738 auto context = FFIData::GetData<CJAbilityContext>(id);
739 if (context == nullptr) {
740 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
741 return ERR_INVALID_INSTANCE_CODE;
742 }
743 auto innerErrCod = context->ReportDrawnCompleted();
744 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
745 }
746
FFIAbilityContextOpenAtomicService(int64_t id,char * cAppId,CJAtomicServiceOptions cAtomicServiceOptions,int32_t requestCode,int64_t lambdaId)747 int32_t FFIAbilityContextOpenAtomicService(
748 int64_t id, char* cAppId, CJAtomicServiceOptions cAtomicServiceOptions, int32_t requestCode, int64_t lambdaId)
749 {
750 auto cjTask = WrapCJAbilityResultTask(lambdaId);
751 RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
752
753 auto context = FFIData::GetData<CJAbilityContext>(id);
754 if (context == nullptr) {
755 TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
756 cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
757 return ERR_INVALID_INSTANCE_CODE;
758 }
759 std::string appId = std::string(cAppId);
760 AAFwk::Want want;
761 AAFwk::StartOptions startOptions;
762 if (cAtomicServiceOptions.hasValue) {
763 AAFwk::WantParams wantParams =
764 OHOS::AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(cAtomicServiceOptions.parameters);
765 want.SetParams(wantParams);
766 if (cAtomicServiceOptions.flags != 0) {
767 want.SetFlags(cAtomicServiceOptions.flags);
768 }
769 UnWrapStartOptions(cAtomicServiceOptions.startOptions, startOptions);
770 }
771 std::string bundleName = ATOMIC_SERVICE_PREFIX + appId;
772 TAG_LOGD(AAFwkTag::CONTEXT, "bundleName: %{public}s", bundleName.c_str());
773 want.SetBundle(bundleName);
774 context->InheritWindowMode(want);
775 want.AddFlags(Want::FLAG_INSTALL_ON_DEMAND);
776 std::string startTime = std::to_string(
777 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
778 .count());
779 want.SetParam(Want::PARAM_RESV_START_TIME, startTime);
780 want.SetParam(Want::PARAM_RESV_FOR_RESULT, true);
781 return context->OpenAtomicService(want, startOptions, requestCode, std::move(task));
782 }
783
FFIAbilityContextOpenLink(int64_t id,char * cLink,CJOpenLinkOptions cOpenLinkOptions,int32_t requestCode,int64_t lambdaId)784 int32_t FFIAbilityContextOpenLink(
785 int64_t id, char* cLink, CJOpenLinkOptions cOpenLinkOptions, int32_t requestCode, int64_t lambdaId)
786 {
787 TAG_LOGD(AAFwkTag::CONTEXT, "called");
788 auto context = FFIData::GetData<CJAbilityContext>(id);
789 if (context == nullptr) {
790 TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
791 return ERR_INVALID_INSTANCE_CODE;
792 }
793 std::string linkValue = std::string(cLink);
794 AAFwk::OpenLinkOptions openLinkOptions;
795 AAFwk::Want want;
796 want.SetParam(APP_LINKING_ONLY, false);
797 if (!CheckUrl(linkValue)) {
798 TAG_LOGE(AAFwkTag::CONTEXT, "invalid link parames");
799 return static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
800 }
801 if (cOpenLinkOptions.hasValue) {
802 AAFwk::WantParams wantParams =
803 OHOS::AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(cOpenLinkOptions.parameters);
804 want.SetParams(wantParams);
805 bool appLinkingOnly = cOpenLinkOptions.appLinkingOnly;
806 openLinkOptions.SetAppLinkingOnly(appLinkingOnly);
807 want.SetParam(APP_LINKING_ONLY, appLinkingOnly);
808 }
809 if (!want.HasParameter(APP_LINKING_ONLY)) {
810 want.SetParam(APP_LINKING_ONLY, false);
811 }
812 want.SetUri(linkValue);
813 std::string startTime = std::to_string(
814 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())
815 .count());
816 want.SetParam(Want::PARAM_RESV_START_TIME, startTime);
817 int nativeRequestCode = -1;
818 if (lambdaId > 0) {
819 auto cjTask = WrapCJAbilityResultTask(lambdaId);
820 RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
821 context->CreateOpenLinkTask(std::move(task), requestCode, want, nativeRequestCode);
822 }
823 auto innerErrCod = context->OpenLink(want, requestCode);
824 if (innerErrCod == AAFwk::ERR_OPEN_LINK_START_ABILITY_DEFAULT_OK) {
825 return SUCCESS_CODE;
826 }
827 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
828 }
829
FFIAbilityContextShowAbility(int64_t id)830 int32_t FFIAbilityContextShowAbility(int64_t id)
831 {
832 auto context = FFIData::GetData<CJAbilityContext>(id);
833 if (context == nullptr) {
834 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
835 return ERR_INVALID_INSTANCE_CODE;
836 }
837 auto innerErrCod = context->ChangeAbilityVisibility(true);
838 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
839 }
840
FFIAbilityContextHideAbility(int64_t id)841 int32_t FFIAbilityContextHideAbility(int64_t id)
842 {
843 auto context = FFIData::GetData<CJAbilityContext>(id);
844 if (context == nullptr) {
845 TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
846 return ERR_INVALID_INSTANCE_CODE;
847 }
848 auto innerErrCod = context->ChangeAbilityVisibility(false);
849 return static_cast<int32_t>(GetJsErrorCodeByNativeError(innerErrCod));
850 }
851
852 #define EXPORT __attribute__((visibility("default")))
FFIAbilityContextGetBroker()853 EXPORT AbilityContextBroker* FFIAbilityContextGetBroker()
854 {
855 static AbilityContextBroker contextFuncs = { .isAbilityContextExisted = FFIAbilityContextIsAbilityContextExisted,
856 .getSizeOfStartOptions = FFIAbilityContextGetSizeOfStartOptions,
857 .getAbilityInfo = FFIAbilityContextGetAbilityInfo,
858 .getHapModuleInfo = FFIAbilityContextGetHapModuleInfo,
859 .getConfiguration = FFIAbilityContextGetConfiguration,
860 .startAbility = FFIAbilityContextStartAbility,
861 .startAbilityWithOption = FFIAbilityContextStartAbilityWithOption,
862 .startAbilityWithAccount = FFIAbilityContextStartAbilityWithAccount,
863 .startAbilityWithAccountAndOption = FFIAbilityContextStartAbilityWithAccountAndOption,
864 .startServiceExtensionAbility = FFIAbilityContextStartServiceExtensionAbility,
865 .startServiceExtensionAbilityWithAccount = FFIAbilityContextStartServiceExtensionAbilityWithAccount,
866 .stopServiceExtensionAbility = FFIAbilityContextStopServiceExtensionAbility,
867 .stopServiceExtensionAbilityWithAccount = FFIAbilityContextStopServiceExtensionAbilityWithAccount,
868 .terminateSelf = FFIAbilityContextTerminateSelf,
869 .terminateSelfWithResult = FFIAbilityContextTerminateSelfWithResult,
870 .isTerminating = FFIAbilityContextIsTerminating,
871 .connectAbility = FFIAbilityContextConnectAbility,
872 .connectAbilityWithAccount = FFIAbilityContextConnectAbilityWithAccount,
873 .disconnectAbility = FFIAbilityContextDisconnectAbility,
874 .startAbilityForResult = FFIAbilityContextStartAbilityForResult,
875 .startAbilityForResultWithOption = FFIAbilityContextStartAbilityForResultWithOption,
876 .startAbilityForResultWithAccount = FFIAbilityContextStartAbilityForResultWithAccount,
877 .startAbilityForResultWithAccountAndOption = FFIAbilityContextStartAbilityForResultWithAccountAndOption,
878 .requestPermissionsFromUser = FFIAbilityContextRequestPermissionsFromUser,
879 .setMissionLabel = FFIAbilityContextSetMissionLabel,
880 .setMissionIcon = FFIAbilityContextSetMissionIcon };
881 return &contextFuncs;
882 }
883
FFIGetContext(int64_t id)884 EXPORT void* FFIGetContext(int64_t id)
885 {
886 if (auto cjContext = FFIData::GetData<CJAbilityContext>(id)) {
887 return cjContext->GetAbilityContext().get();
888 }
889 return nullptr;
890 }
891
892 typedef struct napi_env__* napi_env;
893 typedef struct napi_value__* napi_value;
894
BindJsAbilityContextStartStop(napi_env env,napi_value result)895 void BindJsAbilityContextStartStop(napi_env env, napi_value result)
896 {
897 const char* moduleName = "JsAbilityContext";
898 BindNativeFunction((napi_env)env, result, "startAbility", moduleName, JsAbilityContext::StartAbility);
899 BindNativeFunction((napi_env)env, result, "openLink", moduleName, JsAbilityContext::OpenLink);
900 BindNativeFunction(
901 (napi_env)env, result, "startAbilityAsCaller", moduleName, JsAbilityContext::StartAbilityAsCaller);
902 BindNativeFunction(
903 (napi_env)env, result, "startAbilityWithAccount", moduleName, JsAbilityContext::StartAbilityWithAccount);
904 BindNativeFunction((napi_env)env, result, "startAbilityByCall", moduleName, JsAbilityContext::StartAbilityByCall);
905 BindNativeFunction(
906 (napi_env)env, result, "startAbilityForResult", moduleName, JsAbilityContext::StartAbilityForResult);
907 BindNativeFunction((napi_env)env, result, "startAbilityForResultWithAccount", moduleName,
908 JsAbilityContext::StartAbilityForResultWithAccount);
909 BindNativeFunction((napi_env)env, result, "startServiceExtensionAbility", moduleName,
910 JsAbilityContext::StartServiceExtensionAbility);
911 BindNativeFunction((napi_env)env, result, "startServiceExtensionAbilityWithAccount", moduleName,
912 JsAbilityContext::StartServiceExtensionAbilityWithAccount);
913 BindNativeFunction((napi_env)env, result, "stopServiceExtensionAbility", moduleName,
914 JsAbilityContext::StopServiceExtensionAbility);
915 BindNativeFunction((napi_env)env, result, "stopServiceExtensionAbilityWithAccount", moduleName,
916 JsAbilityContext::StopServiceExtensionAbilityWithAccount);
917 }
918
BindJsAbilityContextOther(napi_env env,napi_value result)919 void BindJsAbilityContextOther(napi_env env, napi_value result)
920 {
921 const char* moduleName = "JsAbilityContext";
922 BindNativeFunction(
923 (napi_env)env, result, "connectServiceExtensionAbility", moduleName, JsAbilityContext::ConnectAbility);
924 BindNativeFunction(
925 (napi_env)env, result, "connectAbilityWithAccount", moduleName, JsAbilityContext::ConnectAbilityWithAccount);
926 BindNativeFunction((napi_env)env, result, "connectServiceExtensionAbilityWithAccount", moduleName,
927 JsAbilityContext::ConnectAbilityWithAccount);
928 BindNativeFunction((napi_env)env, result, "disconnectAbility", moduleName, JsAbilityContext::DisconnectAbility);
929 BindNativeFunction(
930 (napi_env)env, result, "disconnectServiceExtensionAbility", moduleName, JsAbilityContext::DisconnectAbility);
931 BindNativeFunction((napi_env)env, result, "terminateSelf", moduleName, JsAbilityContext::TerminateSelf);
932 BindNativeFunction(
933 (napi_env)env, result, "terminateSelfWithResult", moduleName, JsAbilityContext::TerminateSelfWithResult);
934 BindNativeFunction((napi_env)env, result, "backToCallerAbilityWithResult", moduleName,
935 JsAbilityContext::BackToCallerAbilityWithResult);
936 BindNativeFunction((napi_env)env, result, "restoreWindowStage", moduleName, JsAbilityContext::RestoreWindowStage);
937 BindNativeFunction((napi_env)env, result, "isTerminating", moduleName, JsAbilityContext::IsTerminating);
938 BindNativeFunction((napi_env)env, result, "startRecentAbility", moduleName, JsAbilityContext::StartRecentAbility);
939 BindNativeFunction(
940 (napi_env)env, result, "requestDialogService", moduleName, JsAbilityContext::RequestDialogService);
941 BindNativeFunction(
942 (napi_env)env, result, "reportDrawnCompleted", moduleName, JsAbilityContext::ReportDrawnCompleted);
943 BindNativeFunction(
944 (napi_env)env, result, "setMissionContinueState", moduleName, JsAbilityContext::SetMissionContinueState);
945 BindNativeFunction((napi_env)env, result, "startAbilityByType", moduleName, JsAbilityContext::StartAbilityByType);
946 BindNativeFunction(
947 (napi_env)env, result, "requestModalUIExtension", moduleName, JsAbilityContext::RequestModalUIExtension);
948 BindNativeFunction((napi_env)env, result, "showAbility", moduleName, JsAbilityContext::ShowAbility);
949 BindNativeFunction((napi_env)env, result, "hideAbility", moduleName, JsAbilityContext::HideAbility);
950 BindNativeFunction((napi_env)env, result, "openAtomicService", moduleName, JsAbilityContext::OpenAtomicService);
951 BindNativeFunction(
952 (napi_env)env, result, "moveAbilityToBackground", moduleName, JsAbilityContext::MoveAbilityToBackground);
953 BindNativeFunction((napi_env)env, result, "setRestoreEnabled", moduleName, JsAbilityContext::SetRestoreEnabled);
954 BindNativeFunction(
955 (napi_env)env, result, "startUIServiceExtensionAbility", moduleName, JsAbilityContext::StartUIServiceExtension);
956 BindNativeFunction((napi_env)env, result, "connectUIServiceExtensionAbility", moduleName,
957 JsAbilityContext::ConnectUIServiceExtension);
958 BindNativeFunction((napi_env)env, result, "disconnectUIServiceExtensionAbility", moduleName,
959 JsAbilityContext::DisconnectUIServiceExtension);
960 #ifdef SUPPORT_GRAPHICS
961 BindNativeFunction((napi_env)env, result, "setMissionLabel", moduleName, JsAbilityContext::SetMissionLabel);
962 BindNativeFunction((napi_env)env, result, "setMissionIcon", moduleName, JsAbilityContext::SetMissionIcon);
963 #endif
964 }
965
FFICreateNapiValue(void * env,void * context)966 EXPORT napi_value FFICreateNapiValue(void* env, void* context)
967 {
968 napi_value result = nullptr;
969 napi_create_object((napi_env)env, &result);
970 if (result == nullptr) {
971 TAG_LOGE(AAFwkTag::CONTEXT, "null result");
972 return nullptr;
973 }
974 auto nativeFinalize = [](napi_env env, void* data, void* hint) {
975 auto tmp = reinterpret_cast<std::weak_ptr<Context>*>(data);
976 delete tmp;
977 };
978 auto tmpContext = reinterpret_cast<AbilityContext*>(context);
979 auto weakContext = new std::weak_ptr<Context>(tmpContext->weak_from_this());
980 napi_status status = napi_wrap((napi_env)env, result, weakContext, nativeFinalize, nullptr, nullptr);
981 if (status != napi_ok && weakContext != nullptr) {
982 TAG_LOGE(AAFwkTag::CONTEXT, "napi_wrap Failed: %{public}d", status);
983 delete weakContext;
984 return nullptr;
985 }
986 napi_value value = nullptr;
987 napi_get_boolean((napi_env)env, true, &value);
988 napi_set_named_property((napi_env)env, result, "stageMode", value);
989
990 return result;
991 }
992
FFICreateNapiValueJsAbilityContext(void * env,void * context)993 EXPORT napi_value FFICreateNapiValueJsAbilityContext(void* env, void* context)
994 {
995 napi_value result = FFICreateNapiValue(env, context);
996 BindJsAbilityContextStartStop((napi_env)env, result);
997 BindJsAbilityContextOther((napi_env)env, result);
998 return result;
999 }
1000
FfiConvertUIAbilityContext2Napi(napi_env env,int64_t id)1001 EXPORT napi_value FfiConvertUIAbilityContext2Napi(napi_env env, int64_t id)
1002 {
1003 napi_value undefined = nullptr;
1004 napi_get_undefined(env, &undefined);
1005 auto cjContext = FFIData::GetData<CJAbilityContext>(id);
1006 if (cjContext == nullptr || cjContext->GetAbilityContext() == nullptr) {
1007 TAG_LOGE(AAFwkTag::CONTEXT, "cj context null ptr");
1008 return undefined;
1009 }
1010
1011 napi_value result = CreateJsAbilityContext(env, cjContext->GetAbilityContext());
1012 if (result == nullptr) {
1013 TAG_LOGE(AAFwkTag::CONTEXT, "null object");
1014 return undefined;
1015 }
1016 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(
1017 cjContext->GetAbilityContext());
1018 napi_status status = napi_wrap(env, result, workContext,
1019 [](napi_env, void* data, void*) {
1020 TAG_LOGD(AAFwkTag::ABILITY, "finalizer for weak_ptr ability context is called");
1021 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
1022 },
1023 nullptr, nullptr);
1024 if (status != napi_ok && workContext != nullptr) {
1025 TAG_LOGE(AAFwkTag::ABILITY, "napi_wrap Failed: %{public}d", status);
1026 delete workContext;
1027 return undefined;
1028 }
1029 napi_value falseValue = nullptr;
1030 napi_get_boolean((napi_env)env, true, &falseValue);
1031 napi_set_named_property((napi_env)env, result, "stageMode", falseValue);
1032
1033 return result;
1034 }
1035
FfiCreateUIAbilityContextFromNapi(napi_env env,napi_value uiAbilityContext)1036 EXPORT int64_t FfiCreateUIAbilityContextFromNapi(napi_env env, napi_value uiAbilityContext)
1037 {
1038 if (env == nullptr || uiAbilityContext == nullptr) {
1039 return ERR_INVALID_INSTANCE_CODE;
1040 }
1041
1042 napi_valuetype type;
1043 if (napi_typeof(env, uiAbilityContext, &type) || type != napi_object) {
1044 return ERR_INVALID_INSTANCE_CODE;
1045 }
1046
1047 std::weak_ptr<AbilityContext>* context = nullptr;
1048 napi_status status = napi_unwrap(env, uiAbilityContext, reinterpret_cast<void**>(&context));
1049 if (status != napi_ok) {
1050 return ERR_INVALID_INSTANCE_CODE;
1051 }
1052 if (context == nullptr || (*context).lock() == nullptr) {
1053 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
1054 return ERR_INVALID_INSTANCE_CODE;
1055 }
1056 auto cjContext = FFI::FFIData::Create<CJAbilityContext>((*context).lock());
1057 if (cjContext == nullptr) {
1058 TAG_LOGE(AAFwkTag::CONTEXT, "null cjContext");
1059 return ERR_INVALID_INSTANCE_CODE;
1060 }
1061
1062 return cjContext->GetID();
1063 }
1064
1065 #undef EXPORT
1066 }
1067 } // namespace AbilityRuntime
1068 } // namespace OHOS
1069