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 "accesstoken_kit.h"
19 #include "cj_ability_context.h"
20 #include "cj_ability_connect_callback_object.h"
21 #include "cj_common_ffi.h"
22 #include "ffi_remote_data.h"
23 #include "hilog_tag_wrapper.h"
24 #include "napi_common_start_options.h"
25 #include "napi_common_util.h"
26 #include "pixel_map.h"
27 
28 using namespace OHOS::FFI;
29 
30 namespace OHOS {
31 namespace AbilityRuntime {
32 namespace {
33 constexpr int64_t NOT_SUPPORT = 1;
34 // g_cjAbilityCallbacks is used to save cangjie functions.
35 // It is assigned by the global variable REGISTER_ABILITY_CONTEXT_CALLBACK on the cangjie side which invokes
36 // RegisterCJAbilityCallbacks. And it is never released.
37 CJAbilityCallbacks* g_cjAbilityCallbacks = nullptr;
38 }
39 
UnWrapStartOption(CJStartOptions * source,AAFwk::StartOptions & target)40 void UnWrapStartOption(CJStartOptions* source, AAFwk::StartOptions& target)
41 {
42     if (source == nullptr) {
43         TAG_LOGE(AAFwkTag::CONTEXT, "null source");
44         return;
45     }
46     target.SetWindowMode(source->windowMode);
47     target.SetDisplayID(source->displayId);
48 }
49 
WrapCJAbilityResultTask(int64_t lambdaId)50 std::function<void(int32_t, CJAbilityResult*)> WrapCJAbilityResultTask(int64_t lambdaId)
51 {
52     auto cjTask = [lambdaId](int32_t error, CJAbilityResult* abilityResult) {
53         if (g_cjAbilityCallbacks == nullptr) {
54             TAG_LOGE(AAFwkTag::CONTEXT, "failed, cangjie callbacks are not registered");
55             return;
56         }
57         g_cjAbilityCallbacks->invokeAbilityResultCallback(lambdaId, error, abilityResult);
58         TAG_LOGD(AAFwkTag::CONTEXT, "error: %{public}d", error);
59     };
60     return cjTask;
61 }
62 
WrapRuntimeTask(std::function<void (int32_t,CJAbilityResult *)> cjTask,int32_t error)63 RuntimeTask WrapRuntimeTask(std::function<void(int32_t, CJAbilityResult*)> cjTask, int32_t error)
64 {
65     RuntimeTask task = [cjTask, error](int32_t resultCode, const AAFwk::Want& want, bool isInner) {
66         WantHandle wantHandle = const_cast<AAFwk::Want*>(&want);
67         CJAbilityResult abilityResult = { resultCode, wantHandle };
68         cjTask(error, &abilityResult);
69         TAG_LOGD(AAFwkTag::CONTEXT, "error: %{public}d", error);
70     };
71     return task;
72 }
73 
74 extern "C" {
RegisterCJAbilityCallbacks(void (* registerFunc)(CJAbilityCallbacks *))75 void RegisterCJAbilityCallbacks(void (*registerFunc)(CJAbilityCallbacks*))
76 {
77     if (g_cjAbilityCallbacks != nullptr) {
78         TAG_LOGE(AAFwkTag::CONTEXT, "repeated registration for cj functions of CJAbility");
79         return;
80     }
81 
82     if (registerFunc == nullptr) {
83         TAG_LOGE(AAFwkTag::CONTEXT, "null registerFunc");
84         return;
85     }
86 
87     g_cjAbilityCallbacks = new CJAbilityCallbacks();
88     registerFunc(g_cjAbilityCallbacks);
89 }
90 
FFIAbilityContextIsAbilityContextExisted(int64_t id)91 bool FFIAbilityContextIsAbilityContextExisted(int64_t id)
92 {
93     return FFIData::GetData<CJAbilityContext>(id) != nullptr;
94 }
95 
FFIAbilityContextGetSizeOfStartOptions()96 int64_t FFIAbilityContextGetSizeOfStartOptions()
97 {
98     return sizeof(CJStartOptions);
99 }
100 
FFIAbilityContextGetAbilityInfo(int64_t id)101 int64_t FFIAbilityContextGetAbilityInfo(int64_t id)
102 {
103     auto context = FFIData::GetData<CJAbilityContext>(id);
104     if (context == nullptr) {
105         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
106         return INVALID_DATA_ID;
107     }
108     return NOT_SUPPORT;
109 }
110 
FFIAbilityContextGetHapModuleInfo(int64_t id)111 int64_t FFIAbilityContextGetHapModuleInfo(int64_t id)
112 {
113     auto context = FFIData::GetData<CJAbilityContext>(id);
114     if (context == nullptr) {
115         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
116         return INVALID_DATA_ID;
117     }
118     auto hapModuleInfo = context->GetHapModuleInfo();
119     return NOT_SUPPORT;
120 }
121 
FFIAbilityContextGetConfiguration(int64_t id)122 int64_t FFIAbilityContextGetConfiguration(int64_t id)
123 {
124     auto context = FFIData::GetData<CJAbilityContext>(id);
125     if (context == nullptr) {
126         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
127         return INVALID_DATA_ID;
128     }
129     auto configuration = context->GetConfiguration();
130     return NOT_SUPPORT;
131 }
132 
FFIAbilityContextStartAbility(int64_t id,WantHandle want)133 int32_t FFIAbilityContextStartAbility(int64_t id, WantHandle want)
134 {
135     auto context = FFIData::GetData<CJAbilityContext>(id);
136     if (context == nullptr) {
137         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
138         return ERR_INVALID_INSTANCE_CODE;
139     }
140 
141     auto actualWant = reinterpret_cast<Want*>(want);
142     context->InheritWindowMode(*actualWant);
143     return context->StartAbility(*actualWant);
144 }
145 
FFIAbilityContextStartAbilityWithOption(int64_t id,WantHandle want,CJStartOptions * startOption)146 int32_t FFIAbilityContextStartAbilityWithOption(int64_t id, WantHandle want, CJStartOptions* startOption)
147 {
148     auto context = FFIData::GetData<CJAbilityContext>(id);
149     if (context == nullptr) {
150         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
151         return ERR_INVALID_INSTANCE_CODE;
152     }
153     auto actualWant = reinterpret_cast<Want*>(want);
154     context->InheritWindowMode(*actualWant);
155     AAFwk::StartOptions option;
156     UnWrapStartOption(startOption, option);
157     return context->StartAbility(*actualWant, option);
158 }
159 
FFIAbilityContextStartAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId)160 int32_t FFIAbilityContextStartAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId)
161 {
162     auto context = FFIData::GetData<CJAbilityContext>(id);
163     if (context == nullptr) {
164         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
165         return ERR_INVALID_INSTANCE_CODE;
166     }
167     auto actualWant = reinterpret_cast<Want*>(want);
168     context->InheritWindowMode(*actualWant);
169     return context->StartAbilityWithAccount(*actualWant, accountId);
170 }
171 
FFIAbilityContextStartAbilityWithAccountAndOption(int64_t id,WantHandle want,int32_t accountId,CJStartOptions * startOption)172 int32_t FFIAbilityContextStartAbilityWithAccountAndOption(
173     int64_t id, WantHandle want, int32_t accountId, CJStartOptions* startOption)
174 {
175     auto context = FFIData::GetData<CJAbilityContext>(id);
176     if (context == nullptr) {
177         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
178         return ERR_INVALID_INSTANCE_CODE;
179     }
180     auto actualWant = reinterpret_cast<Want*>(want);
181     context->InheritWindowMode(*actualWant);
182     AAFwk::StartOptions option;
183     UnWrapStartOption(startOption, option);
184     return context->StartAbilityWithAccount(*actualWant, accountId, option);
185 }
186 
FFIAbilityContextStartServiceExtensionAbility(int64_t id,WantHandle want)187 int32_t FFIAbilityContextStartServiceExtensionAbility(int64_t id, WantHandle want)
188 {
189     auto context = FFIData::GetData<CJAbilityContext>(id);
190     if (context == nullptr) {
191         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
192         return ERR_INVALID_INSTANCE_CODE;
193     }
194     auto actualWant = reinterpret_cast<Want*>(want);
195     return context->StartServiceExtensionAbility(*actualWant);
196 }
197 
FFIAbilityContextStartServiceExtensionAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId)198 int32_t FFIAbilityContextStartServiceExtensionAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId)
199 {
200     auto context = FFIData::GetData<CJAbilityContext>(id);
201     if (context == nullptr) {
202         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
203         return ERR_INVALID_INSTANCE_CODE;
204     }
205     auto actualWant = reinterpret_cast<Want*>(want);
206     return context->StartServiceExtensionAbilityWithAccount(*actualWant, accountId);
207 }
208 
FFIAbilityContextStopServiceExtensionAbility(int64_t id,WantHandle want)209 int32_t FFIAbilityContextStopServiceExtensionAbility(int64_t id, WantHandle want)
210 {
211     auto context = FFIData::GetData<CJAbilityContext>(id);
212     if (context == nullptr) {
213         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
214         return ERR_INVALID_INSTANCE_CODE;
215     }
216     auto actualWant = reinterpret_cast<Want*>(want);
217     return context->StopServiceExtensionAbility(*actualWant);
218 }
219 
FFIAbilityContextStopServiceExtensionAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId)220 int32_t FFIAbilityContextStopServiceExtensionAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId)
221 {
222     auto context = FFIData::GetData<CJAbilityContext>(id);
223     if (context == nullptr) {
224         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
225         return ERR_INVALID_INSTANCE_CODE;
226     }
227     auto actualWant = reinterpret_cast<Want*>(want);
228     return context->StopServiceExtensionAbilityWithAccount(*actualWant, accountId);
229 }
230 
FFIAbilityContextTerminateSelf(int64_t id)231 int32_t FFIAbilityContextTerminateSelf(int64_t id)
232 {
233     auto context = FFIData::GetData<CJAbilityContext>(id);
234     if (context == nullptr) {
235         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
236         return ERR_INVALID_INSTANCE_CODE;
237     }
238     return context->TerminateSelf();
239 }
240 
FFIAbilityContextTerminateSelfWithResult(int64_t id,WantHandle want,int32_t resultCode)241 int32_t FFIAbilityContextTerminateSelfWithResult(int64_t id, WantHandle want, int32_t resultCode)
242 {
243     auto context = FFIData::GetData<CJAbilityContext>(id);
244     if (context == nullptr) {
245         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
246         return ERR_INVALID_INSTANCE_CODE;
247     }
248     auto actualWant = reinterpret_cast<Want*>(want);
249     return context->TerminateSelfWithResult(*actualWant, resultCode);
250 }
251 
FFIAbilityContextIsTerminating(int64_t id)252 RetDataBool FFIAbilityContextIsTerminating(int64_t id)
253 {
254     RetDataBool res = { ERR_INVALID_INSTANCE_CODE, false };
255     auto context = FFIData::GetData<CJAbilityContext>(id);
256     if (context == nullptr) {
257         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
258         return res;
259     }
260 
261     auto [code, data] = context->IsTerminating();
262     res.code = code;
263     res.data = data;
264     return res;
265 }
266 
FFIAbilityContextConnectAbility(int64_t id,WantHandle want,int64_t connection)267 int32_t FFIAbilityContextConnectAbility(int64_t id, WantHandle want, int64_t connection)
268 {
269     auto context = FFIData::GetData<CJAbilityContext>(id);
270     if (context == nullptr) {
271         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
272         return ERR_INVALID_INSTANCE_CODE;
273     }
274     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
275     auto res = context->ConnectAbility(*actualWant, connection);
276     return res ? SUCCESS_CODE : ERR_INVALID_INSTANCE_CODE;
277 }
278 
FFIAbilityContextConnectAbilityWithAccount(int64_t id,WantHandle want,int32_t accountId,int64_t connection)279 int32_t FFIAbilityContextConnectAbilityWithAccount(int64_t id, WantHandle want, int32_t accountId, int64_t connection)
280 {
281     auto context = FFIData::GetData<CJAbilityContext>(id);
282     if (context == nullptr) {
283         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
284         return ERR_INVALID_INSTANCE_CODE;
285     }
286     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
287     auto res = context->ConnectAbilityWithAccount(*actualWant, accountId, connection);
288     return res ? SUCCESS_CODE : ERR_INVALID_INSTANCE_CODE;
289 }
290 
FFIAbilityContextDisconnectAbility(int64_t id,WantHandle want,int64_t connection)291 int32_t FFIAbilityContextDisconnectAbility(int64_t id, WantHandle want, int64_t connection)
292 {
293     auto context = FFIData::GetData<CJAbilityContext>(id);
294     if (context == nullptr) {
295         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
296         return ERR_INVALID_INSTANCE_CODE;
297     }
298     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
299     context->ConnectAbility(*actualWant, connection);
300     return SUCCESS_CODE;
301 }
302 
FFIAbilityContextStartAbilityForResult(int64_t id,WantHandle want,int32_t requestCode,int64_t lambdaId)303 int32_t FFIAbilityContextStartAbilityForResult(int64_t id, WantHandle want, int32_t requestCode, int64_t lambdaId)
304 {
305     auto cjTask = WrapCJAbilityResultTask(lambdaId);
306     RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
307 
308     auto context = FFIData::GetData<CJAbilityContext>(id);
309     if (context == nullptr) {
310         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
311         cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
312         return ERR_INVALID_INSTANCE_CODE;
313     }
314 
315     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
316     context->InheritWindowMode(*actualWant);
317     return context->StartAbilityForResult(*actualWant, requestCode, std::move(task));
318 }
319 
FFIAbilityContextStartAbilityForResultWithOption(int64_t id,WantHandle want,CJStartOptions * startOption,int32_t requestCode,int64_t lambdaId)320 int32_t FFIAbilityContextStartAbilityForResultWithOption(
321     int64_t id, WantHandle want, CJStartOptions* startOption, int32_t requestCode, int64_t lambdaId)
322 {
323     auto cjTask = WrapCJAbilityResultTask(lambdaId);
324     RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
325 
326     auto context = FFIData::GetData<CJAbilityContext>(id);
327     if (context == nullptr) {
328         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
329         cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
330         return ERR_INVALID_INSTANCE_CODE;
331     }
332 
333     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
334     context->InheritWindowMode(*actualWant);
335     AAFwk::StartOptions option;
336     UnWrapStartOption(startOption, option);
337     return context->StartAbilityForResult(*actualWant, option, requestCode, std::move(task));
338 }
339 
FFIAbilityContextStartAbilityForResultWithAccount(int64_t id,WantHandle want,int32_t accountId,int32_t requestCode,int64_t lambdaId)340 int32_t FFIAbilityContextStartAbilityForResultWithAccount(
341     int64_t id, WantHandle want, int32_t accountId, int32_t requestCode, int64_t lambdaId)
342 {
343     auto cjTask = WrapCJAbilityResultTask(lambdaId);
344     RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
345 
346     auto context = FFIData::GetData<CJAbilityContext>(id);
347     if (context == nullptr) {
348         TAG_LOGE(AAFwkTag::CONTEXT, "invalid id of cj ability context");
349         cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
350         return ERR_INVALID_INSTANCE_CODE;
351     }
352 
353     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
354     context->InheritWindowMode(*actualWant);
355     return context->StartAbilityForResultWithAccount(*actualWant, accountId, requestCode, std::move(task));
356 }
357 
FFIAbilityContextStartAbilityForResultWithAccountAndOption(int64_t id,WantHandle want,int32_t accountId,CJStartOptions * startOption,int32_t requestCode,int64_t lambdaId)358 int32_t FFIAbilityContextStartAbilityForResultWithAccountAndOption(
359     int64_t id, WantHandle want, int32_t accountId, CJStartOptions* startOption, int32_t requestCode, int64_t lambdaId)
360 {
361     auto cjTask = WrapCJAbilityResultTask(lambdaId);
362     RuntimeTask task = WrapRuntimeTask(cjTask, SUCCESS_CODE);
363 
364     auto context = FFIData::GetData<CJAbilityContext>(id);
365     if (context == nullptr) {
366         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
367         cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
368         return ERR_INVALID_INSTANCE_CODE;
369     }
370 
371     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
372     context->InheritWindowMode(*actualWant);
373     AAFwk::StartOptions option;
374     UnWrapStartOption(startOption, option);
375     return context->StartAbilityForResultWithAccount(*actualWant, accountId, option, requestCode, std::move(task));
376 }
377 
FFIAbilityContextRequestPermissionsFromUser(int64_t id,VectorStringHandle permissions,int32_t requestCode,int64_t lambdaId)378 int32_t FFIAbilityContextRequestPermissionsFromUser(
379     int64_t id, VectorStringHandle permissions, int32_t requestCode, int64_t lambdaId)
380 {
381     auto cjTask = [lambdaId](int32_t error, CJPermissionRequestResult* cjPermissionRequestResult) {
382         if (g_cjAbilityCallbacks == nullptr) {
383             TAG_LOGE(AAFwkTag::CONTEXT, "failed, cangjie callbacks are not registered");
384             return;
385         }
386         g_cjAbilityCallbacks->invokePermissionRequestResultCallback(lambdaId, error, cjPermissionRequestResult);
387         TAG_LOGD(AAFwkTag::CONTEXT, "invoke, error is %{public}d", error);
388     };
389     PermissionRequestTask task = [cjTask](const std::vector<std::string>& permissions,
390                                      const std::vector<int>& grantResults) {
391         VectorStringHandle permissionList = const_cast<std::vector<std::string>*>(&permissions);
392         VectorInt32Handle result = const_cast<std::vector<int>*>(&grantResults);
393         CJPermissionRequestResult cjPermissionRequestResult = { permissionList, result };
394         cjTask(SUCCESS_CODE, &cjPermissionRequestResult);
395     };
396 
397     auto context = FFIData::GetData<CJAbilityContext>(id);
398     if (context == nullptr) {
399         TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
400         cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
401         return ERR_INVALID_INSTANCE_CODE;
402     }
403 
404     auto actualPermissions = reinterpret_cast<std::vector<std::string>*>(permissions);
405     if (actualPermissions->empty()) {
406         TAG_LOGE(AAFwkTag::CONTEXT, "params do not meet specification, permissions is empty");
407         cjTask(ERR_INVALID_INSTANCE_CODE, nullptr);
408         return ERR_INVALID_INSTANCE_CODE;
409     }
410     return true;
411 }
412 
413 #ifdef SUPPORT_GRAPHICS
FFIAbilityContextSetMissionLabel(int64_t id,const char * label)414 int32_t FFIAbilityContextSetMissionLabel(int64_t id, const char* label)
415 {
416     auto context = FFIData::GetData<CJAbilityContext>(id);
417     if (context == nullptr) {
418         TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
419         return ERR_INVALID_INSTANCE_CODE;
420     }
421     return context->SetMissionLabel(label);
422 }
423 
FFIAbilityContextSetMissionIcon(int64_t id,int64_t pixelMapId)424 int32_t FFIAbilityContextSetMissionIcon(int64_t id, int64_t pixelMapId)
425 {
426     auto context = FFIData::GetData<CJAbilityContext>(id);
427     if (context == nullptr) {
428         TAG_LOGE(AAFwkTag::CONTEXT, "null context");
429         return ERR_INVALID_INSTANCE_CODE;
430     }
431     return 0;
432 }
433 #endif
434 
FFIAbilityContextRequestDialogService(int64_t id,WantHandle want,int64_t lambdaId)435 int32_t FFIAbilityContextRequestDialogService(int64_t id, WantHandle want, int64_t lambdaId)
436 {
437     auto context = FFIData::GetData<CJAbilityContext>(id);
438     if (context == nullptr) {
439         TAG_LOGE(AAFwkTag::CONTEXT, "null CJAbilityContext");
440         return ERR_INVALID_INSTANCE_CODE;
441     }
442     RequestDialogResultTask task = [lambdaId](int32_t resultCode, const AAFwk::Want &resultWant) {
443         if (g_cjAbilityCallbacks == nullptr) {
444             TAG_LOGE(AAFwkTag::CONTEXT, "null g_cjAbilityCallbacks");
445             return;
446         }
447         CJDialogRequestResult dialogRequestResult = {
448             .resultCode = resultCode,
449             .wantHandle = (WantHandle)&resultWant
450         };
451         g_cjAbilityCallbacks->invokeDialogRequestResultCallback(lambdaId, resultCode, &dialogRequestResult);
452         TAG_LOGD(AAFwkTag::CONTEXT, "invoke, resultCode is %{public}d", resultCode);
453     };
454     auto actualWant = reinterpret_cast<AAFwk::Want*>(want);
455     return context->RequestDialogService(*actualWant, std::move(task));
456 }
457 
458 #define EXPORT __attribute__((visibility("default")))
FFIAbilityContextGetBroker()459 EXPORT AbilityContextBroker* FFIAbilityContextGetBroker()
460 {
461     static AbilityContextBroker contextFuncs = {
462         .isAbilityContextExisted = FFIAbilityContextIsAbilityContextExisted,
463         .getSizeOfStartOptions = FFIAbilityContextGetSizeOfStartOptions,
464         .getAbilityInfo = FFIAbilityContextGetAbilityInfo,
465         .getHapModuleInfo = FFIAbilityContextGetHapModuleInfo,
466         .getConfiguration = FFIAbilityContextGetConfiguration,
467         .startAbility = FFIAbilityContextStartAbility,
468         .startAbilityWithOption = FFIAbilityContextStartAbilityWithOption,
469         .startAbilityWithAccount = FFIAbilityContextStartAbilityWithAccount,
470         .startAbilityWithAccountAndOption = FFIAbilityContextStartAbilityWithAccountAndOption,
471         .startServiceExtensionAbility = FFIAbilityContextStartServiceExtensionAbility,
472         .startServiceExtensionAbilityWithAccount = FFIAbilityContextStartServiceExtensionAbilityWithAccount,
473         .stopServiceExtensionAbility = FFIAbilityContextStopServiceExtensionAbility,
474         .stopServiceExtensionAbilityWithAccount = FFIAbilityContextStopServiceExtensionAbilityWithAccount,
475         .terminateSelf = FFIAbilityContextTerminateSelf,
476         .terminateSelfWithResult = FFIAbilityContextTerminateSelfWithResult,
477         .isTerminating = FFIAbilityContextIsTerminating,
478         .connectAbility = FFIAbilityContextConnectAbility,
479         .connectAbilityWithAccount = FFIAbilityContextConnectAbilityWithAccount,
480         .disconnectAbility = FFIAbilityContextDisconnectAbility,
481         .startAbilityForResult = FFIAbilityContextStartAbilityForResult,
482         .startAbilityForResultWithOption = FFIAbilityContextStartAbilityForResultWithOption,
483         .startAbilityForResultWithAccount = FFIAbilityContextStartAbilityForResultWithAccount,
484         .startAbilityForResultWithAccountAndOption = FFIAbilityContextStartAbilityForResultWithAccountAndOption,
485         .requestPermissionsFromUser = FFIAbilityContextRequestPermissionsFromUser,
486         .setMissionLabel = FFIAbilityContextSetMissionLabel,
487         .setMissionIcon = FFIAbilityContextSetMissionIcon };
488     return &contextFuncs;
489 }
490 
FFIGetContext(int64_t id)491 EXPORT void *FFIGetContext(int64_t id)
492 {
493     if (auto cjContext = FFIData::GetData<CJAbilityContext>(id)) {
494         return cjContext->GetAbilityContext().get();
495     }
496     return nullptr;
497 }
498 
499 typedef struct napi_env__ *napi_env;
500 typedef struct napi_value__* napi_value;
501 
FFICreateNapiValue(void * env,void * context)502 EXPORT napi_value FFICreateNapiValue(void *env, void *context)
503 {
504     napi_value result = nullptr;
505     napi_create_object((napi_env)env, &result);
506     if (result == nullptr) {
507         TAG_LOGE(AAFwkTag::CONTEXT, "null result");
508         return nullptr;
509     }
510     auto nativeFinalize = [](napi_env env, void* data, void* hint) {
511         auto tmp = reinterpret_cast<std::weak_ptr<Context> *>(data);
512         delete tmp;
513     };
514     auto tmpContext = reinterpret_cast<AbilityContext*>(context);
515     auto weakContext = new std::weak_ptr<Context>(tmpContext->weak_from_this());
516     napi_status status = napi_wrap((napi_env)env, result, weakContext, nativeFinalize, nullptr, nullptr);
517     if (status != napi_ok && weakContext != nullptr) {
518         TAG_LOGE(AAFwkTag::CONTEXT, "napi_wrap Failed: %{public}d", status);
519         delete weakContext;
520         return nullptr;
521     }
522     napi_value value = nullptr;
523     napi_get_boolean((napi_env)env, true, &value);
524     napi_set_named_property((napi_env)env, result, "stageMode", value);
525 
526     return result;
527 }
528 
529 #undef EXPORT
530 }
531 } // namespace AbilityRuntime
532 } // namespace OHOS
533