1 /*
2 * Copyright (c) 2023-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 "light_lux_buffer.h"
17
18 #include <cerrno>
19 #include <cstdlib>
20 #include <new>
21 #include <string>
22 #include <securec.h>
23 #include <securectype.h>
24
25 #include "display_log.h"
26
27 namespace OHOS {
28 namespace DisplayPowerMgr {
29
30 namespace {
31 const unsigned int BUFFER_SIZE_INCREASE = 2;
32 const unsigned int LUX_BUFFER_SIZE_MAX = 512;
33 }
34
LightLuxBuffer(unsigned int initialCapacity)35 LightLuxBuffer::LightLuxBuffer(unsigned int initialCapacity)
36 {
37 if (initialCapacity == 0 || initialCapacity >= LUX_BUFFER_SIZE_MAX) {
38 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "initialCapacity=%{public}d out of range, Reset to %{public}d",
39 initialCapacity, LUX_BUFFER_SIZE_DEFAULT);
40 mCapacity = LUX_BUFFER_SIZE_DEFAULT;
41 } else {
42 mCapacity = initialCapacity;
43 }
44 }
45
~LightLuxBuffer()46 LightLuxBuffer::~LightLuxBuffer()
47 {
48 if (mBufferData != nullptr) {
49 delete[] mBufferData;
50 mBufferData = nullptr;
51 }
52
53 if (mBufferTime != nullptr) {
54 delete[] mBufferTime;
55 mBufferTime = nullptr;
56 }
57 }
58
LuxBufferCheck()59 int LightLuxBuffer::LuxBufferCheck()
60 {
61 if (mBufferData == nullptr) {
62 mBufferData = new(std::nothrow) float[mCapacity];
63 if (mBufferData == nullptr) {
64 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "new mBufferData failed!");
65 return -1;
66 }
67 }
68 if (mBufferTime == nullptr) {
69 mBufferTime = new(std::nothrow) int64_t[mCapacity];
70 if (mBufferTime == nullptr) {
71 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "new mBufferTime failed!");
72 delete[] mBufferData;
73 mBufferData = nullptr;
74 return -1;
75 }
76 }
77 return 0;
78 }
79
CopyLuxBuffer(int newSize)80 int LightLuxBuffer::CopyLuxBuffer(int newSize)
81 {
82 auto newBufferData = new(std::nothrow) float[newSize];
83 if (newBufferData == nullptr) {
84 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "newBufferData id null");
85 return -1;
86 }
87 auto newBufferTime = new(std::nothrow) int64_t[newSize];
88 if (newBufferTime == nullptr) {
89 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "newBufferTime id null");
90 delete[] newBufferData;
91 return -1;
92 }
93 unsigned int length = mCapacity - mStart;
94 bool isError = false;
95 isError = isError || (memcpy_s(newBufferData, newSize * sizeof(newBufferData[0]),
96 mBufferData + mStart, length * sizeof(mBufferData[0])) != EOK);
97 isError = isError || (memcpy_s(newBufferTime, newSize * sizeof(newBufferTime[0]),
98 mBufferTime + mStart, length * sizeof(mBufferTime[0])) != EOK);
99 if (mStart != 0) {
100 isError = isError || (memcpy_s(newBufferData + length, (newSize - length) * sizeof(newBufferData[0]),
101 mBufferData, mStart * sizeof(mBufferData[0])) != EOK);
102 isError = isError || (memcpy_s(newBufferTime + length, (newSize - length) * sizeof(newBufferTime[0]),
103 mBufferTime, mStart * sizeof(mBufferTime[0])) != EOK);
104 }
105 if (isError) {
106 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "memcpy_s error, mCapacity=%{public}d, mStart=%{public}d", mCapacity, mStart);
107 delete[] newBufferData;
108 delete[] newBufferTime;
109 return -1;
110 }
111 delete[] mBufferData;
112 mBufferData = newBufferData;
113 delete[] mBufferTime;
114 mBufferTime = newBufferTime;
115
116 return 0;
117 }
118
Push(const int64_t timestamp,const float data)119 void LightLuxBuffer::Push(const int64_t timestamp, const float data)
120 {
121 if (LuxBufferCheck() != 0) {
122 return;
123 }
124
125 unsigned int next = mEnd;
126 if (mCount == mCapacity) {
127 unsigned long newSize = mCapacity * static_cast<unsigned long>(BUFFER_SIZE_INCREASE);
128 if (newSize > static_cast<unsigned long>(LUX_BUFFER_SIZE_MAX)) {
129 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "buffer size larger than max value %{public}d already, stop expand",
130 LUX_BUFFER_SIZE_MAX);
131 return;
132 }
133 if (mStart >= mCapacity) {
134 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mStart error! mStart(%{public}d) >= mCapacity(%{public}d)",
135 mStart, mCapacity);
136 return;
137 }
138
139 if (CopyLuxBuffer(newSize) != 0) {
140 return;
141 }
142
143 next = mCapacity;
144 mCapacity = static_cast<unsigned int>(newSize);
145 mStart = 0;
146 }
147
148 if (mBufferTime != nullptr) {
149 mBufferTime[next] = timestamp;
150 }
151
152 if (mBufferData != nullptr) {
153 mBufferData[next] = data;
154 }
155
156 mEnd = next + 1;
157 if (mEnd == mCapacity) {
158 mEnd = 0;
159 }
160 mCount++;
161 }
162
Prune(const int64_t horizon)163 void LightLuxBuffer::Prune(const int64_t horizon)
164 {
165 if (mCount == 0 || mBufferTime == nullptr) {
166 return;
167 }
168
169 while (mCount > 1) {
170 unsigned int next = mStart + 1;
171 if (next >= mCapacity) {
172 next -= mCapacity;
173 }
174 if (mBufferTime[next] > horizon) {
175 break;
176 }
177 mStart = next;
178 mCount--;
179 }
180 if (mBufferTime[mStart] < horizon) {
181 mBufferTime[mStart] = horizon;
182 }
183 }
184
Clear()185 void LightLuxBuffer::Clear()
186 {
187 mStart = 0;
188 mEnd = 0;
189 mCount = 0;
190 }
191
GetData(const unsigned int index) const192 float LightLuxBuffer::GetData(const unsigned int index) const
193 {
194 if (mBufferData == nullptr) {
195 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mBufferData is nullptr.");
196 return 0;
197 }
198 if (index >= mCount) {
199 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "error! index = %{public}d, out of range mCount = %{public}d", index, mCount);
200 return 0;
201 }
202 return mBufferData[OffsetOf(index)];
203 }
204
GetTime(const unsigned int index) const205 int64_t LightLuxBuffer::GetTime(const unsigned int index) const
206 {
207 if (mBufferTime == nullptr) {
208 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mBufferTime is nullptr");
209 return 0;
210 }
211
212 if (index >= mCount) {
213 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "error! index = %{public}d, out of range mCount = %{public}d", index, mCount);
214 return 0;
215 }
216 return mBufferTime[OffsetOf(index)];
217 }
218
GetSize() const219 unsigned int LightLuxBuffer::GetSize() const
220 {
221 return mCount;
222 }
223
OffsetOf(const unsigned int index) const224 unsigned int LightLuxBuffer::OffsetOf(const unsigned int index) const
225 {
226 unsigned actualIndex = index + mStart;
227 if (actualIndex >= mCapacity) {
228 actualIndex -= mCapacity;
229 }
230 return actualIndex;
231 }
232
ToString(unsigned int n)233 std::string LightLuxBuffer::ToString(unsigned int n)
234 {
235 std::ostringstream result;
236 if (n > mCount) {
237 n = mCount;
238 }
239 result << "[";
240 for (unsigned int i = mCount-n; i>=0 && i < mCount;i++) {
241 result << GetData(i);
242 result << "/";
243 result << GetTime(i);
244 result << ", ";
245 }
246 result << "]";
247 return result.str();
248 }
249 } // namespace DisplayPowerMgr
250 } // namespace OHOS