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