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>-<The screen will light when tap power key many times after cover P-sensor area in calling.>
這題,加下面這段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
 
 

android P-sensor (Proximity Sensor)相关推荐

  1. Android 8.1 DisplayPowerController(二) Proximity Sensor的亮灭屏

    概述 P-Sensor亮屏和按Power键亮屏流程还是有些不同之处,如开始调用位置.PowerManagerService中的流程等,由于在平常遇到过许多PSensor亮屏相关Bug,因此这里独立地进 ...

  2. Android Proximity Sensor近距离传感器P-Sensor

    好文章: Android 4.4中的距离/接近传感器 P-sensor(一) https://blog.csdn.net/kongjianjian1988/article/details/435248 ...

  3. 2022-04-13 Ambient Light Proximity Sensor 光感和距离传感器 STK3311X调试记录 RK3566 Android11平台

    一.原理图,接口比较简单,就是I2C.  二.光感用轮询方式,距离用中断方式.代码. 1.dts配置 ls_stk3x1x: light@48 {compatible = "ls_stk3x ...

  4. 2022-06-29 AndroidR 获取接近传感器Proximity Sensor的信号,休眠和唤醒。

    一.底层的驱动在这里不提,只关心上层. 二.实现AndroidR 获取接近传感器Proximity Sensor的信号,休眠和唤醒的方法:获取SENSOR_SERVICE服务,侦听Sensor事件. ...

  5. verp之增加接近传感器(proximity sensor)

    V-REP offers a very powerful and efficient way to simulate proximity sensors. The user can model alm ...

  6. android APK 调用G—sensor驱动的过程

    android上层应用apk到G-sensor driver的大致流程: Android HAL层,即硬件抽象层,是Google响应厂家"希望不公开源码"的要求推出的新概念 1,源 ...

  7. Android 屏幕自动旋转-Sensor属性

    在activity中加入下面加粗部分即可,<activity android:name=".demo"  android:label="@string/app_na ...

  8. Android层面上对sensor及event事件的处理

    可能这篇总结写得会有一点凌乱,一会讲sensor,一会又讲event的.但是把两者摆在一起也是有原因的,sensor的处理是event事件的基础上实现的,正是因为sensor对event的依赖性,所以 ...

  9. [Android][sensor]物理sensor bring up流程

    物理sensor bring up流程 物理sensor就是实体sensor,现实存在的.从硬件直接获取数据的sensor. 常见的物理sensor有:加速度acceleration.陀螺仪gyros ...

最新文章

  1. Python 3.10来了!!!
  2. android调用h5预加载图片,使用HTML5的页面资源预加载(Link prefetch)功能加速你的页面加载速度...
  3. Java中Thread中的实例方法_Java多线程2:Thread中的实例方法
  4. swift_022(Swift 的下标脚本)
  5. 外卖流量红利期已过:正从补贴战进入AI赛道
  6. MSSql-1内部数据库版本号
  7. 递归用法之“海盗分赃难题”
  8. python模块(5)-Matplotlib 简易使用教程
  9. 奇怪。短短几天,他们的论文怎么会有这么大的提升?
  10. 大学生利用漏洞薅肯德基羊毛,获刑两年半
  11. Excel导入SQL数据库出现的问题
  12. EDA课程设计代码汇总(信号发生器、抢答器、频率计、秒表、密码锁、计算器、VGA、PS2)
  13. 【jQuery】jQuery 教程
  14. 微信AirSync服务之计步器
  15. 添加fiddler证书到手机根目录
  16. 论文写作学习之引言章节撰写(学习深度之眼课程笔记,侵删)
  17. css网页布局小练习,文字案例,小米官网卡片案例
  18. 代码整洁之道--阅读
  19. 迪赛智慧数——文字(文本墙):80后儿童时期风靡的25种玩具
  20. “这本漫画真厉害!”男性榜第1名,进击的巨人三维模型来了~!

热门文章

  1. stimulsoft oracle,【Stimulsoft Reports Java教程】使用Oracle数据库
  2. python中用来抛出异常的关键字是( )_python如何抛出异常
  3. Microsoft server2008的sql server身份验证出现18456错误
  4. 前端css之 浮动 自学日记
  5. 什么是集成测试?集成测试方法有哪些?
  6. console,控制台也能玩出花样(console操作大全)
  7. Linux线程属性总结
  8. 工程伦理 清华慕课网答案
  9. window引导配置bcdedit
  10. CF447A DZY Loves Hash 模拟