1 /*
2 * Copyright (c) 2024 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 "screen_off_pre_controller.h"
17
18 #include <datetime_ex.h>
19
20 #include "power_log.h"
21 #include "power_mgr_service.h"
22 #include "setting_helper.h"
23 #include "sp_singleton.h"
24
25 namespace OHOS {
26 namespace PowerMgr {
27 namespace {
28 const uint32_t SCREEN_OFF_PRE_STATE = 1;
29 }
30
ScreenOffPreController(std::shared_ptr<PowerStateMachine> & stateMachine)31 ScreenOffPreController::ScreenOffPreController(std::shared_ptr<PowerStateMachine>& stateMachine)
32 {
33 callbackMgr_ = new (std::nothrow) CallbackMgr();
34 queue_ = std::make_shared<FFRTQueue>("screen_off_pre_controller");
35 powerStateMachine_ = stateMachine;
36 }
37
Init()38 void ScreenOffPreController::Init()
39 {
40 POWER_HILOGI(FEATURE_SCREEN_OFF_PRE, "Init start");
41 }
42
IsRegistered()43 bool ScreenOffPreController::IsRegistered()
44 {
45 return isRegistered_;
46 }
47
AddScreenStateCallback(int32_t remainTime,const sptr<IScreenOffPreCallback> & callback)48 void ScreenOffPreController::AddScreenStateCallback(int32_t remainTime, const sptr<IScreenOffPreCallback>& callback)
49 {
50 POWER_HILOGD(FEATURE_SCREEN_OFF_PRE, "remainTime=%{public}d", remainTime);
51 remainTime_ = remainTime;
52 if (callbackMgr_ != nullptr) {
53 callbackMgr_->AddCallback(callback);
54 isRegistered_ = true;
55 if (powerStateMachine_ != nullptr) {
56 int64_t systemTime = powerStateMachine_->GetDisplayOffTime();
57 auto settingTime = SettingHelper::GetSettingDisplayOffTime(systemTime);
58 int64_t dimTime = powerStateMachine_->GetDimTime(systemTime);
59 POWER_HILOGD(FEATURE_SCREEN_OFF_PRE,
60 "systemTime=%{public}lld,settingTime=%{public}lld,dimTime=%{public}lld",
61 static_cast<long long>(systemTime), static_cast<long long>(settingTime),
62 static_cast<long long>(dimTime));
63 SchedulEyeDetectTimeout(powerStateMachine_->GetLastOnTime() + settingTime - dimTime, GetTickCount());
64 }
65 }
66 }
67
DelScreenStateCallback(const sptr<IScreenOffPreCallback> & callback)68 void ScreenOffPreController::DelScreenStateCallback(const sptr<IScreenOffPreCallback>& callback)
69 {
70 POWER_HILOGD(FEATURE_SCREEN_OFF_PRE, "DelScreenStateCallback enter");
71 if (callbackMgr_ != nullptr) {
72 callbackMgr_->RemoveCallback(callback);
73 isRegistered_ = false;
74 }
75 }
76
Reset()77 void ScreenOffPreController::Reset()
78 {
79 if (queue_) {
80 queue_.reset();
81 }
82 }
83
AddCallback(const sptr<IScreenOffPreCallback> & callback)84 void ScreenOffPreController::CallbackMgr::AddCallback(const sptr<IScreenOffPreCallback>& callback)
85 {
86 std::unique_lock lock(mutex_);
87 RETURN_IF((callback == nullptr) || (callback->AsObject() == nullptr));
88 auto object = callback->AsObject();
89 auto retIt = callbackSet_.insert(object);
90 if (retIt.second) {
91 object->AddDeathRecipient(this);
92 }
93 }
94
RemoveCallback(const sptr<IScreenOffPreCallback> & callback)95 void ScreenOffPreController::CallbackMgr::RemoveCallback(const sptr<IScreenOffPreCallback>& callback)
96 {
97 std::unique_lock lock(mutex_);
98 RETURN_IF((callback == nullptr) || (callback->AsObject() == nullptr));
99 auto object = callback->AsObject();
100 auto it = find(callbackSet_.begin(), callbackSet_.end(), object);
101 if (it != callbackSet_.end()) {
102 callbackSet_.erase(it);
103 object->RemoveDeathRecipient(this);
104 }
105 }
106
OnRemoteDied(const wptr<IRemoteObject> & remote)107 void ScreenOffPreController::CallbackMgr::OnRemoteDied(const wptr<IRemoteObject>& remote)
108 {
109 POWER_HILOGW(FEATURE_SCREEN_OFF_PRE, "OnRemoteDied");
110 RETURN_IF(remote.promote() == nullptr);
111 RemoveCallback(iface_cast<IScreenOffPreCallback>(remote.promote()));
112 }
113
Notify()114 void ScreenOffPreController::CallbackMgr::Notify()
115 {
116 std::unique_lock lock(mutex_);
117 for (auto& obj : callbackSet_) {
118 sptr<IScreenOffPreCallback> callback = iface_cast<IScreenOffPreCallback>(obj);
119 if (callback != nullptr) {
120 callback->OnScreenStateChanged(SCREEN_OFF_PRE_STATE);
121 }
122 }
123 }
124
TriggerCallback()125 void ScreenOffPreController::TriggerCallback()
126 {
127 POWER_HILOGD(FEATURE_SCREEN_OFF_PRE, "TriggerCallback");
128 if (callbackMgr_) {
129 callbackMgr_->Notify();
130 }
131 }
132
SchedulEyeDetectTimeout(int64_t nextTimeOut,int64_t now)133 void ScreenOffPreController::SchedulEyeDetectTimeout(int64_t nextTimeOut, int64_t now)
134 {
135 if (remainTime_ <= 0) {
136 POWER_HILOGE(FEATURE_SCREEN_OFF_PRE, "remainTime_ is invalid:%{public}d", remainTime_);
137 return;
138 }
139 int64_t nextEyeDetectTime = nextTimeOut - remainTime_ - now;
140 if (NeedEyeDetectLocked(nextEyeDetectTime)) {
141 CancelEyeDetectTimeout();
142 HandleEyeDetectTimeout(nextEyeDetectTime);
143 }
144 }
145
NeedEyeDetectLocked(int64_t nextEyeDetectTime)146 bool ScreenOffPreController::NeedEyeDetectLocked(int64_t nextEyeDetectTime)
147 {
148 if (nextEyeDetectTime < 0) {
149 POWER_HILOGD(FEATURE_SCREEN_OFF_PRE, "nextEyeDetectTime<0");
150 return false;
151 }
152 return true;
153 }
154
HandleEyeDetectTimeout(int64_t delayTime)155 void ScreenOffPreController::HandleEyeDetectTimeout(int64_t delayTime)
156 {
157 POWER_HILOGD(FEATURE_SCREEN_OFF_PRE,
158 "HandleEyeDetectTimeout delayTime=%{public}lld", static_cast<long long>(delayTime));
159 std::lock_guard lock(ffrtMutex_);
160 FFRTTask handletask = [this] { this->TriggerCallback(); };
161 if (!queue_) {
162 POWER_HILOGE(FEATURE_SCREEN_OFF_PRE, "queue_ is nullptr");
163 return;
164 }
165 eyeDetectTimeOutHandle_ = FFRTUtils::SubmitDelayTask(handletask, delayTime, queue_);
166 }
167
CancelEyeDetectTimeout()168 void ScreenOffPreController::CancelEyeDetectTimeout()
169 {
170 std::lock_guard lock(ffrtMutex_);
171 if (!queue_) {
172 POWER_HILOGE(FEATURE_SCREEN_OFF_PRE, "queue_ is nullptr");
173 return;
174 }
175 FFRTUtils::CancelTask(eyeDetectTimeOutHandle_, queue_);
176 }
177
178 } // namespace PowerMgr
179 } // namespace OHOS
180