1595d5899Sopenharmony_ci/* 2595d5899Sopenharmony_ci * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 3595d5899Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4595d5899Sopenharmony_ci * you may not use this file except in compliance with the License. 5595d5899Sopenharmony_ci * You may obtain a copy of the License at 6595d5899Sopenharmony_ci * 7595d5899Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8595d5899Sopenharmony_ci * 9595d5899Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10595d5899Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11595d5899Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12595d5899Sopenharmony_ci * See the License for the specific language governing permissions and 13595d5899Sopenharmony_ci * limitations under the License. 14595d5899Sopenharmony_ci */ 15595d5899Sopenharmony_ci 16595d5899Sopenharmony_ci#include "light_lux_buffer.h" 17595d5899Sopenharmony_ci 18595d5899Sopenharmony_ci#include <cerrno> 19595d5899Sopenharmony_ci#include <cstdlib> 20595d5899Sopenharmony_ci#include <new> 21595d5899Sopenharmony_ci#include <string> 22595d5899Sopenharmony_ci#include <securec.h> 23595d5899Sopenharmony_ci#include <securectype.h> 24595d5899Sopenharmony_ci 25595d5899Sopenharmony_ci#include "display_log.h" 26595d5899Sopenharmony_ci 27595d5899Sopenharmony_cinamespace OHOS { 28595d5899Sopenharmony_cinamespace DisplayPowerMgr { 29595d5899Sopenharmony_ci 30595d5899Sopenharmony_cinamespace { 31595d5899Sopenharmony_ciconst unsigned int BUFFER_SIZE_INCREASE = 2; 32595d5899Sopenharmony_ciconst unsigned int LUX_BUFFER_SIZE_MAX = 512; 33595d5899Sopenharmony_ci} 34595d5899Sopenharmony_ci 35595d5899Sopenharmony_ciLightLuxBuffer::LightLuxBuffer(unsigned int initialCapacity) 36595d5899Sopenharmony_ci{ 37595d5899Sopenharmony_ci if (initialCapacity == 0 || initialCapacity >= LUX_BUFFER_SIZE_MAX) { 38595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "initialCapacity=%{public}d out of range, Reset to %{public}d", 39595d5899Sopenharmony_ci initialCapacity, LUX_BUFFER_SIZE_DEFAULT); 40595d5899Sopenharmony_ci mCapacity = LUX_BUFFER_SIZE_DEFAULT; 41595d5899Sopenharmony_ci } else { 42595d5899Sopenharmony_ci mCapacity = initialCapacity; 43595d5899Sopenharmony_ci } 44595d5899Sopenharmony_ci} 45595d5899Sopenharmony_ci 46595d5899Sopenharmony_ciLightLuxBuffer::~LightLuxBuffer() 47595d5899Sopenharmony_ci{ 48595d5899Sopenharmony_ci if (mBufferData != nullptr) { 49595d5899Sopenharmony_ci delete[] mBufferData; 50595d5899Sopenharmony_ci mBufferData = nullptr; 51595d5899Sopenharmony_ci } 52595d5899Sopenharmony_ci 53595d5899Sopenharmony_ci if (mBufferTime != nullptr) { 54595d5899Sopenharmony_ci delete[] mBufferTime; 55595d5899Sopenharmony_ci mBufferTime = nullptr; 56595d5899Sopenharmony_ci } 57595d5899Sopenharmony_ci} 58595d5899Sopenharmony_ci 59595d5899Sopenharmony_ciint LightLuxBuffer::LuxBufferCheck() 60595d5899Sopenharmony_ci{ 61595d5899Sopenharmony_ci if (mBufferData == nullptr) { 62595d5899Sopenharmony_ci mBufferData = new(std::nothrow) float[mCapacity]; 63595d5899Sopenharmony_ci if (mBufferData == nullptr) { 64595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "new mBufferData failed!"); 65595d5899Sopenharmony_ci return -1; 66595d5899Sopenharmony_ci } 67595d5899Sopenharmony_ci } 68595d5899Sopenharmony_ci if (mBufferTime == nullptr) { 69595d5899Sopenharmony_ci mBufferTime = new(std::nothrow) int64_t[mCapacity]; 70595d5899Sopenharmony_ci if (mBufferTime == nullptr) { 71595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "new mBufferTime failed!"); 72595d5899Sopenharmony_ci delete[] mBufferData; 73595d5899Sopenharmony_ci mBufferData = nullptr; 74595d5899Sopenharmony_ci return -1; 75595d5899Sopenharmony_ci } 76595d5899Sopenharmony_ci } 77595d5899Sopenharmony_ci return 0; 78595d5899Sopenharmony_ci} 79595d5899Sopenharmony_ci 80595d5899Sopenharmony_ciint LightLuxBuffer::CopyLuxBuffer(int newSize) 81595d5899Sopenharmony_ci{ 82595d5899Sopenharmony_ci auto newBufferData = new(std::nothrow) float[newSize]; 83595d5899Sopenharmony_ci if (newBufferData == nullptr) { 84595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "newBufferData id null"); 85595d5899Sopenharmony_ci return -1; 86595d5899Sopenharmony_ci } 87595d5899Sopenharmony_ci auto newBufferTime = new(std::nothrow) int64_t[newSize]; 88595d5899Sopenharmony_ci if (newBufferTime == nullptr) { 89595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "newBufferTime id null"); 90595d5899Sopenharmony_ci delete[] newBufferData; 91595d5899Sopenharmony_ci return -1; 92595d5899Sopenharmony_ci } 93595d5899Sopenharmony_ci unsigned int length = mCapacity - mStart; 94595d5899Sopenharmony_ci bool isError = false; 95595d5899Sopenharmony_ci isError = isError || (memcpy_s(newBufferData, newSize * sizeof(newBufferData[0]), 96595d5899Sopenharmony_ci mBufferData + mStart, length * sizeof(mBufferData[0])) != EOK); 97595d5899Sopenharmony_ci isError = isError || (memcpy_s(newBufferTime, newSize * sizeof(newBufferTime[0]), 98595d5899Sopenharmony_ci mBufferTime + mStart, length * sizeof(mBufferTime[0])) != EOK); 99595d5899Sopenharmony_ci if (mStart != 0) { 100595d5899Sopenharmony_ci isError = isError || (memcpy_s(newBufferData + length, (newSize - length) * sizeof(newBufferData[0]), 101595d5899Sopenharmony_ci mBufferData, mStart * sizeof(mBufferData[0])) != EOK); 102595d5899Sopenharmony_ci isError = isError || (memcpy_s(newBufferTime + length, (newSize - length) * sizeof(newBufferTime[0]), 103595d5899Sopenharmony_ci mBufferTime, mStart * sizeof(mBufferTime[0])) != EOK); 104595d5899Sopenharmony_ci } 105595d5899Sopenharmony_ci if (isError) { 106595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "memcpy_s error, mCapacity=%{public}d, mStart=%{public}d", mCapacity, mStart); 107595d5899Sopenharmony_ci delete[] newBufferData; 108595d5899Sopenharmony_ci delete[] newBufferTime; 109595d5899Sopenharmony_ci return -1; 110595d5899Sopenharmony_ci } 111595d5899Sopenharmony_ci delete[] mBufferData; 112595d5899Sopenharmony_ci mBufferData = newBufferData; 113595d5899Sopenharmony_ci delete[] mBufferTime; 114595d5899Sopenharmony_ci mBufferTime = newBufferTime; 115595d5899Sopenharmony_ci 116595d5899Sopenharmony_ci return 0; 117595d5899Sopenharmony_ci} 118595d5899Sopenharmony_ci 119595d5899Sopenharmony_civoid LightLuxBuffer::Push(const int64_t timestamp, const float data) 120595d5899Sopenharmony_ci{ 121595d5899Sopenharmony_ci if (LuxBufferCheck() != 0) { 122595d5899Sopenharmony_ci return; 123595d5899Sopenharmony_ci } 124595d5899Sopenharmony_ci 125595d5899Sopenharmony_ci unsigned int next = mEnd; 126595d5899Sopenharmony_ci if (mCount == mCapacity) { 127595d5899Sopenharmony_ci unsigned long newSize = mCapacity * static_cast<unsigned long>(BUFFER_SIZE_INCREASE); 128595d5899Sopenharmony_ci if (newSize > static_cast<unsigned long>(LUX_BUFFER_SIZE_MAX)) { 129595d5899Sopenharmony_ci DISPLAY_HILOGW(FEAT_BRIGHTNESS, "buffer size larger than max value %{public}d already, stop expand", 130595d5899Sopenharmony_ci LUX_BUFFER_SIZE_MAX); 131595d5899Sopenharmony_ci return; 132595d5899Sopenharmony_ci } 133595d5899Sopenharmony_ci if (mStart >= mCapacity) { 134595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mStart error! mStart(%{public}d) >= mCapacity(%{public}d)", 135595d5899Sopenharmony_ci mStart, mCapacity); 136595d5899Sopenharmony_ci return; 137595d5899Sopenharmony_ci } 138595d5899Sopenharmony_ci 139595d5899Sopenharmony_ci if (CopyLuxBuffer(newSize) != 0) { 140595d5899Sopenharmony_ci return; 141595d5899Sopenharmony_ci } 142595d5899Sopenharmony_ci 143595d5899Sopenharmony_ci next = mCapacity; 144595d5899Sopenharmony_ci mCapacity = static_cast<unsigned int>(newSize); 145595d5899Sopenharmony_ci mStart = 0; 146595d5899Sopenharmony_ci } 147595d5899Sopenharmony_ci 148595d5899Sopenharmony_ci if (mBufferTime != nullptr) { 149595d5899Sopenharmony_ci mBufferTime[next] = timestamp; 150595d5899Sopenharmony_ci } 151595d5899Sopenharmony_ci 152595d5899Sopenharmony_ci if (mBufferData != nullptr) { 153595d5899Sopenharmony_ci mBufferData[next] = data; 154595d5899Sopenharmony_ci } 155595d5899Sopenharmony_ci 156595d5899Sopenharmony_ci mEnd = next + 1; 157595d5899Sopenharmony_ci if (mEnd == mCapacity) { 158595d5899Sopenharmony_ci mEnd = 0; 159595d5899Sopenharmony_ci } 160595d5899Sopenharmony_ci mCount++; 161595d5899Sopenharmony_ci} 162595d5899Sopenharmony_ci 163595d5899Sopenharmony_civoid LightLuxBuffer::Prune(const int64_t horizon) 164595d5899Sopenharmony_ci{ 165595d5899Sopenharmony_ci if (mCount == 0 || mBufferTime == nullptr) { 166595d5899Sopenharmony_ci return; 167595d5899Sopenharmony_ci } 168595d5899Sopenharmony_ci 169595d5899Sopenharmony_ci while (mCount > 1) { 170595d5899Sopenharmony_ci unsigned int next = mStart + 1; 171595d5899Sopenharmony_ci if (next >= mCapacity) { 172595d5899Sopenharmony_ci next -= mCapacity; 173595d5899Sopenharmony_ci } 174595d5899Sopenharmony_ci if (mBufferTime[next] > horizon) { 175595d5899Sopenharmony_ci break; 176595d5899Sopenharmony_ci } 177595d5899Sopenharmony_ci mStart = next; 178595d5899Sopenharmony_ci mCount--; 179595d5899Sopenharmony_ci } 180595d5899Sopenharmony_ci if (mBufferTime[mStart] < horizon) { 181595d5899Sopenharmony_ci mBufferTime[mStart] = horizon; 182595d5899Sopenharmony_ci } 183595d5899Sopenharmony_ci} 184595d5899Sopenharmony_ci 185595d5899Sopenharmony_civoid LightLuxBuffer::Clear() 186595d5899Sopenharmony_ci{ 187595d5899Sopenharmony_ci mStart = 0; 188595d5899Sopenharmony_ci mEnd = 0; 189595d5899Sopenharmony_ci mCount = 0; 190595d5899Sopenharmony_ci} 191595d5899Sopenharmony_ci 192595d5899Sopenharmony_cifloat LightLuxBuffer::GetData(const unsigned int index) const 193595d5899Sopenharmony_ci{ 194595d5899Sopenharmony_ci if (mBufferData == nullptr) { 195595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mBufferData is nullptr."); 196595d5899Sopenharmony_ci return 0; 197595d5899Sopenharmony_ci } 198595d5899Sopenharmony_ci if (index >= mCount) { 199595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "error! index = %{public}d, out of range mCount = %{public}d", index, mCount); 200595d5899Sopenharmony_ci return 0; 201595d5899Sopenharmony_ci } 202595d5899Sopenharmony_ci return mBufferData[OffsetOf(index)]; 203595d5899Sopenharmony_ci} 204595d5899Sopenharmony_ci 205595d5899Sopenharmony_ciint64_t LightLuxBuffer::GetTime(const unsigned int index) const 206595d5899Sopenharmony_ci{ 207595d5899Sopenharmony_ci if (mBufferTime == nullptr) { 208595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mBufferTime is nullptr"); 209595d5899Sopenharmony_ci return 0; 210595d5899Sopenharmony_ci } 211595d5899Sopenharmony_ci 212595d5899Sopenharmony_ci if (index >= mCount) { 213595d5899Sopenharmony_ci DISPLAY_HILOGE(FEAT_BRIGHTNESS, "error! index = %{public}d, out of range mCount = %{public}d", index, mCount); 214595d5899Sopenharmony_ci return 0; 215595d5899Sopenharmony_ci } 216595d5899Sopenharmony_ci return mBufferTime[OffsetOf(index)]; 217595d5899Sopenharmony_ci} 218595d5899Sopenharmony_ci 219595d5899Sopenharmony_ciunsigned int LightLuxBuffer::GetSize() const 220595d5899Sopenharmony_ci{ 221595d5899Sopenharmony_ci return mCount; 222595d5899Sopenharmony_ci} 223595d5899Sopenharmony_ci 224595d5899Sopenharmony_ciunsigned int LightLuxBuffer::OffsetOf(const unsigned int index) const 225595d5899Sopenharmony_ci{ 226595d5899Sopenharmony_ci unsigned actualIndex = index + mStart; 227595d5899Sopenharmony_ci if (actualIndex >= mCapacity) { 228595d5899Sopenharmony_ci actualIndex -= mCapacity; 229595d5899Sopenharmony_ci } 230595d5899Sopenharmony_ci return actualIndex; 231595d5899Sopenharmony_ci} 232595d5899Sopenharmony_ci 233595d5899Sopenharmony_cistd::string LightLuxBuffer::ToString(unsigned int n) 234595d5899Sopenharmony_ci{ 235595d5899Sopenharmony_ci std::ostringstream result; 236595d5899Sopenharmony_ci if (n > mCount) { 237595d5899Sopenharmony_ci n = mCount; 238595d5899Sopenharmony_ci } 239595d5899Sopenharmony_ci result << "["; 240595d5899Sopenharmony_ci for (unsigned int i = mCount-n; i>=0 && i < mCount;i++) { 241595d5899Sopenharmony_ci result << GetData(i); 242595d5899Sopenharmony_ci result << "/"; 243595d5899Sopenharmony_ci result << GetTime(i); 244595d5899Sopenharmony_ci result << ", "; 245595d5899Sopenharmony_ci } 246595d5899Sopenharmony_ci result << "]"; 247595d5899Sopenharmony_ci return result.str(); 248595d5899Sopenharmony_ci} 249595d5899Sopenharmony_ci} // namespace DisplayPowerMgr 250595d5899Sopenharmony_ci} // namespace OHOS