1 关键字

屏幕变暗,触摸屏幕,静置20s

2 问题描述

问题现象:在系统设置了最大亮度后,静置大概20多秒,(一般是30秒会自动息屏),在20-30秒之间触摸一下屏幕,必现亮度会变暗,而且不会自动恢复。

测试步骤:开机后设置最大亮度 --- 然后重启 --- 再开机后没有其他操作 -- 等20几秒后 -- 触摸屏幕 -- 亮度变暗

3 问题原因

3.1 正常现象

在开机静置二十多秒后触摸屏幕,更新屏幕亮度时屏幕亮度不变

3.2 异常现象

  1. 开机后静置20多秒后触摸屏幕屏幕变暗

  2. 开机后静置到屏幕熄屏后再按power键,屏幕亮度相比上一次变暗

3.3 问题原因

硬件驱动上的初始屏幕亮度值为200,驱动的亮度取值范围是0-255,系统应用的屏幕亮度值初始化为50,取值范围是0-100。

4 解决方案

  1. base\powermgr\display_manager\service\native\src\screen_controller.cpp 文件中在构造函数里加上 beforeOffBrightness_的初始化

beforeOffBrightness_ = action_->GetBrightness(devId_);
beforeOffBrightness_ = (beforeOffBrightness_ <= DISPLAY_OFF_BRIGHTNESS|| beforeOffBrightness_ > DISPLAY_FULL_BRIGHTNESS) ? DISPLAY_FULL_BRIGHTNESS : beforeOffBrightness_;
  1. device\hihope\hardware\display\src\display_device\drm_connector.cpp 文件的DrmConnector::Init 初始化函数中将 mBrightnessLevel的值设置为固定值200

5 定位过程

  1. 屏幕的点击事件在事件处理中分发到power子系统中,在base\powermgr\power_manager\services\native\src\power_mgr_service.cpp中接收 调用InputCallback::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const函数, 给HandlePointEvent传入2的类型,在HandlePointEvent走了IsScreenOn的条件,调用了RefreshActivity,传入当前时间和UserActivityType类型值2,在此函数里面通过 powerStateMachine_ 调用power的状态管理RefreshActivityInner

powerStateMachine_->RefreshActivityInner(pid, callTimeMs, type, needChangeBacklight);
  1. 屏幕状态管理文件base\powermgr\power_manager\services\native\src\power_state_machine.cpp RefreshActivityInner函数中走了IsScreenOn()的条件执行

stateAction_->RefreshActivity(callTimeMs, type, needChangeBacklight ?
                 REFRESH_ACTIVITY_NEED_CHANGE_LIGHTS : REFRESH_ACTIVITY_NO_CHANGE_LIGHTS);
mDeviceState_.screenState.lastOnTime = GetTickCount();
stateAction_->SetDisplayState(DisplayState::DISPLAY_ON, GetReasonByUserActivity(type));
  1. base\powermgr\power_manager\services\native\src\actions\default\device_state_action.cpp中调用SetDisplayState(const DisplayState state, StateChangeReason reason)函数

bool ret = DisplayPowerMgrClient::GetInstance().SetDisplayState(dispState, reason);//dispState = 2,reason = 3
  1. base\powermgr\display_manager\service\native\src\display_power_mgr_service.cpp中调用 SetDisplayState(uint32_t id, DisplayState state, uint32_t reason)

return iterater->second->UpdateState(state, reason);
  1. base\powermgr\display_manager\service\native\src\screen_controller.cpp调用UpdateState(DisplayState state, uint32_t reason)执行逻辑获取熄屏前亮度,将当前屏幕的亮度设置给屏幕亮度,由于当前状态是亮屏状态所以屏幕亮度值的缓存没有赋值,即为初始值0,所以修改时需在该文件构造函数中初始化。

case DisplayState::DISPLAY_ON: // fall through
case DisplayState::DISPLAY_OFF: {
    DISPLAY_HILOGW(MODULE_SERVICE, "power UpdateState DisplayState::DISPLAY_OFF or DisplayState::DISPLAY_ON");
    BeforeUpdateState(state);
    std::function<void(DisplayState)> callback =
    std::bind(&ScreenController::OnStateChanged, this, std::placeholders::_1);
    bool ret = action_->SetDisplayState(devId_, state, callback);
    if (!ret) {
        DISPLAY_HILOGW(MODULE_SERVICE, "power SetDisplayState failed state=%{public}d", state);
        return ret;
    }
    AfterUpdateState(state);
    break;
}
void ScreenController::BeforeUpdateState(DisplayState state)
{
    DISPLAY_HILOGI(MODULE_SERVICE, "power Screen brightness BeforeUpdateState state=%{public}d beforeOffBrightness_=%{public}d               devId_= %{public}llu",state, beforeOffBrightness_,devId_);
       
    if (state == DisplayState::DISPLAY_OFF) {  
        beforeOffBrightness_ = action_->GetBrightness(devId_);
        DISPLAY_HILOGI(MODULE_SERVICE, "power Screen brightness BeforeUpdateState beforeOffBrightness_= %{public}d", beforeOffBrightness_);
        beforeOffBrightness_ = (beforeOffBrightness_ <= DISPLAY_OFF_BRIGHTNESS || beforeOffBrightness_ > DISPLAY_FULL_BRIGHTNESS) ? DISPLAY_FULL_BRIGHTNESS : beforeOffBrightness_;
        DISPLAY_HILOGI(MODULE_SERVICE, "power Screen brightness before screen off %{public}d", beforeOffBrightness_);
    }
}
void ScreenController::AfterUpdateState(DisplayState state)
{
    if (state == DisplayState::DISPLAY_ON) {
        DISPLAY_HILOGI(MODULE_SERVICE, "power Is SetBrightness Update brightness to beforeOffBrightness_= %{public}d",                                  beforeOffBrightness_);
        bool ret = action_->SetBrightness(devId_, beforeOffBrightness_);
        DISPLAY_HILOGI(MODULE_SERVICE, "power Is SetBrightness ret= %{public}d, Update brightness to beforeOffBrightness_= %{public}d", ret, beforeOffBrightness_);
    }
}
  1. GetBrightness和SetBrightness最终获取的地方是device\hihope\hardware\display\src\display_device\drm_connector.cpp文件中 由于mBrightnessLevel在init函数中赋值为配置文件里面的亮度值与当前驱动下的亮度值不匹配,所以在init中要将mBrightnessLevel的值初始化为驱动里的屏幕亮度值。

int32_t DrmConnector::GetBrightness(uint32_t& level)
{
    DISPLAY_DEBUGLOG("power prop brightness is %{public}d, level is %{public}d", mBrightnessLevel, level);
    if (mPropBrightnessId == DRM_INVALID_ID) {
        DISPLAY_LOGE("the prop id of brightness is invalid");
        return DISPLAY_NOT_SUPPORT;
    }
    level = mBrightnessLevel;
    return DISPLAY_SUCCESS;
}
  
const int BACKLIGHT_MIN = 10;
int32_t DrmConnector::SetBrightness(uint32_t level)
{
    static int32_t brFd = 0;
    const int32_t buffer_size = 10; /* buffer size */
    char buffer[buffer_size];
  
    DISPLAY_DEBUGLOG("power DrmConnector::SetBrightness set level= %{public}d , mPropBrightnessId = %{public}u", level, mPropBrightnessId);
    if (mPropBrightnessId == DRM_INVALID_ID) {
        DISPLAY_LOGE("the prop id of brightness is invalid");
        return DISPLAY_NOT_SUPPORT;
    }
    if (brFd <= 0) {
        brFd = open("/sys/class/backlight/backlight/brightness", O_RDWR);
        if (brFd < 0) {
            DISPLAY_LOGE("oepn Brightness file failed\n");
            return DISPLAY_NOT_SUPPORT;
        }
    }
    errno_t ret = memset_s(buffer, sizeof(buffer), 0, sizeof(buffer));
    if (ret != EOK) {
        DISPLAY_LOGE("memset_s failed\n");
        return DISPLAY_FAILURE;
    }
    if (level < BACKLIGHT_MIN) {
        level = BACKLIGHT_MIN;
    }
  
    int32_t brightness = int32_t(level*2.55);
    DISPLAY_LOGE("power write brightness= %{public}d",brightness);
  
    int bytes = sprintf_s(buffer, sizeof(buffer), "%d\n", brightness);
    if (bytes < 0) {
        DISPLAY_LOGE("change failed\n");
        return DISPLAY_FAILURE;
    }
    write(brFd, buffer, bytes);
    mBrightnessLevel = level;
    DISPLAY_DEBUGLOG("power DrmConnector::SetBrightness end level= %{public}d , mPropBrightnessId = %{public}u", level, mPropBrightnessId);
    return DISPLAY_SUCCESS;
}

6 知识分享

  • 电源子系统的休眠状态管理

  • 多模输入点击事件分发至电源子系统应用

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐