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