遥控器任意按键均能在熄屏下唤醒屏幕分析
1 关键字 熄屏;任意按键;唤醒屏幕 2 问题描述 设备型号:XXXXXX 系统版本:OpenHarmony 3.2 Release 代码版本:XXXXXX 问题现象:在设备熄屏状态下,操作遥控器上的任意按键,屏幕都被唤醒了。 3 问题原因 3.1 正常机制 对遥控器操作,只有在按电源键才会将熄屏的设备屏幕唤醒。 3.2 异常机制 熄屏状态下,遥控器的任意按键都会将屏幕唤醒点亮。 4 解决方案 在
1 关键字
熄屏;任意按键;唤醒屏幕
2 问题描述
设备型号:XXXXXX
系统版本:OpenHarmony 3.2 Release
代码版本:XXXXXX
问题现象:在设备熄屏状态下,操作遥控器上的任意按键,屏幕都被唤醒了。
3 问题原因
3.1 正常机制
对遥控器操作,只有在按电源键才会将熄屏的设备屏幕唤醒。
3.2 异常机制
熄屏状态下,遥控器的任意按键都会将屏幕唤醒点亮。
4 解决方案
在key事件处理将唤醒屏幕的动作进行分类处理,只对遥控器电源按键进行屏幕唤醒,对遥控器其他按键不进行唤醒处理;同时对任意触屏操作也按照遥控器key按键流程处理。
4.1 保留原有电源按键接口HandlePowerKeyUp处理
void PowerMgrService::HandlePowerKeyUp() { POWER_HILOGI(FEATURE_INPUT, "Receive release powerkey"); if (isDialogstatus_ || this->shutdownService_.IsShuttingDown()) { POWER_HILOGW(FEATURE_INPUT, "System is shutting down"); isDialogstatus_ = false; return; } int64_t now = static_cast<int64_t>(time(0)); if (this->IsScreenOn()) { this->SuspendDevice(now, SuspendDeviceType::SUSPEND_DEVICE_REASON_POWER_BUTTON, false); } else { this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_POWER_BUTTON, REASON_POWER_KEY); } }
4.2 处理对除电源按键的其他按键接口HandleKeyEvent事件,使其在屏幕息屏下不会被唤醒
void PowerMgrService::HandleKeyEvent(int32_t keyCode) { POWER_HILOGD(FEATURE_INPUT, "keyCode: %{public}d", keyCode); int64_t now = static_cast<int64_t>(time(0)); if (IsScreenOn()) { this->RefreshActivity(now, UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false); } }
4.3 对触屏事件处理,使其在屏幕息屏下不会被唤醒
void PowerMgrService::HandlePointEvent(int32_t type) { POWER_HILOGD(FEATURE_INPUT, "type: %{public}d", type); int64_t now = static_cast<int64_t>(time(0)); if (this->IsScreenOn()) { this->RefreshActivity(now, UserActivityType::USER_ACTIVITY_TYPE_ATTENTION, false); } }
5 定位过程
5.1 不管是触摸,键盘,还是遥控器,在事件响应类型都会在初始化中进行分类,那么先找到key事件的分类,可以看出在KeyMonitorInit 方法中,对不同类型的事件进行了不同的处理
void PowerMgrService::KeyMonitorInit() { ............ ............ powerkeyLongPressId_ = InputManager::GetInstance()->SubscribeKeyEvent(keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) { POWER_HILOGI(FEATURE_INPUT, "Receive long press powerkey"); handler_->SendEvent(PowermsEventHandler::SHUTDOWN_REQUEST_MSG); }); if (powerkeyLongPressId_ >= 0) { ............ ............ if (!IsScreenOn()) { handler_->SendEvent(PowermsEventHandler::SCREEN_ON_TIMEOUT_MSG, 0, POWER_KEY_PRESS_DELAY_MS); } }); ............. ............. powerkeyReleaseId_ = InputManager::GetInstance()->SubscribeKeyEvent(keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) { powerkeyPressed_ = false; this->HandlePowerKeyUp(); }); ............. ............. doubleClickId_ = InputManager::GetInstance()->SubscribeKeyEvent(keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) { ............. this->HandleKeyEvent(keyEvent->GetKeyCode()); }); } else if (powerkeyLongPressId_ != ERROR_UNSUPPORT) { ............. handler_->SendEvent(PowermsEventHandler::INIT_KEY_MONITOR_MSG, 0, INIT_KEY_MONITOR_DELAY_MS); return; } ............ ............ }
5.2 通过HandlePowerKeyUp方法查看除了电源按键是否还有其他流程处理
void PowerMgrService::HandlePowerKeyUp() { ............ ............ int64_t now = static_cast<int64_t>(time(0)); if (this->IsScreenOn()) { this->SuspendDevice(now, SuspendDeviceType::SUSPEND_DEVICE_REASON_POWER_BUTTON, false); } else { this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_POWER_BUTTON, REASON_POWER_KEY); } }
5.3 继续对HandleKeyEvent事件进行分析,可以看出任意键屏幕唤醒的原因了
void PowerMgrService::HandleKeyEvent(int32_t keyCode) { ............ ............ else { if (keyCode == KeyEvent::KEYCODE_F1) { POWER_HILOGI(FEATURE_WAKEUP, "Wakeup by double click"); std::string reason = "double click"; reason.append(std::to_string(keyCode)); this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK, reason); } else if (keyCode >= KeyEvent::KEYCODE_0 && keyCode <= KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN) { POWER_HILOGI(FEATURE_WAKEUP, "Wakeup by keyboard"); std::string reason = "keyboard:"; reason.append(std::to_string(keyCode)); this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD, reason); } } } 在上面处理中,可以看出对按键KEYCODE_F1以及keyCode在KEYCODE_0和KEYCODE_NUMPAD_RIGHT_PAREN之间的事件都进行了屏幕唤醒,那么我们在处理时不需要进行唤醒即可。
5.4 继续对HandlePointEvent事件进行分析,采用了与HandleKeyEvent类似的处理方式
void PowerMgrService::HandlePointEvent(int32_t type) { ............ ............ else { if (type == PointerEvent::SOURCE_TYPE_MOUSE) { std::string reason = "mouse click"; POWER_HILOGI(FEATURE_WAKEUP, "Wakeup by mouse"); this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_MOUSE, reason); } } } 同上面一样的操作,不需要唤醒屏幕
5.5 那么问题来了,为何原有处理方式会特意对其他按键进行设备唤醒:原来通用的处理方式是需要任意键唤醒的,如我们的电脑在息屏下按任意键。那么针对不同的产品,使用场景要求不一样,就需要进行不同的处理。
6 知识分享
针对不同类型的多模输入设备,其实在底层都是通过key事件进行统一响应,只是针对不同的方式有不同的处理任务,同时可通过上面的按键设置对不同的按键code有更好的了解。
更多推荐
所有评论(0)