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 "brightness_dimming.h"
17
18 #include "brightness_dimming_callback.h"
19 #include "display_log.h"
20 #include "ffrt_utils.h"
21
22 namespace OHOS {
23 namespace DisplayPowerMgr {
24 using namespace PowerMgr;
25 namespace {
26 FFRTHandle g_animatorTaskHandle;
27 }
28
BrightnessDimming(const std::string & name,std::shared_ptr<BrightnessDimmingCallback> & callback)29 BrightnessDimming::BrightnessDimming(const std::string& name, std::shared_ptr<BrightnessDimmingCallback>& callback)
30 : mName(name), mCallback(callback)
31 {
32 mFromBrightness = 0;
33 mToBrightness = 0;
34 mCurrentBrightness = 0;
35 mDuration = 0;
36 mTotalSteps = 0;
37 mStride = 0;
38 mUpdateTime = DEFAULT_UPDATE_TIME;
39 }
40
Init()41 bool BrightnessDimming::Init()
42 {
43 mQueue = std::make_shared<FFRTQueue> ("brightness_animator_queue");
44 if (mQueue == nullptr) {
45 return false;
46 }
47 return true;
48 }
49
Reset()50 void BrightnessDimming::Reset()
51 {
52 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "start dimming queue");
53 if (mQueue) {
54 mQueue.reset();
55 g_animatorTaskHandle = nullptr;
56 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "destruct dimming_queue");
57 }
58 }
59
StartDimming(uint32_t from,uint32_t to,uint32_t duration)60 void BrightnessDimming::StartDimming(uint32_t from, uint32_t to, uint32_t duration)
61 {
62 if (mDimming) {
63 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "animation is running, no need to start again, from=%{public}u, "\
64 " to=%{public}u, duration=%{public}u", from, to, duration);
65 return;
66 }
67 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "animation from=%{public}u, to=%{public}u, duration=%{public}u",
68 from, to, duration);
69 if (mCallback == nullptr) {
70 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "mCallback is nullptr");
71 return;
72 }
73 mFromBrightness = from;
74 mToBrightness = to;
75 mCurrentBrightness = mFromBrightness.load();
76 mDuration = duration;
77 mTotalSteps = mDuration / mUpdateTime;
78 if (mTotalSteps < 1) {
79 mTotalSteps = 1;
80 }
81 int32_t changeBrightness = static_cast<int32_t>(mToBrightness) - static_cast<int32_t>(mFromBrightness);
82 if (changeBrightness == 0) {
83 return;
84 }
85 mStride = changeBrightness / static_cast<int32_t>(mTotalSteps);
86 if (abs(mStride) < STRIDE_ABSOLUTE_MIN) {
87 mStride = (changeBrightness / abs(changeBrightness)) * STRIDE_ABSOLUTE_MIN;
88 }
89 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "animation orig mTotalSteps=%{public}d", static_cast<int32_t>(mTotalSteps));
90 if (mTotalSteps > 1 && abs(mStride) >= 1) {
91 mTotalSteps = (abs(changeBrightness) - abs(mStride) * mTotalSteps) / abs(mStride) + mTotalSteps;
92 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "animation update mTotalSteps=%{public}d", static_cast<int32_t>(mTotalSteps));
93 }
94 mCurrentStep = 0;
95 mDimming = true;
96 FFRTTask task = std::bind(&BrightnessDimming::NextStep, this);
97 g_animatorTaskHandle = FFRTUtils::SubmitDelayTask(task, mUpdateTime, mQueue);
98 }
99
StopDimming()100 void BrightnessDimming::StopDimming()
101 {
102 mDimming = false;
103 FFRTUtils::CancelTask(g_animatorTaskHandle, mQueue);
104 if (mCallback == nullptr) {
105 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Callback is nullptr");
106 return;
107 }
108 mCallback->OnEnd();
109 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "animation stopped");
110 }
111
IsDimming() const112 bool BrightnessDimming::IsDimming() const
113 {
114 return mDimming;
115 }
116
GetDimmingUpdateTime() const117 uint32_t BrightnessDimming::GetDimmingUpdateTime() const
118 {
119 return mUpdateTime;
120 }
121
NextStep()122 void BrightnessDimming::NextStep()
123 {
124 if (!mDimming) {
125 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "is not animating, return");
126 return;
127 }
128 if (mCallback == nullptr) {
129 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Callback is nullptr");
130 return;
131 }
132 mCurrentStep++;
133 if (mCurrentStep == 1) {
134 mCallback->OnStart();
135 }
136 if (mCurrentStep <= mTotalSteps) {
137 uint32_t nextBrightness = mCurrentBrightness + mStride;
138 bool isOutRange = (mStride > 0 ? (nextBrightness >= mToBrightness) : (nextBrightness <= mToBrightness));
139 if (isOutRange) {
140 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "next step brightness is out range, brightness=%{public}u",
141 nextBrightness);
142 mCurrentBrightness = mToBrightness.load();
143 mCallback->OnChanged(mCurrentBrightness);
144 mCallback->OnEnd();
145 mDimming = false;
146 } else {
147 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "next step last mCurrentBrightness=%{public}u, next=%{public}d",
148 mCurrentBrightness.load(), nextBrightness);
149 mCurrentBrightness = nextBrightness;
150 mCallback->OnChanged(mCurrentBrightness);
151 FFRTTask task = std::bind(&BrightnessDimming::NextStep, this);
152 g_animatorTaskHandle = FFRTUtils::SubmitDelayTask(task, mUpdateTime, mQueue);
153 }
154 } else {
155 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "next step last mCurrentBrightness=%{public}u, mToBrightness=%{public}u",
156 mCurrentBrightness.load(), mToBrightness.load());
157 mCurrentBrightness = mToBrightness.load();
158 mCallback->OnChanged(mCurrentBrightness);
159 mCallback->OnEnd();
160 mDimming = false;
161 }
162 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "animating next step, step=%{public}u, brightness=%{public}u, stride=%{public}d",
163 mCurrentStep.load(), mCurrentBrightness.load(), mStride.load());
164 }
165 } // namespace DisplayPowerMgr
166 } // namespace OHOS
167