• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "wakeup_controller.h"
17 
18 #include <datetime_ex.h>
19 #include <hisysevent.h>
20 #include <input_manager.h>
21 #include <ipc_skeleton.h>
22 #include <securec.h>
23 
24 #include "ffrt_utils.h"
25 #include "permission.h"
26 #include "power_errors.h"
27 #include "power_log.h"
28 #include "power_mgr_service.h"
29 #include "power_state_callback_stub.h"
30 #include "setting_helper.h"
31 #include "suspend_controller.h"
32 #include "system_suspend_controller.h"
33 
34 namespace OHOS {
35 namespace PowerMgr {
36 using namespace OHOS::MMI;
37 namespace {
38 sptr<SettingObserver> g_wakeupSourcesKeyObserver = nullptr;
39 FFRTQueue g_queue("power_wakeup_controller");
40 FFRTHandle g_screenTimeoutHandle;
41 }
42 
43 /** WakeupController Implement */
WakeupController(std::shared_ptr<PowerStateMachine> & stateMachine)44 WakeupController::WakeupController(std::shared_ptr<PowerStateMachine>& stateMachine)
45 {
46     stateMachine_ = stateMachine;
47     std::shared_ptr<InputCallback> callback = std::make_shared<InputCallback>();
48     if (monitorId_ < 0) {
49         monitorId_ = InputManager::GetInstance()->AddMonitor(std::static_pointer_cast<IInputEventConsumer>(callback));
50     }
51     eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD, 0);
52     eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_MOUSE, 0);
53     eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_TOUCHPAD, 0);
54     eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_PEN, 0);
55     eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_TOUCH_SCREEN, 0);
56     eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_SINGLE_CLICK, 0);
57 }
58 
~WakeupController()59 WakeupController::~WakeupController()
60 {
61     InputManager* inputManager = InputManager::GetInstance();
62     if (monitorId_ >= 0) {
63         inputManager->RemoveMonitor(monitorId_);
64     }
65 
66     if (g_wakeupSourcesKeyObserver) {
67         SettingHelper::UnregisterSettingWakeupSourcesObserver(g_wakeupSourcesKeyObserver);
68     }
69     if (g_screenTimeoutHandle) {
70         FFRTUtils::CancelTask(g_screenTimeoutHandle, g_queue);
71     }
72 }
73 
Init()74 void WakeupController::Init()
75 {
76     std::shared_ptr<WakeupSources> sources = WakeupSourceParser::ParseSources();
77     sourceList_ = sources->GetSourceList();
78     if (sourceList_.empty()) {
79         POWER_HILOGE(FEATURE_WAKEUP, "InputManager is null");
80         return;
81     }
82 
83     for (auto source = sourceList_.begin(); source != sourceList_.end(); source++) {
84         POWER_HILOGI(FEATURE_WAKEUP, "registered type=%{public}u", (*source).GetReason());
85         std::shared_ptr<WakeupMonitor> monitor = WakeupMonitor::CreateMonitor(*source);
86         if (monitor != nullptr && monitor->Init()) {
87             POWER_HILOGI(FEATURE_WAKEUP, "register type=%{public}u", (*source).GetReason());
88             monitor->RegisterListener(std::bind(&WakeupController::ControlListener, this, std::placeholders::_1));
89             monitorMap_.emplace(monitor->GetReason(), monitor);
90         }
91     }
92     RegisterSettingsObserver();
93 
94     std::function<void(uint32_t)> callback = [&](uint32_t event) {
95         POWER_HILOGI(COMP_SVC, "NotifyDisplayActionDone: %{public}d", event);
96         FFRTUtils::CancelTask(g_screenTimeoutHandle, g_queue);
97     };
98     auto stateAction = stateMachine_->GetStateAction();
99     if (stateAction != nullptr) {
100         stateAction->RegisterCallback(callback);
101         POWER_HILOGI(COMP_SVC, "NotifyDisplayActionDone callback registered");
102     }
103 }
104 
Cancel()105 void WakeupController::Cancel()
106 {
107     for (auto monitor = monitorMap_.begin(); monitor != monitorMap_.end(); monitor++) {
108         monitor->second->Cancel();
109     }
110     monitorMap_.clear();
111 }
112 
RegisterSettingsObserver()113 void WakeupController::RegisterSettingsObserver()
114 {
115     if (g_wakeupSourcesKeyObserver) {
116         POWER_HILOGE(FEATURE_POWER_STATE, "wakeup sources key observer is already registered");
117         return;
118     }
119     SettingObserver::UpdateFunc updateFunc = [&](const std::string&) {
120         std::lock_guard lock(monitorMutex_);
121         POWER_HILOGI(COMP_SVC, "start setting string update");
122         std::string jsonStr = SettingHelper::GetSettingWakeupSources();
123         std::shared_ptr<WakeupSources> sources = WakeupSourceParser::ParseSources(jsonStr);
124         std::vector<WakeupSource> updateSourceList = sources->GetSourceList();
125         if (updateSourceList.size() == 0) {
126             return;
127         }
128         sourceList_ = updateSourceList;
129         POWER_HILOGI(COMP_SVC, "start updateListener");
130         Cancel();
131         for (auto source = sourceList_.begin(); source != sourceList_.end(); source++) {
132             std::shared_ptr<WakeupMonitor> monitor = WakeupMonitor::CreateMonitor(*source);
133             if (monitor != nullptr && monitor->Init()) {
134                 monitor->RegisterListener(std::bind(&WakeupController::ControlListener, this, std::placeholders::_1));
135                 monitorMap_.emplace(monitor->GetReason(), monitor);
136             }
137         }
138     };
139     g_wakeupSourcesKeyObserver = SettingHelper::RegisterSettingWakeupSourcesObserver(updateFunc);
140     POWER_HILOGI(FEATURE_POWER_STATE, "register setting observer fin");
141 }
142 
ExecWakeupMonitorByReason(WakeupDeviceType reason)143 void WakeupController::ExecWakeupMonitorByReason(WakeupDeviceType reason)
144 {
145     std::lock_guard lock(monitorMutex_);
146     if (monitorMap_.find(reason) != monitorMap_.end()) {
147         auto monitor = monitorMap_[reason];
148         monitor->Notify();
149     }
150 }
151 
Wakeup()152 void WakeupController::Wakeup()
153 {
154     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
155     if (pms == nullptr) {
156         POWER_HILOGE(FEATURE_WAKEUP, "get powerMgrService instance error");
157         return;
158     }
159     auto suspendController = pms->GetSuspendController();
160     if (suspendController == nullptr) {
161         POWER_HILOGE(FEATURE_WAKEUP, "get suspendController instance error");
162         return;
163     }
164     suspendController->StopSleep();
165 }
166 
ControlListener(WakeupDeviceType reason)167 void WakeupController::ControlListener(WakeupDeviceType reason)
168 {
169     std::lock_guard lock(mutex_);
170 
171     if (!Permission::IsSystem()) {
172         return;
173     }
174     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
175     if (pms == nullptr) {
176         return;
177     }
178 
179     if (pms->IsScreenOn()) {
180         return;
181     }
182     pid_t pid = IPCSkeleton::GetCallingPid();
183     auto uid = IPCSkeleton::GetCallingUid();
184     POWER_HILOGI(FEATURE_WAKEUP, "Try to wakeup device, pid=%{public}d, uid=%{public}d", pid, uid);
185 
186     if (stateMachine_->GetState() != PowerState::AWAKE) {
187         Wakeup();
188         StartWakeupTimer();
189         SystemSuspendController::GetInstance().Wakeup();
190         POWER_HILOGI(FEATURE_WAKEUP, "wakeup Request: %{public}d", reason);
191         bool ret = stateMachine_->SetState(
192             PowerState::AWAKE, stateMachine_->GetReasonByWakeType(static_cast<WakeupDeviceType>(reason)), true);
193         if (ret != true) {
194             POWER_HILOGI(FEATURE_WAKEUP, "setstate wakeup error");
195         }
196     } else {
197         POWER_HILOGI(FEATURE_WAKEUP, "state=%{public}u no transitor", stateMachine_->GetState());
198     }
199 }
200 
StartWakeupTimer()201 void WakeupController::StartWakeupTimer()
202 {
203     FFRTTask task = [this] {
204         HandleScreenOnTimeout();
205     };
206     g_screenTimeoutHandle = FFRTUtils::SubmitDelayTask(task, WakeupMonitor::POWER_KEY_PRESS_DELAY_MS, g_queue);
207 }
208 
HandleScreenOnTimeout()209 void WakeupController::HandleScreenOnTimeout()
210 {
211     POWER_HILOGW(FEATURE_INPUT, "PowerKey press timeout");
212     std::string message = "POWER KEY TIMEOUT BUT DISPLAY NOT FINISHED";
213     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "SCREEN_ON_TIMEOUT", HiviewDFX::HiSysEvent::EventType::FAULT,
214         "PID", IPCSkeleton::GetCallingPid(), "UID", IPCSkeleton::GetCallingUid(), "PACKAGE_NAME", "", "PROCESS_NAME",
215         "", "MSG", message.c_str());
216     POWER_HILOGD(FEATURE_INPUT, "Send HiSysEvent msg end");
217 }
218 
219 /* InputCallback achieve */
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const220 void InputCallback::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
221 {
222     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
223     if (pms == nullptr) {
224         POWER_HILOGE(FEATURE_WAKEUP, "get powerMgrService instance error");
225         return;
226     }
227     int64_t now = static_cast<int64_t>(time(nullptr));
228     pms->RefreshActivity(now, UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false);
229 
230     PowerState state = pms->GetState();
231     if (state == PowerState::AWAKE || state == PowerState::FREEZE) {
232         return;
233     }
234     std::shared_ptr<WakeupController> wakeupController = pms->GetWakeupController();
235     if (wakeupController == nullptr) {
236         POWER_HILOGE(FEATURE_WAKEUP, "wakeupController is not init");
237         return;
238     }
239 
240     int32_t keyCode = keyEvent->GetKeyCode();
241     WakeupDeviceType wakeupType = WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN;
242     if (keyCode == KeyEvent::KEYCODE_F1) {
243         wakeupType = WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK;
244     }
245 
246     if (keyCode >= KeyEvent::KEYCODE_0 && keyCode <= KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN) {
247         wakeupType = WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD;
248         if (wakeupController->CheckEventReciveTime(wakeupType)) {
249             return;
250         }
251     }
252 
253     POWER_HILOGI(FEATURE_WAKEUP, "KeyEvent wakeupType=%{public}u, keyCode=%{public}d", wakeupType, keyCode);
254     if (wakeupType != WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN) {
255         wakeupController->ExecWakeupMonitorByReason(wakeupType);
256     }
257 }
258 
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const259 void InputCallback::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
260 {
261     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
262     if (pms == nullptr) {
263         return;
264     }
265     int64_t now = static_cast<int64_t>(time(nullptr));
266     pms->RefreshActivity(now, UserActivityType::USER_ACTIVITY_TYPE_TOUCH, false);
267 
268     PowerState state = pms->GetState();
269     if (state == PowerState::AWAKE || state == PowerState::FREEZE) {
270         return;
271     }
272     std::shared_ptr<WakeupController> wakeupController = pms->GetWakeupController();
273     WakeupDeviceType wakeupType = WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN;
274     PointerEvent::PointerItem pointerItem;
275     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
276         POWER_HILOGI(FEATURE_WAKEUP, "GetPointerItem false");
277     }
278     int32_t deviceType = pointerItem.GetToolType();
279     int32_t sourceType = pointerEvent->GetSourceType();
280     if (deviceType == PointerEvent::TOOL_TYPE_PEN) {
281         wakeupType = WakeupDeviceType::WAKEUP_DEVICE_PEN;
282         if (wakeupController->CheckEventReciveTime(wakeupType)) {
283             return;
284         }
285         wakeupController->ExecWakeupMonitorByReason(wakeupType);
286         return;
287     }
288 
289     switch (sourceType) {
290         case PointerEvent::SOURCE_TYPE_MOUSE:
291             wakeupType = WakeupDeviceType::WAKEUP_DEVICE_MOUSE;
292             break;
293         case PointerEvent::SOURCE_TYPE_TOUCHPAD:
294             wakeupType = WakeupDeviceType::WAKEUP_DEVICE_TOUCHPAD;
295             break;
296         case PointerEvent::SOURCE_TYPE_TOUCHSCREEN:
297             wakeupType = WakeupDeviceType::WAKEUP_DEVICE_SINGLE_CLICK;
298             break;
299         default:
300             break;
301     }
302     if (wakeupController->CheckEventReciveTime(wakeupType)) {
303         return;
304     }
305 
306     if (wakeupType != WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN) {
307         wakeupController->ExecWakeupMonitorByReason(wakeupType);
308     }
309 }
310 
OnInputEvent(std::shared_ptr<AxisEvent> axisEvent) const311 void InputCallback::OnInputEvent(std::shared_ptr<AxisEvent> axisEvent) const
312 {
313     POWER_HILOGD(FEATURE_WAKEUP, "AxisEvent");
314     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
315     if (pms == nullptr) {
316         return;
317     }
318     int64_t now = static_cast<int64_t>(time(nullptr));
319     pms->RefreshActivity(now, UserActivityType::USER_ACTIVITY_TYPE_ACCESSIBILITY, false);
320 }
321 
CheckEventReciveTime(WakeupDeviceType wakeupType)322 bool WakeupController::CheckEventReciveTime(WakeupDeviceType wakeupType)
323 {
324     // The minimum refreshactivity interval is 100ms!!
325     std::lock_guard lock(eventHandleMutex_);
326     int64_t now = GetTickCount();
327     if (eventHandleMap_.find(wakeupType) != eventHandleMap_.end()) {
328         if ((eventHandleMap_[wakeupType] + MIN_TIME_MS_BETWEEN_MULTIMODEACTIVITIES) > now) {
329             return true;
330         }
331         eventHandleMap_[wakeupType] = now;
332         return false;
333     }
334     return false;
335 }
336 
337 /* WakeupMonitor Implement */
338 
CreateMonitor(WakeupSource & source)339 std::shared_ptr<WakeupMonitor> WakeupMonitor::CreateMonitor(WakeupSource& source)
340 {
341     WakeupDeviceType reason = source.GetReason();
342     POWER_HILOGE(FEATURE_WAKEUP, "CreateMonitor reason=%{public}d", reason);
343     std::shared_ptr<WakeupMonitor> monitor = nullptr;
344     switch (reason) {
345         case WakeupDeviceType::WAKEUP_DEVICE_POWER_BUTTON:
346             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<PowerkeyWakeupMonitor>(source));
347             break;
348         case WakeupDeviceType::WAKEUP_DEVICE_MOUSE:
349             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<MousekeyWakeupMonitor>(source));
350             break;
351         case WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD:
352             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<KeyboardWakeupMonitor>(source));
353             break;
354         case WakeupDeviceType::WAKEUP_DEVICE_PEN:
355             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<PenWakeupMonitor>(source));
356             break;
357         case WakeupDeviceType::WAKEUP_DEVICE_TOUCHPAD:
358             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<TouchpadWakeupMonitor>(source));
359             break;
360         case WakeupDeviceType::WAKEUP_DEVICE_SINGLE_CLICK:
361             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<SingleClickWakeupMonitor>(source));
362             break;
363         case WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK:
364             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<DoubleClickWakeupMonitor>(source));
365             break;
366         case WakeupDeviceType::WAKEUP_DEVICE_LID:
367             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<LidWakeupMonitor>(source));
368             break;
369         case WakeupDeviceType::WAKEUP_DEVICE_SWITCH:
370             monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<SwitchWakeupMonitor>(source));
371             break;
372         default:
373             POWER_HILOGE(FEATURE_WAKEUP, "CreateMonitor : Invalid reason=%{public}d", reason);
374             break;
375     }
376     return monitor;
377 }
378 
379 /** PowerkeyWakeupMonitor Implement */
380 
Init()381 bool PowerkeyWakeupMonitor::Init()
382 {
383     if (powerkeyShortPressId_ >= 0) {
384         return true;
385     }
386     std::shared_ptr<OHOS::MMI::KeyOption> keyOption = std::make_shared<OHOS::MMI::KeyOption>();
387     std::set<int32_t> preKeys;
388     keyOption.reset();
389     keyOption = std::make_shared<OHOS::MMI::KeyOption>();
390     keyOption->SetPreKeys(preKeys);
391     keyOption->SetFinalKey(OHOS::MMI::KeyEvent::KEYCODE_POWER);
392     keyOption->SetFinalKeyDown(true);
393     keyOption->SetFinalKeyDownDuration(0);
394     powerkeyShortPressId_ = InputManager::GetInstance()->SubscribeKeyEvent(
395         keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) {
396             POWER_HILOGI(FEATURE_WAKEUP, "receive wakeup controller key down");
397             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
398             if (pms == nullptr) {
399                 return;
400             }
401             pms->RefreshActivity(
402                 static_cast<int64_t>(time(nullptr)), UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false);
403             std::shared_ptr<SuspendController> suspendController = pms->GetSuspendController();
404             suspendController->RecordPowerKeyDown();
405             Notify();
406         });
407 
408     POWER_HILOGI(FEATURE_WAKEUP, "powerkey register powerkeyShortPressId_=%{public}d", powerkeyShortPressId_);
409     return powerkeyShortPressId_ >= 0 ? true : false;
410 }
411 
Cancel()412 void PowerkeyWakeupMonitor::Cancel()
413 {
414     if (powerkeyShortPressId_ >= 0) {
415         InputManager::GetInstance()->UnsubscribeKeyEvent(powerkeyShortPressId_);
416     }
417 }
418 
419 /** Keyboard Implement */
420 
Init()421 bool KeyboardWakeupMonitor::Init()
422 {
423     return true;
424 }
425 
Cancel()426 void KeyboardWakeupMonitor::Cancel() {}
427 
428 /** Mouse Implement */
429 
Init()430 bool MousekeyWakeupMonitor::Init()
431 {
432     return true;
433 }
434 
Cancel()435 void MousekeyWakeupMonitor::Cancel() {}
436 
437 /** Mouse Implement */
438 
Init()439 bool TouchpadWakeupMonitor::Init()
440 {
441     return true;
442 }
443 
Cancel()444 void TouchpadWakeupMonitor::Cancel() {}
445 
446 /** Pen Implement */
447 
Init()448 bool PenWakeupMonitor::Init()
449 {
450     return true;
451 }
452 
Cancel()453 void PenWakeupMonitor::Cancel() {}
454 
455 /** SingleClickWakeupMonitor Implement */
456 
Init()457 bool SingleClickWakeupMonitor::Init()
458 {
459     return true;
460 }
461 
Cancel()462 void SingleClickWakeupMonitor::Cancel() {}
463 
464 /** DoubleClickWakeupMonitor Implement */
465 
Init()466 bool DoubleClickWakeupMonitor::Init()
467 {
468     return true;
469 }
470 
Cancel()471 void DoubleClickWakeupMonitor::Cancel() {}
472 
473 /** SwitchWakeupMonitor Implement */
474 
Init()475 bool SwitchWakeupMonitor::Init()
476 {
477     return true;
478 }
479 
Cancel()480 void SwitchWakeupMonitor::Cancel() {}
481 
482 /** LidWakeupMonitor Implement */
483 
Init()484 bool LidWakeupMonitor::Init()
485 {
486     return true;
487 }
488 
Cancel()489 void LidWakeupMonitor::Cancel() {}
490 
491 } // namespace PowerMgr
492 } // namespace OHOS
493