1 /*
2 * Copyright (c) 2022 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 "js_print_extension_context.h"
17
18 #include "js_data_struct_converter.h"
19 #include "js_extension_context.h"
20 #include "js_print_extension_connection.h"
21 #include "js_runtime.h"
22 #include "js_runtime_utils.h"
23 #include "napi/native_api.h"
24 #include "napi_common_start_options.h"
25 #include "napi_common_util.h"
26 #include "napi_common_want.h"
27 #include "napi_print_utils.h"
28 #include "napi_remote_object.h"
29 #include "print_log.h"
30 #include "start_options.h"
31 #include <shared_mutex>
32
33 using namespace OHOS::Print;
34 using noneType = void*;
35
36 namespace OHOS {
37 namespace AbilityRuntime {
38 static constexpr int32_t E_PRINT_INVALID_CONTEXT = 1;
39 static constexpr int32_t E_PRINT_INVALID_CONNECTION = 2;
40
41 class JsPrintExtensionContext final {
42 public:
JsPrintExtensionContext(const std::shared_ptr<PrintExtensionContext> & context)43 explicit JsPrintExtensionContext(const std::shared_ptr<PrintExtensionContext>& context) : context_(context) {}
44 ~JsPrintExtensionContext() = default;
45
Finalizer(napi_env engine,noneType data,noneType hint)46 static void Finalizer(napi_env engine, noneType data, noneType hint)
47 {
48 PRINT_HILOGD("JsAbilityContext::Finalizer is called");
49 std::unique_ptr<JsPrintExtensionContext>(static_cast<JsPrintExtensionContext*>(data));
50 }
51
StartAbility(napi_env engine,napi_callback_info info)52 static napi_value StartAbility(napi_env engine, napi_callback_info info)
53 {
54 JsPrintExtensionContext* me = CheckParamsAndGetThis<JsPrintExtensionContext>(engine, info);
55 return (me != nullptr) ? me->OnStartAbility(engine, info) : nullptr;
56 }
57
StartAbilityWithAccount(napi_env engine,napi_callback_info info)58 static napi_value StartAbilityWithAccount(napi_env engine, napi_callback_info info)
59 {
60 JsPrintExtensionContext* me = CheckParamsAndGetThis<JsPrintExtensionContext>(engine, info);
61 return (me != nullptr) ? me->OnStartAbilityWithAccount(engine, info) : nullptr;
62 }
63
ConnectAbilityWithAccount(napi_env engine,napi_callback_info info)64 static napi_value ConnectAbilityWithAccount(napi_env engine, napi_callback_info info)
65 {
66 JsPrintExtensionContext* me = CheckParamsAndGetThis<JsPrintExtensionContext>(engine, info);
67 return (me != nullptr) ? me->OnConnectAbilityWithAccount(engine, info) : nullptr;
68 }
69
TerminateAbility(napi_env engine,napi_callback_info info)70 static napi_value TerminateAbility(napi_env engine, napi_callback_info info)
71 {
72 JsPrintExtensionContext* me = CheckParamsAndGetThis<JsPrintExtensionContext>(engine, info);
73 return (me != nullptr) ? me->OnTerminateAbility(engine, info) : nullptr;
74 }
75
ConnectAbility(napi_env engine,napi_callback_info info)76 static napi_value ConnectAbility(napi_env engine, napi_callback_info info)
77 {
78 JsPrintExtensionContext* me = CheckParamsAndGetThis<JsPrintExtensionContext>(engine, info);
79 return (me != nullptr) ? me->OnConnectAbility(engine, info) : nullptr;
80 }
81
DisconnectAbility(napi_env engine,napi_callback_info info)82 static napi_value DisconnectAbility(napi_env engine, napi_callback_info info)
83 {
84 JsPrintExtensionContext* me = CheckParamsAndGetThis<JsPrintExtensionContext>(engine, info);
85 return (me != nullptr) ? me->OnDisconnectAbility(engine, info) : nullptr;
86 }
87
88 private:
89 std::weak_ptr<PrintExtensionContext> context_;
90 std::shared_timed_mutex managersMutex_;
91
GetUndefinedValue(napi_env & engine)92 napi_value GetUndefinedValue(napi_env &engine)
93 {
94 PRINT_HILOGE("params count or value is error");
95 napi_value undefineResult = nullptr;
96 napi_get_undefined(engine, &undefineResult);
97 return undefineResult;
98 }
99
GetNapiValueType(napi_env & engine,napi_value & argv)100 napi_valuetype GetNapiValueType(napi_env &engine, napi_value &argv)
101 {
102 napi_valuetype valueType = napi_undefined;
103 napi_typeof(engine, argv, &valueType);
104 return valueType;
105 }
106
OnStartAbility(napi_env & engine,napi_callback_info & info)107 napi_value OnStartAbility(napi_env &engine, napi_callback_info &info)
108 {
109 PRINT_HILOGD("OnStartAbility is called");
110 size_t argc = NapiPrintUtils::MAX_ARGC;
111 napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
112 napi_get_cb_info(engine, info, &argc, argv, nullptr, nullptr);
113 if (argc != NapiPrintUtils::ARGC_ONE && argc != NapiPrintUtils::ARGC_TWO &&
114 argc != NapiPrintUtils::ARGC_THREE) {
115 return GetUndefinedValue(engine);
116 }
117
118 decltype(argc) unwrapArgc = 0;
119 AAFwk::Want want;
120 OHOS::AppExecFwk::UnwrapWant(engine, argv[NapiPrintUtils::INDEX_ZERO], want);
121 PRINT_HILOGD("%{public}s bundlename:%{public}s abilityname:%{public}s", __func__, want.GetBundle().c_str(),
122 want.GetElement().GetAbilityName().c_str());
123 unwrapArgc++;
124
125 AAFwk::StartOptions startOptions;
126 if (argc > NapiPrintUtils::ARGC_ONE && GetNapiValueType(engine, argv[1]) == napi_object) {
127 PRINT_HILOGD("OnStartAbility start options is used.");
128 AppExecFwk::UnwrapStartOptions(engine, argv[1], startOptions);
129 unwrapArgc++;
130 }
131
132 NapiAsyncTask::CompleteCallback complete = [weak = context_, want, startOptions, unwrapArgc](
133 napi_env engine, NapiAsyncTask &task, int32_t status) {
134 PRINT_HILOGD("startAbility begin");
135 auto context = weak.lock();
136 if (!context) {
137 PRINT_HILOGW("context is released");
138 task.Reject(engine, CreateJsError(engine, E_PRINT_INVALID_CONTEXT, "Context is released"));
139 return;
140 }
141
142 ErrCode errcode = ERR_OK;
143 (unwrapArgc == 1) ? errcode = context->StartAbility(want)
144 : errcode = context->StartAbility(want, startOptions);
145 if (errcode == 0) {
146 napi_value undefineResult = nullptr;
147 napi_get_undefined(engine, &undefineResult);
148 task.Resolve(engine, undefineResult);
149 } else {
150 task.Reject(engine, CreateJsError(engine, errcode, "Start Ability failed."));
151 }
152 };
153
154 napi_value lastParam = (argc == unwrapArgc) ? nullptr : argv[unwrapArgc];
155 napi_value result = nullptr;
156 NapiAsyncTask::Schedule("PrintExtensionContext::OnStartAbility", engine,
157 CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
158 return result;
159 }
160
OnStartAbilityWithAccount(napi_env & engine,napi_callback_info & info)161 napi_value OnStartAbilityWithAccount(napi_env &engine, napi_callback_info &info)
162 {
163 size_t argc = NapiPrintUtils::MAX_ARGC;
164 napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
165 napi_get_cb_info(engine, info, &argc, argv, nullptr, nullptr);
166 if (argc != NapiPrintUtils::ARGC_TWO && argc != NapiPrintUtils::ARGC_THREE &&
167 argc != NapiPrintUtils::ARGC_FOUR) {
168 return GetUndefinedValue(engine);
169 }
170
171 decltype(argc) unwrapArgc = 0;
172 AAFwk::Want want;
173 OHOS::AppExecFwk::UnwrapWant(engine, argv[0], want);
174 PRINT_HILOGD("%{public}s bundlename:%{public}s abilityname:%{public}s", __func__, want.GetBundle().c_str(),
175 want.GetElement().GetAbilityName().c_str());
176 unwrapArgc++;
177
178 int32_t accountId = 0;
179 if (!OHOS::AppExecFwk::UnwrapInt32FromJS2(engine, argv[1], accountId)) {
180 return GetUndefinedValue(engine);
181 }
182 PRINT_HILOGD("%{public}d accountId:", accountId);
183 unwrapArgc++;
184
185 AAFwk::StartOptions startOptions;
186 if (static_cast<uint32_t>(argc) > NapiPrintUtils::INDEX_TWO &&
187 GetNapiValueType(engine, argv[NapiPrintUtils::INDEX_TWO]) == napi_object) {
188 AppExecFwk::UnwrapStartOptions(engine, argv[NapiPrintUtils::INDEX_TWO], startOptions);
189 unwrapArgc++;
190 }
191
192 NapiAsyncTask::CompleteCallback complete = [weak = context_, want, accountId, startOptions, unwrapArgc](
193 napi_env engine, NapiAsyncTask &task, int32_t status) {
194 auto context = weak.lock();
195 if (!context) {
196 task.Reject(engine, CreateJsError(engine, E_PRINT_INVALID_CONTEXT, "Context is released"));
197 return;
198 }
199
200 ErrCode errcode = ERR_OK;
201 (unwrapArgc == NapiPrintUtils::ARGC_TWO) ? errcode = context->StartAbilityWithAccount(want, accountId)
202 : errcode = context->StartAbilityWithAccount(want, accountId, startOptions);
203 if (errcode == 0) {
204 napi_value undefineResult = nullptr;
205 napi_get_undefined(engine, &undefineResult);
206 task.Resolve(engine, undefineResult);
207 } else {
208 task.Reject(engine, CreateJsError(engine, errcode, "Start Ability failed."));
209 }
210 };
211
212 napi_value lastParam = (argc == unwrapArgc) ? nullptr : argv[unwrapArgc];
213 napi_value result = nullptr;
214 NapiAsyncTask::Schedule("PrintExtensionContext::OnStartAbilityWithAccount", engine,
215 CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
216 return result;
217 }
218
OnTerminateAbility(napi_env & engine,napi_callback_info & info)219 napi_value OnTerminateAbility(napi_env &engine, napi_callback_info &info)
220 {
221 PRINT_HILOGD("OnTerminateAbility is called");
222 size_t argc = NapiPrintUtils::MAX_ARGC;
223 napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
224 napi_get_cb_info(engine, info, &argc, argv, nullptr, nullptr);
225 if (argc != NapiPrintUtils::ARGC_ZERO && argc != NapiPrintUtils::ARGC_ONE) {
226 return GetUndefinedValue(engine);
227 }
228
229 NapiAsyncTask::CompleteCallback complete = [weak = context_](
230 napi_env engine, NapiAsyncTask &task, int32_t status) {
231 PRINT_HILOGD("TerminateAbility begin");
232 auto context = weak.lock();
233 if (!context) {
234 PRINT_HILOGW("context is released");
235 task.Reject(engine, CreateJsError(engine, E_PRINT_INVALID_CONTEXT, "Context is released"));
236 return;
237 }
238
239 auto errcode = context->TerminateAbility();
240 if (errcode == 0) {
241 napi_value undefineResult = nullptr;
242 napi_get_undefined(engine, &undefineResult);
243 task.Resolve(engine, undefineResult);
244 } else {
245 task.Reject(engine, CreateJsError(engine, errcode, "Terminate Ability failed."));
246 }
247 };
248
249 napi_value lastParam = (argc == NapiPrintUtils::ARGC_ZERO) ? nullptr : argv[0];
250 napi_value result = nullptr;
251 NapiAsyncTask::Schedule("PrintExtensionContext::OnTerminateAbility", engine,
252 CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
253 return result;
254 }
255
OnConnectAbility(napi_env & engine,napi_callback_info & info)256 napi_value OnConnectAbility(napi_env &engine, napi_callback_info &info)
257 {
258 PRINT_HILOGD("OnConnectAbility is called");
259 size_t argc = NapiPrintUtils::MAX_ARGC;
260 napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
261 napi_get_cb_info(engine, info, &argc, argv, nullptr, nullptr);
262 if (argc != NapiPrintUtils::ARGC_TWO) {
263 return GetUndefinedValue(engine);
264 }
265
266 AAFwk::Want want;
267 OHOS::AppExecFwk::UnwrapWant(engine, argv[0], want);
268 PRINT_HILOGD("%{public}s bundlename:%{public}s abilityname:%{public}s", __func__, want.GetBundle().c_str(),
269 want.GetElement().GetAbilityName().c_str());
270
271 sptr<JSPrintExtensionConnection> connection = new JSPrintExtensionConnection(engine);
272 connection->SetJsConnectionObject(argv[1]);
273 int64_t connectId = serialNumber_;
274 ConnecttionKey key;
275 key.id = serialNumber_;
276 key.want = want;
277 std::unique_lock<std::shared_timed_mutex> lock(managersMutex_);
278 connects_.emplace(key, connection);
279 (serialNumber_ < INT64_MAX) ? serialNumber_++ : serialNumber_ = 0;
280 NapiAsyncTask::CompleteCallback complete = [weak = context_, want, connection, connectId](
281 napi_env engine, NapiAsyncTask &task, int32_t status) {
282 PRINT_HILOGD("OnConnectAbility begin");
283 auto context = weak.lock();
284 if (!context) {
285 PRINT_HILOGW("context is released");
286 task.Reject(engine, CreateJsError(engine, E_PRINT_INVALID_CONTEXT, "Context is released"));
287 return;
288 }
289 PRINT_HILOGD("context->ConnectAbility connection:%{public}d", (int32_t)connectId);
290 if (!context->ConnectAbility(want, connection)) {
291 connection->CallJsFailed(E_PRINT_INVALID_CONTEXT);
292 }
293 napi_value undefineResult = nullptr;
294 napi_get_undefined(engine, &undefineResult);
295 task.Resolve(engine, undefineResult);
296 };
297 napi_value result = nullptr;
298 NapiAsyncTask::Schedule("PrintExtensionContext::OnConnectAbility", engine,
299 CreateAsyncTaskWithLastParam(engine, nullptr, nullptr, std::move(complete), &result));
300 napi_value numberResult = nullptr;
301 napi_create_double(engine, connectId, &numberResult);
302 return numberResult;
303 }
304
OnConnectAbilityWithAccount(napi_env & engine,napi_callback_info & info)305 napi_value OnConnectAbilityWithAccount(napi_env &engine, napi_callback_info &info)
306 {
307 PRINT_HILOGD("OnConnectAbilityWithAccount is called");
308 size_t argc = NapiPrintUtils::MAX_ARGC;
309 napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
310 napi_get_cb_info(engine, info, &argc, argv, nullptr, nullptr);
311 if (argc != NapiPrintUtils::ARGC_THREE) {
312 return GetUndefinedValue(engine);
313 }
314
315 AAFwk::Want want;
316 OHOS::AppExecFwk::UnwrapWant(engine, argv[0], want);
317 PRINT_HILOGD("%{public}s bundlename:%{public}s abilityname:%{public}s", __func__, want.GetBundle().c_str(),
318 want.GetElement().GetAbilityName().c_str());
319
320 int32_t accountId = 0;
321 if (!OHOS::AppExecFwk::UnwrapInt32FromJS2(engine, argv[1], accountId)) {
322 PRINT_HILOGD("%{public}s called, the second parameter is invalid.", __func__);
323 return GetUndefinedValue(engine);
324 }
325
326 sptr<JSPrintExtensionConnection> connection = new JSPrintExtensionConnection(engine);
327 connection->SetJsConnectionObject(argv[1]);
328 int64_t connectId = serialNumber_;
329 ConnecttionKey key;
330 key.id = serialNumber_;
331 key.want = want;
332 std::unique_lock<std::shared_timed_mutex> lock(managersMutex_);
333 connects_.emplace(key, connection);
334 (serialNumber_ < INT64_MAX) ? serialNumber_++ : serialNumber_ = 0;
335 NapiAsyncTask::CompleteCallback complete = [weak = context_, want, accountId, connection, connectId](
336 napi_env engine, NapiAsyncTask &task, int32_t status) {
337 PRINT_HILOGD("OnConnectAbilityWithAccount begin");
338 auto context = weak.lock();
339 if (!context) {
340 PRINT_HILOGW("context is released");
341 task.Reject(engine, CreateJsError(engine, E_PRINT_INVALID_CONTEXT, "Context is released"));
342 return;
343 }
344 PRINT_HILOGD("context->ConnectAbilityWithAccount connection:%{public}d", (int32_t)connectId);
345 if (!context->ConnectAbilityWithAccount(want, accountId, connection)) {
346 connection->CallJsFailed(E_PRINT_INVALID_CONTEXT);
347 }
348 napi_value undefineResult = nullptr;
349 napi_get_undefined(engine, &undefineResult);
350 task.Resolve(engine, undefineResult);
351 };
352 napi_value result = nullptr;
353 NapiAsyncTask::Schedule("PrintExtensionContext::OnConnectAbilityWithAccount", engine,
354 CreateAsyncTaskWithLastParam(engine, nullptr, nullptr, std::move(complete), &result));
355 napi_value numberResult = nullptr;
356 napi_create_double(engine, connectId, &numberResult);
357 return numberResult;
358 }
359
OnDisconnectAbility(napi_env & engine,napi_callback_info & info)360 napi_value OnDisconnectAbility(napi_env &engine, napi_callback_info &info)
361 {
362 PRINT_HILOGD("OnDisconnectAbility is called");
363 size_t argc = NapiPrintUtils::MAX_ARGC;
364 napi_value argv[NapiPrintUtils::MAX_ARGC] = { nullptr };
365 napi_get_cb_info(engine, info, &argc, argv, nullptr, nullptr);
366 if (argc != NapiPrintUtils::ARGC_ONE && argc != NapiPrintUtils::ARGC_TWO) {
367 return GetUndefinedValue(engine);
368 }
369
370 AAFwk::Want want;
371 int64_t connectId = -1;
372 sptr<JSPrintExtensionConnection> connection = nullptr;
373 napi_get_value_int64(engine, argv[NapiPrintUtils::INDEX_ZERO], &connectId);
374 PRINT_HILOGD("OnDisconnectAbility connection:%{public}d", static_cast<int32_t>(connectId));
375 auto item = std::find_if(connects_.begin(), connects_.end(),
376 [&connectId](const std::map<ConnecttionKey, sptr<JSPrintExtensionConnection>>::value_type &obj) {
377 return connectId == obj.first.id;
378 });
379 if (item != connects_.end()) {
380 // match id
381 want = item->first.want;
382 connection = item->second;
383 } else {
384 PRINT_HILOGD("%{public}s not find conn exist.", __func__);
385 }
386 NapiAsyncTask::CompleteCallback complete = [weak = context_, want, connection](
387 napi_env engine, NapiAsyncTask &task, int32_t status) {
388 PRINT_HILOGD("OnDisconnectAbility begin");
389 auto context = weak.lock();
390 if (!context) {
391 PRINT_HILOGW("context is released");
392 task.Reject(engine, CreateJsError(engine, E_PRINT_INVALID_CONTEXT, "Context is released"));
393 return;
394 }
395 if (connection == nullptr) {
396 PRINT_HILOGW("connection nullptr");
397 task.Reject(engine, CreateJsError(engine, E_PRINT_INVALID_CONNECTION, "not found connection"));
398 return;
399 }
400 PRINT_HILOGD("context->DisconnectAbility");
401 auto errcode = context->DisconnectAbility(want, connection);
402 napi_value undefineResult = nullptr;
403 napi_get_undefined(engine, &undefineResult);
404 errcode == 0 ? task.Resolve(engine, undefineResult)
405 : task.Reject(engine, CreateJsError(engine, errcode, "Disconnect Ability failed."));
406 };
407
408 napi_value lastParam = (argc == NapiPrintUtils::ARGC_ONE) ? nullptr : argv[1];
409 napi_value result = nullptr;
410 NapiAsyncTask::Schedule("PrintExtensionContext::OnDisconnectAbility", engine,
411 CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
412 return result;
413 }
414 };
415
CreateJsMetadata(napi_env & engine,const AppExecFwk::Metadata & Info)416 napi_value CreateJsMetadata(napi_env &engine, const AppExecFwk::Metadata &Info)
417 {
418 PRINT_HILOGD("CreateJsMetadata");
419 napi_value object = nullptr;
420 napi_create_object(engine, &object);
421
422 napi_set_named_property(engine, object, "name", CreateJsValue(engine, Info.name));
423 napi_set_named_property(engine, object, "value", CreateJsValue(engine, Info.value));
424 napi_set_named_property(engine, object, "resource", CreateJsValue(engine, Info.resource));
425 return object;
426 }
427
CreateJsMetadataArray(napi_env & engine,const std::vector<AppExecFwk::Metadata> & info)428 napi_value CreateJsMetadataArray(napi_env &engine, const std::vector<AppExecFwk::Metadata> &info)
429 {
430 PRINT_HILOGD("CreateJsMetadataArray");
431 napi_value arrayValue = nullptr;
432 napi_status ret = napi_create_array_with_length(engine, info.size(), &arrayValue);
433 if (ret != napi_ok && arrayValue != nullptr) {
434 uint32_t index = 0;
435 for (const auto &item: info) {
436 napi_set_element(engine, arrayValue, index++, CreateJsMetadata(engine, item));
437 }
438 }
439 return arrayValue;
440 }
441
CreateJsExtensionAbilityInfoMessage(napi_env & engine,const AppExecFwk::ExtensionAbilityInfo & info)442 napi_value CreateJsExtensionAbilityInfoMessage(napi_env &engine, const AppExecFwk::ExtensionAbilityInfo &info)
443 {
444 PRINT_HILOGD("CreateJsExtensionAbilityInfoMessage");
445 napi_value object = nullptr;
446 napi_create_object(engine, &object);
447 napi_set_named_property(engine, object, "bundleName", CreateJsValue(engine, info.bundleName));
448 napi_set_named_property(engine, object, "moduleName", CreateJsValue(engine, info.moduleName));
449 napi_set_named_property(engine, object, "name", CreateJsValue(engine, info.name));
450 napi_set_named_property(engine, object, "labelId", CreateJsValue(engine, info.labelId));
451 napi_set_named_property(engine, object, "descriptionId", CreateJsValue(engine, info.descriptionId));
452 napi_set_named_property(engine, object, "iconId", CreateJsValue(engine, info.iconId));
453 napi_set_named_property(engine, object, "isVisible", CreateJsValue(engine, info.visible));
454 napi_set_named_property(engine, object, "extensionAbilityType", CreateJsValue(engine, info.type));
455
456 napi_value permissionArrayValue = nullptr;
457 napi_create_array_with_length(engine, info.permissions.size(), &permissionArrayValue);
458 if (permissionArrayValue != nullptr) {
459 uint32_t index = 0;
460 for (auto permission : info.permissions) {
461 napi_set_element(engine, permissionArrayValue, index++, CreateJsValue(engine, permission));
462 }
463 }
464 napi_set_named_property(engine, object, "permissions", permissionArrayValue);
465 napi_set_named_property(engine, object, "applicationInfo", CreateJsApplicationInfo(engine, info.applicationInfo));
466 napi_set_named_property(engine, object, "metadata", CreateJsMetadataArray(engine, info.metadata));
467 napi_set_named_property(engine, object, "enabled", CreateJsValue(engine, info.enabled));
468 napi_set_named_property(engine, object, "readPermission", CreateJsValue(engine, info.readPermission));
469 napi_set_named_property(engine, object, "writePermission", CreateJsValue(engine, info.writePermission));
470 return object;
471 }
472
CreateJsPrintExtensionContext(napi_env engine,std::shared_ptr<PrintExtensionContext> context,std::string & extensionId)473 napi_value CreateJsPrintExtensionContext(napi_env engine,
474 std::shared_ptr<PrintExtensionContext> context, std::string &extensionId)
475 {
476 PRINT_HILOGD("CreateJsPrintExtensionContext begin");
477 napi_value objValue = CreateJsExtensionContext(engine, context);
478 napi_value object = objValue;
479
480 std::unique_ptr<JsPrintExtensionContext> jsContext = std::make_unique<JsPrintExtensionContext>(context);
481 napi_wrap(engine, object, jsContext.release(), JsPrintExtensionContext::Finalizer, nullptr, nullptr);
482
483 // make handler
484 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
485 const char *moduleName = "JsPrintExtensionContext";
486 BindNativeFunction(engine, object, "startAbility", moduleName, JsPrintExtensionContext::StartAbility);
487 BindNativeFunction(engine, object, "terminateSelf", moduleName, JsPrintExtensionContext::TerminateAbility);
488 BindNativeFunction(engine, object, "connectAbility", moduleName, JsPrintExtensionContext::ConnectAbility);
489 BindNativeFunction(engine, object, "disconnectAbility", moduleName, JsPrintExtensionContext::DisconnectAbility);
490 BindNativeFunction(
491 engine, object, "startAbilityWithAccount", moduleName, JsPrintExtensionContext::StartAbilityWithAccount);
492 BindNativeFunction(
493 engine, object, "connectAbilityWithAccount", moduleName, JsPrintExtensionContext::ConnectAbilityWithAccount);
494 if (context) {
495 PRINT_HILOGD("Set ExtensionAbilityInfo Property");
496 auto abilityInfo = context->GetAbilityInfo();
497 auto hapModuleInfo = context->GetHapModuleInfo();
498 if (abilityInfo && hapModuleInfo) {
499 extensionId = abilityInfo->bundleName;
500 PRINT_HILOGD("Set ExtensionAbilityInfo Property: extensionId = %{public}s", extensionId.c_str());
501 auto isExist = [&abilityInfo](const AppExecFwk::ExtensionAbilityInfo &info) {
502 PRINT_HILOGD("%{public}s, %{public}s", info.bundleName.c_str(), info.name.c_str());
503 return info.bundleName == abilityInfo->bundleName && info.name == abilityInfo->name;
504 };
505 auto infoIter =
506 std::find_if(hapModuleInfo->extensionInfos.begin(), hapModuleInfo->extensionInfos.end(), isExist);
507 if (infoIter == hapModuleInfo->extensionInfos.end()) {
508 PRINT_HILOGD("Get target fail.");
509 return objValue;
510 }
511 napi_set_named_property(engine, object,
512 "extensionAbilityInfo", CreateJsExtensionAbilityInfoMessage(engine, *infoIter));
513 }
514 }
515
516 return objValue;
517 }
518 } // namespace AbilityRuntime
519 } // namespace OHOS
520