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