1 /*
2 * Copyright (c) 2021-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 "ability_runtime/js_ability_context.h"
17
18 #include <cstdint>
19
20 #include "hitrace_meter.h"
21 #include "hilog_wrapper.h"
22 #include "js_context_utils.h"
23 #include "js_data_struct_converter.h"
24 #include "js_error_utils.h"
25 #include "js_runtime_utils.h"
26 #include "ability_runtime/js_caller_complex.h"
27 #include "napi_common_ability.h"
28 #include "napi_common_start_options.h"
29 #include "napi_common_util.h"
30 #include "napi_common_want.h"
31 #include "napi_remote_object.h"
32 #include "start_options.h"
33 #include "want.h"
34 #include "event_handler.h"
35 #include "hitrace_meter.h"
36
37 #ifdef SUPPORT_GRAPHICS
38 #include "pixel_map_napi.h"
39 #endif
40
41 namespace OHOS {
42 namespace AbilityRuntime {
43 constexpr int32_t INDEX_TWO = 2;
44 constexpr size_t ARGC_ZERO = 0;
45 constexpr size_t ARGC_ONE = 1;
46 constexpr size_t ARGC_TWO = 2;
47 constexpr size_t ARGC_THREE = 3;
48 constexpr int32_t ERROR_CODE_ONE = 1;
49
50 class StartAbilityByCallParameters {
51 public:
52 int err = 0;
53 sptr<IRemoteObject> remoteCallee = nullptr;
54 std::shared_ptr<CallerCallBack> callerCallBack = nullptr;
55 std::mutex mutexlock;
56 std::condition_variable condition;
57 };
58
Finalizer(NativeEngine * engine,void * data,void * hint)59 void JsAbilityContext::Finalizer(NativeEngine* engine, void* data, void* hint)
60 {
61 HILOG_INFO("JsAbilityContext::Finalizer is called");
62 std::unique_ptr<JsAbilityContext>(static_cast<JsAbilityContext*>(data));
63 }
64
StartAbility(NativeEngine * engine,NativeCallbackInfo * info)65 NativeValue* JsAbilityContext::StartAbility(NativeEngine* engine, NativeCallbackInfo* info)
66 {
67 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
68 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
69 return (me != nullptr) ? me->OnStartAbility(*engine, *info) : nullptr;
70 }
71
StartRecentAbility(NativeEngine * engine,NativeCallbackInfo * info)72 NativeValue* JsAbilityContext::StartRecentAbility(NativeEngine* engine, NativeCallbackInfo* info)
73 {
74 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
75 return (me != nullptr) ? me->OnStartAbility(*engine, *info, true) : nullptr;
76 }
77
StartAbilityWithAccount(NativeEngine * engine,NativeCallbackInfo * info)78 NativeValue* JsAbilityContext::StartAbilityWithAccount(NativeEngine* engine, NativeCallbackInfo* info)
79 {
80 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
81 return (me != nullptr) ? me->OnStartAbilityWithAccount(*engine, *info) : nullptr;
82 }
83
StartAbilityByCall(NativeEngine * engine,NativeCallbackInfo * info)84 NativeValue* JsAbilityContext::StartAbilityByCall(NativeEngine* engine, NativeCallbackInfo* info)
85 {
86 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
87 return (me != nullptr) ? me->OnStartAbilityByCall(*engine, *info) : nullptr;
88 }
89
StartAbilityForResult(NativeEngine * engine,NativeCallbackInfo * info)90 NativeValue* JsAbilityContext::StartAbilityForResult(NativeEngine* engine, NativeCallbackInfo* info)
91 {
92 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
93 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
94 return (me != nullptr) ? me->OnStartAbilityForResult(*engine, *info) : nullptr;
95 }
96
StartAbilityForResultWithAccount(NativeEngine * engine,NativeCallbackInfo * info)97 NativeValue* JsAbilityContext::StartAbilityForResultWithAccount(NativeEngine* engine, NativeCallbackInfo* info)
98 {
99 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
100 return (me != nullptr) ? me->OnStartAbilityForResultWithAccount(*engine, *info) : nullptr;
101 }
102
StartServiceExtensionAbility(NativeEngine * engine,NativeCallbackInfo * info)103 NativeValue* JsAbilityContext::StartServiceExtensionAbility(NativeEngine* engine, NativeCallbackInfo* info)
104 {
105 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
106 return (me != nullptr) ? me->OnStartExtensionAbility(*engine, *info) : nullptr;
107 }
108
StartServiceExtensionAbilityWithAccount(NativeEngine * engine,NativeCallbackInfo * info)109 NativeValue* JsAbilityContext::StartServiceExtensionAbilityWithAccount(NativeEngine* engine, NativeCallbackInfo* info)
110 {
111 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
112 return (me != nullptr) ? me->OnStartExtensionAbilityWithAccount(*engine, *info) : nullptr;
113 }
114
StopServiceExtensionAbility(NativeEngine * engine,NativeCallbackInfo * info)115 NativeValue* JsAbilityContext::StopServiceExtensionAbility(NativeEngine* engine, NativeCallbackInfo* info)
116 {
117 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
118 return (me != nullptr) ? me->OnStopExtensionAbility(*engine, *info) : nullptr;
119 }
120
StopServiceExtensionAbilityWithAccount(NativeEngine * engine,NativeCallbackInfo * info)121 NativeValue* JsAbilityContext::StopServiceExtensionAbilityWithAccount(NativeEngine* engine, NativeCallbackInfo* info)
122 {
123 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
124 return (me != nullptr) ? me->OnStopExtensionAbilityWithAccount(*engine, *info) : nullptr;
125 }
126
ConnectAbility(NativeEngine * engine,NativeCallbackInfo * info)127 NativeValue* JsAbilityContext::ConnectAbility(NativeEngine* engine, NativeCallbackInfo* info)
128 {
129 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
130 return (me != nullptr) ? me->OnConnectAbility(*engine, *info) : nullptr;
131 }
132
ConnectAbilityWithAccount(NativeEngine * engine,NativeCallbackInfo * info)133 NativeValue* JsAbilityContext::ConnectAbilityWithAccount(NativeEngine* engine, NativeCallbackInfo* info)
134 {
135 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
136 return (me != nullptr) ? me->OnConnectAbilityWithAccount(*engine, *info) : nullptr;
137 }
138
DisconnectAbility(NativeEngine * engine,NativeCallbackInfo * info)139 NativeValue* JsAbilityContext::DisconnectAbility(NativeEngine* engine, NativeCallbackInfo* info)
140 {
141 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
142 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
143 return (me != nullptr) ? me->OnDisconnectAbility(*engine, *info) : nullptr;
144 }
145
TerminateSelf(NativeEngine * engine,NativeCallbackInfo * info)146 NativeValue* JsAbilityContext::TerminateSelf(NativeEngine* engine, NativeCallbackInfo* info)
147 {
148 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
149 return (me != nullptr) ? me->OnTerminateSelf(*engine, *info) : nullptr;
150 }
151
TerminateSelfWithResult(NativeEngine * engine,NativeCallbackInfo * info)152 NativeValue* JsAbilityContext::TerminateSelfWithResult(NativeEngine* engine, NativeCallbackInfo* info)
153 {
154 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
155 return (me != nullptr) ? me->OnTerminateSelfWithResult(*engine, *info) : nullptr;
156 }
157
RequestPermissionsFromUser(NativeEngine * engine,NativeCallbackInfo * info)158 NativeValue* JsAbilityContext::RequestPermissionsFromUser(NativeEngine* engine, NativeCallbackInfo* info)
159 {
160 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
161 return (me != nullptr) ? me->OnRequestPermissionsFromUser(*engine, *info) : nullptr;
162 }
163
RestoreWindowStage(NativeEngine * engine,NativeCallbackInfo * info)164 NativeValue* JsAbilityContext::RestoreWindowStage(NativeEngine* engine, NativeCallbackInfo* info)
165 {
166 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
167 return (me != nullptr) ? me->OnRestoreWindowStage(*engine, *info) : nullptr;
168 }
169
RequestDialogService(NativeEngine * engine,NativeCallbackInfo * info)170 NativeValue* JsAbilityContext::RequestDialogService(NativeEngine* engine, NativeCallbackInfo* info)
171 {
172 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
173 return (me != nullptr) ? me->OnRequestDialogService(*engine, *info) : nullptr;
174 }
175
IsTerminating(NativeEngine * engine,NativeCallbackInfo * info)176 NativeValue* JsAbilityContext::IsTerminating(NativeEngine* engine, NativeCallbackInfo* info)
177 {
178 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
179 return (me != nullptr) ? me->OnIsTerminating(*engine, *info) : nullptr;
180 }
181
OnStartAbility(NativeEngine & engine,NativeCallbackInfo & info,bool isStartRecent)182 NativeValue* JsAbilityContext::OnStartAbility(NativeEngine& engine, NativeCallbackInfo& info, bool isStartRecent)
183 {
184 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
185 HILOG_INFO("OnStartAbility is called.");
186
187 if (info.argc == ARGC_ZERO) {
188 HILOG_ERROR("Not enough params");
189 ThrowTooFewParametersError(engine);
190 return engine.CreateUndefined();
191 }
192
193 AAFwk::Want want;
194 OHOS::AppExecFwk::UnwrapWant(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[0]), want);
195 InheritWindowMode(want);
196 decltype(info.argc) unwrapArgc = 1;
197 HILOG_INFO("Start ability, ability name is %{public}s.", want.GetElement().GetAbilityName().c_str());
198 AAFwk::StartOptions startOptions;
199 if (info.argc > ARGC_ONE && info.argv[1]->TypeOf() == NATIVE_OBJECT) {
200 HILOG_INFO("OnStartAbility start options is used.");
201 AppExecFwk::UnwrapStartOptions(reinterpret_cast<napi_env>(&engine),
202 reinterpret_cast<napi_value>(info.argv[1]), startOptions);
203 unwrapArgc++;
204 }
205
206 if (isStartRecent) {
207 HILOG_INFO("OnStartRecentAbility is called");
208 want.SetParam(Want::PARAM_RESV_START_RECENT, true);
209 }
210
211 AsyncTask::CompleteCallback complete =
212 [weak = context_, want, startOptions, unwrapArgc](NativeEngine& engine, AsyncTask& task, int32_t status) {
213 auto context = weak.lock();
214 if (!context) {
215 HILOG_WARN("context is released");
216 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
217 return;
218 }
219 auto innerErrorCode = (unwrapArgc == 1) ?
220 context->StartAbility(want, -1) : context->StartAbility(want, startOptions, -1);
221 if (innerErrorCode == 0) {
222 task.Resolve(engine, engine.CreateUndefined());
223 } else {
224 task.Reject(engine, CreateJsErrorByNativeErr(engine, innerErrorCode));
225 }
226 };
227
228 NativeValue* lastParam = (info.argc > unwrapArgc) ? info.argv[unwrapArgc] : nullptr;
229 NativeValue* result = nullptr;
230 AsyncTask::Schedule("JsAbilityContext::OnStartAbility",
231 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
232 return result;
233 }
234
OnStartAbilityWithAccount(NativeEngine & engine,NativeCallbackInfo & info)235 NativeValue* JsAbilityContext::OnStartAbilityWithAccount(NativeEngine& engine, NativeCallbackInfo& info)
236 {
237 HILOG_INFO("OnStartAbilityWithAccount is called");
238 if (info.argc < ARGC_TWO) {
239 ThrowTooFewParametersError(engine);
240 return engine.CreateUndefined();
241 }
242 AAFwk::Want want;
243 OHOS::AppExecFwk::UnwrapWant(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[0]), want);
244 InheritWindowMode(want);
245 decltype(info.argc) unwrapArgc = 1;
246 HILOG_INFO("abilityName=%{public}s", want.GetElement().GetAbilityName().c_str());
247 int32_t accountId = 0;
248 if (!OHOS::AppExecFwk::UnwrapInt32FromJS2(reinterpret_cast<napi_env>(&engine),
249 reinterpret_cast<napi_value>(info.argv[1]), accountId)) {
250 HILOG_INFO("%{public}s called, the second parameter is invalid.", __func__);
251 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
252 return engine.CreateUndefined();
253 }
254 unwrapArgc++;
255 AAFwk::StartOptions startOptions;
256 if (info.argc > ARGC_TWO && info.argv[INDEX_TWO]->TypeOf() == NATIVE_OBJECT) {
257 HILOG_INFO("OnStartAbilityWithAccount start options is used.");
258 AppExecFwk::UnwrapStartOptions(reinterpret_cast<napi_env>(&engine),
259 reinterpret_cast<napi_value>(info.argv[ARGC_TWO]), startOptions);
260 unwrapArgc++;
261 }
262 AsyncTask::CompleteCallback complete =
263 [weak = context_, want, accountId, startOptions, unwrapArgc](
264 NativeEngine& engine, AsyncTask& task, int32_t status) {
265 auto context = weak.lock();
266 if (!context) {
267 HILOG_WARN("context is released");
268 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
269 return;
270 }
271
272 auto innerErrorCode = (unwrapArgc == INDEX_TWO) ?
273 context->StartAbilityWithAccount(want, accountId, -1) : context->StartAbilityWithAccount(
274 want, accountId, startOptions, -1);
275 if (innerErrorCode == 0) {
276 task.Resolve(engine, engine.CreateUndefined());
277 } else {
278 task.Reject(engine, CreateJsErrorByNativeErr(engine, innerErrorCode));
279 }
280 };
281
282 NativeValue* lastParam = (info.argc > unwrapArgc) ? info.argv[unwrapArgc] : nullptr;
283 NativeValue* result = nullptr;
284 AsyncTask::Schedule("JsAbilityContext::OnStartAbilityWithAccount",
285 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
286 return result;
287 }
288
OnStartAbilityByCall(NativeEngine & engine,NativeCallbackInfo & info)289 NativeValue* JsAbilityContext::OnStartAbilityByCall(NativeEngine& engine, NativeCallbackInfo& info)
290 {
291 HILOG_DEBUG("JsAbilityContext::%{public}s, called", __func__);
292 if (info.argc < ARGC_ONE) {
293 ThrowTooFewParametersError(engine);
294 return engine.CreateUndefined();
295 }
296
297 AAFwk::Want want;
298 if (info.argv[0]->TypeOf() != NATIVE_OBJECT ||
299 !JsAbilityContext::UnWrapWant(engine, info.argv[0], want)) {
300 HILOG_ERROR("Failed to parse want!");
301 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
302 return engine.CreateUndefined();
303 }
304 InheritWindowMode(want);
305
306 std::shared_ptr<StartAbilityByCallParameters> calls = std::make_shared<StartAbilityByCallParameters>();
307 NativeValue* lastParam = ((info.argc == ARGC_TWO) ? info.argv[ARGC_ONE] : nullptr);
308 NativeValue* retsult = nullptr;
309
310 calls->callerCallBack = std::make_shared<CallerCallBack>();
311
312 auto callBackDone = [calldata = calls] (const sptr<IRemoteObject> &obj) {
313 HILOG_DEBUG("OnStartAbilityByCall callBackDone mutexlock");
314 std::unique_lock<std::mutex> lock(calldata->mutexlock);
315 HILOG_DEBUG("OnStartAbilityByCall callBackDone remoteCallee assignment");
316 calldata->remoteCallee = obj;
317 calldata->condition.notify_all();
318 HILOG_INFO("OnStartAbilityByCall callBackDone is called end");
319 };
320
321 auto releaseListen = [](const std::string &str) {
322 HILOG_INFO("OnStartAbilityByCall releaseListen is called %{public}s", str.c_str());
323 };
324
325 auto callExecute = [calldata = calls] () {
326 constexpr int CALLER_TIME_OUT = 10; // 10s
327 std::unique_lock<std::mutex> lock(calldata->mutexlock);
328 if (calldata->remoteCallee != nullptr) {
329 HILOG_INFO("OnStartAbilityByCall callExecute callee isn`t nullptr");
330 return;
331 }
332
333 if (calldata->condition.wait_for(lock, std::chrono::seconds(CALLER_TIME_OUT)) == std::cv_status::timeout) {
334 HILOG_ERROR("OnStartAbilityByCall callExecute waiting callee timeout");
335 calldata->err = -1;
336 }
337 HILOG_DEBUG("OnStartAbilityByCall callExecute end");
338 };
339
340 auto callComplete = [weak = context_, calldata = calls] (
341 NativeEngine& engine, AsyncTask& task, int32_t status) {
342 if (calldata->err != 0) {
343 HILOG_ERROR("OnStartAbilityByCall callComplete err is %{public}d", calldata->err);
344 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
345 return;
346 }
347
348 auto context = weak.lock();
349 if (context != nullptr && calldata->callerCallBack != nullptr && calldata->remoteCallee != nullptr) {
350 auto releaseCallAbilityFunc = [weak] (
351 const std::shared_ptr<CallerCallBack> &callback) -> ErrCode {
352 auto contextForRelease = weak.lock();
353 if (contextForRelease == nullptr) {
354 HILOG_ERROR("releaseCallAbilityFunction, context is nullptr");
355 return -1;
356 }
357 return contextForRelease->ReleaseCall(callback);
358 };
359 task.Resolve(engine,
360 CreateJsCallerComplex(
361 engine, releaseCallAbilityFunc, calldata->remoteCallee, calldata->callerCallBack));
362 } else {
363 HILOG_ERROR("OnStartAbilityByCall callComplete params error %{public}s is nullptr",
364 context == nullptr ? "context" :
365 (calldata->remoteCallee == nullptr ? "remoteCallee" : "callerCallBack"));
366 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
367 }
368
369 HILOG_DEBUG("OnStartAbilityByCall callComplete end");
370 };
371
372 calls->callerCallBack->SetCallBack(callBackDone);
373 calls->callerCallBack->SetOnRelease(releaseListen);
374
375 auto context = context_.lock();
376 if (context == nullptr) {
377 HILOG_ERROR("OnStartAbilityByCall context is nullptr");
378 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
379 return engine.CreateUndefined();
380 }
381
382 auto ret = context->StartAbilityByCall(want, calls->callerCallBack);
383 if (ret != 0) {
384 HILOG_ERROR("OnStartAbilityByCall StartAbility is failed");
385 ThrowErrorByNativeErr(engine, ret);
386 return engine.CreateUndefined();
387 }
388
389 if (calls->remoteCallee == nullptr) {
390 HILOG_INFO("OnStartAbilityByCall async wait execute");
391 AsyncTask::Schedule("JsAbilityContext::OnStartAbilityByCall",
392 engine,
393 CreateAsyncTaskWithLastParam(
394 engine, lastParam, std::move(callExecute), std::move(callComplete), &retsult));
395 } else {
396 HILOG_INFO("OnStartAbilityByCall promiss return result execute");
397 AsyncTask::Schedule("JsAbilityContext::OnStartAbilityByCall", engine,
398 CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(callComplete), &retsult));
399 }
400
401 HILOG_DEBUG("JsAbilityContext::%{public}s, called end", __func__);
402 return retsult;
403 }
404
OnStartAbilityForResult(NativeEngine & engine,NativeCallbackInfo & info)405 NativeValue* JsAbilityContext::OnStartAbilityForResult(NativeEngine& engine, NativeCallbackInfo& info)
406 {
407 HILOG_INFO("OnStartAbilityForResult is called");
408
409 if (info.argc == ARGC_ZERO) {
410 ThrowTooFewParametersError(engine);
411 return engine.CreateUndefined();
412 }
413
414 AAFwk::Want want;
415 if (!JsAbilityContext::UnWrapWant(engine, info.argv[0], want)) {
416 HILOG_ERROR("%s Failed to parse want!", __func__);
417 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
418 return engine.CreateUndefined();
419 }
420 InheritWindowMode(want);
421 decltype(info.argc) unwrapArgc = 1;
422 AAFwk::StartOptions startOptions;
423 if (info.argc > ARGC_ONE && info.argv[1]->TypeOf() == NATIVE_OBJECT) {
424 HILOG_INFO("OnStartAbilityForResult start options is used.");
425 AppExecFwk::UnwrapStartOptions(reinterpret_cast<napi_env>(&engine),
426 reinterpret_cast<napi_value>(info.argv[1]), startOptions);
427 unwrapArgc++;
428 }
429
430 NativeValue* lastParam = info.argc > unwrapArgc ? info.argv[unwrapArgc] : nullptr;
431 NativeValue* result = nullptr;
432 std::unique_ptr<AsyncTask> uasyncTask =
433 CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, nullptr, &result);
434 std::shared_ptr<AsyncTask> asyncTask = std::move(uasyncTask);
435 RuntimeTask task = [&engine, asyncTask](int resultCode, const AAFwk::Want& want) {
436 HILOG_INFO("OnStartAbilityForResult async callback is called");
437 NativeValue* abilityResult = JsAbilityContext::WrapAbilityResult(engine, resultCode, want);
438 if (abilityResult == nullptr) {
439 HILOG_WARN("wrap abilityResult failed");
440 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
441 } else {
442 asyncTask->Resolve(engine, abilityResult);
443 }
444 };
445 auto context = context_.lock();
446 if (context == nullptr) {
447 HILOG_WARN("context is released");
448 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
449 } else {
450 want.SetParam(Want::PARAM_RESV_FOR_RESULT, true);
451 curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1);
452 (unwrapArgc == 1) ? context->StartAbilityForResult(want, curRequestCode_, std::move(task)) :
453 context->StartAbilityForResult(want, startOptions, curRequestCode_, std::move(task));
454 }
455 HILOG_INFO("OnStartAbilityForResult is called end");
456 return result;
457 }
458
OnStartAbilityForResultWithAccount(NativeEngine & engine,NativeCallbackInfo & info)459 NativeValue* JsAbilityContext::OnStartAbilityForResultWithAccount(NativeEngine& engine, NativeCallbackInfo& info)
460 {
461 HILOG_INFO("OnStartAbilityForResultWithAccount is called");
462 if (info.argc < ARGC_TWO) {
463 HILOG_ERROR("Not enough params");
464 ThrowTooFewParametersError(engine);
465 return engine.CreateUndefined();
466 }
467 AAFwk::Want want;
468 if (!JsAbilityContext::UnWrapWant(engine, info.argv[0], want)) {
469 HILOG_ERROR("%s Failed to parse want!", __func__);
470 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
471 return engine.CreateUndefined();
472 }
473 InheritWindowMode(want);
474 decltype(info.argc) unwrapArgc = 1;
475 int32_t accountId = 0;
476 if (!OHOS::AppExecFwk::UnwrapInt32FromJS2(reinterpret_cast<napi_env>(&engine),
477 reinterpret_cast<napi_value>(info.argv[1]), accountId)) {
478 HILOG_INFO("%{public}s called, the second parameter is invalid.", __func__);
479 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
480 return engine.CreateUndefined();
481 }
482 unwrapArgc++;
483 AAFwk::StartOptions startOptions;
484 if (info.argc > ARGC_TWO && info.argv[INDEX_TWO]->TypeOf() == NATIVE_OBJECT) {
485 HILOG_INFO("OnStartAbilityForResultWithAccount start options is used.");
486 AppExecFwk::UnwrapStartOptions(reinterpret_cast<napi_env>(&engine),
487 reinterpret_cast<napi_value>(info.argv[INDEX_TWO]), startOptions);
488 unwrapArgc++;
489 }
490 NativeValue* lastParam = info.argc > unwrapArgc ? info.argv[unwrapArgc] : nullptr;
491 NativeValue* result = nullptr;
492 std::unique_ptr<AsyncTask> uasyncTask =
493 CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, nullptr, &result);
494 std::shared_ptr<AsyncTask> asyncTask = std::move(uasyncTask);
495 RuntimeTask task = [&engine, asyncTask](int resultCode, const AAFwk::Want& want) {
496 HILOG_INFO("OnStartAbilityForResultWithAccount async callback is called");
497 NativeValue* abilityResult = JsAbilityContext::WrapAbilityResult(engine, resultCode, want);
498 if (abilityResult == nullptr) {
499 HILOG_WARN("wrap abilityResult failed");
500 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
501 } else {
502 asyncTask->Resolve(engine, abilityResult);
503 }
504 HILOG_INFO("OnStartAbilityForResultWithAccount async callback is called end");
505 };
506 auto context = context_.lock();
507 if (context == nullptr) {
508 HILOG_WARN("context is released");
509 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
510 } else {
511 curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1);
512 (unwrapArgc == INDEX_TWO) ? context->StartAbilityForResultWithAccount(
513 want, accountId, curRequestCode_, std::move(task)) : context->StartAbilityForResultWithAccount(
514 want, accountId, startOptions, curRequestCode_, std::move(task));
515 }
516 HILOG_INFO("OnStartAbilityForResultWithAccount is called end");
517 return result;
518 }
519
OnStartExtensionAbility(NativeEngine & engine,NativeCallbackInfo & info)520 NativeValue* JsAbilityContext::OnStartExtensionAbility(NativeEngine& engine, NativeCallbackInfo& info)
521 {
522 HILOG_INFO("OnStartExtensionAbility is called.");
523 if (info.argc < ARGC_ONE) {
524 ThrowTooFewParametersError(engine);
525 return engine.CreateUndefined();
526 }
527
528 AAFwk::Want want;
529 if (!JsAbilityContext::UnWrapWant(engine, info.argv[0], want)) {
530 HILOG_ERROR("Failed to parse want!");
531 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
532 return engine.CreateUndefined();
533 }
534
535 AsyncTask::CompleteCallback complete =
536 [weak = context_, want](NativeEngine& engine, AsyncTask& task, int32_t status) {
537 auto context = weak.lock();
538 if (!context) {
539 HILOG_WARN("context is released");
540 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
541 return;
542 }
543 auto errcode = context->StartServiceExtensionAbility(want);
544 if (errcode == 0) {
545 task.Resolve(engine, engine.CreateUndefined());
546 } else {
547 task.Reject(engine, CreateJsErrorByNativeErr(engine, errcode));
548 }
549 };
550
551 NativeValue* lastParam = (info.argc > ARGC_ONE) ? info.argv[ARGC_ONE] : nullptr;
552 NativeValue* result = nullptr;
553 AsyncTask::Schedule("JsAbilityContext::OnStartExtensionAbility",
554 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
555 return result;
556 }
557
OnStartExtensionAbilityWithAccount(NativeEngine & engine,const NativeCallbackInfo & info)558 NativeValue* JsAbilityContext::OnStartExtensionAbilityWithAccount(NativeEngine& engine, const NativeCallbackInfo& info)
559 {
560 HILOG_INFO("OnStartExtensionAbilityWithAccount is called.");
561 if (info.argc < ARGC_TWO) {
562 HILOG_ERROR("param is too few.");
563 ThrowTooFewParametersError(engine);
564 return engine.CreateUndefined();
565 }
566
567 AAFwk::Want want;
568 int32_t accountId = -1;
569 if (!JsAbilityContext::UnWrapWant(engine, info.argv[0], want) ||
570 !OHOS::AppExecFwk::UnwrapInt32FromJS2(reinterpret_cast<napi_env>(&engine),
571 reinterpret_cast<napi_value>(info.argv[1]), accountId)) {
572 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
573 return engine.CreateUndefined();
574 }
575
576 AsyncTask::CompleteCallback complete =
577 [weak = context_, want, accountId](NativeEngine& engine, AsyncTask& task, int32_t status) {
578 auto context = weak.lock();
579 if (!context) {
580 HILOG_WARN("context is released");
581 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
582 return;
583 }
584 auto errcode = context->StartServiceExtensionAbility(want, accountId);
585 if (errcode == 0) {
586 task.Resolve(engine, engine.CreateUndefined());
587 } else {
588 task.Reject(engine, CreateJsErrorByNativeErr(engine, errcode));
589 }
590 };
591
592 NativeValue* lastParam = (info.argc > ARGC_TWO) ? info.argv[ARGC_TWO] : nullptr;
593 NativeValue* result = nullptr;
594 AsyncTask::Schedule("JsAbilityContext::OnStartExtensionAbilityWithAccount",
595 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
596 return result;
597 }
598
OnStopExtensionAbility(NativeEngine & engine,const NativeCallbackInfo & info)599 NativeValue* JsAbilityContext::OnStopExtensionAbility(NativeEngine& engine, const NativeCallbackInfo& info)
600 {
601 HILOG_INFO("OnStopExtensionAbility is called.");
602 if (info.argc < ARGC_ONE) {
603 HILOG_ERROR("param is too few for stop extension ability.");
604 ThrowTooFewParametersError(engine);
605 return engine.CreateUndefined();
606 }
607
608 AAFwk::Want want;
609 if (!JsAbilityContext::UnWrapWant(engine, info.argv[0], want)) {
610 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
611 return engine.CreateUndefined();
612 }
613
614 AsyncTask::CompleteCallback complete =
615 [weak = context_, want](NativeEngine& engine, AsyncTask& task, int32_t status) {
616 auto context = weak.lock();
617 if (!context) {
618 HILOG_WARN("context is released");
619 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
620 return;
621 }
622 auto errcode = context->StopServiceExtensionAbility(want);
623 if (errcode == 0) {
624 task.Resolve(engine, engine.CreateUndefined());
625 } else {
626 task.Reject(engine, CreateJsErrorByNativeErr(engine, errcode));
627 }
628 };
629
630 NativeValue* lastParam = (info.argc > ARGC_ONE) ? info.argv[ARGC_ONE] : nullptr;
631 NativeValue* result = nullptr;
632 AsyncTask::Schedule("JsAbilityContext::OnStopExtensionAbility",
633 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
634 return result;
635 }
636
OnStopExtensionAbilityWithAccount(NativeEngine & engine,const NativeCallbackInfo & info)637 NativeValue* JsAbilityContext::OnStopExtensionAbilityWithAccount(NativeEngine& engine, const NativeCallbackInfo& info)
638 {
639 HILOG_INFO("OnStartExtensionAbilityWithAccount is called.");
640 if (info.argc < ARGC_TWO) {
641 HILOG_ERROR("param is too few for stop extension ability with account.");
642 ThrowTooFewParametersError(engine);
643 return engine.CreateUndefined();
644 }
645
646 int32_t accountId = -1;
647 AAFwk::Want want;
648 if (!JsAbilityContext::UnWrapWant(engine, info.argv[0], want) ||
649 !OHOS::AppExecFwk::UnwrapInt32FromJS2(reinterpret_cast<napi_env>(&engine),
650 reinterpret_cast<napi_value>(info.argv[1]), accountId)) {
651 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
652 return engine.CreateUndefined();
653 }
654
655 AsyncTask::CompleteCallback complete =
656 [weak = context_, want, accountId](NativeEngine& engine, AsyncTask& task, int32_t status) {
657 auto context = weak.lock();
658 if (!context) {
659 HILOG_WARN("context is released");
660 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
661 return;
662 }
663 auto errcode = context->StopServiceExtensionAbility(want, accountId);
664 if (errcode == 0) {
665 task.Resolve(engine, engine.CreateUndefined());
666 } else {
667 task.Reject(engine, CreateJsErrorByNativeErr(engine, errcode));
668 }
669 };
670
671 NativeValue* lastParam = (info.argc > ARGC_TWO) ? info.argv[ARGC_TWO] : nullptr;
672 NativeValue* result = nullptr;
673 AsyncTask::Schedule("JsAbilityContext::OnStopExtensionAbilityWithAccount",
674 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
675 return result;
676 }
677
OnTerminateSelfWithResult(NativeEngine & engine,NativeCallbackInfo & info)678 NativeValue* JsAbilityContext::OnTerminateSelfWithResult(NativeEngine& engine, NativeCallbackInfo& info)
679 {
680 HILOG_INFO("OnTerminateSelfWithResult is called");
681
682 if (info.argc == 0) {
683 HILOG_ERROR("Not enough params");
684 ThrowTooFewParametersError(engine);
685 return engine.CreateUndefined();
686 }
687
688 int resultCode = 0;
689 AAFwk::Want want;
690 if (!JsAbilityContext::UnWrapAbilityResult(engine, info.argv[0], resultCode, want)) {
691 HILOG_ERROR("%s Failed to parse ability result!", __func__);
692 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
693 return engine.CreateUndefined();
694 }
695
696 auto abilityContext = context_.lock();
697 if (abilityContext != nullptr) {
698 abilityContext->SetTerminating(true);
699 }
700
701 AsyncTask::CompleteCallback complete =
702 [weak = context_, want, resultCode](NativeEngine& engine, AsyncTask& task, int32_t status) {
703 auto context = weak.lock();
704 if (!context) {
705 HILOG_WARN("context is released");
706 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
707 return;
708 }
709
710 auto errorCode = context->TerminateAbilityWithResult(want, resultCode);
711 if (errorCode == 0) {
712 task.Resolve(engine, engine.CreateUndefined());
713 } else {
714 task.Reject(engine, CreateJsErrorByNativeErr(engine, errorCode));
715 }
716 };
717
718 NativeValue* lastParam = (info.argc > ARGC_ONE) ? info.argv[1] : nullptr;
719 NativeValue* result = nullptr;
720 AsyncTask::Schedule("JsAbilityContext::OnTerminateSelfWithResult",
721 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
722 HILOG_INFO("OnTerminateSelfWithResult is called end");
723 return result;
724 }
725
OnConnectAbility(NativeEngine & engine,NativeCallbackInfo & info)726 NativeValue* JsAbilityContext::OnConnectAbility(NativeEngine& engine, NativeCallbackInfo& info)
727 {
728 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
729 HILOG_INFO("Connect ability called.");
730 // only support two params
731 if (info.argc < ARGC_TWO) {
732 HILOG_ERROR("Connect ability failed, not enough params.");
733 ThrowTooFewParametersError(engine);
734 return engine.CreateUndefined();
735 }
736
737 // unwrap want
738 AAFwk::Want want;
739 OHOS::AppExecFwk::UnwrapWant(reinterpret_cast<napi_env>(&engine),
740 reinterpret_cast<napi_value>(info.argv[0]), want);
741 HILOG_INFO("Connect ability called, callee:%{public}s.%{public}s.",
742 want.GetBundle().c_str(),
743 want.GetElement().GetAbilityName().c_str());
744
745 // unwarp connection
746 sptr<JSAbilityConnection> connection = new JSAbilityConnection(engine);
747 connection->SetJsConnectionObject(info.argv[1]);
748 int64_t connectId = g_serialNumber;
749 ConnectionKey key;
750 key.id = g_serialNumber;
751 key.want = want;
752 connection->SetConnectionId(key.id);
753 abilityConnects_.emplace(key, connection);
754 if (g_serialNumber < INT32_MAX) {
755 g_serialNumber++;
756 } else {
757 g_serialNumber = 0;
758 }
759
760 AsyncTask::CompleteCallback complete =
761 [weak = context_, want, connection, connectId](NativeEngine& engine, AsyncTask& task, int32_t status) {
762 auto context = weak.lock();
763 if (!context) {
764 HILOG_ERROR("Connect ability failed, context is released.");
765 task.Reject(engine, CreateJsError(engine, 1, "Context is released"));
766 return;
767 }
768 if (!context->ConnectAbility(want, connection)) {
769 connection->CallJsFailed(ERROR_CODE_ONE);
770 }
771 task.Resolve(engine, engine.CreateUndefined());
772 };
773 NativeValue* result = nullptr;
774 AsyncTask::Schedule("JsAbilityContext::OnConnectAbility",
775 engine, CreateAsyncTaskWithLastParam(engine, nullptr, nullptr, std::move(complete), &result));
776 return engine.CreateNumber(connectId);
777 }
778
OnConnectAbilityWithAccount(NativeEngine & engine,NativeCallbackInfo & info)779 NativeValue* JsAbilityContext::OnConnectAbilityWithAccount(NativeEngine& engine, NativeCallbackInfo& info)
780 {
781 HILOG_INFO("OnConnectAbility is called");
782 // only support three params
783 if (info.argc < ARGC_THREE) {
784 HILOG_ERROR("Not enough params");
785 ThrowTooFewParametersError(engine);
786 return engine.CreateUndefined();
787 }
788
789 // unwrap want
790 AAFwk::Want want;
791 OHOS::AppExecFwk::UnwrapWant(reinterpret_cast<napi_env>(&engine),
792 reinterpret_cast<napi_value>(info.argv[0]), want);
793 HILOG_INFO("%{public}s bundlename:%{public}s abilityname:%{public}s",
794 __func__,
795 want.GetBundle().c_str(),
796 want.GetElement().GetAbilityName().c_str());
797
798 int32_t accountId = 0;
799 if (!OHOS::AppExecFwk::UnwrapInt32FromJS2(reinterpret_cast<napi_env>(&engine),
800 reinterpret_cast<napi_value>(info.argv[1]), accountId)) {
801 HILOG_INFO("%{public}s called, the second parameter is invalid.", __func__);
802 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
803 return engine.CreateUndefined();
804 }
805
806 // unwarp connection
807 sptr<JSAbilityConnection> connection = new JSAbilityConnection(engine);
808 connection->SetJsConnectionObject(info.argv[INDEX_TWO]);
809 int64_t connectId = g_serialNumber;
810 ConnectionKey key;
811 key.id = g_serialNumber;
812 key.want = want;
813 connection->SetConnectionId(key.id);
814 abilityConnects_.emplace(key, connection);
815 if (g_serialNumber < INT32_MAX) {
816 g_serialNumber++;
817 } else {
818 g_serialNumber = 0;
819 }
820 AsyncTask::CompleteCallback complete =
821 [weak = context_, want, accountId, connection, connectId](
822 NativeEngine& engine, AsyncTask& task, int32_t status) {
823 auto context = weak.lock();
824 if (!context) {
825 HILOG_ERROR("context is released");
826 task.Reject(engine, CreateJsError(engine, 1, "Context is released"));
827 return;
828 }
829 HILOG_INFO("context->ConnectAbilityWithAccount connection:%{public}d", (int32_t)connectId);
830 if (!context->ConnectAbilityWithAccount(want, accountId, connection)) {
831 connection->CallJsFailed(ERROR_CODE_ONE);
832 }
833 task.Resolve(engine, engine.CreateUndefined());
834 };
835 NativeValue* result = nullptr;
836 AsyncTask::Schedule("JsAbilityContext::OnConnectAbilityWithAccount",
837 engine, CreateAsyncTaskWithLastParam(engine, nullptr, nullptr, std::move(complete), &result));
838 return engine.CreateNumber(connectId);
839 }
840
OnDisconnectAbility(NativeEngine & engine,NativeCallbackInfo & info)841 NativeValue* JsAbilityContext::OnDisconnectAbility(NativeEngine& engine, NativeCallbackInfo& info)
842 {
843 HILOG_INFO("OnDisconnectAbility is called");
844 // only support one or two params
845 if (info.argc < ARGC_ONE) {
846 HILOG_ERROR("Not enough params");
847 ThrowTooFewParametersError(engine);
848 return engine.CreateUndefined();
849 }
850
851 // unwrap want
852 AAFwk::Want want;
853 // unwrap connectId
854 int64_t connectId = -1;
855 sptr<JSAbilityConnection> connection = nullptr;
856 napi_get_value_int64(reinterpret_cast<napi_env>(&engine),
857 reinterpret_cast<napi_value>(info.argv[0]), &connectId);
858 HILOG_INFO("Disconnect ability begin, connection:%{public}d.", (int32_t)connectId);
859 auto item = std::find_if(abilityConnects_.begin(),
860 abilityConnects_.end(),
861 [&connectId](const std::map<ConnectionKey, sptr<JSAbilityConnection>>::value_type &obj) {
862 return connectId == obj.first.id;
863 });
864 if (item != abilityConnects_.end()) {
865 // match id
866 want = item->first.want;
867 connection = item->second;
868 HILOG_INFO("%{public}s find conn ability exist", __func__);
869 } else {
870 HILOG_INFO("%{public}s not find conn exist.", __func__);
871 }
872 // begin disconnect
873 AsyncTask::CompleteCallback complete =
874 [weak = context_, want, connection](
875 NativeEngine& engine, AsyncTask& task, int32_t status) {
876 HILOG_INFO("OnDisconnectAbility begin");
877 auto context = weak.lock();
878 if (!context) {
879 HILOG_WARN("OnDisconnectAbility context is released");
880 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
881 return;
882 }
883 if (connection == nullptr) {
884 HILOG_WARN("connection nullptr");
885 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
886 return;
887 }
888 HILOG_INFO("context->DisconnectAbility");
889 context->DisconnectAbility(want, connection);
890 task.Resolve(engine, engine.CreateUndefined());
891 };
892
893 NativeValue* lastParam = (info.argc > ARGC_ONE) ? info.argv[1] : nullptr;
894 NativeValue* result = nullptr;
895 AsyncTask::Schedule("JsAbilityContext::OnDisconnectAbility",
896 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
897 return result;
898 }
899
OnTerminateSelf(NativeEngine & engine,NativeCallbackInfo & info)900 NativeValue* JsAbilityContext::OnTerminateSelf(NativeEngine& engine, NativeCallbackInfo& info)
901 {
902 HILOG_INFO("OnTerminateSelf is called");
903 auto abilityContext = context_.lock();
904 if (abilityContext != nullptr) {
905 abilityContext->SetTerminating(true);
906 }
907
908 AsyncTask::CompleteCallback complete =
909 [weak = context_](NativeEngine& engine, AsyncTask& task, int32_t status) {
910 auto context = weak.lock();
911 if (!context) {
912 HILOG_WARN("context is released");
913 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
914 return;
915 }
916
917 auto errcode = context->TerminateSelf();
918 if (errcode == 0) {
919 task.Resolve(engine, engine.CreateUndefined());
920 } else {
921 task.Reject(engine, CreateJsErrorByNativeErr(engine, errcode));
922 }
923 };
924
925 NativeValue* lastParam = (info.argc > ARGC_ZERO) ? info.argv[ARGC_ZERO] : nullptr;
926 NativeValue* result = nullptr;
927 AsyncTask::Schedule("JsAbilityContext::OnTerminateSelf",
928 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
929 return result;
930 }
931
OnRequestPermissionsFromUser(NativeEngine & engine,NativeCallbackInfo & info)932 NativeValue* JsAbilityContext::OnRequestPermissionsFromUser(NativeEngine& engine, NativeCallbackInfo& info)
933 {
934 HILOG_INFO("OnRequestPermissionsFromUser is called");
935
936 if (info.argc < ARGC_ONE) {
937 HILOG_ERROR("Not enough params");
938 ThrowTooFewParametersError(engine);
939 return engine.CreateUndefined();
940 }
941
942 std::vector<std::string> permissionList;
943 if (!OHOS::AppExecFwk::UnwrapArrayStringFromJS(reinterpret_cast<napi_env>(&engine),
944 reinterpret_cast<napi_value>(info.argv[0]), permissionList)) {
945 HILOG_ERROR("%{public}s called, the first parameter is invalid.", __func__);
946 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
947 return engine.CreateUndefined();
948 }
949
950 if (permissionList.size() == 0) {
951 HILOG_ERROR("%{public}s called, params do not meet specification.", __func__);
952 }
953
954 NativeValue* lastParam = (info.argc == ARGC_ONE) ? nullptr : info.argv[ARGC_ONE];
955 NativeValue* result = nullptr;
956 auto uasyncTask = CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, nullptr, &result);
957 std::shared_ptr<AsyncTask> asyncTask = std::move(uasyncTask);
958 PermissionRequestTask task =
959 [&engine, asyncTask](const std::vector<std::string> &permissions, const std::vector<int> &grantResults) {
960 HILOG_INFO("OnRequestPermissionsFromUser async callback is called");
961 NativeValue* requestResult = JsAbilityContext::WrapPermissionRequestResult(engine, permissions, grantResults);
962 if (requestResult == nullptr) {
963 HILOG_WARN("wrap requestResult failed");
964 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
965 } else {
966 asyncTask->Resolve(engine, requestResult);
967 }
968 HILOG_INFO("OnRequestPermissionsFromUser async callback is called end");
969 };
970 auto context = context_.lock();
971 if (context == nullptr) {
972 HILOG_WARN("context is released");
973 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
974 } else {
975 curRequestCode_ = (curRequestCode_ == INT_MAX) ? 0 : (curRequestCode_ + 1);
976 context->RequestPermissionsFromUser(engine, permissionList, curRequestCode_, std::move(task));
977 }
978 HILOG_INFO("OnRequestPermissionsFromUser is called end");
979 return result;
980 }
981
OnRestoreWindowStage(NativeEngine & engine,NativeCallbackInfo & info)982 NativeValue* JsAbilityContext::OnRestoreWindowStage(NativeEngine& engine, NativeCallbackInfo& info)
983 {
984 HILOG_INFO("OnRestoreWindowStage is called, argc = %{public}d", static_cast<int>(info.argc));
985 if (info.argc < ARGC_ONE) {
986 HILOG_ERROR("OnRestoreWindowStage need one parameters");
987 ThrowTooFewParametersError(engine);
988 return engine.CreateUndefined();
989 }
990 auto context = context_.lock();
991 if (!context) {
992 HILOG_ERROR("OnRestoreWindowStage context is released");
993 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
994 return engine.CreateUndefined();
995 }
996 auto errcode = context->RestoreWindowStage(engine, info.argv[0]);
997 if (errcode != 0) {
998 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
999 return CreateJsError(engine, errcode, "RestoreWindowStage failed.");
1000 }
1001 return engine.CreateUndefined();
1002 }
1003
OnRequestDialogService(NativeEngine & engine,NativeCallbackInfo & info)1004 NativeValue* JsAbilityContext::OnRequestDialogService(NativeEngine& engine, NativeCallbackInfo& info)
1005 {
1006 HILOG_INFO("OnRequestDialogService is called");
1007
1008 if (info.argc < ARGC_ONE) {
1009 HILOG_ERROR("Not enough params");
1010 ThrowTooFewParametersError(engine);
1011 return engine.CreateUndefined();
1012 }
1013
1014 AAFwk::Want want;
1015 OHOS::AppExecFwk::UnwrapWant(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[0]), want);
1016 HILOG_INFO("requestdialogservice, target:%{public}s.%{public}s.", want.GetBundle().c_str(),
1017 want.GetElement().GetAbilityName().c_str());
1018
1019 NativeValue* lastParam = (info.argc > ARGC_ONE) ? info.argv[ARGC_ONE] : nullptr;
1020 NativeValue* result = nullptr;
1021 auto uasyncTask = CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, nullptr, &result);
1022 std::shared_ptr<AsyncTask> asyncTask = std::move(uasyncTask);
1023 RequestDialogResultTask task =
1024 [&engine, asyncTask](int32_t resultCode) {
1025 HILOG_INFO("OnRequestDialogService async callback is called");
1026 NativeValue* requestResult = JsAbilityContext::WrapRequestDialogResult(engine, resultCode);
1027 if (requestResult == nullptr) {
1028 HILOG_WARN("wrap requestResult failed");
1029 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
1030 } else {
1031 asyncTask->Resolve(engine, requestResult);
1032 }
1033 HILOG_INFO("OnRequestDialogService async callback is called end");
1034 };
1035 auto context = context_.lock();
1036 if (context == nullptr) {
1037 HILOG_WARN("context is released, can not requestDialogService");
1038 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
1039 } else {
1040 auto errCode = context->RequestDialogService(engine, want, std::move(task));
1041 if (errCode != ERR_OK) {
1042 asyncTask->Reject(engine, CreateJsError(engine, GetJsErrorCodeByNativeError(errCode)));
1043 }
1044 }
1045 HILOG_INFO("OnRequestDialogService is called end");
1046 return result;
1047 }
1048
OnIsTerminating(NativeEngine & engine,NativeCallbackInfo & info)1049 NativeValue* JsAbilityContext::OnIsTerminating(NativeEngine& engine, NativeCallbackInfo& info)
1050 {
1051 HILOG_INFO("OnIsTerminating is called");
1052 auto context = context_.lock();
1053 if (context == nullptr) {
1054 HILOG_ERROR("OnIsTerminating context is nullptr");
1055 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
1056 return engine.CreateUndefined();
1057 }
1058 return engine.CreateBoolean(context->IsTerminating());
1059 }
1060
UnWrapWant(NativeEngine & engine,NativeValue * argv,AAFwk::Want & want)1061 bool JsAbilityContext::UnWrapWant(NativeEngine& engine, NativeValue* argv, AAFwk::Want& want)
1062 {
1063 if (argv == nullptr) {
1064 HILOG_WARN("%s argv == nullptr!", __func__);
1065 return false;
1066 }
1067 return AppExecFwk::UnwrapWant(reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(argv), want);
1068 }
1069
WrapWant(NativeEngine & engine,const AAFwk::Want & want)1070 NativeValue* JsAbilityContext::WrapWant(NativeEngine& engine, const AAFwk::Want& want)
1071 {
1072 return reinterpret_cast<NativeValue*>(AppExecFwk::WrapWant(reinterpret_cast<napi_env>(&engine), want));
1073 }
1074
UnWrapAbilityResult(NativeEngine & engine,NativeValue * argv,int & resultCode,AAFwk::Want & want)1075 bool JsAbilityContext::UnWrapAbilityResult(NativeEngine& engine, NativeValue* argv, int& resultCode, AAFwk::Want& want)
1076 {
1077 if (argv == nullptr) {
1078 HILOG_WARN("%s argv == nullptr!", __func__);
1079 return false;
1080 }
1081 if (argv->TypeOf() != NativeValueType::NATIVE_OBJECT) {
1082 HILOG_WARN("%s invalid type of abilityResult!", __func__);
1083 return false;
1084 }
1085 NativeObject* jObj = ConvertNativeValueTo<NativeObject>(argv);
1086 NativeValue* jResultCode = jObj->GetProperty("resultCode");
1087 if (jResultCode == nullptr) {
1088 HILOG_WARN("%s jResultCode == nullptr!", __func__);
1089 return false;
1090 }
1091 if (jResultCode->TypeOf() != NativeValueType::NATIVE_NUMBER) {
1092 HILOG_WARN("%s invalid type of resultCode!", __func__);
1093 return false;
1094 }
1095 resultCode = int64_t(*ConvertNativeValueTo<NativeNumber>(jObj->GetProperty("resultCode")));
1096 NativeValue* jWant = jObj->GetProperty("want");
1097 if (jWant == nullptr) {
1098 HILOG_WARN("%s jWant == nullptr!", __func__);
1099 return false;
1100 }
1101 if (jWant->TypeOf() != NativeValueType::NATIVE_OBJECT) {
1102 HILOG_WARN("%s invalid type of want!", __func__);
1103 return false;
1104 }
1105 return JsAbilityContext::UnWrapWant(engine, jWant, want);
1106 }
1107
WrapRequestDialogResult(NativeEngine & engine,int32_t resultCode)1108 NativeValue* JsAbilityContext::WrapRequestDialogResult(NativeEngine& engine, int32_t resultCode)
1109 {
1110 NativeValue *objValue = engine.CreateObject();
1111 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
1112 if (object == nullptr) {
1113 HILOG_ERROR("Native object is nullptr.");
1114 return objValue;
1115 }
1116
1117 object->SetProperty("result", CreateJsValue(engine, resultCode));
1118 return objValue;
1119 }
1120
WrapAbilityResult(NativeEngine & engine,const int & resultCode,const AAFwk::Want & want)1121 NativeValue* JsAbilityContext::WrapAbilityResult(NativeEngine& engine, const int& resultCode, const AAFwk::Want& want)
1122 {
1123 NativeValue* jAbilityResult = engine.CreateObject();
1124 NativeObject* abilityResult = ConvertNativeValueTo<NativeObject>(jAbilityResult);
1125 abilityResult->SetProperty("resultCode", engine.CreateNumber(resultCode));
1126 abilityResult->SetProperty("want", JsAbilityContext::WrapWant(engine, want));
1127 return jAbilityResult;
1128 }
1129
WrapPermissionRequestResult(NativeEngine & engine,const std::vector<std::string> & permissions,const std::vector<int> & grantResults)1130 NativeValue* JsAbilityContext::WrapPermissionRequestResult(NativeEngine& engine,
1131 const std::vector<std::string> &permissions, const std::vector<int> &grantResults)
1132 {
1133 NativeValue* jsPermissionRequestResult = engine.CreateObject();
1134 NativeObject* permissionRequestResult = ConvertNativeValueTo<NativeObject>(jsPermissionRequestResult);
1135 permissionRequestResult->SetProperty("permissions", CreateNativeArray(engine, permissions));
1136 permissionRequestResult->SetProperty("authResults", CreateNativeArray(engine, grantResults));
1137 return jsPermissionRequestResult;
1138 }
1139
InheritWindowMode(AAFwk::Want & want)1140 void JsAbilityContext::InheritWindowMode(AAFwk::Want &want)
1141 {
1142 HILOG_INFO("%{public}s called.", __func__);
1143 #ifdef SUPPORT_GRAPHICS
1144 // only split mode need inherit
1145 auto context = context_.lock();
1146 if (!context) {
1147 HILOG_ERROR("context is nullptr.");
1148 return;
1149 }
1150 auto windowMode = context->GetCurrentWindowMode();
1151 if (windowMode == AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY ||
1152 windowMode == AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY) {
1153 want.SetParam(Want::PARAM_RESV_WINDOW_MODE, windowMode);
1154 }
1155 HILOG_INFO("%{public}s called end. window mode is %{public}d", __func__, windowMode);
1156 #endif
1157 }
1158
ConfigurationUpdated(NativeEngine * engine,std::shared_ptr<NativeReference> & jsContext,const std::shared_ptr<AppExecFwk::Configuration> & config)1159 void JsAbilityContext::ConfigurationUpdated(NativeEngine* engine, std::shared_ptr<NativeReference> &jsContext,
1160 const std::shared_ptr<AppExecFwk::Configuration> &config)
1161 {
1162 HILOG_INFO("ConfigurationUpdated begin.");
1163 if (jsContext == nullptr || config == nullptr) {
1164 HILOG_INFO("jsContext is nullptr.");
1165 return;
1166 }
1167
1168 NativeValue* value = jsContext->Get();
1169 NativeObject* object = ConvertNativeValueTo<NativeObject>(value);
1170 if (object == nullptr) {
1171 HILOG_INFO("object is nullptr.");
1172 return;
1173 }
1174
1175 NativeValue* method = object->GetProperty("onUpdateConfiguration");
1176 if (method == nullptr) {
1177 HILOG_ERROR("Failed to get onUpdateConfiguration from object");
1178 return;
1179 }
1180 HILOG_INFO("JSAbilityConnection::CallFunction onUpdateConfiguration, success");
1181
1182 HILOG_INFO("OnAbilityConnectDone begin NAPI_ohos_rpc_CreateJsRemoteObject");
1183 NativeValue* argv[] = {CreateJsConfiguration(*engine, *config)};
1184 engine->CallFunction(value, method, argv, ARGC_ONE);
1185 }
1186
CreateJsAbilityContext(NativeEngine & engine,std::shared_ptr<AbilityContext> context,DetachCallback detach,AttachCallback attach)1187 NativeValue* CreateJsAbilityContext(NativeEngine& engine, std::shared_ptr<AbilityContext> context,
1188 DetachCallback detach, AttachCallback attach)
1189 {
1190 NativeValue* objValue = CreateJsBaseContext(engine, context, detach, attach);
1191 NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
1192
1193 std::unique_ptr<JsAbilityContext> jsContext = std::make_unique<JsAbilityContext>(context);
1194 object->SetNativePointer(jsContext.release(), JsAbilityContext::Finalizer, nullptr);
1195
1196 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
1197
1198 auto abilityInfo = context->GetAbilityInfo();
1199 if (abilityInfo != nullptr) {
1200 object->SetProperty("abilityInfo", CreateJsAbilityInfo(engine, *abilityInfo));
1201 }
1202
1203 auto configuration = context->GetConfiguration();
1204 if (configuration != nullptr) {
1205 object->SetProperty("config", CreateJsConfiguration(engine, *configuration));
1206 }
1207
1208 const char *moduleName = "JsAbilityContext";
1209 BindNativeFunction(engine, *object, "startAbility", moduleName, JsAbilityContext::StartAbility);
1210 BindNativeFunction(engine, *object, "startAbilityWithAccount", moduleName,
1211 JsAbilityContext::StartAbilityWithAccount);
1212 BindNativeFunction(engine, *object, "startAbilityByCall", moduleName, JsAbilityContext::StartAbilityByCall);
1213 BindNativeFunction(engine, *object, "startAbilityForResult", moduleName, JsAbilityContext::StartAbilityForResult);
1214 BindNativeFunction(engine, *object, "startAbilityForResultWithAccount", moduleName,
1215 JsAbilityContext::StartAbilityForResultWithAccount);
1216 BindNativeFunction(engine, *object, "startServiceExtensionAbility", moduleName,
1217 JsAbilityContext::StartServiceExtensionAbility);
1218 BindNativeFunction(engine, *object, "startServiceExtensionAbilityWithAccount", moduleName,
1219 JsAbilityContext::StartServiceExtensionAbilityWithAccount);
1220 BindNativeFunction(engine, *object, "stopServiceExtensionAbility", moduleName,
1221 JsAbilityContext::StopServiceExtensionAbility);
1222 BindNativeFunction(engine, *object, "stopServiceExtensionAbilityWithAccount", moduleName,
1223 JsAbilityContext::StopServiceExtensionAbilityWithAccount);
1224 BindNativeFunction(engine, *object, "connectAbility", moduleName, JsAbilityContext::ConnectAbility);
1225 BindNativeFunction(engine, *object, "connectServiceExtensionAbility", moduleName, JsAbilityContext::ConnectAbility);
1226 BindNativeFunction(engine, *object, "connectAbilityWithAccount", moduleName,
1227 JsAbilityContext::ConnectAbilityWithAccount);
1228 BindNativeFunction(engine, *object, "connectServiceExtensionAbilityWithAccount", moduleName,
1229 JsAbilityContext::ConnectAbilityWithAccount);
1230 BindNativeFunction(engine, *object, "disconnectAbility", moduleName, JsAbilityContext::DisconnectAbility);
1231 BindNativeFunction(
1232 engine, *object, "disconnectServiceExtensionAbility", moduleName, JsAbilityContext::DisconnectAbility);
1233 BindNativeFunction(engine, *object, "terminateSelf", moduleName, JsAbilityContext::TerminateSelf);
1234 BindNativeFunction(engine, *object, "terminateSelfWithResult", moduleName,
1235 JsAbilityContext::TerminateSelfWithResult);
1236 BindNativeFunction(engine, *object, "requestPermissionsFromUser", moduleName,
1237 JsAbilityContext::RequestPermissionsFromUser);
1238 BindNativeFunction(engine, *object, "restoreWindowStage", moduleName, JsAbilityContext::RestoreWindowStage);
1239 BindNativeFunction(engine, *object, "isTerminating", moduleName, JsAbilityContext::IsTerminating);
1240 BindNativeFunction(engine, *object, "startRecentAbility", moduleName,
1241 JsAbilityContext::StartRecentAbility);
1242 BindNativeFunction(engine, *object, "requestDialogService", moduleName,
1243 JsAbilityContext::RequestDialogService);
1244
1245 #ifdef SUPPORT_GRAPHICS
1246 BindNativeFunction(engine, *object, "setMissionLabel", moduleName, JsAbilityContext::SetMissionLabel);
1247 BindNativeFunction(engine, *object, "setMissionIcon", moduleName, JsAbilityContext::SetMissionIcon);
1248 #endif
1249 return objValue;
1250 }
1251
JSAbilityConnection(NativeEngine & engine)1252 JSAbilityConnection::JSAbilityConnection(NativeEngine& engine) : engine_(engine) {}
1253
~JSAbilityConnection()1254 JSAbilityConnection::~JSAbilityConnection()
1255 {
1256 uv_loop_t *loop = engine_.GetUVLoop();
1257 if (loop == nullptr) {
1258 HILOG_ERROR("~JSAbilityConnection: failed to get uv loop.");
1259 return;
1260 }
1261
1262 ConnectCallback *cb = new (std::nothrow) ConnectCallback();
1263 if (cb == nullptr) {
1264 HILOG_ERROR("~JSAbilityConnection: failed to create cb.");
1265 return;
1266 }
1267 cb->jsConnectionObject_ = std::move(jsConnectionObject_);
1268
1269 uv_work_t *work = new (std::nothrow) uv_work_t;
1270 if (work == nullptr) {
1271 HILOG_ERROR("~JSAbilityConnection: failed to create work.");
1272 delete cb;
1273 cb = nullptr;
1274 return;
1275 }
1276 work->data = reinterpret_cast<void *>(cb);
1277 int ret = uv_queue_work(loop, work, [](uv_work_t *work) {},
1278 [](uv_work_t *work, int status) {
1279 if (work == nullptr) {
1280 HILOG_ERROR("~JSAbilityConnection: work is nullptr.");
1281 return;
1282 }
1283 if (work->data == nullptr) {
1284 HILOG_ERROR("~JSAbilityConnection: data is nullptr.");
1285 delete work;
1286 work = nullptr;
1287 return;
1288 }
1289 ConnectCallback *cb = reinterpret_cast<ConnectCallback *>(work->data);
1290 delete cb;
1291 cb = nullptr;
1292 delete work;
1293 work = nullptr;
1294 });
1295 if (ret != 0) {
1296 if (cb != nullptr) {
1297 delete cb;
1298 cb = nullptr;
1299 }
1300 if (work != nullptr) {
1301 delete work;
1302 work = nullptr;
1303 }
1304 }
1305 }
1306
SetConnectionId(int64_t id)1307 void JSAbilityConnection::SetConnectionId(int64_t id)
1308 {
1309 connectionId_ = id;
1310 }
1311
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)1312 void JSAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
1313 const sptr<IRemoteObject> &remoteObject, int resultCode)
1314 {
1315 HILOG_INFO("OnAbilityConnectDone begin, resultCode:%{public}d", resultCode);
1316 if (handler_ == nullptr) {
1317 HILOG_INFO("handler_ nullptr");
1318 return;
1319 }
1320
1321 wptr<JSAbilityConnection> connection = this;
1322 auto task = [connection, element, remoteObject, resultCode] {
1323 sptr<JSAbilityConnection> connectionSptr = connection.promote();
1324 if (!connectionSptr) {
1325 HILOG_INFO("connectionSptr nullptr");
1326 return;
1327 }
1328 connectionSptr->HandleOnAbilityConnectDone(element, remoteObject, resultCode);
1329 };
1330 handler_->PostTask(task, "OnAbilityConnectDone");
1331 }
1332
HandleOnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)1333 void JSAbilityConnection::HandleOnAbilityConnectDone(const AppExecFwk::ElementName &element,
1334 const sptr<IRemoteObject> &remoteObject, int resultCode)
1335 {
1336 HILOG_INFO("HandleOnAbilityConnectDone begin, resultCode:%{public}d", resultCode);
1337 if (jsConnectionObject_ == nullptr) {
1338 HILOG_ERROR("jsConnectionObject_ nullptr");
1339 return;
1340 }
1341 NativeValue* value = jsConnectionObject_->Get();
1342 NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
1343 if (obj == nullptr) {
1344 HILOG_ERROR("Failed to get object");
1345 return;
1346 }
1347 NativeValue* methodOnConnect = obj->GetProperty("onConnect");
1348 if (methodOnConnect == nullptr) {
1349 HILOG_ERROR("Failed to get onConnect from object");
1350 return;
1351 }
1352 HILOG_INFO("JSAbilityConnection::CallFunction onConnect, success");
1353
1354 // wrap RemoteObject
1355 HILOG_INFO("OnAbilityConnectDone begin NAPI_ohos_rpc_CreateJsRemoteObject");
1356 napi_value napiRemoteObject = NAPI_ohos_rpc_CreateJsRemoteObject(
1357 reinterpret_cast<napi_env>(&engine_), remoteObject);
1358 NativeValue* nativeRemoteObject = reinterpret_cast<NativeValue*>(napiRemoteObject);
1359 NativeValue* argv[] = { ConvertElement(element), nativeRemoteObject };
1360 engine_.CallFunction(value, methodOnConnect, argv, ARGC_TWO);
1361 HILOG_INFO("OnAbilityConnectDone end");
1362 }
1363
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)1364 void JSAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
1365 {
1366 HILOG_INFO("OnAbilityDisconnectDone begin, resultCode:%{public}d", resultCode);
1367 if (handler_ == nullptr) {
1368 HILOG_INFO("handler_ nullptr");
1369 return;
1370 }
1371
1372 wptr<JSAbilityConnection> connection = this;
1373 auto task = [connection, element, resultCode] {
1374 sptr<JSAbilityConnection> connectionSptr = connection.promote();
1375 if (!connectionSptr) {
1376 HILOG_INFO("connectionSptr nullptr");
1377 return;
1378 }
1379 connectionSptr->HandleOnAbilityDisconnectDone(element, resultCode);
1380 };
1381 handler_->PostTask(task, "OnAbilityDisconnectDone");
1382 }
1383
HandleOnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)1384 void JSAbilityConnection::HandleOnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
1385 int resultCode)
1386 {
1387 HILOG_INFO("HandleOnAbilityDisconnectDone begin, resultCode:%{public}d", resultCode);
1388 if (jsConnectionObject_ == nullptr) {
1389 HILOG_ERROR("jsConnectionObject_ nullptr");
1390 return;
1391 }
1392 NativeValue* value = jsConnectionObject_->Get();
1393 NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
1394 if (obj == nullptr) {
1395 HILOG_ERROR("Failed to get object");
1396 return;
1397 }
1398
1399 NativeValue* method = obj->GetProperty("onDisconnect");
1400 if (method == nullptr) {
1401 HILOG_ERROR("Failed to get onDisconnect from object");
1402 return;
1403 }
1404
1405 // release connect
1406 HILOG_INFO("OnAbilityDisconnectDone abilityConnects_.size:%{public}zu", abilityConnects_.size());
1407 std::string bundleName = element.GetBundleName();
1408 std::string abilityName = element.GetAbilityName();
1409 auto item = std::find_if(abilityConnects_.begin(), abilityConnects_.end(),
1410 [bundleName, abilityName, connectionId = connectionId_] (
1411 const std::map<ConnectionKey, sptr<JSAbilityConnection>>::value_type &obj) {
1412 return (bundleName == obj.first.want.GetBundle()) &&
1413 (abilityName == obj.first.want.GetElement().GetAbilityName()) &&
1414 connectionId == obj.first.id;
1415 });
1416 if (item != abilityConnects_.end()) {
1417 // match bundlename && abilityname
1418 abilityConnects_.erase(item);
1419 HILOG_INFO("OnAbilityDisconnectDone erase abilityConnects_.size:%{public}zu", abilityConnects_.size());
1420 }
1421
1422 NativeValue* argv[] = { ConvertElement(element) };
1423 HILOG_INFO("OnAbilityDisconnectDone CallFunction success");
1424 engine_.CallFunction(value, method, argv, ARGC_ONE);
1425 }
1426
CallJsFailed(int32_t errorCode)1427 void JSAbilityConnection::CallJsFailed(int32_t errorCode)
1428 {
1429 HILOG_INFO("CallJsFailed begin");
1430 if (jsConnectionObject_ == nullptr) {
1431 HILOG_ERROR("jsConnectionObject_ nullptr");
1432 return;
1433 }
1434 NativeValue* value = jsConnectionObject_->Get();
1435 NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
1436 if (obj == nullptr) {
1437 HILOG_ERROR("Failed to get object");
1438 return;
1439 }
1440
1441 NativeValue* method = obj->GetProperty("onFailed");
1442 if (method == nullptr) {
1443 HILOG_ERROR("Failed to get onFailed from object");
1444 return;
1445 }
1446
1447 NativeValue* argv[] = {engine_.CreateNumber(errorCode)};
1448 HILOG_INFO("CallJsFailed CallFunction success");
1449 engine_.CallFunction(value, method, argv, ARGC_ONE);
1450 HILOG_INFO("CallJsFailed end");
1451 }
1452
ConvertElement(const AppExecFwk::ElementName & element)1453 NativeValue* JSAbilityConnection::ConvertElement(const AppExecFwk::ElementName &element)
1454 {
1455 napi_value napiElementName = OHOS::AppExecFwk::WrapElementName(reinterpret_cast<napi_env>(&engine_), element);
1456 return reinterpret_cast<NativeValue*>(napiElementName);
1457 }
1458
SetJsConnectionObject(NativeValue * jsConnectionObject)1459 void JSAbilityConnection::SetJsConnectionObject(NativeValue* jsConnectionObject)
1460 {
1461 jsConnectionObject_ = std::unique_ptr<NativeReference>(engine_.CreateReference(jsConnectionObject, 1));
1462 }
1463
1464 #ifdef SUPPORT_GRAPHICS
SetMissionLabel(NativeEngine * engine,NativeCallbackInfo * info)1465 NativeValue* JsAbilityContext::SetMissionLabel(NativeEngine* engine, NativeCallbackInfo* info)
1466 {
1467 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
1468 return (me != nullptr) ? me->OnSetMissionLabel(*engine, *info) : nullptr;
1469 }
1470
SetMissionIcon(NativeEngine * engine,NativeCallbackInfo * info)1471 NativeValue* JsAbilityContext::SetMissionIcon(NativeEngine* engine, NativeCallbackInfo* info)
1472 {
1473 JsAbilityContext* me = CheckParamsAndGetThis<JsAbilityContext>(engine, info);
1474 return (me != nullptr) ? me->OnSetMissionIcon(*engine, *info) : nullptr;
1475 }
1476
OnSetMissionLabel(NativeEngine & engine,NativeCallbackInfo & info)1477 NativeValue* JsAbilityContext::OnSetMissionLabel(NativeEngine& engine, NativeCallbackInfo& info)
1478 {
1479 HILOG_INFO("OnSetMissionLabel is called, argc = %{public}d", static_cast<int>(info.argc));
1480 if (info.argc < ARGC_ONE) {
1481 HILOG_ERROR("OnSetMissionLabel, Not enough params");
1482 ThrowTooFewParametersError(engine);
1483 return engine.CreateUndefined();
1484 }
1485
1486 std::string label;
1487 if (!ConvertFromJsValue(engine, info.argv[0], label)) {
1488 HILOG_ERROR("OnSetMissionLabel, parse label failed.");
1489 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
1490 return engine.CreateUndefined();
1491 }
1492
1493 AsyncTask::CompleteCallback complete =
1494 [weak = context_, label](NativeEngine& engine, AsyncTask& task, int32_t status) {
1495 auto context = weak.lock();
1496 if (!context) {
1497 HILOG_WARN("context is released");
1498 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
1499 return;
1500 }
1501
1502 auto errcode = context->SetMissionLabel(label);
1503 if (errcode == 0) {
1504 task.Resolve(engine, engine.CreateUndefined());
1505 } else {
1506 task.Reject(engine, CreateJsErrorByNativeErr(engine, errcode));
1507 }
1508 };
1509
1510 NativeValue* lastParam = (info.argc > ARGC_ONE) ? info.argv[ARGC_ONE] : nullptr;
1511 NativeValue* result = nullptr;
1512 AsyncTask::Schedule("JsAbilityContext::OnSetMissionLabel",
1513 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
1514 return result;
1515 }
1516
OnSetMissionIcon(NativeEngine & engine,NativeCallbackInfo & info)1517 NativeValue* JsAbilityContext::OnSetMissionIcon(NativeEngine& engine, NativeCallbackInfo& info)
1518 {
1519 HILOG_INFO("OnSetMissionIcon is called, argc = %{public}d", static_cast<int>(info.argc));
1520 if (info.argc < ARGC_ONE) {
1521 HILOG_ERROR("OnSetMissionIcon, Not enough params");
1522 ThrowTooFewParametersError(engine);
1523 return engine.CreateUndefined();
1524 }
1525
1526 auto icon = OHOS::Media::PixelMapNapi::GetPixelMap(reinterpret_cast<napi_env>(&engine),
1527 reinterpret_cast<napi_value>(info.argv[0]));
1528 if (!icon) {
1529 HILOG_ERROR("OnSetMissionIcon, parse icon failed.");
1530 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
1531 return engine.CreateUndefined();
1532 }
1533
1534 AsyncTask::CompleteCallback complete =
1535 [weak = context_, icon](NativeEngine& engine, AsyncTask& task, int32_t status) {
1536 auto context = weak.lock();
1537 if (!context) {
1538 HILOG_WARN("context is released when set mission icon");
1539 task.Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
1540 return;
1541 }
1542
1543 auto errcode = context->SetMissionIcon(icon);
1544 if (errcode == 0) {
1545 task.Resolve(engine, engine.CreateUndefined());
1546 } else {
1547 task.Reject(engine, CreateJsErrorByNativeErr(engine, errcode));
1548 }
1549 };
1550
1551 NativeValue* lastParam = (info.argc > ARGC_ONE) ? info.argv[1] : nullptr;
1552 NativeValue* result = nullptr;
1553 AsyncTask::Schedule("JsAbilityContext::OnSetMissionIcon",
1554 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
1555 return result;
1556 }
1557 #endif
1558 } // namespace AbilityRuntime
1559 } // namespace OHOS
1560