1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_fence_extension_context.h"
17 
18 #include "location_log.h"
19 
20 namespace OHOS {
21 namespace Location {
22 constexpr size_t ARGC_ZERO = 0;
23 constexpr size_t ARGC_ONE = 1;
24 constexpr size_t ARGC_TWO = 2;
JsFenceExtensionContext(const std::shared_ptr<FenceExtensionContext> & context)25 JsFenceExtensionContext::JsFenceExtensionContext(const std::shared_ptr<FenceExtensionContext> &context)
26     : context_(context)
27 {}
28 
~JsFenceExtensionContext()29 JsFenceExtensionContext::~JsFenceExtensionContext()
30 {}
31 
CreateJsFenceExtensionContext(const::napi_env & env,std::shared_ptr<FenceExtensionContext> context)32 ::napi_value JsFenceExtensionContext::CreateJsFenceExtensionContext(
33     const ::napi_env &env, std::shared_ptr<FenceExtensionContext> context)
34 {
35     LBSLOGI(FENCE_EXTENSION, "Begin");
36     std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo = nullptr;
37     if (context) {
38         abilityInfo = context->GetAbilityInfo();
39     } else {
40         return nullptr;
41     }
42     ::napi_value objValue = AbilityRuntime::CreateJsExtensionContext(env, context, abilityInfo);
43 
44     std::unique_ptr<JsFenceExtensionContext> jsContext = std::make_unique<JsFenceExtensionContext>(context);
45     ::napi_status retStatus =
46         ::napi_wrap(env, objValue, jsContext.release(), JsFenceExtensionContext::Finalizer, nullptr, nullptr);
47     if (retStatus != ::napi_status::napi_ok) {
48         LBSLOGI(FENCE_EXTENSION, "Bind native context to js context error");
49     }
50     const char *moduleName = "JsFenceExtensionContext";
51     AbilityRuntime::BindNativeFunction(
52         env, objValue, "startAbility", moduleName, JsFenceExtensionContext::StartAbility);
53     LBSLOGI(FENCE_EXTENSION, "End");
54     return objValue;
55 }
56 
OnStartAbility(napi_env env,AbilityRuntime::NapiCallbackInfo & info)57 napi_value JsFenceExtensionContext::OnStartAbility(napi_env env, AbilityRuntime::NapiCallbackInfo &info)
58 {
59     LBSLOGI(FENCE_EXTENSION, "OnStartAbility");
60     if (info.argc < ARGC_ONE) {
61         LBSLOGE(FENCE_EXTENSION, "invalid argc");
62         AbilityRuntime::ThrowTooFewParametersError(env);
63         return AbilityRuntime::CreateJsUndefined(env);
64     }
65 
66     AAFwk::Want want;
67     if (!AppExecFwk::UnwrapWant(env, info.argv[ARGC_ZERO], want)) {
68         AbilityRuntime::ThrowInvalidParamError(env, "Parse param want failed, must be a Want.");
69         return AbilityRuntime::CreateJsUndefined(env);
70     }
71     auto isStartService = want.GetBoolParam("startService", true);
72     if (isStartService) {
73         return JsFenceExtensionContext::OnStartExtensionAbility(want, env, info);
74     }
75     LBSLOGE(FENCE_EXTENSION, "not support start ui ability");
76     AbilityRuntime::ThrowInvalidParamError(env, "Not support start ui ability.");
77     return AbilityRuntime::CreateJsUndefined(env);
78 }
79 
OnStartExtensionAbility(AAFwk::Want want,napi_env env,AbilityRuntime::NapiCallbackInfo & info)80 napi_value JsFenceExtensionContext::OnStartExtensionAbility(
81     AAFwk::Want want, napi_env env, AbilityRuntime::NapiCallbackInfo &info)
82 {
83     LBSLOGI(FENCE_EXTENSION, "OnStartExtensionAbility");
84 
85     AbilityRuntime::NapiAsyncTask::CompleteCallback complete =
86         [weak = context_, want](napi_env env, AbilityRuntime::NapiAsyncTask &task, int32_t status) {
87             auto context = weak.lock();
88             if (!context) {
89                 LBSLOGW(FENCE_EXTENSION, "context is released");
90                 task.Reject(env, CreateJsError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT));
91                 return;
92             }
93             auto innerErrorCode = context->StartServiceExtensionAbility(want);
94             if (innerErrorCode == 0) {
95                 task.Resolve(env, AbilityRuntime::CreateJsUndefined(env));
96             } else {
97                 task.Reject(env, AbilityRuntime::CreateJsErrorByNativeErr(env, innerErrorCode));
98             }
99         };
100 
101     napi_value lastParam = (info.argc <= ARGC_ONE) ? nullptr : info.argv[ARGC_ONE];
102     napi_value result = nullptr;
103     AbilityRuntime::NapiAsyncTask::ScheduleHighQos("JsFenceExtensionContext::OnStartExtensionAbility",
104         env,
105         CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
106     return result;
107 }
108 
Finalizer(::napi_env env,void * data,void * hint)109 void JsFenceExtensionContext::Finalizer(::napi_env env, void *data, void *hint)
110 {
111     std::unique_ptr<JsFenceExtensionContext>(static_cast<JsFenceExtensionContext *>(data));
112 }
113 }  // namespace Location
114 }  // namespace OHOS