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 = GetCallbackInfo(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
SystemSetValue()115 void Brightness::SystemSetValue()
116 {
117 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "System brightness interface");
118 if (napiValRef_ == nullptr) {
119 result_.Error(INPUT_ERROR_CODE, SET_VALUE_ERROR_MGR);
120 } else {
121 int32_t brightness = MIN_BRIGHTNESS;
122 napi_value napiVal = nullptr;
123 napi_get_reference_value(env_, napiValRef_, &napiVal);
124 napi_get_value_int32(env_, napiVal, &brightness);
125 brightnessInfo_.SetBrightness(brightness, false);
126 ReleaseReference(napiValRef_);
127 }
128 ExecuteCallback();
129 }
130
GetMode()131 void Brightness::GetMode()
132 {
133 int32_t isAuto = brightnessInfo_.GetAutoMode();
134 result_.SetResult(BRIGHTNESS_MODE, isAuto);
135 ExecuteCallback();
136 }
137
SetMode()138 void Brightness::SetMode()
139 {
140 DISPLAY_HILOGD(COMP_FWK, "Set auto brightness");
141 if (napiValRef_ == nullptr) {
142 result_.Error(INPUT_ERROR_CODE, SET_MODE_ERROR_MGR);
143 } else {
144 int32_t mode = 0;
145 napi_value napiMode = nullptr;
146 napi_get_reference_value(env_, napiValRef_, &napiMode);
147 napi_get_value_int32(env_, napiMode, &mode);
148 if (!brightnessInfo_.SetAutoMode(static_cast<bool>(mode))) {
149 result_.Error(COMMON_ERROR_COED, SET_MODE_NOT_SUPPORTED_ERROR_MGR);
150 }
151 ReleaseReference(napiValRef_);
152 }
153 ExecuteCallback();
154 }
155
SetKeepScreenOn()156 void Brightness::SetKeepScreenOn()
157 {
158 DISPLAY_HILOGD(COMP_FWK, "Set keep screen on");
159 if (napiValRef_ == nullptr) {
160 result_.Error(INPUT_ERROR_CODE, SET_KEEP_SCREENON_ERROR_MGR);
161 } else {
162 napi_value napiKeep = nullptr;
163 napi_get_reference_value(env_, napiValRef_, &napiKeep);
164 bool screenOn = false;
165 napi_get_value_bool(env_, napiKeep, &screenOn);
166 brightnessInfo_.ScreenOn(screenOn, runningLock_);
167 ReleaseReference(napiValRef_);
168 }
169 ExecuteCallback();
170 }
171
GetCallbackInfo(napi_callback_info & info,uint32_t index,napi_valuetype checkType)172 napi_value Brightness::GetCallbackInfo(napi_callback_info& info, uint32_t index, napi_valuetype checkType)
173 {
174 size_t argc = MAX_ARGC;
175 napi_value argv[argc];
176 napi_value thisVar = nullptr;
177 void* data = nullptr;
178 if (napi_ok != napi_get_cb_info(env_, info, &argc, argv, &thisVar, &data)) {
179 DISPLAY_HILOGW(COMP_FWK, "Failed to get the input parameter");
180 return nullptr;
181 }
182
183 if (argc > MAX_ARGC || index >= argc) {
184 DISPLAY_HILOGW(COMP_FWK, "parameter %{public}u is invalid", index);
185 return nullptr;
186 }
187
188 napi_value options = argv[index];
189 RETURN_IF_WITH_RET(!CheckValueType(options, checkType), nullptr);
190 return options;
191 }
192
CreateCallbackRef(napi_value & options)193 bool Brightness::CreateCallbackRef(napi_value& options)
194 {
195 RETURN_IF_WITH_RET(!CheckValueType(options, napi_object), false);
196
197 napi_value succCallBack = GetOptions(options, FUNC_SUCEESS_NAME, napi_function);
198 if (succCallBack != nullptr) {
199 napi_create_reference(env_, succCallBack, 1, &successRef_);
200 }
201
202 napi_value failCallBack = GetOptions(options, FUNC_FAIL_NAME, napi_function);
203 if (failCallBack != nullptr) {
204 napi_create_reference(env_, failCallBack, 1, &failRef_);
205 }
206
207 napi_value completeCallBack = GetOptions(options, FUNC_COMPLETE_NAME, napi_function);
208 if (completeCallBack != nullptr) {
209 napi_create_reference(env_, completeCallBack, 1, &completeRef_);
210 }
211 return true;
212 }
213
CreateValueRef(napi_value & options,const std::string & valName,napi_valuetype checkType)214 void Brightness::CreateValueRef(napi_value& options, const std::string& valName, napi_valuetype checkType)
215 {
216 napi_value value = GetOptions(options, valName, checkType);
217 if (value != nullptr) {
218 napi_create_reference(env_, value, 1, &napiValRef_);
219 }
220 }
221
Error(int32_t code,const std::string & msg)222 void Brightness::Result::Error(int32_t code, const std::string& msg)
223 {
224 code_ = code;
225 msg_ = msg;
226 DISPLAY_HILOGW(COMP_FWK, "Error message, code: %{public}d, msg: %{public}s", code_, msg_.c_str());
227 }
228
GetError(napi_env env,napi_value * error,size_t & size) const229 void Brightness::Result::GetError(napi_env env, napi_value* error, size_t& size) const
230 {
231 if (!error) {
232 DISPLAY_HILOGW(COMP_FWK, "error is null");
233 return;
234 }
235 napi_value data = nullptr;
236 napi_value code = nullptr;
237 napi_create_string_utf8(env, msg_.c_str(), msg_.size(), &data);
238 napi_create_int32(env, code_, &code);
239 size = MAX_FAIL_ARGC;
240 error[ERR_DATA_INDEX] = data;
241 error[ERR_CODE_INDEX] = code;
242 }
243
GetError(napi_env & env)244 napi_value Brightness::Result::GetError(napi_env& env)
245 {
246 napi_value napiError = nullptr;
247 if (!IsError()) {
248 napi_get_undefined(env, &napiError);
249 return napiError;
250 }
251
252 std::string msg;
253 auto item = errorTable_.find(static_cast<DisplayErrors>(code_));
254 if (item != errorTable_.end()) {
255 msg = item->second;
256 }
257 napi_value napiMsg;
258 NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), msg.size(), &napiMsg));
259 NAPI_CALL(env, napi_create_error(env, nullptr, napiMsg, &napiError));
260
261 napi_value napiCode;
262 NAPI_CALL(env, napi_create_int32(env, code_, &napiCode));
263
264 napi_set_named_property(env, napiError, "code", napiCode);
265 napi_set_named_property(env, napiError, "message", napiMsg);
266
267 DISPLAY_HILOGW(COMP_FWK, "throw error code: %{public}d, msg: %{public}s,", code_, msg.c_str());
268 return napiError;
269 }
270
ThrowError(napi_env & env,DisplayErrors code)271 napi_value Brightness::Result::ThrowError(napi_env& env, DisplayErrors code)
272 {
273 Error(static_cast<int32_t>(code));
274 napi_value error = GetError(env);
275 RETURN_IF_WITH_RET(error == nullptr, nullptr);
276 napi_throw(env, error);
277 return nullptr;
278 }
279
GetResult(napi_env env)280 napi_value Brightness::Result::GetResult(napi_env env)
281 {
282 napi_value result = nullptr;
283 NAPI_CALL(env, napi_create_object(env, &result));
284 for (const auto& it : mapResult_) {
285 napi_value napiValue = 0;
286 NAPI_CALL(env, napi_create_int32(env, it.second, &napiValue));
287 NAPI_CALL(env, napi_set_named_property(env, result, it.first.c_str(), napiValue));
288 }
289 return result;
290 }
291
GetBrightness() const292 uint32_t Brightness::BrightnessInfo::GetBrightness() const
293 {
294 uint32_t brightness = DisplayPowerMgrClient::GetInstance().GetBrightness(MAIN_DISPLAY_ID);
295 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Get brightness: %{public}d", brightness);
296 return brightness;
297 }
298
SetBrightness(int32_t value,bool continuous)299 bool Brightness::BrightnessInfo::SetBrightness(int32_t value, bool continuous)
300 {
301 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Set brightness: %{public}d, %{public}d", value, continuous);
302 value = value > static_cast<int32_t>(MAX_BRIGHTNESS) ? static_cast<int32_t>(MAX_BRIGHTNESS) : value;
303 value = value < static_cast<int32_t>(MIN_BRIGHTNESS) ? static_cast<int32_t>(MIN_BRIGHTNESS) : value;
304 bool isSucc = DisplayPowerMgrClient::GetInstance().SetBrightness(value, 0, continuous);
305 if (!isSucc) {
306 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Failed to set brightness: %{public}d", value);
307 }
308 return isSucc;
309 }
310
GetAutoMode() const311 int32_t Brightness::BrightnessInfo::GetAutoMode() const
312 {
313 bool isAuto = DisplayPowerMgrClient::GetInstance().IsAutoAdjustBrightness();
314 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Automatic brightness adjustment: %{public}d", isAuto);
315 return static_cast<int32_t>(isAuto);
316 }
317
SetAutoMode(bool mode)318 bool Brightness::BrightnessInfo::SetAutoMode(bool mode)
319 {
320 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "AutoAdjustBrightness begin");
321 bool isSucc = DisplayPowerMgrClient::GetInstance().AutoAdjustBrightness(mode);
322 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "set auto brightness mode: %{public}d, succ: %{public}d", mode, isSucc);
323 return isSucc;
324 }
325
ScreenOn(bool keep,std::shared_ptr<RunningLock> & runningLock)326 void Brightness::BrightnessInfo::ScreenOn(bool keep, std::shared_ptr<RunningLock>& runningLock)
327 {
328 if (runningLock != nullptr) {
329 DISPLAY_HILOGD(COMP_FWK, "Keep screen on, keep: %{public}d, isUsed: %{public}d", keep, runningLock->IsUsed());
330 keep ? runningLock->Lock() : runningLock->UnLock();
331 }
332 }
333
GetServiceError() const334 DisplayErrors Brightness::BrightnessInfo::GetServiceError() const
335 {
336 return DisplayPowerMgrClient::GetInstance().GetError();
337 }
338
ExecuteCallback()339 void Brightness::ExecuteCallback()
340 {
341 bool error = result_.IsError();
342 if (!error) {
343 DISPLAY_HILOGD(COMP_FWK, "Call the js success method");
344 napi_value result = result_.GetResult(env_);
345 size_t argc = result ? CALLBACK_ARGC : 0;
346 CallFunction(successRef_, argc, result ? &result : nullptr);
347 }
348
349 if (error) {
350 DISPLAY_HILOGD(COMP_FWK, "Call the js fail method");
351 size_t argc = MAX_FAIL_ARGC;
352 napi_value argv[argc];
353 result_.GetError(env_, argv, argc);
354 CallFunction(failRef_, argc, argv);
355 }
356 DISPLAY_HILOGD(COMP_FWK, "Call the js complete method");
357 CallFunction(completeRef_, 0, nullptr);
358 }
359
CheckValueType(napi_value & value,napi_valuetype checkType)360 bool Brightness::CheckValueType(napi_value& value, napi_valuetype checkType)
361 {
362 napi_valuetype valueType = napi_undefined;
363 napi_typeof(env_, value, &valueType);
364 if (valueType != checkType) {
365 DISPLAY_HILOGD(COMP_FWK, "Check input parameter error");
366 return false;
367 }
368 return true;
369 }
370
GetOptions(napi_value & options,const std::string & name,napi_valuetype checkType)371 napi_value Brightness::GetOptions(napi_value& options, const std::string& name, napi_valuetype checkType)
372 {
373 napi_value property = nullptr;
374 napi_status status = napi_get_named_property(env_, options, name.c_str(), &property);
375 if (status != napi_ok) {
376 DISPLAY_HILOGW(COMP_FWK, "Failed to get the %{public}s Options property", name.c_str());
377 return nullptr;
378 }
379 if (!CheckValueType(property, checkType)) {
380 DISPLAY_HILOGW(COMP_FWK, "Get %{public}s Options property type mismatch", name.c_str());
381 return nullptr;
382 }
383 return property;
384 }
385
CallFunction(napi_ref & callbackRef,size_t argc,napi_value * response)386 void Brightness::CallFunction(napi_ref& callbackRef, size_t argc, napi_value* response)
387 {
388 RETURN_IF(callbackRef == nullptr);
389
390 napi_value callResult = 0;
391 napi_value callback = nullptr;
392 napi_get_reference_value(env_, callbackRef, &callback);
393 napi_status status = napi_call_function(env_, nullptr, callback, argc, response, &callResult);
394 if (status != napi_ok) {
395 DISPLAY_HILOGW(COMP_FWK, "Failed to call the callback function");
396 }
397 ReleaseReference(callbackRef);
398 }
399
ReleaseReference(napi_ref & ref)400 void Brightness::ReleaseReference(napi_ref& ref)
401 {
402 if (ref != nullptr) {
403 napi_delete_reference(env_, ref);
404 ref = nullptr;
405 }
406 }
407 } // namespace DisplayPowerMgr
408 } // namespace OHOS
409