1 /*
2 * Copyright (c) 2021-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 "brightness.h"
17 #include "napi/native_common.h"
18 #include "display_common.h"
19 #include "display_log.h"
20 #include "display_power_mgr_client.h"
21
22 using namespace OHOS::PowerMgr;
23
24 namespace OHOS {
25 namespace DisplayPowerMgr {
26 namespace {
27 const uint32_t MAX_ARGC = 2;
28 const uint32_t CALLBACK_ARGC = 1;
29 const uint32_t ARGV_BRIGHTNESS_INDEX = 0;
30 const uint32_t ARGV_CONTINUOUS_INDEX = 1;
31 const uint32_t ERR_DATA_INDEX = 0;
32 const uint32_t ERR_CODE_INDEX = 1;
33 const uint32_t MAX_FAIL_ARGC = 2;
34 const uint32_t MAX_BRIGHTNESS = DisplayPowerMgrClient::GetInstance().GetMaxBrightness();
35 const uint32_t MIN_BRIGHTNESS = DisplayPowerMgrClient::GetInstance().GetMinBrightness();
36 const uint32_t DEFAULT_BRIGHTNESS = DisplayPowerMgrClient::GetInstance().GetDefaultBrightness();
37 const uint32_t MAIN_DISPLAY_ID = DisplayPowerMgrClient::GetInstance().GetMainDisplayId();
38
39 const std::string FUNC_SUCEESS_NAME = "success";
40 const std::string FUNC_FAIL_NAME = "fail";
41 const std::string FUNC_COMPLETE_NAME = "complete";
42
43 const int32_t COMMON_ERROR_COED = 200;
44 const int32_t INPUT_ERROR_CODE = 202;
45
46 const std::string SET_VALUE_ERROR_MGR = "value is not an available number";
47 const std::string GET_VALUE_ERROR_MGR = "get system screen brightness fail";
48 const std::string SET_MODE_ERROR_MGR = "value is not an available number";
49 const std::string SET_MODE_NOT_SUPPORTED_ERROR_MGR = "Auto adjusting brightness is not supported";
50 const std::string SET_KEEP_SCREENON_ERROR_MGR = "value is not an available boolean";
51 } // namespace
52
53 std::map<DisplayErrors, std::string> Brightness::Result::errorTable_ = {
54 {DisplayErrors::ERR_CONNECTION_FAIL, "Failed to connect to the service."},
55 {DisplayErrors::ERR_PERMISSION_DENIED, "Permission is denied" },
56 {DisplayErrors::ERR_SYSTEM_API_DENIED, "System permission is denied" },
57 {DisplayErrors::ERR_PARAM_INVALID, "Invalid input parameter." }
58 };
59
Brightness(napi_env env,std::shared_ptr<RunningLock> runningLock)60 Brightness::Brightness(napi_env env, std::shared_ptr<RunningLock> runningLock) : env_(env), runningLock_(runningLock) {}
61
~Brightness()62 Brightness::~Brightness()
63 {
64 ReleaseReference(successRef_);
65 ReleaseReference(failRef_);
66 ReleaseReference(completeRef_);
67 ReleaseReference(napiValRef_);
68 }
69
GetValue()70 void Brightness::GetValue()
71 {
72 uint32_t brightness = brightnessInfo_.GetBrightness();
73 if (brightness < MIN_BRIGHTNESS || brightness > MAX_BRIGHTNESS) {
74 result_.Error(COMMON_ERROR_COED, GET_VALUE_ERROR_MGR);
75 } else {
76 result_.SetResult(BRIGHTNESS_VALUE, brightness);
77 }
78 ExecuteCallback();
79 }
80
SetValue(napi_callback_info & info)81 void Brightness::SetValue(napi_callback_info& info)
82 {
83 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness interface");
84 napi_value napiBrightness = GetCallbackInfo(info, ARGV_BRIGHTNESS_INDEX, napi_number);
85 napi_value napiUndefined = GetCallbackInfo(info, ARGV_BRIGHTNESS_INDEX, napi_undefined);
86 if (napiBrightness == nullptr && napiUndefined == nullptr) {
87 result_.ThrowError(env_, DisplayErrors::ERR_PARAM_INVALID);
88 return;
89 }
90
91 int32_t value = MIN_BRIGHTNESS;
92 bool continuous = false;
93 if (napi_get_value_int32(env_, napiBrightness, &value) != napi_ok) {
94 if (napiUndefined != nullptr) {
95 return;
96 } else {
97 DISPLAY_HILOGW(COMP_FWK, "Failed to get the input number");
98 result_.ThrowError(env_, DisplayErrors::ERR_PARAM_INVALID);
99 return;
100 }
101 }
102 napi_value napiContinuous = GetCallbackInfoWithThrow(info, ARGV_CONTINUOUS_INDEX, napi_boolean);
103 if (napiContinuous != nullptr) {
104 napi_get_value_bool(env_, napiContinuous, &continuous);
105 }
106
107 if (!brightnessInfo_.SetBrightness(value, continuous)) {
108 DisplayErrors error = brightnessInfo_.GetServiceError();
109 if (error != DisplayErrors::ERR_OK) {
110 result_.ThrowError(env_, error);
111 }
112 }
113 }
114
GetCallbackInfoWithThrow(napi_callback_info & info,uint32_t index,napi_valuetype checkType)115 napi_value Brightness::GetCallbackInfoWithThrow(napi_callback_info& info, uint32_t index, napi_valuetype checkType)
116 {
117 size_t argc = MAX_ARGC;
118 napi_value argv[argc];
119 napi_value thisVar = nullptr;
120 void* data = nullptr;
121 if (napi_ok != napi_get_cb_info(env_, info, &argc, argv, &thisVar, &data)) {
122 DISPLAY_HILOGW(COMP_FWK, "Failed to get the input parameter");
123 return nullptr;
124 }
125
126 if (argc > MAX_ARGC || index >= argc) {
127 DISPLAY_HILOGW(COMP_FWK, "parameter %{public}u is invalid", index);
128 return nullptr;
129 }
130
131 napi_value options = argv[index];
132 if (!CheckValueType(options, checkType)) {
133 return result_.ThrowError(env_, DisplayErrors::ERR_PARAM_INVALID);
134 }
135 return options;
136 }
137
SystemSetValue()138 void Brightness::SystemSetValue()
139 {
140 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "System brightness interface");
141 if (napiValRef_ == nullptr) {
142 result_.Error(INPUT_ERROR_CODE, SET_VALUE_ERROR_MGR);
143 } else {
144 int32_t brightness = MIN_BRIGHTNESS;
145 napi_value napiVal = nullptr;
146 napi_get_reference_value(env_, napiValRef_, &napiVal);
147 napi_get_value_int32(env_, napiVal, &brightness);
148 brightnessInfo_.SetBrightness(brightness, false);
149 ReleaseReference(napiValRef_);
150 }
151 ExecuteCallback();
152 }
153
GetMode()154 void Brightness::GetMode()
155 {
156 int32_t isAuto = brightnessInfo_.GetAutoMode();
157 result_.SetResult(BRIGHTNESS_MODE, isAuto);
158 ExecuteCallback();
159 }
160
SetMode()161 void Brightness::SetMode()
162 {
163 DISPLAY_HILOGD(COMP_FWK, "Set auto brightness");
164 if (napiValRef_ == nullptr) {
165 result_.Error(INPUT_ERROR_CODE, SET_MODE_ERROR_MGR);
166 } else {
167 int32_t mode = 0;
168 napi_value napiMode = nullptr;
169 napi_get_reference_value(env_, napiValRef_, &napiMode);
170 napi_get_value_int32(env_, napiMode, &mode);
171 if (!brightnessInfo_.SetAutoMode(static_cast<bool>(mode))) {
172 result_.Error(COMMON_ERROR_COED, SET_MODE_NOT_SUPPORTED_ERROR_MGR);
173 }
174 ReleaseReference(napiValRef_);
175 }
176 ExecuteCallback();
177 }
178
SetKeepScreenOn()179 void Brightness::SetKeepScreenOn()
180 {
181 DISPLAY_HILOGD(COMP_FWK, "Set keep screen on");
182 if (napiValRef_ == nullptr) {
183 result_.Error(INPUT_ERROR_CODE, SET_KEEP_SCREENON_ERROR_MGR);
184 } else {
185 napi_value napiKeep = nullptr;
186 napi_get_reference_value(env_, napiValRef_, &napiKeep);
187 bool screenOn = false;
188 napi_get_value_bool(env_, napiKeep, &screenOn);
189 brightnessInfo_.ScreenOn(screenOn, runningLock_);
190 ReleaseReference(napiValRef_);
191 }
192 ExecuteCallback();
193 }
194
GetCallbackInfo(napi_callback_info & info,uint32_t index,napi_valuetype checkType)195 napi_value Brightness::GetCallbackInfo(napi_callback_info& info, uint32_t index, napi_valuetype checkType)
196 {
197 size_t argc = MAX_ARGC;
198 napi_value argv[argc];
199 napi_value thisVar = nullptr;
200 void* data = nullptr;
201 if (napi_ok != napi_get_cb_info(env_, info, &argc, argv, &thisVar, &data)) {
202 DISPLAY_HILOGW(COMP_FWK, "Failed to get the input parameter");
203 return nullptr;
204 }
205
206 if (argc > MAX_ARGC || index >= argc) {
207 DISPLAY_HILOGW(COMP_FWK, "parameter %{public}u is invalid", index);
208 return nullptr;
209 }
210
211 napi_value options = argv[index];
212 RETURN_IF_WITH_RET(!CheckValueType(options, checkType), nullptr);
213 return options;
214 }
215
CreateCallbackRef(napi_value & options)216 bool Brightness::CreateCallbackRef(napi_value& options)
217 {
218 RETURN_IF_WITH_RET(!CheckValueType(options, napi_object), false);
219
220 napi_value succCallBack = GetOptions(options, FUNC_SUCEESS_NAME, napi_function);
221 if (succCallBack != nullptr) {
222 napi_create_reference(env_, succCallBack, 1, &successRef_);
223 }
224
225 napi_value failCallBack = GetOptions(options, FUNC_FAIL_NAME, napi_function);
226 if (failCallBack != nullptr) {
227 napi_create_reference(env_, failCallBack, 1, &failRef_);
228 }
229
230 napi_value completeCallBack = GetOptions(options, FUNC_COMPLETE_NAME, napi_function);
231 if (completeCallBack != nullptr) {
232 napi_create_reference(env_, completeCallBack, 1, &completeRef_);
233 }
234 return true;
235 }
236
CreateValueRef(napi_value & options,const std::string & valName,napi_valuetype checkType)237 void Brightness::CreateValueRef(napi_value& options, const std::string& valName, napi_valuetype checkType)
238 {
239 napi_value value = GetOptions(options, valName, checkType);
240 if (value != nullptr) {
241 napi_create_reference(env_, value, 1, &napiValRef_);
242 }
243 }
244
Error(int32_t code,const std::string & msg)245 void Brightness::Result::Error(int32_t code, const std::string& msg)
246 {
247 code_ = code;
248 msg_ = msg;
249 DISPLAY_HILOGW(COMP_FWK, "Error message, code: %{public}d, msg: %{public}s", code_, msg_.c_str());
250 }
251
GetError(napi_env env,napi_value * error,size_t & size) const252 void Brightness::Result::GetError(napi_env env, napi_value* error, size_t& size) const
253 {
254 if (!error) {
255 DISPLAY_HILOGW(COMP_FWK, "error is null");
256 return;
257 }
258 napi_value data = nullptr;
259 napi_value code = nullptr;
260 napi_create_string_utf8(env, msg_.c_str(), msg_.size(), &data);
261 napi_create_int32(env, code_, &code);
262 size = MAX_FAIL_ARGC;
263 error[ERR_DATA_INDEX] = data;
264 error[ERR_CODE_INDEX] = code;
265 }
266
GetError(napi_env & env)267 napi_value Brightness::Result::GetError(napi_env& env)
268 {
269 napi_value napiError = nullptr;
270 if (!IsError()) {
271 napi_get_undefined(env, &napiError);
272 return napiError;
273 }
274
275 std::string msg;
276 auto item = errorTable_.find(static_cast<DisplayErrors>(code_));
277 if (item != errorTable_.end()) {
278 msg = item->second;
279 }
280 napi_value napiMsg;
281 NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), msg.size(), &napiMsg));
282 NAPI_CALL(env, napi_create_error(env, nullptr, napiMsg, &napiError));
283
284 napi_value napiCode;
285 NAPI_CALL(env, napi_create_int32(env, code_, &napiCode));
286
287 napi_set_named_property(env, napiError, "code", napiCode);
288 napi_set_named_property(env, napiError, "message", napiMsg);
289
290 DISPLAY_HILOGW(COMP_FWK, "throw error code: %{public}d, msg: %{public}s,", code_, msg.c_str());
291 return napiError;
292 }
293
ThrowError(napi_env & env,DisplayErrors code)294 napi_value Brightness::Result::ThrowError(napi_env& env, DisplayErrors code)
295 {
296 Error(static_cast<int32_t>(code));
297 napi_value error = GetError(env);
298 RETURN_IF_WITH_RET(error == nullptr, nullptr);
299 napi_throw(env, error);
300 return nullptr;
301 }
302
GetResult(napi_env env)303 napi_value Brightness::Result::GetResult(napi_env env)
304 {
305 napi_value result = nullptr;
306 NAPI_CALL(env, napi_create_object(env, &result));
307 for (const auto& it : mapResult_) {
308 napi_value napiValue = 0;
309 NAPI_CALL(env, napi_create_int32(env, it.second, &napiValue));
310 NAPI_CALL(env, napi_set_named_property(env, result, it.first.c_str(), napiValue));
311 }
312 return result;
313 }
314
GetBrightness() const315 uint32_t Brightness::BrightnessInfo::GetBrightness() const
316 {
317 uint32_t brightness = DisplayPowerMgrClient::GetInstance().GetBrightness(MAIN_DISPLAY_ID);
318 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Get brightness: %{public}d", brightness);
319 return brightness;
320 }
321
SetBrightness(int32_t value,bool continuous)322 bool Brightness::BrightnessInfo::SetBrightness(int32_t value, bool continuous)
323 {
324 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Set brightness: %{public}d, %{public}d", value, continuous);
325 value = value > static_cast<int32_t>(MAX_BRIGHTNESS) ? static_cast<int32_t>(MAX_BRIGHTNESS) : value;
326 value = value < static_cast<int32_t>(MIN_BRIGHTNESS) ? static_cast<int32_t>(MIN_BRIGHTNESS) : value;
327 bool isSucc = DisplayPowerMgrClient::GetInstance().SetBrightness(value, 0, continuous);
328 if (!isSucc) {
329 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Failed to set brightness: %{public}d", value);
330 }
331 return isSucc;
332 }
333
GetAutoMode() const334 int32_t Brightness::BrightnessInfo::GetAutoMode() const
335 {
336 bool isAuto = DisplayPowerMgrClient::GetInstance().IsAutoAdjustBrightness();
337 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Automatic brightness adjustment: %{public}d", isAuto);
338 return static_cast<int32_t>(isAuto);
339 }
340
SetAutoMode(bool mode)341 bool Brightness::BrightnessInfo::SetAutoMode(bool mode)
342 {
343 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "AutoAdjustBrightness begin");
344 bool isSucc = DisplayPowerMgrClient::GetInstance().AutoAdjustBrightness(mode);
345 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "set auto brightness mode: %{public}d, succ: %{public}d", mode, isSucc);
346 return isSucc;
347 }
348
ScreenOn(bool keep,std::shared_ptr<RunningLock> & runningLock)349 void Brightness::BrightnessInfo::ScreenOn(bool keep, std::shared_ptr<RunningLock>& runningLock)
350 {
351 if (runningLock != nullptr) {
352 DISPLAY_HILOGD(COMP_FWK, "Keep screen on, keep: %{public}d, isUsed: %{public}d", keep, runningLock->IsUsed());
353 keep ? runningLock->Lock() : runningLock->UnLock();
354 }
355 }
356
GetServiceError() const357 DisplayErrors Brightness::BrightnessInfo::GetServiceError() const
358 {
359 return DisplayPowerMgrClient::GetInstance().GetError();
360 }
361
ExecuteCallback()362 void Brightness::ExecuteCallback()
363 {
364 bool error = result_.IsError();
365 if (!error) {
366 DISPLAY_HILOGD(COMP_FWK, "Call the js success method");
367 napi_value result = result_.GetResult(env_);
368 size_t argc = result ? CALLBACK_ARGC : 0;
369 CallFunction(successRef_, argc, result ? &result : nullptr);
370 }
371
372 if (error) {
373 DISPLAY_HILOGD(COMP_FWK, "Call the js fail method");
374 size_t argc = MAX_FAIL_ARGC;
375 napi_value argv[argc];
376 result_.GetError(env_, argv, argc);
377 CallFunction(failRef_, argc, argv);
378 }
379 DISPLAY_HILOGD(COMP_FWK, "Call the js complete method");
380 CallFunction(completeRef_, 0, nullptr);
381 }
382
CheckValueType(napi_value & value,napi_valuetype checkType)383 bool Brightness::CheckValueType(napi_value& value, napi_valuetype checkType)
384 {
385 napi_valuetype valueType = napi_undefined;
386 napi_typeof(env_, value, &valueType);
387 if (valueType != checkType) {
388 DISPLAY_HILOGD(COMP_FWK, "Check input parameter error");
389 return false;
390 }
391 return true;
392 }
393
GetOptions(napi_value & options,const std::string & name,napi_valuetype checkType)394 napi_value Brightness::GetOptions(napi_value& options, const std::string& name, napi_valuetype checkType)
395 {
396 napi_value property = nullptr;
397 napi_status status = napi_get_named_property(env_, options, name.c_str(), &property);
398 if (status != napi_ok) {
399 DISPLAY_HILOGW(COMP_FWK, "Failed to get the %{public}s Options property", name.c_str());
400 return nullptr;
401 }
402 if (!CheckValueType(property, checkType)) {
403 DISPLAY_HILOGW(COMP_FWK, "Get %{public}s Options property type mismatch", name.c_str());
404 return nullptr;
405 }
406 return property;
407 }
408
CallFunction(napi_ref & callbackRef,size_t argc,napi_value * response)409 void Brightness::CallFunction(napi_ref& callbackRef, size_t argc, napi_value* response)
410 {
411 RETURN_IF(callbackRef == nullptr);
412
413 napi_value callResult = 0;
414 napi_value callback = nullptr;
415 napi_get_reference_value(env_, callbackRef, &callback);
416 napi_status status = napi_call_function(env_, nullptr, callback, argc, response, &callResult);
417 if (status != napi_ok) {
418 DISPLAY_HILOGW(COMP_FWK, "Failed to call the callback function");
419 }
420 ReleaseReference(callbackRef);
421 }
422
ReleaseReference(napi_ref & ref)423 void Brightness::ReleaseReference(napi_ref& ref)
424 {
425 if (ref != nullptr) {
426 napi_delete_reference(env_, ref);
427 ref = nullptr;
428 }
429 }
430 } // namespace DisplayPowerMgr
431 } // namespace OHOS
432