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