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 #ifdef POWER_WAKEUPDOUBLE_OR_PICKUP_ENABLE
24 #include <dlfcn.h>
25 #endif
26 #include "json/json.h"
27 #include "permission.h"
28 #include "power_errors.h"
29 #include "power_log.h"
30 #include "power_mgr_service.h"
31 #include "power_state_callback_stub.h"
32 #include "setting_helper.h"
33 #include "suspend_controller.h"
34 #include "system_suspend_controller.h"
35
36 namespace OHOS {
37 namespace PowerMgr {
38 using namespace OHOS::MMI;
39 namespace {
40 sptr<SettingObserver> g_wakeupSourcesKeyObserver = nullptr;
41 #ifdef POWER_WAKEUPDOUBLE_OR_PICKUP_ENABLE
42 const int32_t ERR_FAILED = -1;
43 #endif
44
45 constexpr int32_t WAKEUP_LOCK_TIMEOUT_MS = 5000;
46 constexpr int32_t COLLABORATION_REMOTE_DEVICE_ID = 0xAAAAAAFF;
47 }
48 std::mutex WakeupController::sourceUpdateMutex_;
49
50 /** WakeupController Implement */
WakeupController(std::shared_ptr<PowerStateMachine> & stateMachine)51 WakeupController::WakeupController(std::shared_ptr<PowerStateMachine>& stateMachine)
52 {
53 stateMachine_ = stateMachine;
54 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
55 std::shared_ptr<InputCallback> callback = std::make_shared<InputCallback>();
56 if (monitorId_ < 0) {
57 monitorId_ = InputManager::GetInstance()->AddMonitor(std::static_pointer_cast<IInputEventConsumer>(callback));
58 }
59 #endif
60 eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD, 0);
61 eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_MOUSE, 0);
62 eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_TOUCHPAD, 0);
63 eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_PEN, 0);
64 eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_TOUCH_SCREEN, 0);
65 eventHandleMap_.emplace(WakeupDeviceType::WAKEUP_DEVICE_SINGLE_CLICK, 0);
66 }
67
~WakeupController()68 WakeupController::~WakeupController()
69 {
70 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
71 InputManager* inputManager = InputManager::GetInstance();
72 if (monitorId_ >= 0) {
73 inputManager->RemoveMonitor(monitorId_);
74 }
75 #endif
76 UnregisterSettingsObserver();
77 }
78
Init()79 void WakeupController::Init()
80 {
81 std::lock_guard lock(monitorMutex_);
82 std::shared_ptr<WakeupSources> sources = WakeupSourceParser::ParseSources();
83 sourceList_ = sources->GetSourceList();
84 if (sourceList_.empty()) {
85 POWER_HILOGE(FEATURE_WAKEUP, "InputManager is null");
86 return;
87 }
88
89 for (auto source = sourceList_.begin(); source != sourceList_.end(); source++) {
90 POWER_HILOGI(FEATURE_WAKEUP, "registered type=%{public}u", (*source).GetReason());
91 #ifdef POWER_WAKEUPDOUBLE_OR_PICKUP_ENABLE
92 SetOriginSettingValue((*source));
93 #endif
94 std::shared_ptr<WakeupMonitor> monitor = WakeupMonitor::CreateMonitor(*source);
95 if (monitor != nullptr && monitor->Init()) {
96 POWER_HILOGI(FEATURE_WAKEUP, "monitor init success, type=%{public}u", (*source).GetReason());
97 monitor->RegisterListener([this](WakeupDeviceType reason) { this->ControlListener(reason); });
98 monitorMap_.emplace(monitor->GetReason(), monitor);
99 }
100 }
101 RegisterSettingsObserver();
102 }
103
Cancel()104 void WakeupController::Cancel()
105 {
106 for (auto monitor = monitorMap_.begin(); monitor != monitorMap_.end(); monitor++) {
107 monitor->second->Cancel();
108 }
109 monitorMap_.clear();
110 }
111
RegisterSettingsObserver()112 void WakeupController::RegisterSettingsObserver()
113 {
114 if (g_wakeupSourcesKeyObserver) {
115 POWER_HILOGE(FEATURE_POWER_STATE, "wakeup sources key observer is already registered");
116 return;
117 }
118 SettingObserver::UpdateFunc updateFunc = [&](const std::string&) {
119 std::lock_guard lock(monitorMutex_);
120 POWER_HILOGI(COMP_SVC, "start setting string update");
121 std::string jsonStr = SettingHelper::GetSettingWakeupSources();
122 std::shared_ptr<WakeupSources> sources = WakeupSourceParser::ParseSources(jsonStr);
123 std::vector<WakeupSource> updateSourceList = sources->GetSourceList();
124 if (updateSourceList.size() == 0) {
125 return;
126 }
127 sourceList_ = updateSourceList;
128 POWER_HILOGI(COMP_SVC, "start updateListener");
129 Cancel();
130 uint32_t id = 0;
131 for (auto source = sourceList_.begin(); source != sourceList_.end(); source++, id++) {
132 std::shared_ptr<WakeupMonitor> monitor = WakeupMonitor::CreateMonitor(*source);
133 POWER_HILOGI(FEATURE_WAKEUP, "UpdateFunc CreateMonitor[%{public}u] reason=%{public}d",
134 id, source->GetReason());
135 if (monitor != nullptr && monitor->Init()) {
136 monitor->RegisterListener([this](WakeupDeviceType reason) { this->ControlListener(reason); });
137 monitorMap_.emplace(monitor->GetReason(), monitor);
138 }
139 }
140 };
141 g_wakeupSourcesKeyObserver = SettingHelper::RegisterSettingWakeupSourcesObserver(updateFunc);
142 POWER_HILOGI(FEATURE_POWER_STATE, "register setting observer fin");
143 }
144
UnregisterSettingsObserver()145 void WakeupController::UnregisterSettingsObserver()
146 {
147 if (g_wakeupSourcesKeyObserver) {
148 SettingHelper::UnregisterSettingObserver(g_wakeupSourcesKeyObserver);
149 g_wakeupSourcesKeyObserver = nullptr;
150 }
151 }
152
153 #ifdef POWER_WAKEUPDOUBLE_OR_PICKUP_ENABLE
SetOriginSettingValue(WakeupSource & source)154 void WakeupController::SetOriginSettingValue(WakeupSource& source)
155 {
156 if (source.GetReason() == WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK) {
157 if (SettingHelper::IsWakeupDoubleSettingValid() == false) {
158 POWER_HILOGI(COMP_SVC, "the origin doubleClick_enable is: %{public}d", source.IsEnable());
159 SettingHelper::SetSettingWakeupDouble(source.IsEnable());
160 SetWakeupDoubleClickSensor(source.IsEnable());
161 return;
162 }
163
164 auto enable = SettingHelper::GetSettingWakeupDouble();
165 SetWakeupDoubleClickSensor(enable);
166 } else if (source.GetReason() == WakeupDeviceType::WAKEUP_DEVICE_PICKUP) {
167 if (!SettingHelper::IsWakeupPickupSettingValid()) {
168 POWER_HILOGI(FEATURE_WAKEUP, "GetReason_WAKEUP_DEVICE_PICKUP,source enable=%{public}d", source.IsEnable());
169 SettingHelper::SetSettingWakeupPickup(source.IsEnable());
170 PickupConnectMotionConfig(source.IsEnable());
171 return;
172 }
173
174 auto enable = SettingHelper::GetSettingWakeupPickup();
175 PickupConnectMotionConfig(enable);
176 }
177 }
178
ChangeWakeupSourceConfig(bool updateEnable)179 void WakeupController::ChangeWakeupSourceConfig(bool updateEnable)
180 {
181 std::lock_guard lock(sourceUpdateMutex_);
182 std::string jsonStr = SettingHelper::GetSettingWakeupSources();
183 if (jsonStr.empty()) {
184 POWER_HILOGE(COMP_SVC, "there is no such configuration file available");
185 return;
186 }
187 POWER_HILOGI(COMP_SVC, "the origin ccmJson is: %{public}s", jsonStr.c_str());
188 Json::Value root;
189 Json::Reader reader;
190 if (!reader.parse(jsonStr.data(), jsonStr.data() + jsonStr.size(), root)) {
191 POWER_HILOGE(COMP_SVC, "json parse error");
192 return;
193 }
194 if (root["touchscreen"].isNull()) {
195 POWER_HILOGE(COMP_SVC, "this touchscreenNode is empty");
196 return;
197 }
198 if (root["touchscreen"]["enable"].isNull()) {
199 POWER_HILOGE(COMP_SVC, "the touchscreenNode is empty");
200 return;
201 }
202 if (!root["touchscreen"]["enable"].isBool()) {
203 POWER_HILOGE(COMP_SVC, "the origin touchscreenEnable value is invalid");
204 return;
205 }
206 bool originEnable = root["touchscreen"]["enable"].asBool();
207 if (originEnable == updateEnable) {
208 POWER_HILOGI(COMP_SVC, "no need change jsonConfig value");
209 return;
210 }
211
212 root["touchscreen"]["enable"] = updateEnable;
213 POWER_HILOGI(COMP_SVC, "the new doubleJsonConfig is: %{public}s", root.toStyledString().c_str());
214 SettingHelper::SetSettingWakeupSources(root.toStyledString());
215 }
216
217 static const char* SET_WAKEUP_DOUBLE_CLICK_SENSOR = "SetWakeupDoubleClickSensor";
218 static const char* POWER_DOUBLE_CLICK_PATH = "/system/lib64/libpower_manager_ext.z.so";
219 typedef int32_t(*Func)(bool);
SetWakeupDoubleClickSensor(bool enable)220 int32_t WakeupController::SetWakeupDoubleClickSensor(bool enable)
221 {
222 POWER_HILOGI(COMP_SVC, "enter SetWakeupDoubleClickSensor");
223 void *handler = dlopen(POWER_DOUBLE_CLICK_PATH, RTLD_LAZY | RTLD_NODELETE);
224 if (handler == nullptr) {
225 POWER_HILOGE(FEATURE_SHUTDOWN, "Dlopen failed, reason : %{public}s", dlerror());
226 return ERR_FAILED;
227 }
228
229 Func PowerDoubleClickFlag = (Func)dlsym(handler, SET_WAKEUP_DOUBLE_CLICK_SENSOR);
230 if (PowerDoubleClickFlag == nullptr) {
231 POWER_HILOGE(FEATURE_SHUTDOWN, "find function failed, reason : %{public}s", dlerror());
232 dlclose(handler);
233 return ERR_FAILED;
234 }
235 auto resCode = PowerDoubleClickFlag(enable);
236 dlclose(handler);
237 return resCode;
238 }
239
240 static const char* SET_WAKEUP_MOTION_SUBSCRIBER_CONFIG = "PickupMotionSubscriber";
241 static const char* SET_WAKEUP_MOTION_UNSUBSCRIBER_CONFIG = "PickupMotionUnsubscriber";
242 static const char* POWER_MANAGER_EXT_PATH = "/system/lib64/libpower_manager_ext.z.so";
243 typedef void(*FuncSubscriber)();
244 typedef void(*FuncUnsubscriber)();
245
PickupConnectMotionConfig(bool databaseSwitchValue)246 void WakeupController::PickupConnectMotionConfig(bool databaseSwitchValue)
247 {
248 POWER_HILOGI(COMP_SVC, "open enter PickupConnectMotionConfig");
249 if (databaseSwitchValue) {
250 void *subscriberHandler = dlopen(POWER_MANAGER_EXT_PATH, RTLD_LAZY | RTLD_NODELETE);
251 if (subscriberHandler == nullptr) {
252 POWER_HILOGE(COMP_SVC, "Dlopen failed, reason : %{public}s", dlerror());
253 return;
254 }
255 FuncSubscriber powerPickupMotionSubscriberFlag = reinterpret_cast<FuncSubscriber>(dlsym(subscriberHandler,
256 SET_WAKEUP_MOTION_SUBSCRIBER_CONFIG));
257 if (powerPickupMotionSubscriberFlag == nullptr) {
258 POWER_HILOGE(COMP_SVC, "find Subscriber function failed, reason : %{public}s", dlerror());
259 dlclose(subscriberHandler);
260 return;
261 }
262 powerPickupMotionSubscriberFlag();
263 POWER_HILOGI(COMP_SVC, "powerservice enable powerPickupMotionSubscriberFlag isSettingEnable=%{public}d",
264 databaseSwitchValue);
265 dlclose(subscriberHandler);
266 POWER_HILOGI(COMP_SVC, "open to close PickupMotionSubscriberConfig");
267 } else {
268 void *unsubscriberHandler = dlopen(POWER_MANAGER_EXT_PATH, RTLD_LAZY | RTLD_NODELETE);
269 if (unsubscriberHandler == nullptr) {
270 POWER_HILOGE(COMP_SVC, "Dlopen failed, reason : %{public}s", dlerror());
271 return;
272 }
273 FuncUnsubscriber powerPickupMotionUnsubscriberFlag = reinterpret_cast<FuncUnsubscriber>(dlsym(
274 unsubscriberHandler, SET_WAKEUP_MOTION_UNSUBSCRIBER_CONFIG));
275 if (powerPickupMotionUnsubscriberFlag == nullptr) {
276 POWER_HILOGE(COMP_SVC, "find Unsubscriber function failed, reason : %{public}s", dlerror());
277 dlclose(unsubscriberHandler);
278 return;
279 }
280 powerPickupMotionUnsubscriberFlag();
281 POWER_HILOGI(COMP_SVC, "powerservice disable powerPickupMotionUnsubscriberFlag isSettingEnable=%{public}d",
282 databaseSwitchValue);
283 dlclose(unsubscriberHandler);
284 POWER_HILOGI(COMP_SVC, "open to close PickupMotionSubscriberConfig");
285 }
286 }
287
ChangePickupWakeupSourceConfig(bool updataEnable)288 void WakeupController::ChangePickupWakeupSourceConfig(bool updataEnable)
289 {
290 std::lock_guard lock(sourceUpdateMutex_);
291 std::string jsonStr = SettingHelper::GetSettingWakeupSources();
292 if (jsonStr.empty()) {
293 POWER_HILOGE(COMP_SVC, "there is no such configuration file available");
294 return;
295 }
296 POWER_HILOGI(COMP_SVC, "%{public}s(%{public}d)", __func__, updataEnable);
297 Json::Value root;
298 Json::Reader reader;
299 reader.parse(jsonStr, root);
300 if (!reader.parse(jsonStr, root)) {
301 POWER_HILOGE(COMP_SVC, "Failed to parse json string");
302 return;
303 }
304 if (root["pickup"].isNull()) {
305 POWER_HILOGE(COMP_SVC, "this pickNode is empty");
306 return;
307 }
308 if (root["pickup"]["enable"].isNull()) {
309 POWER_HILOGE(COMP_SVC, "the pickupNode is empty");
310 return;
311 }
312 if (!root["pickup"]["enable"].isBool()) {
313 POWER_HILOGE(COMP_SVC, "the origin pickupEnable value is invalid");
314 return;
315 }
316 bool originEnable = root["pickup"]["enable"].asBool();
317 if (originEnable == updataEnable) {
318 POWER_HILOGI(COMP_SVC, "no need change jsonconfig_value");
319 return;
320 }
321 root["pickup"]["enable"] = updataEnable;
322 POWER_HILOGI(COMP_SVC, "the new pickupJsonConfig is: %{public}s", root.toStyledString().c_str());
323 SettingHelper::SetSettingWakeupSources(root.toStyledString());
324 }
325 #endif
326
ChangeLidWakeupSourceConfig(bool updataEnable)327 void WakeupController::ChangeLidWakeupSourceConfig(bool updataEnable)
328 {
329 std::lock_guard lock(sourceUpdateMutex_);
330 std::string jsonStr = SettingHelper::GetSettingWakeupSources();
331 POWER_HILOGI(FEATURE_POWER_STATE, "%{public}s", jsonStr.c_str());
332 Json::Value root;
333 Json::Reader reader;
334 reader.parse(jsonStr, root);
335 if (!reader.parse(jsonStr, root)) {
336 POWER_HILOGE(FEATURE_POWER_STATE, "Failed to parse json string");
337 return;
338 }
339 bool originEnable = true;
340 if (root["lid"]["enable"].isBool()) {
341 originEnable = root["lid"]["enable"].asBool();
342 }
343
344 if (originEnable == updataEnable) {
345 POWER_HILOGI(FEATURE_POWER_STATE, "no need change jsonConfig value");
346 return;
347 }
348 if (root["lid"]["enable"].isBool()) {
349 root["lid"]["enable"] = updataEnable;
350 }
351 SettingHelper::SetSettingWakeupSources(root.toStyledString());
352 }
353
354
ExecWakeupMonitorByReason(WakeupDeviceType reason)355 void WakeupController::ExecWakeupMonitorByReason(WakeupDeviceType reason)
356 {
357 FFRTUtils::SubmitTask([this, reason] {
358 std::lock_guard lock(monitorMutex_);
359 if (monitorMap_.find(reason) != monitorMap_.end()) {
360 auto monitor = monitorMap_[reason];
361 monitor->Notify();
362 }
363 });
364 }
365
Wakeup()366 void WakeupController::Wakeup()
367 {
368 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
369 if (pms == nullptr) {
370 POWER_HILOGE(FEATURE_WAKEUP, "get powerMgrService instance error");
371 return;
372 }
373 auto suspendController = pms->GetSuspendController();
374 if (suspendController == nullptr) {
375 POWER_HILOGE(FEATURE_WAKEUP, "get suspendController instance error");
376 return;
377 }
378 suspendController->StopSleep();
379 }
380
SleepGuard(const sptr<PowerMgrService> & pms)381 WakeupController::SleepGuard::SleepGuard(const sptr<PowerMgrService>& pms) : pms_(pms)
382 {
383 token_ = new (std::nothrow) RunningLockTokenStub();
384 if (token_ == nullptr) {
385 POWER_HILOGE(COMP_SVC, "create runninglock token failed");
386 return;
387 }
388 RunningLockInfo info = {"SleepGuard", OHOS::PowerMgr::RunningLockType::RUNNINGLOCK_BACKGROUND_TASK};
389 pms_->CreateRunningLock(token_, info);
390 pms_->Lock(token_, WAKEUP_LOCK_TIMEOUT_MS);
391 }
392
~SleepGuard()393 WakeupController::SleepGuard::~SleepGuard()
394 {
395 if (token_ == nullptr) {
396 POWER_HILOGE(COMP_SVC, "dtor: token_ is nullptr, direct return ");
397 return;
398 }
399 pms_->ReleaseRunningLock(token_);
400 }
401
402 #ifdef POWER_MANAGER_WAKEUP_ACTION
IsLowCapacityWakeup(WakeupDeviceType reason)403 bool WakeupController::IsLowCapacityWakeup(WakeupDeviceType reason)
404 {
405 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
406 if (pms == nullptr) {
407 POWER_HILOGE(FEATURE_WAKEUP, "[UL_POWER] pms is nullptr");
408 return false;
409 }
410 auto wakeupActionController = pms->GetWakeupActionController();
411 if (wakeupActionController == nullptr) {
412 POWER_HILOGE(FEATURE_WAKEUP, "[UL_POWER] wakeupActionController is nullptr.");
413 return false;
414 }
415 return (reason == WakeupDeviceType::WAKEUP_DEVICE_POWER_BUTTON) &&
416 (wakeupActionController->IsLowCapacityWakeup());
417 }
418
ProcessLowCapacityWakeup()419 void WakeupController::ProcessLowCapacityWakeup()
420 {
421 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] processing low capacity wake up begins.");
422 if (stateMachine_->GetState() != PowerState::SLEEP) {
423 POWER_HILOGE(FEATURE_WAKEUP, "[UL_POWER] the current power state is not sleep.");
424 return;
425 }
426 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
427 if (pms == nullptr) {
428 POWER_HILOGE(FEATURE_WAKEUP, "[UL_POWER] pms is nullptr");
429 return;
430 }
431 auto wakeupActionController = pms->GetWakeupActionController();
432 if (wakeupActionController == nullptr) {
433 POWER_HILOGE(FEATURE_WAKEUP, "[UL_POWER] wakeupActionController is nullptr");
434 return;
435 }
436 SleepGuard sleepGuard(pms);
437 Wakeup();
438 auto suspendController = pms->GetSuspendController();
439 if (suspendController != nullptr) {
440 POWER_HILOGI(FEATURE_WAKEUP, "ControlListener TriggerSyncSleepCallback start.");
441 suspendController->TriggerSyncSleepCallback(true);
442 }
443 wakeupActionController->ExecuteByGetReason();
444 }
445 #endif
446
ControlListener(WakeupDeviceType reason)447 void WakeupController::ControlListener(WakeupDeviceType reason)
448 {
449 std::lock_guard lock(mutex_);
450 if (!Permission::IsSystem()) {
451 return;
452 }
453 #ifdef POWER_MANAGER_WAKEUP_ACTION
454 if (IsLowCapacityWakeup(reason)) {
455 ProcessLowCapacityWakeup();
456 return;
457 }
458 #endif
459
460 #ifdef POWER_MANAGER_POWER_ENABLE_S4
461 if (!stateMachine_->IsSwitchOpen() || stateMachine_->IsHibernating()) {
462 #else
463 if (!stateMachine_->IsSwitchOpen()) {
464 #endif
465 POWER_HILOGI(FEATURE_WAKEUP, "Switch is closed or hibernating, wakeup control listerner do nothing.");
466 return;
467 }
468 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
469 if ((pms == nullptr || pms->IsScreenOn()) && (reason != WakeupDeviceType::WAKEUP_DEVICE_SWITCH) &&
470 (reason != WakeupDeviceType::WAKEUP_DEVICE_LID)) {
471 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] The Screen is on, ignore this event: %{public}d", reason);
472 return;
473 }
474 pid_t pid = IPCSkeleton::GetCallingPid();
475 auto uid = IPCSkeleton::GetCallingUid();
476 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Try to wakeup device, pid=%{public}d, uid=%{public}d", pid, uid);
477 if (stateMachine_->GetState() != PowerState::AWAKE || reason == WakeupDeviceType::WAKEUP_DEVICE_SWITCH ||
478 reason == WakeupDeviceType::WAKEUP_DEVICE_LID) {
479 SleepGuard sleepGuard(pms);
480 Wakeup();
481 SystemSuspendController::GetInstance().Wakeup();
482 POWER_HILOGI(FEATURE_WAKEUP, "wakeup Request: %{public}d", reason);
483 if (stateMachine_->GetState() == PowerState::SLEEP && pms->GetSuspendController() != nullptr) {
484 POWER_HILOGI(FEATURE_WAKEUP, "WakeupController::ControlListener TriggerSyncSleepCallback start.");
485 pms->GetSuspendController()->TriggerSyncSleepCallback(true);
486 }
487 if (!stateMachine_->SetState(PowerState::AWAKE, stateMachine_->GetReasonByWakeType(reason), true)) {
488 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] setstate wakeup error");
489 }
490 } else {
491 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] state=%{public}u no transitor", stateMachine_->GetState());
492 }
493 }
494
495 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
496 /* InputCallback achieve */
497 bool InputCallback::IsRemoteEvent(std::shared_ptr<InputEvent> event) const
498 {
499 return event->GetDeviceId() == COLLABORATION_REMOTE_DEVICE_ID;
500 }
501
502 void InputCallback::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
503 {
504 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
505 if (pms == nullptr || keyEvent == nullptr) {
506 POWER_HILOGE(FEATURE_WAKEUP, "get powerMgrService instance error");
507 return;
508 }
509 // ignores remote event
510 if (IsRemoteEvent(keyEvent)) {
511 return;
512 }
513 int64_t now = static_cast<int64_t>(time(nullptr));
514 pms->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false);
515
516 PowerState state = pms->GetState();
517 if (state == PowerState::AWAKE || state == PowerState::FREEZE) {
518 return;
519 }
520 std::shared_ptr<WakeupController> wakeupController = pms->GetWakeupController();
521 if (wakeupController == nullptr) {
522 POWER_HILOGE(FEATURE_WAKEUP, "wakeupController is not init");
523 return;
524 }
525
526 int32_t keyCode = keyEvent->GetKeyCode();
527 WakeupDeviceType wakeupType = WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN;
528 if (keyCode == KeyEvent::KEYCODE_F1) {
529 wakeupType = WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK;
530 } else if (keyCode == KeyEvent::KEYCODE_STYLUS_SCREEN) {
531 wakeupType = WakeupDeviceType::WAKEUP_DEVICE_PEN;
532 }
533
534 if (keyCode >= KeyEvent::KEYCODE_0 && keyCode <= KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN
535 && keyCode != KeyEvent::KEYCODE_F1) {
536 wakeupType = WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD;
537 if (wakeupController->CheckEventReciveTime(wakeupType) ||
538 keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
539 return;
540 }
541 }
542
543 POWER_HILOGD(FEATURE_WAKEUP, "[UL_POWER] KeyEvent wakeupType=%{public}u, keyCode=%{public}d", wakeupType, keyCode);
544 if (wakeupType != WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN) {
545 wakeupController->ExecWakeupMonitorByReason(wakeupType);
546 }
547 }
548
549 void InputCallback::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
550 {
551 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
552 if (pms == nullptr || pointerEvent == nullptr) {
553 return;
554 }
555 if (!NonWindowEvent(pointerEvent)) {
556 return;
557 }
558 if (IsRemoteEvent(pointerEvent)) {
559 return;
560 }
561 int64_t now = static_cast<int64_t>(time(nullptr));
562 pms->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_TOUCH, false);
563
564 PowerState state = pms->GetState();
565 if (state == PowerState::AWAKE || state == PowerState::FREEZE) {
566 return;
567 }
568 std::shared_ptr<WakeupController> wakeupController = pms->GetWakeupController();
569 WakeupDeviceType wakeupType = WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN;
570 PointerEvent::PointerItem pointerItem;
571 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
572 POWER_HILOGI(FEATURE_WAKEUP, "GetPointerItem false");
573 }
574 int32_t deviceType = pointerItem.GetToolType();
575 int32_t sourceType = pointerEvent->GetSourceType();
576 if (deviceType == PointerEvent::TOOL_TYPE_PEN) {
577 wakeupType = WakeupDeviceType::WAKEUP_DEVICE_PEN;
578 } else {
579 switch (sourceType) {
580 case PointerEvent::SOURCE_TYPE_MOUSE:
581 wakeupType = WakeupDeviceType::WAKEUP_DEVICE_MOUSE;
582 break;
583 case PointerEvent::SOURCE_TYPE_TOUCHPAD:
584 wakeupType = WakeupDeviceType::WAKEUP_DEVICE_TOUCHPAD;
585 break;
586 case PointerEvent::SOURCE_TYPE_TOUCHSCREEN:
587 wakeupType = WakeupDeviceType::WAKEUP_DEVICE_SINGLE_CLICK;
588 break;
589 default:
590 break;
591 }
592 }
593 if (wakeupController->CheckEventReciveTime(wakeupType)) {
594 return;
595 }
596
597 if (wakeupType != WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN) {
598 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] PointerEvent wakeupType=%{public}u", wakeupType);
599 wakeupController->ExecWakeupMonitorByReason(wakeupType);
600 }
601 }
602
603 bool InputCallback::NonWindowEvent(const std::shared_ptr<PointerEvent>& pointerEvent) const
604 {
605 auto action = pointerEvent->GetPointerAction();
606 if (action == PointerEvent::POINTER_ACTION_ENTER_WINDOW ||
607 action == PointerEvent::POINTER_ACTION_LEAVE_WINDOW ||
608 action == PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
609 action == PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
610 return false;
611 }
612 return true;
613 }
614
615 void InputCallback::OnInputEvent(std::shared_ptr<AxisEvent> axisEvent) const
616 {
617 POWER_HILOGD(FEATURE_WAKEUP, "AxisEvent");
618 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
619 if (pms == nullptr || axisEvent == nullptr) {
620 return;
621 }
622 int64_t now = static_cast<int64_t>(time(nullptr));
623 pms->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_ACCESSIBILITY, false);
624 }
625 #endif
626
627 bool WakeupController::CheckEventReciveTime(WakeupDeviceType wakeupType)
628 {
629 // The minimum refreshactivity interval is 100ms!!
630 std::lock_guard lock(eventHandleMutex_);
631 int64_t now = GetTickCount();
632 if (eventHandleMap_.find(wakeupType) != eventHandleMap_.end()) {
633 if ((eventHandleMap_[wakeupType] + MIN_TIME_MS_BETWEEN_MULTIMODEACTIVITIES) > now) {
634 return true;
635 }
636 eventHandleMap_[wakeupType] = now;
637 return false;
638 }
639 return false;
640 }
641
642 /* WakeupMonitor Implement */
643
644 std::shared_ptr<WakeupMonitor> WakeupMonitor::CreateMonitor(WakeupSource& source)
645 {
646 WakeupDeviceType reason = source.GetReason();
647 std::shared_ptr<WakeupMonitor> monitor = nullptr;
648 switch (reason) {
649 case WakeupDeviceType::WAKEUP_DEVICE_POWER_BUTTON:
650 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<PowerkeyWakeupMonitor>(source));
651 break;
652 case WakeupDeviceType::WAKEUP_DEVICE_MOUSE:
653 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<MousekeyWakeupMonitor>(source));
654 break;
655 case WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD:
656 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<KeyboardWakeupMonitor>(source));
657 break;
658 case WakeupDeviceType::WAKEUP_DEVICE_PEN:
659 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<PenWakeupMonitor>(source));
660 break;
661 case WakeupDeviceType::WAKEUP_DEVICE_TOUCHPAD:
662 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<TouchpadWakeupMonitor>(source));
663 break;
664 case WakeupDeviceType::WAKEUP_DEVICE_SINGLE_CLICK:
665 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<SingleClickWakeupMonitor>(source));
666 break;
667 case WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK:
668 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<DoubleClickWakeupMonitor>(source));
669 break;
670 case WakeupDeviceType::WAKEUP_DEVICE_LID:
671 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<LidWakeupMonitor>(source));
672 break;
673 case WakeupDeviceType::WAKEUP_DEVICE_SWITCH:
674 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<SwitchWakeupMonitor>(source));
675 break;
676 case WakeupDeviceType::WAKEUP_DEVICE_PICKUP:
677 monitor = std::static_pointer_cast<WakeupMonitor>(std::make_shared<PickupWakeupMonitor>(source));
678 break;
679 default:
680 POWER_HILOGE(FEATURE_WAKEUP, "CreateMonitor : Invalid reason=%{public}d", reason);
681 break;
682 }
683 return monitor;
684 }
685
686 /** PowerkeyWakeupMonitor Implement */
687 bool PowerkeyWakeupMonitor::Init()
688 {
689 if (powerkeyShortPressId_ >= 0) {
690 return true;
691 }
692 std::shared_ptr<OHOS::MMI::KeyOption> keyOption = std::make_shared<OHOS::MMI::KeyOption>();
693 std::set<int32_t> preKeys;
694 keyOption.reset();
695 keyOption = std::make_shared<OHOS::MMI::KeyOption>();
696 keyOption->SetPreKeys(preKeys);
697 keyOption->SetFinalKey(OHOS::MMI::KeyEvent::KEYCODE_POWER);
698 keyOption->SetFinalKeyDown(true);
699 keyOption->SetFinalKeyDownDuration(0);
700 powerkeyShortPressId_ = InputManager::GetInstance()->SubscribeKeyEvent(
701 keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) {
702 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Received powerkey down");
703
704 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
705 if (pms == nullptr) {
706 return;
707 }
708 pms->RefreshActivityInner(
709 static_cast<int64_t>(time(nullptr)), UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false);
710 std::shared_ptr<SuspendController> suspendController = pms->GetSuspendController();
711 bool poweroffInterrupted = false;
712 if (PowerKeySuspendMonitor::powerkeyScreenOff_.load()) {
713 auto stateMachine = pms->GetPowerStateMachine();
714 if (!stateMachine) {
715 POWER_HILOGE(FEATURE_WAKEUP, "TryToCancelScreenOff, state machine is nullptr");
716 } else {
717 poweroffInterrupted = stateMachine->TryToCancelScreenOff();
718 }
719 }
720 // sync with the end of powerkey screen off task
721 ffrt::wait({&PowerKeySuspendMonitor::powerkeyScreenOff_});
722 suspendController->RecordPowerKeyDown(poweroffInterrupted);
723 Notify();
724 });
725
726 POWER_HILOGI(FEATURE_WAKEUP, "powerkey register powerkeyShortPressId_=%{public}d", powerkeyShortPressId_);
727 return powerkeyShortPressId_ >= 0 ? true : false;
728 }
729
730 void PowerkeyWakeupMonitor::Cancel()
731 {
732 if (powerkeyShortPressId_ >= 0) {
733 POWER_HILOGI(FEATURE_WAKEUP, "UnsubscribeKeyEvent: PowerkeyWakeupMonitor");
734 InputManager::GetInstance()->UnsubscribeKeyEvent(powerkeyShortPressId_);
735 }
736 }
737
738 /** Keyboard Implement */
739
740 bool KeyboardWakeupMonitor::Init()
741 {
742 return true;
743 }
744
745 void KeyboardWakeupMonitor::Cancel() {}
746
747 /** Mouse Implement */
748
749 bool MousekeyWakeupMonitor::Init()
750 {
751 return true;
752 }
753
754 void MousekeyWakeupMonitor::Cancel() {}
755
756 /** Mouse Implement */
757
758 bool TouchpadWakeupMonitor::Init()
759 {
760 return true;
761 }
762
763 void TouchpadWakeupMonitor::Cancel() {}
764
765 /** Pen Implement */
766
767 bool PenWakeupMonitor::Init()
768 {
769 return true;
770 }
771
772 void PenWakeupMonitor::Cancel() {}
773
774 /** SingleClickWakeupMonitor Implement */
775
776 bool SingleClickWakeupMonitor::Init()
777 {
778 return true;
779 }
780
781 void SingleClickWakeupMonitor::Cancel() {}
782
783 /** DoubleClickWakeupMonitor Implement */
784
785 bool DoubleClickWakeupMonitor::Init()
786 {
787 return true;
788 }
789
790 void DoubleClickWakeupMonitor::Cancel() {}
791
792 /** SwitchWakeupMonitor Implement */
793
794 bool SwitchWakeupMonitor::Init()
795 {
796 return true;
797 }
798
799 void SwitchWakeupMonitor::Cancel() {}
800
801 /** LidWakeupMonitor Implement */
802
803 bool LidWakeupMonitor::Init()
804 {
805 return true;
806 }
807
808 void LidWakeupMonitor::Cancel() {}
809
810 /** PickupWakeupMonitor Implement */
811
812 bool PickupWakeupMonitor::Init()
813 {
814 return true;
815 }
816
817 void PickupWakeupMonitor::Cancel() {}
818 } // namespace PowerMgr
819 } // namespace OHOS
820