概述
P-Sensor亮屏和按Power键亮屏流程还是有些不同之处,如开始调用位置、PowerManagerService中的流程等,由于在平常遇到过许多PSensor亮屏相关Bug,因此这里独立地进行下分析。
流程
在DisplayPowerController中,实例化了一个SensorEventListener
对PSensor事件进行监听:
private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (mProximitySensorEnabled) {
//获取当前系统时间
final long time = SystemClock.uptimeMillis();
//获取distance值,表示距离
final float distance = event.values[0];
//如果distance>=0.0f
boolean positive = distance >= 0.0f && distance < mProximityThreshold;
//处理PSensor上报事件
handleProximitySensorEvent(time, positive);
}
}
SensorEventListener是一个用于接收Sensor新数据的接口,只有两个方法:
onSensorChanged(SensorEvent event)
:当有新Sensor事件时进行回调;onAccuracyChanged(Sensor, int accuracy)
:Sensor注册的精度值发生改变时调用;
在DisplayPowerController中,重写了onSensorChanged()
方法,因此,在接收到PSensor新事件时,会回调该方法。在这个方法中可以看到,只有mProximitySensorEnabled这个全局变量为true时,才会进入该方法体,这个值表示PSensor是否可用,由屏幕状态和PMS中的请求参数useProximitySensor共同决定,只有满足useProximitySensor=true && state!=Display.STATE_OFF
时,该值才会为true,而useProximitySensor=true的条件是当前系统持有PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK
类型的锁。
现在进入方法体中,它记录了当前系统时间,并根据SensorEvent判断是否是靠近还是远离后,将time和distance作为参数传给了handleProximitySensorEvent()
方法,该方法如下:
private void handleProximitySensorEvent(long time, boolean positive) {
//PSensor是否可用,由setProximitySensorEnabled()方法根据PMS中请求的参数
//useProximitySensor和STATE_OFF决定
if (mProximitySensorEnabled) {
//mPendingProximity表示"将要进行的PSensor状态",初始值为
// PROXIMITY_UNKNOWN,PROXIMITY_NEGATIVE&&positive=false都表示远离,
// 所以没有值变化,直接返回,下同
if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
return; // no change
}
if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
return; // no change
}
//取消延迟处理Psensor事件的Handler
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
//如果是靠近
if (positive) {
//设置mPendingProximity 值,PROXIMITY_POSITIVE表示靠近设备
mPendingProximity = PROXIMITY_POSITIVE;
//设置PSensor去抖动时间(或转换延迟时间),会申请一个Display锁
// 靠近时立即灭屏
setPendingProximityDebounceTime(
time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY);
} else {
mPendingProximity = PROXIMITY_NEGATIVE;
//设置去抖动时间,远离时会稍等会再亮屏
setPendingProximityDebounceTime(
time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY);
}
// Debounce the new sensor reading.
//读取新Psensor数据
debounceProximitySensor();
}
}
在这个方法中,如果PSensor数据没有改变,则直接返回。如果上报值发生了改变,则首先设置mPendingProximity,表示“将要、打算进行的PSensor事件”,如果是靠近则设置该变量值为PROXIMITY_POSITIVE
,远离则设置该变量值为PROXIMITY_NEGATIVE
,同时调用setPendingProximityDebounceTime()
方法,该方法用来设置PSensor的转换延迟时间,并会通过DisplayPowerCallback向PMS中申请一个Display锁,如果是靠近,延迟时间为0,也即不会进行延迟;如果是远离,默认延迟时间为250。该方法如下:
private void setPendingProximityDebounceTime(long debounceTime) {
if (mPendingProximityDebounceTime < 0) {
//申请一个PowerManagerService.Display的SuspendBlocker锁
mCallbacks.acquireSuspendBlocker(); // acquire wake lock
}
//PSensor转换延迟时间
mPendingProximityDebounceTime = debounceTime;
}
当设置完毕mPendingProximity和mPendingProximityDebounceTime后,会调用debounceProximitySensor()
方法,读取新的PSensor数据,该方法如下: