Android 8.1 PowerManagerService分析(五)——灭屏流程分析

相关文章:
[Android Framework] 8.1 PowerManagerService分析(一)——PMS的启动
[Android Framework] 8.1 PowerManagerService分析(二) ——updatePowerStateLocked()方法
[Android Framework] 8.1 PowerManagerService分析(三)——WakeLock机制
[Android Framework] 8.1 PowerManagerService分析(四)——亮屏流程分析

前言

在之前的PMS文章分析中知道,PMS中定义了四种屏幕状态:

  • Awake状态:表示唤醒状态
  • Dream状态:表示处于屏保状态
  • Doze状态:表示处于Doze状态
  • Asleep状态:表示处于休眠状态

Power键灭屏

当power键灭屏时,会在PhoneWindowManager中处理按键事件后,调用到PMS的gotoSleep()进行灭屏处理,下面直接看看PhoneWindowManger中对Power键灭屏的处理以及和PMS的交互。

在按power后,PWS中如下:

case KeyEvent.KEYCODE_POWER: {
   
    // Any activity on the power button stops the accessibility shortcut
    cancelPendingAccessibilityShortcutAction();
    result &= ~ACTION_PASS_TO_USER;
    isWakeKey = false; // wake-up will be handled separately
    if (down) {
   //按下时
        //处理按下事件
        interceptPowerKeyDown(event, interactive);
    } else //抬起时
        //处理抬起事件
        interceptPowerKeyUp(event, interactive, canceled);
    }
    break;
}

在处理Power键抬起事件时,开始了灭屏流程:

private void powerPress(long eventTime, boolean interactive, int count) {
   
    if (mScreenOnEarly && !mScreenOnFully) {
   
        Slog.i(TAG, "Suppressed redundant power key press while "
                + "already in the process of turning the screen on.");
        return;
    }
    if (count == 2) {
   
       ......
    } else if (interactive && !mBeganFromNonInteractive) {
   
        switch (mShortPressOnPowerBehavior) {
   
            //灭屏
            case SHORT_PRESS_POWER_GO_TO_SLEEP:
                goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
                break;
            //灭屏,直接跳过Doze状态
            case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
                goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
                        PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
                break;
                } else {
   
                    shortPressPowerGoHome();
                }
                break;
            }
        }
    }
}

在这里调用了goToSleep()方法,该方法如下:

private void goToSleep(long eventTime, int reason, int flags) {
   
    mRequestedOrGoingToSleep = true;
    mPowerManager.goToSleep(eventTime, reason, flags);
}

最终,PhoneWindowManager中调用了PowerManager的goToSleep()方法来灭屏。

现在我们进入到PowerManager.goToSleep()方法:

public void goToSleep(long time, int reason, int flags) {
   
    try {
   
        mService.goToSleep(time, reason, flags);
    } catch (RemoteException e) {
   
        throw e.rethrowFromSystemServer();
    }
}

可以看到,在PowerManger中开始向下调用到了PoweManagerService(以下简称PMS)中的goToSleep()中。
我们进入PMS中,就需要详细分析其中的方法了,先来看看goToSleep()方法:

/**
 * @param eventTime 时间
 * @param reason 原因,Power键灭屏则是owerManager.GO_TO_SLEEP_REASON_POWER_BUTTON
 * @param flags 目前只有两个值:0和1(GO_TO_SLEEP_FLAG_NO_DOZE)
 */
@Override // Binder call
public void goToSleep(long eventTime, int reason, int flags) {
   
    if (eventTime > SystemClock.uptimeMillis()) {
   
        throw new IllegalArgumentException("event time must not be in the future");
    }
    //检查权限
    mContext.enforceCallingOrSelfPermission(
            android.Manifest.permission.DEVICE_POWER, null);

    final int uid = Binder.getCallingUid();
    final long ident = Binder.clearCallingIdentity();
    try {
   
        //调用gotToSleepInternal
        goToSleepInternal(eventTime, reason, flags, uid);
    } finally {
   
        Binder.restoreCallingIdentity(ident);
    }
}

这个方法的参数和PowerManager,PhoneWindowManager中的同名方法对应,需要注意的是第二个参数和第三个参数;
第二个参数:表示灭屏原因,在PowerManager中定义了一些常量值来表示;
第三个参数:是一个标识,用来表示是否直接进入灭屏,一般的灭屏流程,都会先进入Doze状态,然后才会进入Sleep状态,如果将flag设置为1,则将会直接进入Sleep状态,这部分会在下文中逐渐分析到。

在goToSleep()方法中,检查权限之后,开始调用了goToSleepInternal()方法,该方法如下:

private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
   
    synchronized (mLock) {
   
        if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
   
            updatePowerStateLocked();
        }
    }
}

这个方法逻辑很简单,首先是调用了goToSleepNoUpdateLocked()方法,并根据该方法返回值来决定是否调用updatePowerStateLocked()方法。

一般来说,goToSleepNoUpdateLocked()都会返回true,现在看看该方法:

@SuppressWarnings("deprecation")
private boolean goToSleepNoUpdateLocked(long eventTime
  • 10
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值