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 "standby_napi_module.h"
17
18 #include <vector>
19
20 #include "napi_base_context.h"
21 #include "singleton.h"
22
23 #include "allow_info.h"
24 #include "allow_type.h"
25 #include "resourcce_request.h"
26 #include "standby_service_log.h"
27 #include "standby_service_client.h"
28
29 #include "common.h"
30
31 namespace OHOS {
32 namespace DevStandbyMgr {
33 namespace {
34 constexpr uint32_t IS_DEVICE_IN_STANDBY_MIN_PARAMS = 0;
35 constexpr uint32_t IS_DEVICE_IN_STANDBY_PARAMS = 1;
36 constexpr uint32_t GET_ALLOW_LIST_MIN_PARAMS = 1;
37 constexpr uint32_t GET_ALLOW_LIST_STANDBY_PARAMS = 2;
38 constexpr uint32_t APPLY_ALLOW_RESOURCE_PARAMS = 1;
39 }
40
41 struct AsyncCallbackInfoIsDeviceInStandby : public AsyncWorkData {
AsyncCallbackInfoIsDeviceInStandbyOHOS::DevStandbyMgr::AsyncCallbackInfoIsDeviceInStandby42 explicit AsyncCallbackInfoIsDeviceInStandby(napi_env env) : AsyncWorkData(env) {}
43 bool isStandby {false};
44 };
45
46 struct IsDeviceInStandbyParamsInfo {
47 napi_ref callback = nullptr;
48 };
49
ParseInStandbyParameters(const napi_env & env,const napi_callback_info & info,IsDeviceInStandbyParamsInfo & params)50 napi_value ParseInStandbyParameters(const napi_env& env, const napi_callback_info& info,
51 IsDeviceInStandbyParamsInfo& params)
52 {
53 size_t argc = IS_DEVICE_IN_STANDBY_PARAMS;
54 napi_value argv[IS_DEVICE_IN_STANDBY_PARAMS] = {nullptr};
55 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
56 if (argc != IS_DEVICE_IN_STANDBY_MIN_PARAMS && argc != IS_DEVICE_IN_STANDBY_PARAMS) {
57 Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR);
58 return nullptr;
59 }
60
61 // argv[0]: callback
62 if (argc == IS_DEVICE_IN_STANDBY_PARAMS) {
63 napi_valuetype valuetype = napi_undefined;
64 NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
65 if (valuetype != napi_function) {
66 Common::HandleParamErr(env, ERR_CALLBACK_NULL_OR_TYPE_ERR);
67 return nullptr;
68 }
69 NAPI_CALL(env, napi_create_reference(env, argv[0], 1, ¶ms.callback));
70 }
71
72 return Common::NapiGetNull(env);
73 }
74
AddInStandbyExecuteCB(napi_env env,void * data)75 void AddInStandbyExecuteCB(napi_env env, void *data)
76 {
77 AsyncCallbackInfoIsDeviceInStandby *asyncCallbackInfo =
78 static_cast<AsyncCallbackInfoIsDeviceInStandby *>(data);
79 if (asyncCallbackInfo != nullptr) {
80 // return current state, whether in standby state or not
81 asyncCallbackInfo->errCode = StandbyServiceClient::GetInstance().
82 IsDeviceInStandby(asyncCallbackInfo->isStandby);
83 }
84 }
85
AddInStandbyCallbackCompleteCB(napi_env env,napi_status status,void * data)86 void AddInStandbyCallbackCompleteCB(napi_env env, napi_status status, void *data)
87 {
88 AsyncCallbackInfoIsDeviceInStandby *asyncCallbackInfo =
89 static_cast<AsyncCallbackInfoIsDeviceInStandby *>(data);
90 std::unique_ptr<AsyncCallbackInfoIsDeviceInStandby> callbackPtr {asyncCallbackInfo};
91 if (asyncCallbackInfo != nullptr) {
92 napi_value result = nullptr;
93 napi_create_int32(env, asyncCallbackInfo->isStandby, &result);
94 Common::ReturnCallbackPromise(env, *asyncCallbackInfo, result);
95 }
96 }
97
IsDeviceInStandby(napi_env env,napi_callback_info info)98 napi_value IsDeviceInStandby(napi_env env, napi_callback_info info)
99 {
100 IsDeviceInStandbyParamsInfo params;
101 if (ParseInStandbyParameters(env, info, params) == nullptr) {
102 return nullptr;
103 }
104
105 napi_value promise = nullptr;
106 AsyncCallbackInfoIsDeviceInStandby *asyncCallbackInfo =
107 new (std::nothrow) AsyncCallbackInfoIsDeviceInStandby(env);
108 if (!asyncCallbackInfo) {
109 return nullptr;
110 }
111 std::unique_ptr<AsyncCallbackInfoIsDeviceInStandby> callbackPtr {asyncCallbackInfo};
112 Common::PaddingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise);
113
114 napi_value resourceName = nullptr;
115 NAPI_CALL(env, napi_create_string_latin1(env, "IsDeviceInStandby", NAPI_AUTO_LENGTH, &resourceName));
116
117 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, AddInStandbyExecuteCB,
118 AddInStandbyCallbackCompleteCB, static_cast<void *>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork));
119
120 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
121 callbackPtr.release();
122 if (asyncCallbackInfo->isCallback) {
123 return Common::NapiGetNull(env);
124 }
125 return promise;
126 }
127
128 struct AsyncCallbackInfoGetAllowList : public AsyncWorkData {
AsyncCallbackInfoGetAllowListOHOS::DevStandbyMgr::AsyncCallbackInfoGetAllowList129 explicit AsyncCallbackInfoGetAllowList(napi_env env) : AsyncWorkData(env) {}
130 uint32_t allowType = 0;
131 std::vector<AllowInfo> allowInfoArray {};
132 };
133
134 struct GetAllowListParamsInfo {
135 uint32_t allowType = 0;
136 napi_ref callback = nullptr;
137 };
138
AddGetAllowListExecuteCB(napi_env env,void * data)139 void AddGetAllowListExecuteCB(napi_env env, void *data)
140 {
141 AsyncCallbackInfoGetAllowList *asyncCallbackInfo =
142 static_cast<AsyncCallbackInfoGetAllowList *>(data);
143 if (asyncCallbackInfo != nullptr) {
144 asyncCallbackInfo->errCode = StandbyServiceClient::GetInstance().GetAllowList(
145 asyncCallbackInfo->allowType, asyncCallbackInfo->allowInfoArray, ReasonCodeEnum::REASON_APP_API);
146 }
147 }
148
AddGetAllowListCallbackCompleteCB(napi_env env,napi_status status,void * data)149 void AddGetAllowListCallbackCompleteCB(napi_env env, napi_status status, void *data)
150 {
151 AsyncCallbackInfoGetAllowList *asyncCallbackInfo =
152 static_cast<AsyncCallbackInfoGetAllowList *>(data);
153 std::unique_ptr<AsyncCallbackInfoGetAllowList> callbackPtr {asyncCallbackInfo};
154 if (asyncCallbackInfo != nullptr) {
155 napi_value result = nullptr;
156 napi_create_array(env, &result);
157 int32_t index = 0;
158 for (const auto& allowInfo : asyncCallbackInfo->allowInfoArray) {
159 napi_value allowInfoObj = nullptr;
160 napi_create_object(env, &allowInfoObj);
161 Common::SetUint32Value(env, "resourceTypes", static_cast<uint32_t>(allowInfo.GetAllowType()), allowInfoObj);
162 Common::SetStringValue(env, "name", allowInfo.GetName(), allowInfoObj);
163 Common::SetInt32Value(env, "duration", allowInfo.GetDuration(), allowInfoObj);
164 napi_set_element(env, result, index, allowInfoObj);
165 ++index;
166 }
167
168 Common::ReturnCallbackPromise(env, *asyncCallbackInfo, result);
169 }
170 }
171
ParseGetAllowListParameters(const napi_env & env,const napi_callback_info & info,GetAllowListParamsInfo & params)172 napi_value ParseGetAllowListParameters(const napi_env& env, const napi_callback_info& info,
173 GetAllowListParamsInfo& params)
174 {
175 size_t argc = GET_ALLOW_LIST_STANDBY_PARAMS;
176 napi_value argv[GET_ALLOW_LIST_STANDBY_PARAMS] = {nullptr};
177 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
178 if (argc != GET_ALLOW_LIST_MIN_PARAMS && argc != GET_ALLOW_LIST_STANDBY_PARAMS) {
179 Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR);
180 return nullptr;
181 }
182
183 // argv[0]: allowType
184 if (Common::GetUint32Value(env, argv[0], params.allowType) == nullptr) {
185 STANDBYSERVICE_LOGE("ParseParameters failed, allowType is nullptr.");
186 Common::HandleParamErr(env, ERR_RESOURCE_TYPES_INVALID);
187 return nullptr;
188 }
189
190 // argv[1]: callback
191 if (argc == GET_ALLOW_LIST_STANDBY_PARAMS) {
192 napi_valuetype valuetype = napi_undefined;
193 NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype));
194 if (valuetype != napi_function) {
195 Common::HandleParamErr(env, ERR_CALLBACK_NULL_OR_TYPE_ERR);
196 return nullptr;
197 }
198 NAPI_CALL(env, napi_create_reference(env, argv[1], 1, ¶ms.callback));
199 }
200
201 if (params.allowType == 0) {
202 Common::HandleParamErr(env, ERR_RESOURCE_TYPES_INVALID);
203 return nullptr;
204 }
205
206 return Common::NapiGetNull(env);
207 }
208
GetExemptionListApps(napi_env env,napi_callback_info info)209 napi_value GetExemptionListApps(napi_env env, napi_callback_info info)
210 {
211 GetAllowListParamsInfo params;
212 if (ParseGetAllowListParameters(env, info, params) == nullptr) {
213 return nullptr;
214 }
215
216 napi_value promise = nullptr;
217 AsyncCallbackInfoGetAllowList *asyncCallbackInfo =
218 new (std::nothrow) AsyncCallbackInfoGetAllowList(env);
219 if (!asyncCallbackInfo) {
220 return nullptr;
221 }
222 std::unique_ptr<AsyncCallbackInfoGetAllowList> callbackPtr {asyncCallbackInfo};
223 asyncCallbackInfo->allowType = params.allowType;
224 Common::PaddingAsyncWorkData(env, params.callback, *asyncCallbackInfo, promise);
225
226 napi_value resourceName = nullptr;
227 NAPI_CALL(env, napi_create_string_latin1(env, "GetAllowList", NAPI_AUTO_LENGTH, &resourceName));
228
229 NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, AddGetAllowListExecuteCB,
230 AddGetAllowListCallbackCompleteCB, static_cast<void *>(asyncCallbackInfo),
231 &asyncCallbackInfo->asyncWork));
232
233 NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
234 callbackPtr.release();
235 if (asyncCallbackInfo->isCallback) {
236 return Common::NapiGetNull(env);
237 }
238 return promise;
239 }
240
ParseAllowResParameters(const napi_env & env,const napi_callback_info & info,sptr<ResourceRequest> & resourceRequest)241 napi_value ParseAllowResParameters(const napi_env &env, const napi_callback_info &info,
242 sptr<ResourceRequest> &resourceRequest)
243 {
244 size_t argc = APPLY_ALLOW_RESOURCE_PARAMS;
245 napi_value argv[APPLY_ALLOW_RESOURCE_PARAMS] = {nullptr};
246 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
247 if (argc != APPLY_ALLOW_RESOURCE_PARAMS) {
248 Common::HandleParamErr(env, ERR_PARAM_NUMBER_ERR);
249 return nullptr;
250 }
251 int32_t allowType {0};
252 int32_t uid {0};
253 std::string name {};
254 int32_t duration {0};
255 std::string reason {};
256
257 if (!Common::GetNamedInt32Value(env, argv[0], "resourceTypes", allowType) || allowType <= 0
258 || static_cast<uint32_t>(allowType) > MAX_ALLOW_TYPE_NUMBER) {
259 Common::HandleParamErr(env, ERR_RESOURCE_TYPES_INVALID);
260 return nullptr;
261 }
262 if (!Common::GetNamedInt32Value(env, argv[0], "uid", uid) || uid < 0) {
263 Common::HandleParamErr(env, ERR_UID_INVALID);
264 return nullptr;
265 }
266 if (!Common::GetNamedStringValue(env, argv[0], "name", name) || name.empty()) {
267 Common::HandleParamErr(env, ERR_NAME_INVALID_OR_EMPTY);
268 return nullptr;
269 }
270 if (!Common::GetNamedInt32Value(env, argv[0], "duration", duration)) {
271 Common::HandleParamErr(env, ERR_DURATION_INVALID);
272 return nullptr;
273 }
274 if (!Common::GetNamedStringValue(env, argv[0], "reason", reason)) {
275 Common::HandleParamErr(env, ERR_REASON_INVALID_TYPE_ERR);
276 return nullptr;
277 }
278 resourceRequest = new (std::nothrow) ResourceRequest(allowType, uid,
279 name, duration, reason, ReasonCodeEnum::REASON_APP_API);
280 return Common::NapiGetNull(env);
281 }
282
ApplyAllowResource(napi_env env,napi_callback_info info)283 napi_value ApplyAllowResource(napi_env env, napi_callback_info info)
284 {
285 sptr<ResourceRequest> resourceRequest {};
286 if (ParseAllowResParameters(env, info, resourceRequest) == nullptr) {
287 return Common::NapiGetNull(env);
288 }
289 ErrCode errCode = StandbyServiceClient::GetInstance().ApplyAllowResource(resourceRequest);
290 Common::HandleErrCode(env, errCode);
291 return Common::NapiGetNull(env);
292 }
293
UnapplyAllowResource(napi_env env,napi_callback_info info)294 napi_value UnapplyAllowResource(napi_env env, napi_callback_info info)
295 {
296 sptr<ResourceRequest> resourceRequest {};
297 if (ParseAllowResParameters(env, info, resourceRequest) == nullptr) {
298 return Common::NapiGetNull(env);
299 }
300 ErrCode errCode = StandbyServiceClient::GetInstance().UnapplyAllowResource(resourceRequest);
301 Common::HandleErrCode(env, errCode);
302 return Common::NapiGetNull(env);
303 }
304 } // namespace DevStandbyMgr
305 } // namespace OHOS