• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 #include "conditions/screen_listener.h"
16 
17 #include <string>
18 #include <cinttypes>
19 
20 #include "common_event_manager.h"
21 #include "common_event_support.h"
22 #include "matching_skills.h"
23 #include "want.h"
24 #include "work_sched_hilog.h"
25 #include "work_sched_utils.h"
26 #include "work_status.h"
27 #include "work_event_handler.h"
28 #include "work_scheduler_service.h"
29 #include "work_sched_constants.h"
30 #include "conditions/timer_info.h"
31 #include "work_sched_hisysevent_report.h"
32 #include "work_sched_data_manager.h"
33 
34 namespace OHOS {
35 namespace WorkScheduler {
ScreenEventSubscriber(const EventFwk::CommonEventSubscribeInfo & subscribeInfo,ScreenListener & listener)36 ScreenEventSubscriber::ScreenEventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo,
37     ScreenListener &listener) : EventFwk::CommonEventSubscriber(subscribeInfo), listener_(listener) {}
38 
OnReceiveEvent(const EventFwk::CommonEventData & data)39 void ScreenEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
40 {
41     const std::string action = data.GetWant().GetAction();
42     WS_HILOGI("OnReceiveEvent get action: %{public}s", action.c_str());
43     auto eventHandler = listener_.service_->GetHandler();
44     if (!eventHandler) {
45         WS_HILOGE("event handler is null");
46         return;
47     }
48     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
49         if (DelayedSingleton<DataManager>::GetInstance()->GetDeepIdle()) {
50             DelayedSingleton<DataManager>::GetInstance()->SetDeepIdle(false);
51             WorkSchedUtil::HiSysEventStateChanged({"DEEP_IDLE", 0});
52         }
53         listener_.StopTimer();
54         listener_.OnConditionChanged(WorkCondition::Type::DEEP_IDLE,
55             std::make_shared<DetectorValue>(0, 0, false, std::string()));
56         auto task = [weak = weak_from_this()]() {
57             auto strong = weak.lock();
58             if (!strong) {
59                 WS_HILOGE("ScreenEventSubscriber::OnReceiveEvent strong is null");
60                 return;
61             }
62             int32_t ret = strong->listener_.service_->StopDeepIdleWorks();
63             if (ret != ERR_OK) {
64                 WS_HILOGE("stop work after unlocking failed, error code:%{public}d.", ret);
65             } else {
66                 WS_HILOGI("stop work after unlocking successed.");
67             }
68         };
69         eventHandler->PostTask(task);
70     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
71         if (listener_.timerId_ != 0) {
72             WS_HILOGW("has send check deep idle msg, ignore");
73             return;
74         }
75         listener_.StartTimer();
76     }
77 }
78 
ScreenListener(std::shared_ptr<WorkQueueManager> workQueueManager,std::shared_ptr<WorkSchedulerService> service)79 ScreenListener::ScreenListener(std::shared_ptr<WorkQueueManager> workQueueManager,
80     std::shared_ptr<WorkSchedulerService> service)
81 {
82     workQueueManager_ = workQueueManager;
83     service_ = service;
84 }
85 
~ScreenListener()86 ScreenListener::~ScreenListener()
87 {
88     this->Stop();
89 }
90 
CreateScreenEventSubscriber(ScreenListener & listener)91 std::shared_ptr<EventFwk::CommonEventSubscriber> CreateScreenEventSubscriber(ScreenListener &listener)
92 {
93     EventFwk::MatchingSkills skill = EventFwk::MatchingSkills();
94     skill.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
95     skill.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
96     EventFwk::CommonEventSubscribeInfo info(skill);
97     return std::make_shared<ScreenEventSubscriber>(info, listener);
98 }
99 
Start()100 bool ScreenListener::Start()
101 {
102     WS_HILOGD("screen listener start.");
103     this->commonEventSubscriber = CreateScreenEventSubscriber(*this);
104     return EventFwk::CommonEventManager::SubscribeCommonEvent(this->commonEventSubscriber);
105 }
106 
Stop()107 bool ScreenListener::Stop()
108 {
109     WS_HILOGD("screen listener stop.");
110     if (this->commonEventSubscriber != nullptr) {
111         bool result = EventFwk::CommonEventManager::UnSubscribeCommonEvent(this->commonEventSubscriber);
112         if (result) {
113             this->commonEventSubscriber = nullptr;
114         }
115         return result;
116     }
117     return true;
118 }
119 
OnConditionChanged(WorkCondition::Type conditionType,std::shared_ptr<DetectorValue> conditionVal)120 void ScreenListener::OnConditionChanged(WorkCondition::Type conditionType,
121     std::shared_ptr<DetectorValue> conditionVal)
122 {
123     if (workQueueManager_ != nullptr) {
124         workQueueManager_->OnConditionChanged(conditionType, conditionVal);
125     } else {
126         WS_HILOGE("workQueueManager_ is nullptr.");
127     }
128 }
129 
StartTimer()130 void ScreenListener::StartTimer()
131 {
132     WS_HILOGI("deep idle timer start with time = %{public}d.", MIN_DEEP_IDLE_SCREEN_OFF_TIME_MIN);
133     auto task = [=]() {
134         WS_HILOGI("Into deep idle mode");
135         DelayedSingleton<DataManager>::GetInstance()->SetDeepIdle(true);
136         service_->HandleDeepIdleMsg();
137     };
138     auto timerInfo = std::make_shared<TimerInfo>();
139     uint8_t type = static_cast<uint8_t>(timerInfo->TIMER_TYPE_EXACT) |
140         static_cast<uint8_t>(timerInfo->TIMER_TYPE_REALTIME);
141     timerInfo->SetType(static_cast<int>(type));
142     timerInfo->SetRepeat(false);
143     timerInfo->SetInterval(MIN_DEEP_IDLE_SCREEN_OFF_TIME_MIN);
144     timerInfo->SetCallbackInfo(task);
145     timerId_ = TimeServiceClient::GetInstance()->CreateTimer(timerInfo);
146     if (timerId_ == 0) {
147         WS_HILOGE("TimerListener CreateTimer failed");
148         return;
149     }
150     bool res = TimeServiceClient::GetInstance()->StartTimer(timerId_,
151         TimeServiceClient::GetInstance()->GetBootTimeMs() + MIN_DEEP_IDLE_SCREEN_OFF_TIME_MIN);
152     WS_HILOGI("deep idle timer start, res is %{public}d, timerId %{public}" PRIu64, res, timerId_);
153 }
154 
StopTimer()155 void ScreenListener::StopTimer()
156 {
157     if (timerId_ > 0) {
158         MiscServices::TimeServiceClient::GetInstance()->StopTimer(timerId_);
159         MiscServices::TimeServiceClient::GetInstance()->DestroyTimer(timerId_);
160         timerId_ = 0;
161         WS_HILOGI("deep idle timer stop success");
162     }
163     WS_HILOGI("deep idle timer stop end");
164 }
165 } // namespace WorkScheduler
166 } // namespace OHOS