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 "gradual_animator.h"
17
18 #include "ffrt_utils.h"
19 #include "display_log.h"
20
21 namespace OHOS {
22 namespace DisplayPowerMgr {
23 using namespace PowerMgr;
24 namespace {
25 FFRTQueue g_animatorQueue("display_animator_queue");
26 FFRTHandle g_animatorTaskHandle;
27 }
GradualAnimator(const std::string & name,std::shared_ptr<AnimateCallback> & callback)28 GradualAnimator::GradualAnimator(const std::string& name, std::shared_ptr<AnimateCallback>& callback)
29 : name_(name), callback_(callback)
30 {
31 fromBrightness_ = 0;
32 toBrightness_ = 0;
33 currentBrightness_ = 0;
34 duration_ = 0;
35 totalSteps_ = 0;
36 stride_ = 0;
37 updateTime_ = DEFAULT_UPDATE_TIME;
38 }
39
StartAnimation(uint32_t from,uint32_t to,uint32_t duration)40 void GradualAnimator::StartAnimation(uint32_t from, uint32_t to, uint32_t duration)
41 {
42 if (animating_) {
43 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "animation is running, no need to start again");
44 return;
45 }
46 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "animation from=%{public}u, to=%{public}u, duration=%{public}u",
47 from, to, duration);
48 if (callback_ == nullptr) {
49 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "callback_ is nullptr");
50 return;
51 }
52 fromBrightness_ = from;
53 toBrightness_ = to;
54 currentBrightness_ = fromBrightness_.load();
55 duration_ = duration;
56 totalSteps_ = duration_ / updateTime_;
57 if (totalSteps_ < 1) {
58 totalSteps_ = 1;
59 }
60 int32_t changeBrightness = static_cast<int32_t>(toBrightness_) - static_cast<int32_t>(fromBrightness_);
61 if (changeBrightness == 0) {
62 return;
63 }
64 stride_ = changeBrightness / static_cast<int32_t>(totalSteps_);
65 if (abs(stride_) < STRIDE_ABSOLUTE_MIN) {
66 stride_ = (changeBrightness / abs(changeBrightness)) * STRIDE_ABSOLUTE_MIN;
67 }
68 currentStep_ = 0;
69 animating_ = true;
70 FFRTTask task = std::bind(&GradualAnimator::NextStep, this);
71 g_animatorTaskHandle = FFRTUtils::SubmitDelayTask(task, updateTime_, g_animatorQueue);
72 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "animation started");
73 }
74
StopAnimation()75 void GradualAnimator::StopAnimation()
76 {
77 animating_ = false;
78 FFRTUtils::CancelTask(g_animatorTaskHandle, g_animatorQueue);
79 if (callback_ == nullptr) {
80 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Callback is nullptr");
81 return;
82 }
83 callback_->OnEnd();
84 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "animation stopped");
85 }
86
IsAnimating() const87 bool GradualAnimator::IsAnimating() const
88 {
89 return animating_;
90 }
91
GetAnimationUpdateTime() const92 uint32_t GradualAnimator::GetAnimationUpdateTime() const
93 {
94 return updateTime_;
95 }
96
NextStep()97 void GradualAnimator::NextStep()
98 {
99 if (!animating_) {
100 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "is not animating, return");
101 return;
102 }
103 if (callback_ == nullptr) {
104 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Callback is nullptr");
105 return;
106 }
107 currentStep_++;
108 if (currentStep_ == 1) {
109 callback_->OnStart();
110 }
111 if (currentStep_ < totalSteps_) {
112 uint32_t nextBrightness = currentBrightness_ + stride_;
113 bool isOutRange = stride_ > 0 ? (nextBrightness >= toBrightness_) : (nextBrightness <= toBrightness_);
114 if (isOutRange) {
115 currentBrightness_ = toBrightness_.load();
116 callback_->OnChanged(currentBrightness_);
117 callback_->OnEnd();
118 animating_ = false;
119 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "next step brightness is out range, brightness=%{public}u", nextBrightness);
120 } else {
121 currentBrightness_ = nextBrightness;
122 callback_->OnChanged(currentBrightness_);
123 FFRTTask task = std::bind(&GradualAnimator::NextStep, this);
124 g_animatorTaskHandle = FFRTUtils::SubmitDelayTask(task, updateTime_, g_animatorQueue);
125 }
126 } else {
127 currentBrightness_ = toBrightness_.load();
128 callback_->OnChanged(currentBrightness_);
129 callback_->OnEnd();
130 animating_ = false;
131 }
132 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "animating next step, step=%{public}u, brightness=%{public}u, stride=%{public}d",
133 currentStep_.load(), currentBrightness_.load(), stride_.load());
134 }
135 } // namespace DisplayPowerMgr
136 } // namespace OHOS
137