Android 4.4 Kitkat Phone工作流程浅析(十一)__PSensor工作流程浅析

阈值比较法实现psensor功能 1 P_Sensor功能简述     接近传感器(proximity sensor)可以不断向外发射红外光,当有遮挡物遮挡住其所发射的红外光时,会有部分甚至全部的红外光反射至接近传感器。由此,可以根据遮挡物反射的红外光的能量信号检测用户的移动信息。接近传感器可以将光强度转换为数字信号,且可以通过I2C进行数据的读取。psensor的红外线会周期性的计算反光量,并将光强度转化为数字值,存储于pse... 阅读详情
本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉。

前置文章:

《 Android 4.4 Kitkat Phone工作流程浅析(一)__概要和学习计划 》

《Android 4.4 Kitkat Phone工作流程浅析(二)__UI结构分析》

《Android 4.4 Kitkat Phone工作流程浅析(三)__MO(去电)流程分析》

《Android 4.4 Kitkat Phone工作流程浅析(四)__RILJ工作流程简析》

《Android 4.4 Kitkat Phone工作流程浅析(五)__MT(来电)流程分析》

《Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程》

《Android 4.4 Kitkat Phone工作流程浅析(七)__来电(MT)响铃流程》

《Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析》

《Android 4.4 Kitkat Phone工作流程浅析(九)__状态通知流程分析》

《Android 4.4 Kitkat Phone工作流程浅析(十)__"通话显示"查询流程》

概要

       在Android手机通话过程中,用户将手机靠近/远离头部,会导致手机屏幕灭/亮,这实际上是Proximity Sensor在起作用(参考1)。通俗的来讲Proximity Sensor就是近距离传感器,后文简写为PSensor,近距离传感器可用于测量物体靠近或远离。根据PSensor的这一特征,在计数以及自动化控制等领域都有使用近距离传感器(参考2,参考3)。目前,市面上主流的智能手机均包含了近距离传感器。PSensor检测到手机被遮挡则关闭屏幕,反之则点亮屏幕,一方面可以省电(LCD是耗电大户),另一方面可以防止用户近耳接听时触碰到屏幕引发误操作。

       本文主要分析PSensor在整个通话过程中实现屏幕亮灭的控制原理。


本文来自http://blog.youkuaiyun.com/yihongyuelan 转载请务必注明出处

ProximitySensor初始化流程

       在Android 4.4以后,Phone分为了TeleService和InCallUI两个部分,通话过程中PSensor的控制由packages/apps/InCallUI/src/com/android/incallui/ProximitySensor.java负责。在以前发布的文章《Android 4.4 Kitkat Phone工作流程浅析(七)__来电(MT)响铃流程》和《Android 4.4 Kitkat Phone工作流程浅析(九)__状态通知流程分析》中已经分析通话状态变更流程 ( Modem->RILC->RILJ->Framework->Telephony->InCallUI ) ,而TeleService与InCallUI建立连接是在通话状态变更之后。因此ProximitySensor的初始化建立在通话状态第一次变更后,整个流程如图1所示:


图 1 ProximitySensor初始化流程

       InCallUI与TeleService通过两种方式进行通信,即Broadcast和AIDL。当MO流程发起时,InCallUI最终会通过广播的方式将MO请求传递给TeleService。而当通话状态返回以及通话控制命令发起时,InCallUI和TeleService之间将会通过AIDL的方式进行通信,即CallHandlerService和CallHandlerServiceProxy,以及CallCommandService和CallCommandClient。使用AIDL方式通信需要建立连接(bindService),而在建立连接的时候对ProximitySensor进行了初始化操作。

ProximitySensor初始化小结

1. ProximitySensor初始化是在InCallPresenter中完成;

在InCallPresenter中实例化了ProximitySensor对象并将其添加到Set<InCallStateListener>序列中,当通话状态变更时回调ProximitySensor的onStateChanged()方法。

2. ProximitySensor的初始化依赖于InCallUI中CallHandlerService的绑定;

当TeleService通过bindService连接CallHandlerServiceProxy和CallHandlerService时,经过逐步调用后完成ProximitySensor的初始化。而bindService的调用则依赖于Call State的改变,Call State的改变有两种情况:incoming 和 update,即当有来电或者通话状态改变时,会触发TeleService的bindService操作。

ProximitySensor使用流程

       通话状态变更之后ProximitySensor完成初始化。ProximitySensor.java的关键方法如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 构造方法,完成初始化  
  2. // PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK是@hide的,普通app无法获取  
  3. public ProximitySensor(Context context, AudioModeProvider audioModeProvider) {  
  4.     mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
  5.     if (mPowerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {  
  6.         mProximityWakeLock = mPowerManager.newWakeLock(  
  7.                 PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);  
  8.     } else {  
  9.         mProximityWakeLock = null;  
  10.     }  
  11.     mAccelerometerListener = new AccelerometerListener(context, this);  
  12.     mAudioModeProvider = audioModeProvider;  
  13.     mAudioModeProvider.addListener(this);  
  14. }  
  15.   
  16. // 完成善后工作,初始化以及挂断电话后会被调用  
  17. public void tearDown() {  
  18.     mAudioModeProvider.removeListener(this);  
  19.     mAccelerometerListener.enable(false);  
  20.     if (mProximityWakeLock != null && mProximityWakeLock.isHeld()) {  
  21.         mProximityWakeLock.release();  
  22.     }  
  23. }  
  24.   
  25. // 当设备的方向改变之后会执行,用于判断是否启用PSensor(注:在灭屏状态下不会触发)  
  26. // mOrientation的值包含:  
  27. // ORIENTATION_UNKNOWN = 0  
  28. // ORIENTATION_VERTICAL = 1   垂直摆放  
  29. // ORIENTATION_HORIZONTAL = 2 水平摆放  
  30. @Override  
  31. public void orientationChanged(int orientation) {  
  32.     mOrientation = orientation;  
  33.     updateProximitySensorMode();  
  34. }  
  35.   
  36. // 当通话状态有改变则会通过InCallPresenter回调  
  37. @Override  
  38. public void onStateChange(InCallState state, CallList callList) {  
  39.     // 如果是来电则无须启用PSensor  
  40.     boolean isOffhook = (InCallState.INCALL == state  
  41.             || InCallState.OUTGOING == state);  
  42.     if (isOffhook != mIsPhoneOffhook) {  
  43.         mIsPhoneOffhook = isOffhook;  
  44.         mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;  
  45.         mAccelerometerListener.enable(mIsPhoneOffhook);  
  46.         updateProximitySensorMode();  
  47.     }  
  48. }  
  49.   
  50. //... ...省略  
  51.   
  52. // 当通话过程中Audio模式有变化则执行,包括:  
  53. // 1. 蓝牙耳机连接  
  54. // 2. 有线耳机连接  
  55. // 3. 开启扬声器  
  56. @Override  
  57. public void onAudioMode(int mode) {  
  58.     updateProximitySensorMode();  
  59. }  
  60.   
  61. // 拨号盘显示时回调,此时禁用PSensor以便用户输入  
  62. public void onDialpadVisible(boolean visible) {  
  63.     mDialpadVisible = visible;  
  64.     updateProximitySensorMode();  
  65. }  
  66.   
  67. // Config改变时回调,如开启物理键盘(如今许多设备都已不再配备物理键盘)  
  68. public void onConfigurationChanged(Configuration newConfig) {  
  69.     mIsHardKeyboardOpen = newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;  
  70.     // Update the Proximity sensor based on keyboard state  
  71.     updateProximitySensorMode();  
  72. }  
  73.   
  74. // InCallUI显示或隐藏时回调  
  75. public void onInCallShowing(boolean showing) {  
  76.     if (showing) {  
  77.         mUiShowing = true;  
  78.     } else if (mPowerManager.isScreenOn()) {  
  79.         mUiShowing = false;  
  80.     }  
  81.     updateProximitySensorMode();  
  82. }  
通过查看不难发现,以上方法(除了构造方法以外)均调用了updateProximitySensorMode方法,整个通话过程中正是由其触发PSensor的控制,关键代码如下:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 根据当前设备状态,使用wake lock锁来控制PSensor的行为 
  3.  * On devices that have a proximity sensor, to avoid false touches 
  4.  * during a call, we hold a PROXIMITY_SCREEN_OFF_WAKE_LOCK wake lock 
  5.  * whenever the phone is off hook.  (When held, that wake lock causes 
  6.  * the screen to turn off automatically when the sensor detects an 
  7.  * object close to the screen.) 
  8.  * 以上为google解释通话过程中PSensor的工作原理,即 
  9.  * 在通话过程中持有PROXIMITY_SCREEN_OFF_WAKE_LOCK的wake lock,如果检测物体靠近 
  10.  * 则关闭屏幕以防止用户误点击 
  11.  * 
  12.  * 以下情况将会禁用PSensor的亮灭屏控制,即PSensor无效: 
  13.  * 1) 设备已连接蓝牙耳机 
  14.  * 2) 设备已插入有线耳机 
  15.  * 3) 设备开启扬声器 
  16.  * 4) 设备开启物理键盘(如今许多设备都已不再配备物理键盘) 
  17.  */  
  18. private void updateProximitySensorMode() {  
  19.     if (proximitySensorModeEnabled()) {  
  20.         synchronized (mProximityWakeLock) {  
  21.             final int audioMode = mAudioModeProvider.getAudioMode();  
  22.             // 以下情况将会禁用PSensor,是否禁用需根据update时具体状态决定:  
  23.             // 1. 插入有线耳机  
  24.             // 2. 接入蓝牙耳机  
  25.             // 3. 开启扬声器  
  26.             // 4. 开启物理键盘(如今许多设备都已不再配备物理键盘)  
  27.             // 5. 设备水平放置  
  28.             // screenOnImmediately = true表示禁用PSensor  
  29.             // screenOnImmediately = false表示启用PSensor,此时屏幕的亮灭则根据是否  
  30.             // 有物体靠近或远离PSensor决定,靠近则灭屏,远离则亮屏  
  31.             boolean screenOnImmediately = (AudioMode.WIRED_HEADSET == audioMode  
  32.                     || AudioMode.SPEAKER == audioMode  
  33.                     || AudioMode.BLUETOOTH == audioMode  
  34.                     || mIsHardKeyboardOpen);  
  35.             //... ...省略  
  36.             // 当设备水平放置,且InCallActivity不在前台显示时,此时!mUiShowing && horizontal = true  
  37.             // 从而screenOnImmediately = true,并最终禁用PSensor  
  38.             final boolean horizontal =  
  39.                     (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);  
  40.             screenOnImmediately |= !mUiShowing && horizontal;  
  41.   
  42.             // 当设备水平放置且开启拨号盘时,screenOnImmediately = true,禁用PSensor  
  43.             screenOnImmediately |= mDialpadVisible && horizontal;  
  44.             if (mIsPhoneOffhook && !screenOnImmediately) {  
  45.                 final String logStr = "turning on proximity sensor: ";  
  46.                 if (!mProximityWakeLock.isHeld()) {  
  47.                     Log.i(this, logStr + "acquiring");  
  48.                     // 如果没有执行过acquire方法则执行wakelock申请的动作  
  49.                     // 该方法用于Enable PSensor的亮灭屏控制  
  50.                     mProximityWakeLock.acquire();  
  51.                 } else {  
  52.                     // 无须再次acquire  
  53.                     Log.i(this, logStr + "already acquired");  
  54.                 }  
  55.             } else {  
  56.                 final String logStr = "turning off proximity sensor: ";  
  57.                 if (mProximityWakeLock.isHeld()) {  
  58.                     Log.i(this, logStr + "releasing");  
  59.                     // Wait until user has moved the phone away from his head if we are  
  60.                     // releasing due to the phone call ending.  
  61.                     // Qtherwise, turn screen on immediately  
  62.                     // 禁用PSensor的亮灭屏控制包含两种情况:  
  63.                     // 第一种:  
  64.                     // 如果当前设备不再是OFFHOOK状态,比如已经挂断电话即 mIsPhoneOffhook = false  
  65.                     // 此时screenOnImmediately有可能为false,即设备还处于灭屏的状态,这种情况下会根据  
  66.                     // PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE 这个FLAG来release wake lock  
  67.                     // 也就是说会立即释放锁,但需要等用户远离PSensor时才会禁用PSensor并点亮屏幕  
  68.                     // 第二种:  
  69.                     // 当update时发现需要禁用PSensor,比如在PSensor被遮挡设备灭屏的情况下插入有线耳机  
  70.                     // 此时会导致Audio模式的改变从而调用updateProximitySensorMode,同时,在这种情况下  
  71.                     // screenOnImmediately = true,则会立即禁用PSensor并release wake lock点亮屏幕  
  72.                     int flags =  
  73.                         (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);  
  74.                     mProximityWakeLock.release(flags);  
  75.                 } else {  
  76.                     Log.i(this, logStr + "already released");  
  77.                 }  
  78.             }  
  79.         }  
  80.     }  
  81. }  
通过以上代码的分析可以知道,屏幕的亮灭有多种情况。在InCallUI中通过mProximityWakeLock.acquire()和mProximityWakeLock.release()申请/释放wake lock来 Enable/Unenable PSensor,从而让PSensor来控制屏幕的亮灭。从这一点也可以看出,通话过程中屏幕的亮灭的控制,实际上与Telephony没有多大关系。

ProximitySensor使用流程小结

1. 在InCallUI中通过ProximitySensor提供的public接口,调用updateProximitySensorMode()更新PSensor的Enable/Unenable状态。

public接口包括:

orientationChanged():设备方向改变后回调;

onStateChange():设备InCallState改变后回调;

onAudioMode():设备Audio模式改变后回调,Audio模式包括连接蓝牙耳机,插入有线耳机,开启扬声器;

onDialpadVisible():设备通话时时Dialpad显示状态改变后回调;

onConfigurationChanged():设备Configuration改变后回调,如弹出物理键盘;

onInCallShowing():设备InCallActivity显示状态改变后回调;

2. PSensor的控制在ProximitySensor中通过如下方式完成:

①. 实例化PowerManager.WakeLock

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
  2. if (mPowerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {  
  3.     mProximityWakeLock = mPowerManager.newWakeLock(  
  4.             PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);  
  5. } else {  
  6.     mProximityWakeLock = null;  
  7. }  
②. 通过WakeLock的acquire和release方法Enable/Unenable PSensor
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. mProximityWakeLock.acquire(); // 申请,即Enable PSensor  
  2. if (mProximityWakeLock.isHeld()) {  
  3.     int flags =(screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);  
  4.     mProximityWakeLock.release(flags); // 释放,即Unenable PSensor  
  5. }  

PSensor工作流程

       在分析了InCallUI中ProximitySensor的初始化流程和控制流程之后,还需具体查看在整个通话过程中,PSensor是如何完成工作屏幕亮灭控制的。在前文的分析中,ProximitySensor通过mProximityWakeLock.acquire()和mProximityWakeLock.release()来实现PSensor的Enable/Unenable,从而让PSensor完成屏幕亮灭的控制。整个流程大致分为:WakeLock申请、PSensor关闭/点亮屏幕、系统休眠/唤醒三大部分。

       可能有童鞋要问了:WakeLock是什么?PSensor与WakeLock有什么关系?申请和释放WakeLock的作用什么?后文会为大家一一解释。

WakeLock

       WakeLock也可称之为唤醒锁,是Android提供的一种机制,用于阻止设备进入深度休眠(CPU、Memory掉电参考4 参考5)。当一个应用程序申请了WakeLock后,即使用户按下Power键关闭屏幕,该应用依然可以保持运行,如音乐播放器。

       Android提供了五种类型的WakeLock,即PARTIAL_WAKE_LOCK、SCREEN_DIM_WAKE_LOCK、SCREEN_BRIGHT_WAKE_LOCK、FULL_WAKE_LOCK、PROXIMITY_SCREEN_OFF_WAKE_LOCK。其中SCREEN_DIM_WAKE_LOCK、SCREEN_BRIGHT_WAKE_LOCK、FULL_WAKE_LOCK不再建议使用,取而代之的是android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON。PARTIAL_WAKE_LOCK表示设备CPU 持续运转,屏幕和键盘背光允许关闭,普通应用可以获取,而PROXIMITY_SCREEN_OFF_WAKE_LOCK则是PSensor的专用,只有系统APP才有权使用。

       用户在通话过程中自然不希望设备进入深度休眠,因此电话应用(这里指InCallUI)会申请WakeLock,而这一步实际上在ProximitySensor的updateProximitySensorMode方法中完成,关键代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private final PowerManager mPowerManager;  
  2. private final PowerManager.WakeLock mProximityWakeLock;  
  3.   
  4. mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
  5. if (mPowerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {  
  6.     mProximityWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);  
  7.     // 申请WakeLock  
  8.     mProximityWakeLock.acquire();  
  9.     // 释放WakeLock  
  10.     int flags = (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);  
  11.     mProximityWakeLock.release(flags);  
这里需要注意:

1. PROXIMITY_SCREEN_OFF_WAKE_LOCK在PowerManager定义为@hide因此普通APP无法直接调用;

2. 申请WakeLock需要在AndroidManifest.xml添加android.permission.WAKE_LOCK权限;

3. flags为0表示立即释放锁,屏幕会立即点亮。flags为PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE则表示立即释放锁,但此时已然Enable PSensor,需要等待物体远离后再亮屏;

       普通应用也可以申请/释放WakeLock,但PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK只有系统应用才有权申请/释放,也就是说该类型的WakeLock是为PSensor量身打造的。在acquire/release WakeLock的过程中,实际上也一并完成了PSensor的Enable/Unenable,具体将在下一节给大家解释。

PSensor关闭/点亮屏幕

       本文提及的PSensor关闭/点亮屏幕指的是,Enable PSensor并满足特定条件(靠近/远离)后,触发屏幕关闭/开启流程(实际上是休眠/唤醒流程,后文解释),而整个流程分为两步:注册PSensor Listener及PSensor状态触发亮灭屏。

注册PSensor Listener

       InCallUI中完成WakeLock的申请后,便进入到frameworks/base/core/java/anroid/os/PowerManager.java的acquire方法中,并开启了WakeLock的处理流程,关键代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void acquire() {  
  2.     //... ...省略  
  3.     acquireLocked();  
  4. }  
  5. Private void acquireLocked() {  
  6.     // ... ..省略 mService即PowerManagerService对象  
  7.     mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);  
  8. }  
对于上层应用来说PowerManager实际上只是一个接口,真正实现在frameworks/base/services/java/com/android/server/power/PowerManagerService.java中:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,  
  3.         WorkSource ws) {  
  4.     //... ...省略  
  5.     try {  
  6.         acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid);  
  7.     } finally {  
  8.         Binder.restoreCallingIdentity(ident);  
  9.     }  
  10. }  
  11.   
  12. private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,  
  13.         WorkSource ws, int uid, int pid) {  
  14.     synchronized (mLock) {  
  15.         //... ...省略  
  16.         updatePowerStateLocked();  
  17.     }  
  18. }  
因为在本节中我们主要关心关闭/点亮屏幕的操作,期间省略了很多状态更新以及权限检查的代码。在acquireWakeLockInternal最后调用了updatePowerStateLocked,该方法是PowerManagerService中最为重要的方法,也即Android的休眠/唤醒入口方法。其中具有具有5大关键步骤,核心代码如下:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void updatePowerStateLocked() {  
  2.     //... ...省略  
  3.   
  4.     // Phase 0: Basic state updates.  
  5.     // 基本状态更新  
  6.     updateIsPoweredLocked(mDirty);  
  7.     updateStayOnLocked(mDirty); // 是否有开启"充电保持唤醒"功能  
  8.   
  9.     // Phase 1: Update wakefulness.  
  10.     // Loop because the wake lock and user activity computations are influenced  
  11.     // by changes in wakefulness.  
  12.     final long now = SystemClock.uptimeMillis();  
  13.     int dirtyPhase2 = 0;  
  14.     for (;;) {  
  15.         int dirtyPhase1 = mDirty;  
  16.         dirtyPhase2 |= dirtyPhase1;  
  17.         mDirty = 0;  
  18.         //检查当前系统中所有激活的(没有释放)WakeLock  
  19.         updateWakeLockSummaryLocked(dirtyPhase1);  
  20.         //更新主动申请的系统状态如bright/dim  
  21.         updateUserActivitySummaryLocked(now, dirtyPhase1);  
  22.         // 如果经过前面的检查和更新后,没有新的状态变更则退出循环准备休眠  
  23.         if (!updateWakefulnessLocked(dirtyPhase1)) {  
  24.             break;  
  25.         }  
  26.     }  
  27.   
  28.     // Phase 2: Update dreams and display power state.  
  29.     // 更新dream屏保状态  
  30.     updateDreamLocked(dirtyPhase2);  
  31.     // 更新显示状态,包含关闭/点亮屏幕  
  32.     updateDisplayPowerStateLocked(dirtyPhase2);  
  33.   
  34.     // Phase 3: Send notifications, if needed.  
  35.     // 休眠/唤醒是否准备完成  
  36.     if (mDisplayReady) {  
  37.         sendPendingNotificationsLocked();  
  38.     }  
  39.   
  40.     // Phase 4: Update suspend blocker.  
  41.     // Because we might release the last suspend blocker here, we need to make sure  
  42.     // we finished everything else first!  
  43.     // 休眠/唤醒前最后一步,之后会跳转到native层执行申请/释放锁的操作  
  44.     updateSuspendBlockerLocked();  
  45. }  
经过前文的分析,申请WakeLock之后会调用到updatePowerStateLocked()中,而在该方法中通过调用updateDisplayPowerStateLocked()更新显示状态,关键方法如下:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void updateDisplayPowerStateLocked(int dirty) {  
  2.     //... ...省略  
  3.     mDisplayReady = mDisplayPowerController.requestPowerState(mDisplayPowerRequest,  
  4.                 mRequestWaitForNegativeProximity);  
  5.     //... ...省略  
  6. }  
mDisplayPowerController是frameworks/base/services/java/com/android/server/power/DisplayPowerController.java的对象,在PowerManagerService的SystemReady()方法中完成初始化。继续查看DisplayPowerController的requestPowerState方法:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public boolean requestPowerState(DisplayPowerRequest request,  
  2.         boolean waitForNegativeProximity) {  
  3.     //... ...省略  
  4.     if (changed && !mPendingRequestChangedLocked) {  
  5.         mPendingRequestChangedLocked = true;  
  6.         sendUpdatePowerStateLocked();  
  7.     }  
  8.     //... ...省略  
  9. }  
这里会执行sendUpatePowerStateLocked方法,该方法中会使用sendMessage()发送一个MSG_UPDATE_POWER_STATE消息,而该消息的接收者正是DisplayPowerController的内部类DisplayControllerHandler,并执行updatePowerState()方法。当第一次执行updatePowerState()方法时,仅register PSensor的Listener而不会继续往后执行,关键代码如下:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void updatePowerState() {  
  2.     //... ...省略  
  3.     setProximitySensorEnabled(true);  
  4.     //... ....省略  
  5. }  
  6.   
  7. private void setProximitySensorEnabled(boolean enable) {  
  8.     if (enable) {  
  9.         if (!mProximitySensorEnabled) {  
  10.             // Register the listener.  
  11.             mProximitySensorEnabled = true;  
  12.             mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,  
  13.                     SensorManager.SENSOR_DELAY_NORMAL, mHandler);  
  14.         }  
  15.     } else {  
  16.         if (mProximitySensorEnabled) {  
  17.             // Unregister the listener.  
  18.             //... ...省略  
  19.             mSensorManager.unregisterListener(mProximitySensorListener);  
  20.             //... ...省略  
  21.         }  
  22.     }  
  23. }  

整个注册PSensor Listener流程如图2所示:


图 2 PSensor Enable流程

PSensor状态触发亮灭屏

       当PSensor的状态发生改变之后便会回调其Listener的onSensorChanged()方法,并判断当前遮挡物是靠近还是远离PSensor:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private final SensorEventListener mProximitySensorListener = new SensorEventListener() {  
  2.     @Override  
  3.     public void onSensorChanged(SensorEvent event) {  
  4.         if (mProximitySensorEnabled) {  
  5.             final long time = SystemClock.uptimeMillis();  
  6.             //从Event中获取distance值,这个值与driver上报有关,不同设备有可能不同  
  7.             //从当前测试设备上返回的数据来看,靠近时distance=0.0,远离时distance=1.0  
  8.             final float distance = event.values[0];  
  9.             //mProximityThreshold的默认值为5.0f,具体是在driver中设置的  
  10.             //靠近:distance = 0.0 -> positive = true  -> POSITIVE  
  11.             //远离:distance = 1.0 -> positive = false -> NEGATIVE  
  12.             boolean positive = distance >= 0.0f && distance < mProximityThreshold;  
  13.             handleProximitySensorEvent(time, positive);  
  14.         }  
  15.     }  
  16.     //... ...省略  
  17. };  

以上信息也可以在log中获取到,如:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 01-02 08:51:56.963 D/PowerManagerDisplayController(  735): P-Sensor Changed: false ->远离  
  2. 01-02 08:51:59.621 D/PowerManagerDisplayController(  735): P-Sensor Changed: true  ->靠近  
  3. 01-02 08:52:22.510 D/PowerManagerDisplayController(  735): P-Sensor Changed: false ->远离  

在onSensorChanged()方法中会继续调用handleProximitySensorEvent()进而调用debounceProximitySensor()方法,最后会调用到updatePowerState()方法。此时,该方法会根据PSensor的状态决发起真正的关闭/点亮屏幕流程,关键代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void updatePowerState() {  
  2.     //... ...省略  
  3.     // Apply the proximity sensor.  
  4.         //acquire即Enable PSensor  
  5.         if (mPowerRequest.useProximitySensor) {  
  6.             // 如果当前不是灭屏状态就执行  
  7.             if (mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {  
  8.                 // 注册PSensor监听,即Enable PSensor  
  9.                 setProximitySensorEnabled(true);  
  10.                 // 如果不需要强制唤醒则执行  
  11.                 if (!mPowerRequest.forceWakeUpEnable){  
  12.                     // 默认mScreenOffBecauseOfProximity = false  
  13.                     // 同时当前PSensor处于被遮挡当状态,即物体靠近  
  14.                     if (!mScreenOffBecauseOfProximity  
  15.                             && mProximity == PROXIMITY_POSITIVE) {  
  16.                         mScreenOffBecauseOfProximity = true;  
  17.                         //回调PowerManagerService中的updatePowerStateLocked()  
  18.                         sendOnProximityPositiveWithWakelock();  
  19.                         if (DEBUG) {  
  20.                             Slog.d(TAG, "setScreenOn false becaue of P-sensor");  
  21.                         }  
  22.                         // 根据PSensor状态关闭屏幕,这块原生AOSP是放在后面做的,MTK将其提前了  
  23.                         setScreenOn(false);  
  24.                     }  
  25.                 }  
  26.             } else if (mScreenOffBecauseOfProximity  
  27.                         && mProximity == PROXIMITY_POSITIVE) {  
  28.                 // 通话过程中设备PSensor被遮挡,屏幕关闭  
  29.                 // 此时,对方挂断电话后屏幕会保持关闭,直到PSensor不再被遮挡才会亮屏  
  30.                 if (DEBUG) {  
  31.                     Slog.d(TAG, "enable P-sensor and wait for P-sensor negative");  
  32.                 }  
  33.                 setProximitySensorEnabled(true);  
  34.             } else if (mPowerRequest.forceProximitySensorEnable) {  
  35.                 if (DEBUG) {  
  36.                     Slog.d(TAG, "force enable P-sensor for talking screen off timeout");  
  37.                 }  
  38.                 setProximitySensorEnabled(true);  
  39.                 if (!mScreenOffBecauseOfProximity  
  40.                         && mProximity == PROXIMITY_POSITIVE) {  
  41.                     mScreenOffBecauseOfProximity = true;  
  42.                 }  
  43.             } else {  
  44.             }  
  45.         } else {  
  46.             //realse WakeLock后执行,即Unenable PSensor  
  47.             if (mWaitingForNegativeProximity  
  48.                 && mScreenOffBecauseOfProximity  
  49.                 && mProximity == PROXIMITY_POSITIVE) {  
  50.                 // 通话过程中设备PSensor被遮挡,屏幕关闭  
  51.                 // 此时,对方挂断电话后屏幕会保持关闭,直到PSensor不再被遮挡才会亮屏  
  52.                 if (DEBUG) {  
  53.                     Slog.d(TAG, "proximity wakelock released but still enable P-sensor and wait for P-sensor negative");  
  54.                 }  
  55.                 setProximitySensorEnabled(true);  
  56.             } else {  
  57.                 setProximitySensorEnabled(false);  
  58.                 mWaitingForNegativeProximity = false;  
  59.             }  
  60.         }  
  61.         //... ...省略  
  62.     } else {  
  63.         mWaitingForNegativeProximity = false;  
  64.     }  
  65.     //... ...省略  
  66.     // Animate the screen on or off.  
  67.     if (!mScreenOffBecauseOfProximity || mPowerRequest.forceWakeUpEnable) {  
  68.         if (wantScreenOn(mPowerRequest.screenState)) {  
  69.             // Want screen on  
  70.             if (!mElectronBeamOffAnimator.isStarted()) {  
  71.                 // PSensor遮挡物远离,点亮屏幕  
  72.                 setScreenOn(true);  
  73.                 //... ...省略  
  74.             }  
  75.         } else {  
  76.             // Want screen off.  
  77.             if (!mElectronBeamOnAnimator.isStarted()) {  
  78.                 if (!mElectronBeamOffAnimator.isStarted()) {  
  79.                     if (mPowerState.getElectronBeamLevel() == 0.0f || mShutDownFlag_D) {  
  80.                         // 动画执行完毕后关闭屏幕  
  81.                         setScreenOn(false);  
  82.                         //... ...省略  
  83.                 }  
  84.             }  
  85.         }  
  86.     }  
  87.     //... ...省略  
  88. }  

updatePowerState主要功能如下:

1. 启用或禁用PSensor;这部分之前有做分析,不再赘述。在MTK代码中,PSensor的灭屏操作也放在了这块代码中处理,而原生AOSP灭屏操作放在动画执行之前。

2. 设置亮度具体值; 该亮度值主要用于设置亮灭屏动画。
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. animateScreenBrightness(clampScreenBrightness(target),slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);  

3. 执行灭屏/亮屏动画;执行动画前会调用setScreenOn()方法关闭/点亮屏幕。原生AOSP将PSensor的亮灭屏处理也放在这块代码中,AOSP中代码结构如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if (mScreenOffBecauseOfProximity) {  
  2.     setScreenOn(false);  
  3. } else if(wantScreenOn(mPowerRequest.screenState)) {  
  4.     // Want screen on  
  5.     // 亮屏动画  
  6.     mElectronBeamOnAnimator.start();  
  7.     //... ...省略  
  8.     mElectronBeamOnAnimator.end();  
  9. } else {  
  10.     // Want screen off.  
  11.     // 灭屏动画  
  12.     mElectronBeamOffAnimator.start();  
  13.     //... ...省略  
  14.     mElectronBeamOffAnimator.end();  
  15. }  

MTK则是将 if (mScreenOffBecauseOfProximity)提到了PSensor启用/禁用代码中,修改之后的代码逻辑更为清晰。

通过setScreenOn()会最终执行到LightService的setLightLocked()方法中,并通过JNI的方式将亮度值传递给背光模组。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);  

PSensor关闭/点亮屏幕小结

屏幕的关闭与点亮最终是由LightService来做的,而PSensor仅仅充当了触发条件。在设备屏幕关闭/点亮流程中,需要注意以下关键点:

1. 第一次执行WakeLock的acquire()方法时并不会关闭屏幕,而是注册PSensor的EventListener;

2. PROXIMITY_SCREEN_OFF_WAKE_LOCK锁acquire/release表示register/unregister PSensor EventListener;

即决定是否将PSensor作为屏幕关闭/点亮的控制条件,acquire()表示启用该控制条件,release()表示取消该控制条件。

3. PSensor EventListener回调onSensorChanged()触发屏幕背光控制;

onSensorChanged()最终会调用updatePowerState()方法,根据PSensor是否被遮挡从而执行屏幕背光的设置,并在背光设置完成后回调到PowerManagerService的updatePowerStateLocked方法中继续后面的流程。

4. 屏幕关闭/点亮会触发Android休眠/唤醒机制;

在PowerManagerService中,updatePowerStateLocked是系统休眠/唤醒的上层入口,当更新完设备状态后通过JNI的方式,触发系统进入休眠/唤醒流程。

PSensor控制屏幕背光流程如图3:


图 3 PSensor控制屏幕背光流程

系统休眠/唤醒

       前文分析了PSensor是如何控制屏幕关闭/点亮,即通过PowerManagerService中的updateDisplayPowerStateLocked()并最终调用LightService的setLight_native()方法完成。当完成屏幕关闭/点亮之后会继续执行updatePowerStateLocked()中余下流程,其中最重要的就是updateSuspendBlockerLocked()。该方法触发系统了休眠/唤醒机制,关键代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private void updateSuspendBlockerLocked() {  
  2.     //... ...省略  
  3.     //acquire WakeLock,系统中如有WakeLock没有释放则无法进入深度休眠  
  4.     if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {  
  5.         mWakeLockSuspendBlocker.acquire();  
  6.         mHoldingWakeLockSuspendBlocker = true;  
  7.     }  
  8.     //... ...省略  
  9.   
  10.     // release WakeLock,释放系统的WakeLock以使系统可以正常进入休眠  
  11.     if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {  
  12.         mWakeLockSuspendBlocker.release();  
  13.         mHoldingWakeLockSuspendBlocker = false;  
  14.     }  
  15.     //... ..省略  
  16. }  
这里的acquire和release最终调用到frameworks/base/services/jni/com_android_server_power_PowerManagerService.cpp中:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {  
  2.     ScopedUtfChars name(env, nameStr);  
  3.     acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());  
  4. }  
  5.   
  6. static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {  
  7.     ScopedUtfChars name(env, nameStr);  
  8.     release_wake_lock(name.c_str());  
  9. }  

从代码中可以看到,系统实际处理的WakeLock只有PARTIAL_WAKE_LOCK,再往后就是Android的休眠/唤醒流程了,这里不再详述。

       需要注意的是Android JellyBean之前的系统休眠/唤醒流程大致如:earlysuspend -> wake_unlock -> suspend -> late suspend -> sleep -> wakeup -> early resume -> resume -> late resume,而在Android JellyBean之后Android使用AutoSleep逐渐替代了earlysuspend。earlysuspend和WakeLock是Android创造的一种高效休眠机制,无奈这种修改得不到Linux社区的承认,最终只能在Linux的Wakeup机制上重新修改。虽然Android在JellyBean中已经移除了earlysuspend机制,但MTK依然在AutoSleep的基础上加入了经过修改后的earlysuspend,而Qcom默认使用的是AutoSleep,不过也有个别ODM厂商将earlysuspend机制加入到Qcom代码中。

系统休眠/唤醒小结

       在PSensor触发灭屏操作之后,系统实际上会进入休眠流程,关于休眠/唤醒的具体流程可查看参考6  参考7。通过前面的分析可以知道,因为申请了PARTIAL_WAKE_LOCK,因此在try_to_suspend()方法中会一直循环检测,不会执行pm_suspend()。也就是说此时系统并没有完全休眠( MTK平台会完成earlysuspend ),休眠流程开始部分时序如图4:


图 4 休眠流程(开始部分)

总结

       本文主要分析了在InCallUI中PSensor如何控制屏幕的亮灭及其实现原理。全文分为三大部分,即:ProximitySensor初始化流程,ProximitySensor使用流程和PSensor工作流程。前两部分主要分析了上层应用如何使用PSensor提供的接口,第三部分则详细分析了PSensor如何控制屏幕的关闭/点亮。

ProximitySensor初始化流程需要注意:

1. ProximitySensor初始化是在InCallPresenter中完成;

2. ProximitySensor的初始化依赖于InCallUI中CallHandlerService的绑定,Call 状态改变触发绑定;

ProximitySensor使用流程需要注意:

1.在InCallUI中通过ProximitySensor提供的接口,调用updateProximitySensorMode()更新PSensor的Enable状态;

2. 在ProximitySensor中,通过acquire/release PowerManager.WakeLock来 Enable/Unenalbe PSensor;

PSensor工作流程需要注意:

因为PSensor工作流程细分为WakeLock申请、PSensor关闭/点亮屏幕、系统休眠/唤醒三个部分,各个部分都有一些需要注意的地方。

WakeLock:

1. PROXIMITY_SCREEN_OFF_WAKE_LOCK普通APP无法申请,在系统中即PSensor专用 ( 实际在底层对应的还是PARTIAL_WAKE_LOCK );

2. 使用WakeLock需要在AndroidManifest.xml添加android.permission.WAKE_LOCK权限;

PSensor点亮/关闭屏幕需要注意:

PSensor关闭/点亮屏幕流程分为两步:注册PSensor Listener和PSensor状态触发亮灭屏,其中需要注意:

1. 第一次执行WakeLock的acquire()方法时并不会关闭屏幕,仅仅是注册PSensor的EventListener;

2. PROXIMITY_SCREEN_OFF_WAKE_LOCK锁acquire/release表示register/unregister PSensor EventListener;

3. 根据PSensor EventListener回调onSensorChanged()触发屏幕背光控制;

4. 屏幕亮灭会触发Android休眠/唤醒机制;

系统休眠/唤醒需要注意:

1. PROXIMITY_SCREEN_OFF_WAKE_LOCK实际上对应底层的PARTIAL_WAKE_LOCK,该锁会保持CPU持续运转不会进入休眠;

2. Android JellyBean之后默认不再使用earlysuspend,取而代之的是AutoSleep机制,对上层来说没有影响;

3. 如果系统支持earlysuspend,则PSensor灭屏会使系统走完earlysuspend流程,最终在try_to_sleep()方法中一直循环检测;

综上,PSensor在整个通话过程中实现屏幕亮灭的控制流程如图5所示:


图 5 PSensor通话过程中控制屏幕亮灭

Android—传感器-距离传感器(ProximitySensor) 距离传感器(ProximitySensor) P-Sensor距离感应器,可以感应手机和人体距离。具体使用用途是在通话过程中打开P-Sensor,那么当手机屏幕贴近用户脸部时,就会自动感应出手机和人体距离是多少。当小于某一个值时,就会熄灭屏幕,不再接收用户触摸屏幕事件,从而有效的防止通话过程中误触摸事件的出现。 例子1:利用按钮实现切换背景颜色 XML文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 阅读详情

相关推荐

and5.1PowerManagerService深入分析(四)PMS与Display模块

PMS与Display模块的交互在之前的一篇博客也写过,但不是写的很详细。 在PMS的systemReady方法中,有如下两段代码: mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); mDisplayManagerInternal.initPowerManag

kc58236582的博客 4179

探秘手机距离传感器工作背后的那些事儿

距离传感器

Fybon的专栏 2万+

R分析|怎么样使用piecewiseSEM构建结构方程模型?保姆级教程

计算科学的发展让我们有了更先进的工具揭示自然规律。结构方程模型(SEM)已被广泛应用于多学科进行数据挖掘。其中在R中实现的结构方程模型是方便快捷的。今天要介绍的piecewiseSEM包就是R中实现SEM的一种方式。piecewiseSEM被开发出来主要目的是为了解决复杂模型简化后进行分段分析。个人认为最大的特点是更灵活,且采用的是原始数据,并不是传统的协方差矩阵。其次,将SEM破碎化为多个独立的方程,对样本量要求较少。

weixin_46814750的博客 6939

Psensor driver 一(原理介绍)

(近距离传感器)采用光学原理,包含红外线发射器、红外线监测器,当没有物体遮挡时,红外线监测器监测到的是Ambient light(环境光)及Crosstalk(串扰)光线中的红外线。proximity sensor通过I2C接口和BB通信,PS功能打开,当有物体接近或离开时,会通过EINT产生中断,两路电源VDD、LED_AL,如上图,硬件连接很简单。转自:https://blog.csdn.net/u013531497/article/details/38388589。如上图所示,proximity。

小厨的博客 2791

告别‘火龙’:实测BES2800/RK2108等主流芯片,聊聊AI眼镜的功耗与散热‘内卷’实战

本文深入探讨了AI智能眼镜在功耗与散热方面的挑战,重点分析了恒玄BES2800和瑞芯微RK2108等主控芯片的能效表现。通过实测数据和优化策略,揭示了在6nm工艺、异构计算和系统级散热方案下的实战经验,为AI眼镜的功耗管理提供了实用解决方案。

weixin_30839881的博客 946

智能织梦:基于Rokid AR眼镜的家庭情感记忆增强系统设计与实践

本文介绍了基于Rokid AR眼镜的'智能织梦'系统,通过增强现实技术捕捉和重现家庭情感记忆。系统利用多模态传感器和轻量级情感识别模型,自动记录家庭互动中的情感峰值时刻,并生成沉浸式记忆片段。测试数据显示,该系统显著提升了家庭情感互动的频率和质量,特别适用于多代同堂家庭和记忆唤醒场景。

sre5engineer的博客 536

近距离传感器 (proximity sensor )

  近距离传感器的作用:   近距离传感器是通过红外线进行测距,当手机用户接听电话或者装进口袋时,传感器可以判断出手机贴近了人的脸部或者衣服而关闭屏幕的触控功能,这样就可以防止误操作。同样,这功能可以用在所有应用触摸屏的便携设备上。   近距离传感器的作用:   近距离传感器是通过红外线进行测距,当手机用户接听电话或者装进口袋时,传感器可以判断出手机贴近了人的脸部或者衣服而关闭屏幕...

iteye_8846的博客 7078

激光甲烷传感器DIY指南:从DFB激光器选型到Herriott池光路搭建

本文详细介绍了如何DIY激光甲烷传感器,从DFB激光器选型到Herriott池光路搭建的全过程。通过TDLAS技术实现ppm级甲烷检测,适用于家用燃气泄漏监测和农业沼气监测等场景。文章包含核心器件选型、光路搭建技巧、信号调理方案及系统集成优化,为创客提供实用指南。

f9g0h的博客 596

proximity sensor driver (一)

1 硬件原理   如上图所示,proximity sensor(近距离传感器)采用光学原理,包含红外线发射器、红外线监测器,当没有物体遮挡时,红外线监测器监测到的是Ambient light(环境光)及Crosstalk(串扰)光线中的红外线。如果结构做得好,Ambient light 和 Crosstalk 造成的背景噪声 a  是很小的。当有物体遮挡,红外线发射器发射的红外

u013531497的专栏 9932

BIOS硬件监控实战:如何手动读取IT8738芯片的温度与风扇数据(附代码)

本文深入探讨了如何绕过操作系统和HWMonitor等监控软件,直接通过寄存器级操作读取IT8738超级I/O芯片的硬件监控数据。文章提供了从动态定位EC空间、构建底层读写函数到解码传感器寄存器映射的完整实战指南,并附有C语言代码示例,帮助开发者理解BIOS硬件监控的底层原理,适用于定制硬件开发与故障诊断。

weixin_29192211的博客 110

Halcon 3D点云匹配实战:从预处理到模板创建的完整流程(附代码)

本文详细介绍了Halcon在3D点云匹配中的实战应用,涵盖从预处理到模板创建的完整流程。通过代码示例和实用技巧,帮助开发者掌握点云采样、降噪、三角化等关键技术,并优化匹配参数以提高精度和效率。适用于工业检测、机器人引导等领域。

weixin_33670786的博客 433

ubuntu篇---系统下查看CPU和GPU温度

ubuntu篇---系统下查看CPU和GPU温度

心惠天意 3837

uniapp - 应用软件在运行时,未见向用户告知权限申请的目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准(uniApp开发安卓APP上架应用市场审核被拒绝驳回,详细解决方案)

uniApp应用软件在运行时,未见向用户告知权限申请的目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准。uniapp vue2 vue3解决软件在运行时,未见向用户告知权限申请的目的,华为等上架被拒问题,关于华为应用市场上架需要同步告知使用权限的解决方案,uniApp应用软件在运行时,不符合华为应用市场审核标准。解决方案合集!app上架-您的应用在运行时,未同步告知权限申请的使用目的,向用户索取(相机)等权限,不符合华为应用市场审核标准。华为应用市场审核新规(未同步告知权限申请的使用目

🏆 前端领域优质创作者 4164

linux远程访问图形硬件,Psensor - 图形硬件温度监控器适用于Linux

一般来说,Linux管理员都应该跟踪您的计算机硬件问题或可能发生意外故障的性能。 有时,如果早期没有检测到这些问题的过热问题,可能是由于各种软件问题,例如越野车的显卡驱动程序,误配置的风扇控制程序,故障的CPU频率调节守护进程,等等,这些可能成为严重威胁这可能会造成永久性损坏您的硬件。 因此,在密切关注过热的问题应该是你的首要任务。Psensor被认为是给监视硬件温度并从原始数据绘制实时分析为快速...

weixin_42524762的博客 1067

低轨通信 | 手机直连低轨卫星通信:架构、关键技术与未来展望

手机直连低轨卫星通信正推动人类进入"全域连接"时代。当中国星网GW星座与千帆星座的万颗卫星点亮夜空,当普通智能手机在珠峰之巅仍能流畅视频通话,当远洋渔船通过卫星物联网实现精准捕捞——这些场景不仅重构通信产业格局,更将深刻改变人类生产生活方式。正如工信部《指导意见》所规划,到2030年我国将发展超千万卫星通信用户,催生万亿级新市场[1][5]。在这场太空基建竞赛中,技术创新与标准制定的双重突破,将决定未来数字文明的星空版图。

尘世冰封的专栏 939

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Ubuntu环境下检查CPU 的温度

Psensor最新的版本同样提供了Ubuntu中的指示小程序,这样使得在Ubuntu中监控温度变得更加容易。你可以选择在面板的右上角显示温度。在Application Indicator菜单下,选择你想要显示温度的组件并勾上Display sensor in the label选项。你所要做的就是在这里监控CPU温度。你可以时刻注意并帮助你找出使计算机过热的进程。如果你想要测量磁盘温度,你还需要安装hddtemp。在安装Psensor前,你需要安装和配置lm-sensors,这是一个用于硬件监控的。

Free雅轩的博客 2416

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

android app防止锁屏_Android手机中P-Sensor驱动开发调试及功能介绍

近期由于刚换了新工作,好久没有更新文章了,现在终于能抽出时间写点东西了!先拿我们手机上都有的psensor开刀吧。Psensor功能Proximity Sensor就是接近传感器,也就是我们常说的PSensor,用于测量物体靠近或远离手机,一般放置在手机屏幕的最上部位置。当物体接近PSensor时,PSensor的值会越来越大,当大于一定值(接近的门限值)时,就会上报接近事件给android;当物...

weixin_35756690的博客 1914

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

关于Android 电话接通的时候,将proximity sensor开启的源码分析

1.当在进入电话进来,并且没有接通的界面的时候,向右滑动会触发turnOnProximitySensor(ProximitySensor.java)方法,该方法中的mProximityWakeLock在其构造器中已经设置好了flag=PROXIMITY_SCREEN_OFF_WAKE_LOCK; 2.这样我们会进入PowerManager.java 的类种类WakeLock的acquire()方

ffightingg的博客 2831

linux监视硬件,PSensor 轻松让你在Ubuntu中监视硬件温度

PSensor是一个在Linux下非常成熟的硬件温度检测软件。这是我显卡风扇的运转情况。好吧,我想说的是真正让我崩溃的是这风扇奇大无比的噪音!我打算换一个新的散热器了,但在此之间,PSensor帮我记录一段时间内硬件的温度,并以图表的形式帮我显示出来。当然了,还有高级选项,它可以在硬件温度达到设定时报警。其他硬件不仅仅是检测你的显卡。PSensor还可以监控你的其它硬件温度.......主板和CP...

weixin_42398050的博客 1390

Linux安装配置硬件温度及风扇转速监测软件(sensor、psensor)

Linux安装配置硬件温度监控软件(sensor、psensor)   这两天给偶尔使用的台式机装了个外置电源开关,将其放到桌子后面来节省空间,应为担心会有散热问题,所以配置了温度监测软件。 安装 现说明一下本系统的环境如下,桌面为Xfce 安装命令 sudo apt install lm-sensors hddtemp psensor 配置 1、配置lm_sensors sudo sensors-detect 每一项都选择yes 2、运行sensor即可查看硬件信息 sensors 3、每次都输

MyCyber 1万+

P_sensor 距离感应器 阈值如何设置

DESCRIPTION] p sensor靠近时的阈值如何设定   [PLATFORM]  MT6575 MT6577 MT6589   [SOLUTION] 通过过程中,当靠近psensor时,屏幕灭屏,靠近的距离主要和psensor设定的阈值有关。   阈值的设定方法如下,可以在工厂模式下,进入alsps测试选项,可观察到psensor的数值变化,此即为从p sensor寄存

欢迎加入Android老司机学院 482266514(技术交流群)密码优快云 7830

linux温度监控软件,PSensor:Linux下硬件温度监控软件

PSensor是一款Linux下监测硬件温度的小工具。你可以设定阈值,达到阈值时发出报警。psensor 是一个图形化的硬件温度传感器的监控工具,基于 Linux 的 lm-sensors 和 GTK 库。为 Ubuntu 应用指示器增加了特定的图标,更改 Ubuntu 二进制打包更好的遵循打包规则。lm_sensors的软件可以帮助我们来监控主板,CPU的工作电压,风扇转速、温度等数据。这些数据...

weixin_36429611的博客 2681

Android距离感应器P-Sensor浅析

(一)  前言 P-Sensor,距离感应器,可以感应手机和人体距离。具体使用用途是在通话过程中打开P-Sensor,那么当手机屏幕贴近用户脸部时,就会自动感应出手机和人体距离是多少。当小于某一个值时,就会熄灭屏幕,不再接收用户触摸屏幕事件,从而有效的防止通话过程中误触摸事件的出现。(有很多人通话过程中脸部会触碰到挂断键,从而导致通话中断有没有? ^_^)。 (二)  打开P-Sensor

xing176的专栏 2869

TWS ChargerBox 驱动篇(二):Proximity Sensor

文章目录1.器件特性1.1 功能框图1.2 关键参数1.3 状态图2.寄存器解释 1.器件特性 以AMS的 TMD2637 为例,熟悉红外传感器的主要配置参数及配置方法 1.1 功能框图   接近传感器包括红外发射器和红外接收器(光电二极管)。发光二极管的驱动电流、脉冲宽度和数量、发光周期等可编程控制。光电二极管采样得到的数据将经过信号放大(增益Gain)和偏差校准。 INT为开漏输出,内置ADC用于光电二极管采样 Prox Thresholds接近阈值:上限和下限 1.2 关键参数   红外发射

la_fe_的博客 1125
上一篇: Android 4.4 Kitkat Phone工作流程浅析(十二)__4.4小结与5.0概览
下一篇: Android 4.4 Kitkat Phone工作流程浅析(十)__"通话显示"查询流程
roclee_csdn
博客等级 码龄11年 3粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值