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_startup_config.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "js_runtime_utils.h"
20
21 namespace OHOS {
22 namespace AbilityRuntime {
23
JsStartupConfig(napi_env env)24 JsStartupConfig::JsStartupConfig(napi_env env) : StartupConfig(), env_(env)
25 {}
26
27 JsStartupConfig::~JsStartupConfig() = default;
28
Init(std::unique_ptr<NativeReference> & configEntryJsRef)29 int32_t JsStartupConfig::Init(std::unique_ptr<NativeReference> &configEntryJsRef)
30 {
31 if (configEntryJsRef == nullptr) {
32 TAG_LOGE(AAFwkTag::STARTUP, "config entry null");
33 return ERR_STARTUP_INTERNAL_ERROR;
34 }
35 HandleScope handleScope(env_);
36
37 napi_value configEntry = configEntryJsRef->GetNapiValue();
38 if (!CheckTypeForNapiValue(env_, configEntry, napi_object)) {
39 TAG_LOGE(AAFwkTag::STARTUP, "not napi object");
40 return ERR_STARTUP_INTERNAL_ERROR;
41 }
42 napi_value onConfig = nullptr;
43 napi_get_named_property(env_, configEntry, "onConfig", &onConfig);
44 if (onConfig == nullptr) {
45 TAG_LOGE(AAFwkTag::STARTUP, "onConfig invalid");
46 return ERR_STARTUP_INTERNAL_ERROR;
47 }
48 bool isCallable = false;
49 napi_is_callable(env_, onConfig, &isCallable);
50 if (!isCallable) {
51 TAG_LOGE(AAFwkTag::STARTUP, "onConfig not callable");
52 return ERR_STARTUP_INTERNAL_ERROR;
53 }
54 napi_value config = nullptr;
55 napi_call_function(env_, configEntry, onConfig, 0, nullptr, &config);
56 if (config == nullptr) {
57 TAG_LOGE(AAFwkTag::STARTUP, "config null");
58 return ERR_STARTUP_INTERNAL_ERROR;
59 }
60
61 InitAwaitTimeout(env_, config);
62 InitListener(env_, config);
63 return ERR_OK;
64 }
65
Init(napi_value config)66 int32_t JsStartupConfig::Init(napi_value config)
67 {
68 if (config == nullptr) {
69 TAG_LOGE(AAFwkTag::STARTUP, "config null");
70 return ERR_STARTUP_INTERNAL_ERROR;
71 }
72
73 InitAwaitTimeout(env_, config);
74 InitListener(env_, config);
75 return ERR_OK;
76 }
77
InitAwaitTimeout(napi_env env,napi_value config)78 void JsStartupConfig::InitAwaitTimeout(napi_env env, napi_value config)
79 {
80 napi_value awaitTimeout = nullptr;
81 napi_get_named_property(env, config, "timeoutMs", &awaitTimeout);
82 if (awaitTimeout == nullptr) {
83 TAG_LOGD(AAFwkTag::STARTUP, "timeoutMs invalid");
84 return;
85 }
86 int32_t awaitTimeoutNum = DEFAULT_AWAIT_TIMEOUT_MS;
87 if (!ConvertFromJsValue(env, awaitTimeout, awaitTimeoutNum)) {
88 TAG_LOGD(AAFwkTag::STARTUP, "covert failed");
89 return;
90 }
91 if (awaitTimeoutNum <= 0) {
92 TAG_LOGE(AAFwkTag::STARTUP, "invalid argc");
93 awaitTimeoutNum = DEFAULT_AWAIT_TIMEOUT_MS;
94 }
95 TAG_LOGD(AAFwkTag::STARTUP, "set awaitTimeoutMs to %{public}d", awaitTimeoutNum);
96 awaitTimeoutMs_ = awaitTimeoutNum;
97 }
98
InitListener(napi_env env,napi_value config)99 void JsStartupConfig::InitListener(napi_env env, napi_value config)
100 {
101 napi_value listener = nullptr;
102 napi_get_named_property(env, config, "startupListener", &listener);
103 if (listener == nullptr) {
104 TAG_LOGD(AAFwkTag::STARTUP, "null startupListener");
105 return;
106 }
107 if (!CheckTypeForNapiValue(env, listener, napi_object)) {
108 TAG_LOGD(AAFwkTag::STARTUP, "not napi object");
109 return;
110 }
111
112 napi_value onCompleted = nullptr;
113 napi_get_named_property(env, listener, "onCompleted", &onCompleted);
114 if (onCompleted == nullptr) {
115 TAG_LOGD(AAFwkTag::STARTUP, "null onCompleted");
116 return;
117 }
118 napi_ref listenerRef = nullptr;
119 napi_create_reference(env, listener, 1, &listenerRef);
120 std::shared_ptr<NativeReference> listenerRefSp(reinterpret_cast<NativeReference *>(listenerRef));
121 OnCompletedCallbackFunc onCompletedCallback =
122 [env, listenerRefSp](const std::shared_ptr<StartupTaskResult> &result) {
123 if (env == nullptr || listenerRefSp == nullptr) {
124 TAG_LOGE(AAFwkTag::STARTUP, "env or listenerRefSp null");
125 return;
126 }
127 HandleScope handleScope(env);
128 napi_value listener = listenerRefSp->GetNapiValue();
129
130 napi_value onCompleted = nullptr;
131 napi_get_named_property(env, listener, "onCompleted", &onCompleted);
132 if (onCompleted == nullptr) {
133 TAG_LOGE(AAFwkTag::STARTUP, "null onCompleted");
134 return;
135 }
136 bool isCallable = false;
137 napi_is_callable(env, onCompleted, &isCallable);
138 if (!isCallable) {
139 TAG_LOGE(AAFwkTag::STARTUP, "onCompleted not callable");
140 return;
141 }
142 napi_value argv[1] = { JsStartupConfig::BuildResult(env, result) };
143 napi_call_function(env, listener, onCompleted, 1, argv, nullptr);
144 };
145 listener_ = std::make_shared<StartupListener>(onCompletedCallback);
146 }
147
BuildResult(napi_env env,const std::shared_ptr<StartupTaskResult> & result)148 napi_value JsStartupConfig::BuildResult(napi_env env, const std::shared_ptr<StartupTaskResult> &result)
149 {
150 if (result == nullptr) {
151 return CreateJsError(env, ERR_STARTUP_INTERNAL_ERROR,
152 StartupUtils::GetErrorMessage(ERR_STARTUP_INTERNAL_ERROR));
153 }
154 if (result->GetResultCode() != ERR_OK) {
155 return CreateJsError(env, result->GetResultCode(), result->GetResultMessage());
156 }
157 return CreateJsNull(env);
158 }
159 } // namespace AbilityRuntime
160 } // namespace OHOS
161