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