1 /*
2 * Copyright (c) 2022-2025 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 "efficiency_resources_operation.h"
17
18 #include "singleton.h"
19
20 #include "common.h"
21 #include "background_task_manager.h"
22 #include "efficiency_resource_info.h"
23 #include "efficiency_resource_log.h"
24 #include "hitrace_meter.h"
25
26 namespace OHOS {
27 namespace BackgroundTaskMgr {
28 namespace {
29 static constexpr int32_t APPLY_EFFICIENCY_RESOURCES_PARAMS = 1;
30 }
31
32 struct AsyncCallbackInfoGetAllEfficiencyResources : public AsyncWorkData {
AsyncCallbackInfoGetAllEfficiencyResourcesOHOS::BackgroundTaskMgr::AsyncCallbackInfoGetAllEfficiencyResources33 explicit AsyncCallbackInfoGetAllEfficiencyResources(napi_env env) : AsyncWorkData(env) {}
34 std::vector<std::shared_ptr<EfficiencyResourceInfo>> efficiencyResourceInfoList; // out
35 };
36
GetNamedBoolValue(const napi_env & env,napi_value & object,const char * utf8name,bool & result,bool isNecessary)37 napi_value GetNamedBoolValue(const napi_env &env, napi_value &object, const char* utf8name,
38 bool& result, bool isNecessary)
39 {
40 bool hasNamedProperty = false;
41 napi_value boolValue = nullptr;
42 if (napi_has_named_property(env, object, utf8name, &hasNamedProperty) != napi_ok || !hasNamedProperty) {
43 if (isNecessary) {
44 BGTASK_LOGE("ParseParameters failed, %{public}s not exist, is nullptr", utf8name);
45 return nullptr;
46 } else {
47 return Common::NapiGetNull(env);
48 }
49 }
50 BGTASK_NAPI_CALL(env, napi_get_named_property(env, object, utf8name, &boolValue));
51 if (!Common::GetBooleanValue(env, boolValue, result)) {
52 BGTASK_LOGE("ParseParameters failed, %{public}s is nullptr", utf8name);
53 return nullptr;
54 }
55 BGTASK_LOGD("GetNamedBoolValue: %{public}s is %{public}d", utf8name, result);
56 return Common::NapiGetNull(env);
57 }
58
GetNamedInt32Value(const napi_env & env,napi_value & object,const char * utf8name,int32_t & result)59 napi_value GetNamedInt32Value(const napi_env &env, napi_value &object, const char* utf8name,
60 int32_t& result)
61 {
62 bool hasNamedProperty = false;
63 napi_value intValue = nullptr;
64 if (napi_has_named_property(env, object, utf8name, &hasNamedProperty) != napi_ok || !hasNamedProperty) {
65 BGTASK_LOGE("ParseParameters failed, %{public}s not exist, is nullptr", utf8name);
66 return nullptr;
67 }
68 BGTASK_NAPI_CALL(env, napi_get_named_property(env, object, utf8name, &intValue));
69 if (!Common::GetInt32NumberValue(env, intValue, result)) {
70 BGTASK_LOGE("ParseParameters failed, %{public}s is nullptr", utf8name);
71 return nullptr;
72 }
73 if (result < 0) {
74 BGTASK_LOGE("%{public}s can't be a negtive number: %{public}d", utf8name, result);
75 return nullptr;
76 }
77 BGTASK_LOGD("GetNamedInt32Value: %{public}s is %{public}d", utf8name, result);
78 return Common::NapiGetNull(env);
79 }
80
GetNamedStringValue(const napi_env & env,napi_value & object,std::string & result)81 napi_value GetNamedStringValue(const napi_env &env, napi_value &object, std::string& result)
82 {
83 bool hasNamedProperty = false;
84 napi_value stringValue = nullptr;
85 if (napi_has_named_property(env, object, "reason", &hasNamedProperty) != napi_ok || !hasNamedProperty) {
86 BGTASK_LOGE("ParseParameters failed, reason not exist, is nullptr");
87 return nullptr;
88 }
89 BGTASK_NAPI_CALL(env, napi_get_named_property(env, object, "reason", &stringValue));
90 if (!Common::GetStringValue(env, stringValue, result)) {
91 BGTASK_LOGE("ParseParameters failed, reason is nullptr");
92 return nullptr;
93 }
94 BGTASK_LOGD("GetNamedStringValue: reason is %{public}s", result.c_str());
95 return Common::NapiGetNull(env);
96 }
97
ParseParameters(const napi_env & env,const napi_callback_info & info,EfficiencyResourceInfo & params,bool isThrow)98 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info,
99 EfficiencyResourceInfo ¶ms, bool isThrow)
100 {
101 size_t argc = APPLY_EFFICIENCY_RESOURCES_PARAMS;
102 napi_value argv[APPLY_EFFICIENCY_RESOURCES_PARAMS] = {nullptr};
103 BGTASK_NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
104 if (argc != APPLY_EFFICIENCY_RESOURCES_PARAMS) {
105 Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR, isThrow);
106 return nullptr;
107 }
108 int32_t resourceNumber {0};
109 bool isApply {false};
110 int32_t timeOut {0};
111 std::string reason {""};
112 bool isPersist {false};
113 bool isProcess {false};
114
115 if (!GetNamedInt32Value(env, argv[0], "resourceTypes", resourceNumber)) {
116 Common::HandleParamErr(env, ERR_RESOURCE_TYPES_INVALID, isThrow);
117 return nullptr;
118 }
119 if (!GetNamedBoolValue(env, argv[0], "isApply", isApply, true)) {
120 Common::HandleParamErr(env, ERR_ISAPPLY_NULL_OR_TYPE_ERR, isThrow);
121 return nullptr;
122 }
123 if (!GetNamedInt32Value(env, argv[0], "timeOut", timeOut)) {
124 Common::HandleParamErr(env, ERR_TIMEOUT_INVALID, isThrow);
125 return nullptr;
126 }
127 if (!GetNamedStringValue(env, argv[0], reason)) {
128 Common::HandleParamErr(env, ERR_REASON_NULL_OR_TYPE_ERR, isThrow);
129 return nullptr;
130 }
131 if (!GetNamedBoolValue(env, argv[0], "isPersist", isPersist, false)) {
132 Common::HandleParamErr(env, ERR_ISPERSIST_NULL_OR_TYPE_ERR, isThrow);
133 return nullptr;
134 }
135 if (!GetNamedBoolValue(env, argv[0], "isProcess", isProcess, false)) {
136 Common::HandleParamErr(env, ERR_ISPROCESS_NULL_OR_TYPE_ERR, isThrow);
137 return nullptr;
138 }
139 params = EfficiencyResourceInfo {resourceNumber, isApply, timeOut, reason, isPersist, isProcess};
140 return Common::NapiGetNull(env);
141 }
142
CheckValidInfo(napi_env env,const EfficiencyResourceInfo & params,bool isThrow)143 bool CheckValidInfo(napi_env env, const EfficiencyResourceInfo ¶ms, bool isThrow)
144 {
145 if (params.GetResourceNumber() == 0) {
146 Common::HandleParamErr(env, ERR_RESOURCE_TYPES_INVALID, isThrow);
147 return false;
148 }
149 if (params.IsApply() && !params.IsPersist() && params.GetTimeOut() == 0) {
150 Common::HandleParamErr(env, ERR_TIMEOUT_INVALID, isThrow);
151 return false;
152 }
153 return true;
154 }
155
ApplyEfficiencyResources(napi_env env,napi_callback_info info)156 napi_value ApplyEfficiencyResources(napi_env env, napi_callback_info info)
157 {
158 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
159 "BackgroundTaskManager::EfficiencyResource::Napi::ApplyEfficiencyResources");
160 EfficiencyResourceInfo params;
161 if (ParseParameters(env, info, params, true) == nullptr || !CheckValidInfo(env, params, true)) {
162 return Common::NapiGetNull(env);
163 }
164 ErrCode errCode = DelayedSingleton<BackgroundTaskManager>::GetInstance()->ApplyEfficiencyResources(params);
165 Common::HandleErrCode(env, errCode, true);
166 return Common::NapiGetNull(env);
167 }
168
ResetAllEfficiencyResources(napi_env env,napi_callback_info info)169 napi_value ResetAllEfficiencyResources(napi_env env, napi_callback_info info)
170 {
171 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
172 "BackgroundTaskManager::EfficiencyResource::Napi::ResetAllEfficiencyResources");
173 ErrCode errCode = DelayedSingleton<BackgroundTaskManager>::GetInstance()->ResetAllEfficiencyResources();
174 Common::HandleErrCode(env, errCode, true);
175 return Common::NapiGetNull(env);
176 }
177
GetAllEfficiencyResourcesAsyncWork(napi_env env,void * data)178 void GetAllEfficiencyResourcesAsyncWork(napi_env env, void *data)
179 {
180 AsyncCallbackInfoGetAllEfficiencyResources *asyncCallbackInfo =
181 static_cast<AsyncCallbackInfoGetAllEfficiencyResources *>(data);
182 if (asyncCallbackInfo == nullptr || asyncCallbackInfo->errCode != ERR_OK) {
183 BGTASK_LOGE("asyncCallbackInfo is nullptr");
184 return;
185 }
186 asyncCallbackInfo->errCode = DelayedSingleton<BackgroundTaskManager>::GetInstance()->
187 GetAllEfficiencyResources(asyncCallbackInfo->efficiencyResourceInfoList);
188 }
189
GetAllEfficiencyResourcesAsyncWork(napi_env env,napi_status status,void * data)190 void GetAllEfficiencyResourcesAsyncWork(napi_env env, napi_status status, void *data)
191 {
192 AsyncCallbackInfoGetAllEfficiencyResources *asyncCallbackInfo =
193 static_cast<AsyncCallbackInfoGetAllEfficiencyResources *>(data);
194 if (asyncCallbackInfo == nullptr) {
195 BGTASK_LOGE("asyncCallbackInfo is nullptr");
196 return;
197 }
198 napi_value result = nullptr;
199 if (asyncCallbackInfo->errCode == ERR_OK) {
200 NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &result));
201 if (asyncCallbackInfo->efficiencyResourceInfoList.size() > 0) {
202 uint32_t count = 0;
203 for (const auto &efficiencyResourceTaskInfo : asyncCallbackInfo->efficiencyResourceInfoList) {
204 napi_value napiWork = Common::GetNapiEfficiencyResourcesInfo(env, efficiencyResourceTaskInfo);
205 NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, count, napiWork));
206 count++;
207 }
208 }
209 NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncCallbackInfo->deferred, result));
210 } else {
211 std::string errMsg = Common::FindErrMsg(env, asyncCallbackInfo->errCode);
212 int32_t errCodeInfo = Common::FindErrCode(env, asyncCallbackInfo->errCode);
213 result = Common::GetCallbackErrorValue(env, errCodeInfo, errMsg);
214 NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result));
215 }
216 }
217
GetAllEfficiencyResources(napi_env env,napi_callback_info info)218 napi_value GetAllEfficiencyResources(napi_env env, napi_callback_info info)
219 {
220 HitraceScoped traceScoped(HITRACE_TAG_OHOS,
221 "BackgroundTaskManager::EfficiencyResource::Napi::GetAllEfficiencyResources");
222
223 // Get params
224 napi_ref callback = nullptr;
225 napi_value promise = nullptr;
226 AsyncCallbackInfoGetAllEfficiencyResources *asyncCallbackInfo =
227 new (std::nothrow)AsyncCallbackInfoGetAllEfficiencyResources(env);
228 if (!asyncCallbackInfo) {
229 BGTASK_LOGE("asyncCallbackInfo is nullptr");
230 return Common::JSParaError(env, callback);
231 }
232 std::unique_ptr<AsyncCallbackInfoGetAllEfficiencyResources> callbackPtr {asyncCallbackInfo};
233 Common::PaddingAsyncWorkData(env, callback, *asyncCallbackInfo, promise);
234
235 napi_value resourceName = nullptr;
236 NAPI_CALL(env, napi_create_string_latin1(env, "GetAllEfficiencyResources", NAPI_AUTO_LENGTH, &resourceName));
237
238 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName,
239 [](napi_env env, void *data) {
240 GetAllEfficiencyResourcesAsyncWork(env, data);
241 },
242 [](napi_env env, napi_status status, void *data) {
243 GetAllEfficiencyResourcesAsyncWork(env, status, data);
244 },
245 static_cast<AsyncCallbackInfoGetAllEfficiencyResources *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork));
246
247 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
248 if (asyncCallbackInfo->isCallback) {
249 callbackPtr.release();
250 return Common::NapiGetNull(env);
251 } else {
252 callbackPtr.release();
253 return promise;
254 }
255 }
256 }
257 }