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