您的位置:首页 > 移动开发 > Android开发

android Phone 距离感应器锁的实现

2013-12-09 11:08 253 查看
android手机在正常打电话的过程中,靠近面部会灭屏,这个主要是PhoneApp中的mProximityWakeLock的作用。这个锁是在PhoneApp中被初始化的。

[java]
view plaincopy

if ((pm.getSupportedWakeLockFlags()
& PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) != 0x0) {
mProximityWakeLock =
pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
}

初始化这个锁之后,就有acquire与release这把锁来亮灭屏了,主要是函数updateProximitySensorMode(Phone.State state) 发挥的作用,这个函数在电话状态发生改变的时候会调用(还有类似手机插拔,手机方向改变等等)。那我们来看下这个函数主要做了什么。

此函数在源码中的解释已经很清楚了,在此不做赘述,这个函数主要是acquire与release mProximityWakeLock这把锁。那么,我们来看下,申请这把锁的时候,究竟干了什么事情。PhoneApp里的mProximityWakeLock.acquire() 调用PowerManager里的acquire(),然后调用PowerManagerService里的acquireWakeLock(),接着调用acquireWakeLockLocked()。这个函数就是我们最终申请锁的地方。

我们看下比较重要的地方

[java]
view plaincopy

if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
mProximityWakeLockCount++;
if (mProximityWakeLockCount == 1) {
enableProximityLockLocked();
}
}

这个地方就是判断,如果我们申请的是PROXIMITY_SCREEN_OFF_WAKE_LOCK,那么就enableProximityLockLocked();mProximityWakeLockCount说明的是PROXIMITY_SCREEN_OFF_WAKE_LOCK是采用计数方式的锁。

继续看enableProximityLockLocked()做了什么

[java]
view plaincopy

private void enableProximityLockLocked() {
if (mDebugProximitySensor) {
Slog.d(TAG, "enableProximityLockLocked");
}
if (!mProximitySensorEnabled) {
// clear calling identity so sensor manager battery stats are accurate
long identity = Binder.clearCallingIdentity();
try {
mSensorManager.registerListener(mProximityListener, mProximitySensor,
SensorManager.SENSOR_DELAY_NORMAL);
mProximitySensorEnabled = true;
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}

原来,这个函数主要是注册了mProximityListener,也就是说,我们监听距离感应器的操作是在加锁之后发生的。灭屏是在距离感应器监听到数值才激发的,那么我们看下mProximityListener。

[java]
view plaincopy

SensorEventListener mProximityListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
long milliseconds = SystemClock.elapsedRealtime();
synchronized (mLocks) {
float distance = event.values[0];
long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
mLastProximityEventTime = milliseconds;
mHandler.removeCallbacks(mProximityTask);
boolean proximityTaskQueued = false;

// compare against getMaximumRange to support sensors that only return 0 or 1
boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
distance < mProximitySensor.getMaximumRange());

if (mDebugProximitySensor) {
Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
}
if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
// enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
mProximityPendingValue = (active ? 1 : 0);
mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
proximityTaskQueued = true;
} else {
// process the value immediately
mProximityPendingValue = -1;
proximityChangedLocked(active);
}

// update mProximityPartialLock state
boolean held = mProximityPartialLock.isHeld();
if (!held && proximityTaskQueued) {
// hold wakelock until mProximityTask runs
mProximityPartialLock.acquire();
} else if (held && !proximityTaskQueued) {
mProximityPartialLock.release();
}
}
}

复写了onSensorChanged()函数,当检测到actiove的时候,执行了proximityChangedLocked并申请了一个mProximityPartialLock。(if else里的代码都会执行proximityChangedLocked)。proximityChangedLocked()函数会在active的时候执行goToSleepLocked。

至此,加锁过程分析完毕,解锁过程与加锁过程分析方法一样,不再赘述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: