• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "napi_common_util.h"
21 #include "napi_common_want.h"
22 
23 namespace OHOS {
24 namespace AbilityRuntime {
25 
JsStartupConfig(napi_env env)26 JsStartupConfig::JsStartupConfig(napi_env env) : StartupConfig(), env_(env)
27 {}
28 
29 JsStartupConfig::~JsStartupConfig() = default;
30 
Init(std::unique_ptr<NativeReference> & configEntryJsRef,std::shared_ptr<AAFwk::Want> want)31 int32_t JsStartupConfig::Init(std::unique_ptr<NativeReference> &configEntryJsRef,
32     std::shared_ptr<AAFwk::Want> want)
33 {
34     if (configEntryJsRef == nullptr) {
35         TAG_LOGE(AAFwkTag::STARTUP, "null configEntry");
36         return ERR_STARTUP_INTERNAL_ERROR;
37     }
38     HandleScope handleScope(env_);
39 
40     napi_value configEntry = configEntryJsRef->GetNapiValue();
41     if (!CheckTypeForNapiValue(env_, configEntry, napi_object)) {
42         TAG_LOGE(AAFwkTag::STARTUP, "not napi object");
43         return ERR_STARTUP_INTERNAL_ERROR;
44     }
45     napi_value onConfig = nullptr;
46     napi_get_named_property(env_, configEntry, "onConfig", &onConfig);
47     if (onConfig == nullptr) {
48         TAG_LOGE(AAFwkTag::STARTUP, "null onConfig");
49         return ERR_STARTUP_INTERNAL_ERROR;
50     }
51     bool isCallable = false;
52     napi_is_callable(env_, onConfig, &isCallable);
53     if (!isCallable) {
54         TAG_LOGE(AAFwkTag::STARTUP, "onConfig not callable");
55         return ERR_STARTUP_INTERNAL_ERROR;
56     }
57     napi_value config = nullptr;
58     napi_call_function(env_, configEntry, onConfig, 0, nullptr, &config);
59     if (config == nullptr) {
60         TAG_LOGE(AAFwkTag::STARTUP, "null config");
61         return ERR_STARTUP_INTERNAL_ERROR;
62     }
63 
64     InitAwaitTimeout(env_, config);
65     InitListener(env_, config);
66     InitCustomization(env_, configEntry, want);
67     return ERR_OK;
68 }
69 
Init(napi_value config)70 int32_t JsStartupConfig::Init(napi_value config)
71 {
72     if (config == nullptr) {
73         TAG_LOGE(AAFwkTag::STARTUP, "null config");
74         return ERR_STARTUP_INTERNAL_ERROR;
75     }
76 
77     InitAwaitTimeout(env_, config);
78     InitListener(env_, config);
79     return ERR_OK;
80 }
81 
InitAwaitTimeout(napi_env env,napi_value config)82 void JsStartupConfig::InitAwaitTimeout(napi_env env, napi_value config)
83 {
84     napi_value awaitTimeout = nullptr;
85     napi_get_named_property(env, config, "timeoutMs", &awaitTimeout);
86     if (awaitTimeout == nullptr) {
87         TAG_LOGD(AAFwkTag::STARTUP, "timeoutMs invalid");
88         return;
89     }
90     int32_t awaitTimeoutNum = DEFAULT_AWAIT_TIMEOUT_MS;
91     if (!ConvertFromJsValue(env, awaitTimeout, awaitTimeoutNum)) {
92         TAG_LOGD(AAFwkTag::STARTUP, "covert failed");
93         return;
94     }
95     if (awaitTimeoutNum <= 0) {
96         TAG_LOGE(AAFwkTag::STARTUP, "invalid argc");
97         awaitTimeoutNum = DEFAULT_AWAIT_TIMEOUT_MS;
98     }
99     TAG_LOGD(AAFwkTag::STARTUP, "set awaitTimeoutMs to %{public}d", awaitTimeoutNum);
100     awaitTimeoutMs_ = awaitTimeoutNum;
101 }
102 
InitListener(napi_env env,napi_value config)103 void JsStartupConfig::InitListener(napi_env env, napi_value config)
104 {
105     napi_value listener = nullptr;
106     napi_get_named_property(env, config, "startupListener", &listener);
107     if (listener == nullptr) {
108         TAG_LOGD(AAFwkTag::STARTUP, "null startupListener");
109         return;
110     }
111     if (!CheckTypeForNapiValue(env, listener, napi_object)) {
112         TAG_LOGD(AAFwkTag::STARTUP, "not napi object");
113         return;
114     }
115 
116     napi_value onCompleted = nullptr;
117     napi_get_named_property(env, listener, "onCompleted", &onCompleted);
118     if (onCompleted == nullptr) {
119         TAG_LOGD(AAFwkTag::STARTUP, "null onCompleted");
120         return;
121     }
122     napi_ref listenerRef = nullptr;
123     napi_create_reference(env, listener, 1, &listenerRef);
124     std::shared_ptr<NativeReference> listenerRefSp(reinterpret_cast<NativeReference *>(listenerRef));
125     OnCompletedCallbackFunc onCompletedCallback =
126         [env, listenerRefSp](const std::shared_ptr<StartupTaskResult> &result) {
127             if (env == nullptr || listenerRefSp == nullptr) {
128                 TAG_LOGE(AAFwkTag::STARTUP, "null env or listenerRefSp");
129                 return;
130             }
131             HandleScope handleScope(env);
132             napi_value listener = listenerRefSp->GetNapiValue();
133 
134             napi_value onCompleted = nullptr;
135             napi_get_named_property(env, listener, "onCompleted", &onCompleted);
136             if (onCompleted == nullptr) {
137                 TAG_LOGE(AAFwkTag::STARTUP, "null onCompleted");
138                 return;
139             }
140             bool isCallable = false;
141             napi_is_callable(env, onCompleted, &isCallable);
142             if (!isCallable) {
143                 TAG_LOGE(AAFwkTag::STARTUP, "onCompleted not callable");
144                 return;
145             }
146             napi_value argv[1] = { JsStartupConfig::BuildResult(env, result) };
147             napi_call_function(env, listener, onCompleted, 1, argv, nullptr);
148         };
149     listener_ = std::make_shared<StartupListener>(onCompletedCallback);
150 }
151 
InitCustomization(napi_env env,napi_value configEntry,std::shared_ptr<AAFwk::Want> want)152 void JsStartupConfig::InitCustomization(napi_env env, napi_value configEntry, std::shared_ptr<AAFwk::Want> want)
153 {
154     TAG_LOGD(AAFwkTag::STARTUP, "InitCustomization");
155     if (!want) {
156         TAG_LOGD(AAFwkTag::STARTUP, "want is null");
157         return;
158     }
159 
160     napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, *want);
161     napi_value method = nullptr;
162     napi_get_named_property(env, configEntry, "onRequestCustomMatchRule", &method);
163     if (method == nullptr) {
164         TAG_LOGE(AAFwkTag::APPKIT, "null method onRequestCustomMatchRule");
165         return;
166     }
167 
168     bool isCallable = false;
169     napi_is_callable(env, method, &isCallable);
170     if (!isCallable) {
171         TAG_LOGI(AAFwkTag::STARTUP, "onRequestCustomMatchRule not callable");
172         return;
173     }
174 
175     constexpr size_t argc = 1;
176     napi_value argv[] = { napiWant };
177     napi_value callResult = nullptr;
178     napi_status status = napi_call_function(env, configEntry, method, argc, argv, &callResult);
179     if (status != napi_ok) {
180         TAG_LOGE(AAFwkTag::ABILITYMGR, "call js func onRequestCustomMatchRule failed: %{public}d", status);
181     }
182     customization_ = AppExecFwk::UnwrapStringFromJS(env, callResult);
183 }
184 
BuildResult(napi_env env,const std::shared_ptr<StartupTaskResult> & result)185 napi_value JsStartupConfig::BuildResult(napi_env env, const std::shared_ptr<StartupTaskResult> &result)
186 {
187     if (result == nullptr) {
188         return CreateJsError(env, ERR_STARTUP_INTERNAL_ERROR,
189             StartupUtils::GetErrorMessage(ERR_STARTUP_INTERNAL_ERROR));
190     }
191     if (result->GetResultCode() != ERR_OK) {
192         return CreateJsError(env, result->GetResultCode(), result->GetResultMessage());
193     }
194     return CreateJsNull(env);
195 }
196 } // namespace AbilityRuntime
197 } // namespace OHOS
198