P-sensor (Proximity Sensor) 手机接听电话时,贴近屏幕时,屏幕会灭屏,以防止脸部触碰屏幕引起误操作。当我们的脸离开屏幕时,屏幕会自动亮屏.   phone app(maybe incallUI) 会申请 wakeLock( PROXIMITY_SCREEN_OFF_WAKE_LOCK)       wakeLock =context.getSystemService(PowerManager.class)
                .newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);     wakeLock.acquire();   //通话时候会acquire 这个wakeLock, framework会enable p-sensor
    wakeLock.release();  //通话结束时会释放这个wakeLock, framework 会 disable p-sensor
  主要code: base\services\core\java\com\android\server\display\DisplayPowerController.java base\services\core\java\com\android\server\power\PowerManagerService.java     大致的工作流程是:     acquire()                         --PowerManager.java acquireLocked() acquireWakeLock()                 --PowerManagerService.java  acquireWakeLockInternal()   updatePowerStateLocked() updateDisplayPowerStateLocked()       private boolean updateDisplayPowerStateLocked(int dirty) {         ......              //p-sensor wakeLock acquire后,useProximitySensor为true; release后useProximitySensor为false
            mDisplayPowerRequest. useProximitySensor = shouldUseProximitySensorLocked();
        ......             mDisplayReady = mDisplayManagerInternal. requestPowerState(mDisplayPowerRequest,
                    mRequestWaitForNegativeProximity);   requestPowerState()                --DisplayManagerService.java requestPowerState()                --DisplayPowerController.java sendUpdatePowerStateLocked() MSG_UPDATE_POWER_STATE handleMessage()                      updatePowerState()       private void updatePowerState() { // 更新屏幕状态         ......          // 根据当前状态enable/disable p-Sensor         // Apply the proximity sensor.
        if (mProximitySensor != null) {
            if (mPowerRequest. useProximitySensor && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true); //enable p-Sensor
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE) {                      mScreenOffBecauseOfProximity = true//p-Sensor 遮挡, 屏幕暗掉
                    sendOnProximityPositiveWithWakelock();
                }
            } else if (mWaitingForNegativeProximity
                    && mScreenOffBecauseOfProximity
                    && mProximity == PROXIMITY_POSITIVE
                    && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true); //enable on p-Sensor
            } else {
                setProximitySensorEnabled(false); // disable off p-Sensor, 屏幕亮起
                mWaitingForNegativeProximity = false;
            }
            if (mScreenOffBecauseOfProximity
                    && mProximity != PROXIMITY_POSITIVE) {
                mScreenOffBecauseOfProximity = false;  // p-Sensor 没用遮挡, 起作用
                sendOnProximityNegativeWithWakelock();
            }
        } else {
            mWaitingForNegativeProximity = false;
        }           if ( mScreenOffBecauseOfProximity) {   // p_Sensor 遮挡, screen off
            state = Display.STATE_OFF;
        }           // Use zero brightness when screen is off.
        if ( state == Display.STATE_OFF) {
            brightness = PowerManager.BRIGHTNESS_OFF;
        }           ......
            if ((state == Display.STATE_ON
                    && mSkipRampState == RAMP_STATE_SKIP_NONE
                    || state == Display.STATE_DOZE)
                    && !wasOrWillBeInVr) {
                animateScreenBrightness(brightness,
                        slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
            } else {
                animateScreenBrightness(brightness, 0);
            }   }
      private void setProximitySensorEnabled(boolean enable) {
        if (enable) {
            if (!mProximitySensorEnabled) {
                // Register the listener.
                // Proximity sensor state already cleared initially.

                mProximitySensorEnabled = true;
                mSensorManager.registerListener( mProximitySensorListener, mProximitySensor,
                        SensorManager.SENSOR_DELAY_NORMAL, mHandler);
            }
        } else {
            if (mProximitySensorEnabled) {
                 // Unregister the listener.
                // Clear the proximity sensor state for next time.

                mProximitySensorEnabled = false;
                mProximity = PROXIMITY_UNKNOWN;
                mPendingProximity = PROXIMITY_UNKNOWN;
                mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
                mSensorManager.unregisterListener(mProximitySensorListener);
                clearPendingProximityDebounceTime(); // release wake lock (must be last)
            }
        }
    }
    //监听p-Sensor, p-Sensor变化后,收到onSensorChanged,判断是否发生遮挡,     //然后调用updatePowerState()办法更新屏幕状态     private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            if (mProximitySensorEnabled) {
                final long time = SystemClock.uptimeMillis();
                final float distance = event.values[0];
                boolean positive = distance >= 0.0f && distance < mProximityThreshold;
                handleProximitySensorEvent(time, positive);
            }
        }       handleProximitySensorEvent()     debounceProximitySensor()     updatePowerState() // 更新屏幕状态       [Z20] ARIMA00015441 GST-PV<7947_Driver_pSensor>-   這題,加下面這段code 應該可以fix     PowerManagerService.java (base\services\core\java\com\android\server\power)     private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
        synchronized (mLock) {
           
            if (mProximityPositive && reason == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON) {
                Slog.d(TAG, "Proximity positive sleep and do not sleep by power button");
                return;
            }

          
            if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
                updatePowerStateLocked();
            }
        }
    } 從code分析,我覺得這個應該是android的原始行為: in call的時候,p-sensor起作用, p-sensor遮住時,只是屏幕滅掉,手機並沒有進sleep模式
這時候,按power key, 手機會進入sleep 模式, p-sensor 會被關閉
    private void updatePowerState() {
         ......
        // Apply the proximity sensor.
        if (mProximitySensor != null) {
            if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true);
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE) {
                    mScreenOffBecauseOfProximity = true;
                    sendOnProximityPositiveWithWakelock();
                }
            } else if (mWaitingForNegativeProximity
                    && mScreenOffBecauseOfProximity
                    && mProximity == PROXIMITY_POSITIVE
                    && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true);
            } else {
                setProximitySensorEnabled(false); // 按power key的時候,p-sensor 會被關閉
                mWaitingForNegativeProximity = false;
            } 應為p-sensor已經被關閉了,所以再按一次power key, 手機會亮起來             通过dumpsys display 可以查看p-sensor的状态   adb shell dumpsys display > d:\display.txt   Display Power Controller Thread State:
  mPowerRequest=policy=BRIGHT, useProximitySensor=true, screenBrightness=128, screenAutoBrightnessAdjustment=0.0, screenLowPowerBrightnessFactor=0.5, brightnessSetByUser=true, useAutoBrightness=false, blockScreenOn=false, lowPowerMode=false, boostScreenBrightness=false, dozeScreenBrightness=-1, dozeScreenState=UNKNOWN
  mWaitingForNegativeProximity=false
  mProximitySensor={Sensor name="EPL259x ALS/PS EPL259x", vendor="Eminent", version=2, type=8, maxRange=5.000305, resolution=0.0010070801, power=0.32, minDelay=0}
  mProximitySensorEnabled=true
  mProximityThreshold=5.0
  mProximity=Positive
  mPendingProximity=Positive
  mPendingProximityDebounceTime=-1 (4802060 ms ago)
  mScreenOffBecauseOfProximity=true
  mAppliedAutoBrightness=false
  mAppliedDimming=false
  mAppliedLowPower=false
  mPendingScreenOnUnblocker=null
  mPendingScreenOff=false
  mReportedToPolicy=REPORTED_TO_POLICY_SCREEN_ON
  mScreenBrightnessRampAnimator.isAnimating()=false
  mColorFadeOnAnimator.isStarted()=false
  mColorFadeOffAnimator.isStarted()=false          

更多相关文章

  1. Android控件之ImageButton
  2. android状态机机制StateMachine
  3. Android(安卓)进入后台触发的事件,一般用于APP屏幕解锁
  4. Android:Xmpp协议的简单分析
  5. android获取屏幕的尺寸,宽度和高度
  6. Android状态栏上添加按钮(程序部分)
  7. Android(安卓)OpenGL ES 开发教程(10):绘制线段Line Segment
  8. Android进阶之路 - 软键盘顶起解决方案
  9. Android之dialog实现底部出现对话框

随机推荐

  1. Android(安卓)4高级编程(第3版)
  2. Android(安卓)开发 Tip 15 -- can be rep
  3. Android实现可复用的筛选页面
  4. Android探索:全面分析Activity的生命周期&
  5. android scrollview 滑动到顶端或者指定
  6. android 与C/C++混合编程小例子讲解o
  7. Android入门学习_Android获取来电号码
  8. eclipse ADT插件安装碰到的错误
  9. Android(安卓)Bugly 热修复 快速接入
  10. Android-telephony各文件解释