1 /*
2 * Copyright (c) 2023-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_ability_context.h"
17
18 #include "ability_business_error.h"
19 #include "hilog_tag_wrapper.h"
20 #include "js_context_utils.h"
21 #include "js_data_converter.h"
22 #include "js_resource_manager_utils.h"
23 #include "js_runtime_utils.h"
24
25 namespace OHOS {
26 namespace AbilityRuntime {
27 namespace {
28 constexpr size_t ARGC_ZERO = 0;
29 constexpr size_t ARGC_ONE = 1;
30 }
Finalizer(napi_env env,void * data,void * hint)31 void JsAbilityContext::Finalizer(napi_env env, void *data, void *hint)
32 {
33 TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
34 std::unique_ptr<JsAbilityContext>(static_cast<JsAbilityContext*>(data));
35 }
36
StartAbility(napi_env env,napi_callback_info info)37 napi_value JsAbilityContext::StartAbility(napi_env env, napi_callback_info info)
38 {
39 return nullptr;
40 }
41
StartAbilityAsCaller(napi_env env,napi_callback_info info)42 napi_value JsAbilityContext::StartAbilityAsCaller(napi_env env, napi_callback_info info)
43 {
44 return nullptr;
45 }
46
StartRecentAbility(napi_env env,napi_callback_info info)47 napi_value JsAbilityContext::StartRecentAbility(napi_env env, napi_callback_info info)
48 {
49 return nullptr;
50 }
51
StartAbilityWithAccount(napi_env env,napi_callback_info info)52 napi_value JsAbilityContext::StartAbilityWithAccount(napi_env env, napi_callback_info info)
53 {
54 return nullptr;
55 }
56
StartAbilityByCall(napi_env env,napi_callback_info info)57 napi_value JsAbilityContext::StartAbilityByCall(napi_env env, napi_callback_info info)
58 {
59 return nullptr;
60 }
61
StartAbilityForResult(napi_env env,napi_callback_info info)62 napi_value JsAbilityContext::StartAbilityForResult(napi_env env, napi_callback_info info)
63 {
64 return nullptr;
65 }
66
StartAbilityForResultWithAccount(napi_env env,napi_callback_info info)67 napi_value JsAbilityContext::StartAbilityForResultWithAccount(napi_env env, napi_callback_info info)
68 {
69 return nullptr;
70 }
71
StartServiceExtensionAbility(napi_env env,napi_callback_info info)72 napi_value JsAbilityContext::StartServiceExtensionAbility(napi_env env, napi_callback_info info)
73 {
74 return nullptr;
75 }
76
StartServiceExtensionAbilityWithAccount(napi_env env,napi_callback_info info)77 napi_value JsAbilityContext::StartServiceExtensionAbilityWithAccount(napi_env env, napi_callback_info info)
78 {
79 return nullptr;
80 }
81
StopServiceExtensionAbility(napi_env env,napi_callback_info info)82 napi_value JsAbilityContext::StopServiceExtensionAbility(napi_env env, napi_callback_info info)
83 {
84 return nullptr;
85 }
86
StopServiceExtensionAbilityWithAccount(napi_env env,napi_callback_info info)87 napi_value JsAbilityContext::StopServiceExtensionAbilityWithAccount(napi_env env, napi_callback_info info)
88 {
89 return nullptr;
90 }
91
ConnectAbility(napi_env env,napi_callback_info info)92 napi_value JsAbilityContext::ConnectAbility(napi_env env, napi_callback_info info)
93 {
94 return nullptr;
95 }
96
ConnectAbilityWithAccount(napi_env env,napi_callback_info info)97 napi_value JsAbilityContext::ConnectAbilityWithAccount(napi_env env, napi_callback_info info)
98 {
99 return nullptr;
100 }
101
DisconnectAbility(napi_env env,napi_callback_info info)102 napi_value JsAbilityContext::DisconnectAbility(napi_env env, napi_callback_info info)
103 {
104 return nullptr;
105 }
106
TerminateSelf(napi_env env,napi_callback_info info)107 napi_value JsAbilityContext::TerminateSelf(napi_env env, napi_callback_info info)
108 {
109 GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnTerminateSelf);
110 }
111
OnTerminateSelf(napi_env env,NapiCallbackInfo & info)112 napi_value JsAbilityContext::OnTerminateSelf(napi_env env, NapiCallbackInfo &info)
113 {
114 TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
115 auto abilityContext = context_.lock();
116 if (abilityContext == nullptr) {
117 return nullptr;
118 }
119 abilityContext->SetTerminating(true);
120
121 napi_value lastParam = (info.argc > ARGC_ZERO) ? info.argv[ARGC_ZERO] : nullptr;
122 napi_value result = nullptr;
123 auto task = CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
124 if (task == nullptr) {
125 return nullptr;
126 }
127
128 auto errcode = abilityContext->TerminateSelf();
129 if (errcode == 0) {
130 task->Resolve(env, CreateJsUndefined(env));
131 } else {
132 task->Reject(env, CreateJsErrorByNativeErr(env, errcode));
133 }
134
135 return result;
136 }
137
TerminateSelfWithResult(napi_env env,napi_callback_info info)138 napi_value JsAbilityContext::TerminateSelfWithResult(napi_env env, napi_callback_info info)
139 {
140 GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnTerminateSelfWithResult);
141 }
142
OnTerminateSelfWithResult(napi_env env,NapiCallbackInfo & info)143 napi_value JsAbilityContext::OnTerminateSelfWithResult(napi_env env, NapiCallbackInfo &info)
144 {
145 TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
146 auto abilityContext = context_.lock();
147 if (abilityContext == nullptr) {
148 return nullptr;
149 }
150 abilityContext->SetTerminating(true);
151
152 napi_value lastParam = (info.argc > ARGC_ONE) ? info.argv[ARGC_ONE] : nullptr;
153 napi_value result = nullptr;
154 auto task = CreateAsyncTaskWithLastParam(env, lastParam, nullptr, nullptr, &result);
155 if (task == nullptr) {
156 return nullptr;
157 }
158
159 auto errcode = abilityContext->TerminateSelf();
160 if (errcode == 0) {
161 task->Resolve(env, CreateJsUndefined(env));
162 } else {
163 task->Reject(env, CreateJsErrorByNativeErr(env, errcode));
164 }
165
166 return result;
167 }
168
RestoreWindowStage(napi_env env,napi_callback_info info)169 napi_value JsAbilityContext::RestoreWindowStage(napi_env env, napi_callback_info info)
170 {
171 return nullptr;
172 }
173
RequestDialogService(napi_env env,napi_callback_info info)174 napi_value JsAbilityContext::RequestDialogService(napi_env env, napi_callback_info info)
175 {
176 return nullptr;
177 }
178
IsTerminating(napi_env env,napi_callback_info info)179 napi_value JsAbilityContext::IsTerminating(napi_env env, napi_callback_info info)
180 {
181 GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnIsTerminating);
182 }
183
OnIsTerminating(napi_env env,NapiCallbackInfo & info)184 napi_value JsAbilityContext::OnIsTerminating(napi_env env, NapiCallbackInfo &info)
185 {
186 TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
187 auto context = context_.lock();
188 if (context == nullptr) {
189 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null context");
190 return CreateJsUndefined(env);
191 }
192 return CreateJsValue(env, context->IsTerminating());
193 }
194
CreateJsErrorByNativeErr(napi_env env,int32_t err,const std::string & permission)195 napi_value CreateJsErrorByNativeErr(napi_env env, int32_t err, const std::string &permission)
196 {
197 auto errCode = GetJsErrorCodeByNativeError(err);
198 auto errMsg = (errCode == AbilityErrorCode::ERROR_CODE_PERMISSION_DENIED && !permission.empty()) ?
199 GetNoPermissionErrorMsg(permission) : GetErrorMsg(errCode);
200 return CreateJsError(env, static_cast<int32_t>(errCode), errMsg);
201 }
202
ConfigurationUpdated(napi_env env,std::shared_ptr<NativeReference> & jsContext,const std::shared_ptr<AppExecFwk::Configuration> & config)203 void JsAbilityContext::ConfigurationUpdated(napi_env env, std::shared_ptr<NativeReference> &jsContext,
204 const std::shared_ptr<AppExecFwk::Configuration> &config)
205 {
206 TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
207 if (jsContext == nullptr || config == nullptr) {
208 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null jsContext");
209 return;
210 }
211
212 napi_value value = jsContext->GetNapiValue();
213 if (value == nullptr) {
214 TAG_LOGE(AAFwkTag::ABILITY_SIM, "null value");
215 return;
216 }
217
218 napi_value method = nullptr;
219 napi_get_named_property(env, value, "onUpdateConfiguration", &method);
220 if (method == nullptr) {
221 TAG_LOGE(AAFwkTag::ABILITY_SIM, "failed");
222 return;
223 }
224
225 napi_value argv[] = { CreateJsConfiguration(env, *config) };
226 napi_value callResult = nullptr;
227 napi_call_function(env, nullptr, method, 1, argv, &callResult);
228 }
229
CreateJsAbilityContext(napi_env env,const std::shared_ptr<AbilityContext> & context)230 napi_value CreateJsAbilityContext(napi_env env, const std::shared_ptr<AbilityContext> &context)
231 {
232 napi_value object = CreateJsBaseContext(env, context);
233
234 std::unique_ptr<JsAbilityContext> jsContext = std::make_unique<JsAbilityContext>(context);
235 napi_wrap(env, object, jsContext.release(), JsAbilityContext::Finalizer, nullptr, nullptr);
236
237 auto resourceManager = context->GetResourceManager();
238 if (resourceManager != nullptr) {
239 napi_set_named_property(env, object, "resourceManager",
240 CreateJsResourceManager(env, resourceManager, context));
241 }
242
243 auto abilityInfo = context->GetAbilityInfo();
244 if (abilityInfo != nullptr) {
245 napi_set_named_property(
246 env, object, "abilityInfo", CreateJsAbilityInfo(env, *abilityInfo));
247 }
248
249 auto configuration = context->GetConfiguration();
250 if (configuration != nullptr) {
251 napi_set_named_property(
252 env, object, "config", CreateJsConfiguration(env, *configuration));
253 }
254
255 const char *moduleName = "JsAbilityContext";
256 BindNativeFunction(env, object, "startAbility", moduleName, JsAbilityContext::StartAbility);
257 BindNativeFunction(env, object, "startAbilityAsCaller", moduleName, JsAbilityContext::StartAbilityAsCaller);
258 BindNativeFunction(env, object, "startAbilityWithAccount", moduleName,
259 JsAbilityContext::StartAbilityWithAccount);
260 BindNativeFunction(env, object, "startAbilityByCall", moduleName, JsAbilityContext::StartAbilityByCall);
261 BindNativeFunction(env, object, "startAbilityForResult", moduleName, JsAbilityContext::StartAbilityForResult);
262 BindNativeFunction(env, object, "startAbilityForResultWithAccount", moduleName,
263 JsAbilityContext::StartAbilityForResultWithAccount);
264 BindNativeFunction(env, object, "startServiceExtensionAbility", moduleName,
265 JsAbilityContext::StartServiceExtensionAbility);
266 BindNativeFunction(env, object, "startServiceExtensionAbilityWithAccount", moduleName,
267 JsAbilityContext::StartServiceExtensionAbilityWithAccount);
268 BindNativeFunction(env, object, "stopServiceExtensionAbility", moduleName,
269 JsAbilityContext::StopServiceExtensionAbility);
270 BindNativeFunction(env, object, "stopServiceExtensionAbilityWithAccount", moduleName,
271 JsAbilityContext::StopServiceExtensionAbilityWithAccount);
272 BindNativeFunction(env, object, "connectAbility", moduleName, JsAbilityContext::ConnectAbility);
273 BindNativeFunction(env, object, "connectServiceExtensionAbility", moduleName, JsAbilityContext::ConnectAbility);
274 BindNativeFunction(env, object, "connectAbilityWithAccount", moduleName,
275 JsAbilityContext::ConnectAbilityWithAccount);
276 BindNativeFunction(env, object, "connectServiceExtensionAbilityWithAccount", moduleName,
277 JsAbilityContext::ConnectAbilityWithAccount);
278 BindNativeFunction(env, object, "disconnectAbility", moduleName, JsAbilityContext::DisconnectAbility);
279 BindNativeFunction(
280 env, object, "disconnectServiceExtensionAbility", moduleName, JsAbilityContext::DisconnectAbility);
281 BindNativeFunction(env, object, "terminateSelf", moduleName, JsAbilityContext::TerminateSelf);
282 BindNativeFunction(env, object, "terminateSelfWithResult", moduleName,
283 JsAbilityContext::TerminateSelfWithResult);
284 BindNativeFunction(env, object, "restoreWindowStage", moduleName, JsAbilityContext::RestoreWindowStage);
285 BindNativeFunction(env, object, "isTerminating", moduleName, JsAbilityContext::IsTerminating);
286 BindNativeFunction(env, object, "startRecentAbility", moduleName,
287 JsAbilityContext::StartRecentAbility);
288 BindNativeFunction(env, object, "requestDialogService", moduleName,
289 JsAbilityContext::RequestDialogService);
290
291 return object;
292 }
293 } // namespace AbilityRuntime
294 } // namespace OHOS
295