android Phone 距离感应器锁的实现
2012-12-30 14:17 Kevin-wang 阅读(746) 评论(0) 编辑 收藏 举报android手机在正常打电话的过程中,靠近面部会灭屏,这个主要是PhoneApp中的mProximityWakeLock的作用。这个锁是在PhoneApp中被初始化的。
1: if ((pm.getSupportedWakeLockFlags()
2: & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) != 0x0) {
3: mProximityWakeLock =
4: pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
5: }
初始化这个锁之后,就有acquire与release这把锁来亮灭屏了,主要是函数updateProximitySensorMode(Phone.State state) 发挥的作用,这个函数在电话状态发生改变的时候会调用(还有类似手机插拔,手机方向改变等等)。那我们来看下这个函数主要做了什么。
此函数在源码中的解释已经很清楚了,在此不做赘述,这个函数主要是acquire与release mProximityWakeLock这把锁。那么,我们来看下,申请这把锁的时候,究竟干了什么事情。PhoneApp里的mProximityWakeLock.acquire() 调用PowerManager里的acquire(),然后调用PowerManagerService里的acquireWakeLock(),接着调用acquireWakeLockLocked()。这个函数就是我们最终申请锁的地方。
我们看下比较重要的地方
1: if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {
2: mProximityWakeLockCount++;
3: if (mProximityWakeLockCount == 1) {
4: enableProximityLockLocked();
5: }
6: }
这个地方就是判断,如果我们申请的是PROXIMITY_SCREEN_OFF_WAKE_LOCK,那么就enableProximityLockLocked();mProximityWakeLockCount说明的是PROXIMITY_SCREEN_OFF_WAKE_LOCK是采用计数方式的锁。
继续看enableProximityLockLocked()做了什么
1: private void enableProximityLockLocked() {
2: if (mDebugProximitySensor) {
3: Slog.d(TAG, "enableProximityLockLocked");
4: }
5: if (!mProximitySensorEnabled) {
6: // clear calling identity so sensor manager battery stats are accurate
7: long identity = Binder.clearCallingIdentity();
8: try {
9: mSensorManager.registerListener(mProximityListener, mProximitySensor,
10: SensorManager.SENSOR_DELAY_NORMAL);
11: mProximitySensorEnabled = true;
12: } finally {
13: Binder.restoreCallingIdentity(identity);
14: }
15: }
16: }
1: SensorEventListener mProximityListener = new SensorEventListener() {
2: public void onSensorChanged(SensorEvent event) {
3: long milliseconds = SystemClock.elapsedRealtime();
4: synchronized (mLocks) {
5: float distance = event.values[0];
6: long timeSinceLastEvent = milliseconds - mLastProximityEventTime;
7: mLastProximityEventTime = milliseconds;
8: mHandler.removeCallbacks(mProximityTask);
9: boolean proximityTaskQueued = false;
10:
11: // compare against getMaximumRange to support sensors that only return 0 or 1
12: boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
13: distance < mProximitySensor.getMaximumRange());
14:
15: if (mDebugProximitySensor) {
16: Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
17: }
18: if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
19: // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
20: mProximityPendingValue = (active ? 1 : 0);
21: mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
22: proximityTaskQueued = true;
23: } else {
24: // process the value immediately
25: mProximityPendingValue = -1;
26: proximityChangedLocked(active);
27: }
28:
29: // update mProximityPartialLock state
30: boolean held = mProximityPartialLock.isHeld();
31: if (!held && proximityTaskQueued) {
32: // hold wakelock until mProximityTask runs
33: mProximityPartialLock.acquire();
34: } else if (held && !proximityTaskQueued) {
35: mProximityPartialLock.release();
36: }
37: }
38: }