Android7.0 PowerManagerService亮灭屏分析(三)

来源:互联网 发布:阿里云服务器登录地址 编辑:程序博客网 时间:2024/05/23 01:19

在前面两部分已经对绘制windows与设置设备状态进行了详细讲解. 之后接着就该对亮度值进行设置, 实现亮屏动作了.

在DisplayPowerController中的animateScreenBrightness函数通过亮度渐变动画来将亮度设置到目标亮度.

[java] view plain copy
  1. // Brightness animation ramp rate in brightness units per second.  
  2. private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40;     //亮度渐变动画较慢的速率, 每秒变化40个亮度单位   
  3.   
  4.     mBrightnessRampRateFast = resources.getInteger(  
  5.             com.android.internal.R.integer.config_brightness_ramp_rate_fast);   //从配置文件中获取较快的亮度速率  
  6.   
  7.     // Animate the screen brightness when the screen is on or dozing.  
  8.     // Skip the animation when the screen is off or suspended.  
  9.     if (!mPendingScreenOff) {  
  10.         if (state == Display.STATE_ON || state == Display.STATE_DOZE) {  
  11.             animateScreenBrightness(brightness,      //当亮屏或doze状态时有亮度渐变动画  
  12.                     slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : mBrightnessRampRateFast);  
  13.         } else {  
  14.             animateScreenBrightness(brightness, 0);   //灭屏时没有亮度渐变动画,直接将亮度设置为0  
  15.         }  
  16.     }  
在animateScreenBrightness函数中调用动画mScreenBrightnessRampAnimator对亮度值处理, 而mScreenBrightnessRampAnimator是在initialize()函数中进行初始化的, 在构造函数中将DisplayPowerState和DisplayPowerState.SCREEN_BRIGHTNESS传输过去.

[java] view plain copy
  1.   private void initialize() {  
  2.       //....  
  3.         mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(  //泛型为DisplayPowerState  
  4.                 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);  
  5.         mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);  
  6.      //...  
  7. }  
  8.   
  9.     private void animateScreenBrightness(int target, int rate) {  
  10.         if (DEBUG) {  
  11.             Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);  
  12.         }  
  13.         if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {    //动画处理亮度值  
  14.             try {  
  15.                 mBatteryStats.noteScreenBrightness(target);  
  16.             } catch (RemoteException ex) {  
  17.                 // same process  
  18.             }  
  19.         }  
  20.     }  

在RampAnimator的构造函数中将DisplayPowerState赋值给mObject, DisplayPowerState.SCREEN_BRIGHTNESS赋值给mProperty, 并且创建mChoreographer实例.

[java] view plain copy
  1. public RampAnimator(T object, IntProperty<T> property) {  
  2.     mObject = object;  
  3.     mProperty = property;  
  4.     mChoreographer = Choreographer.getInstance();  
  5. }  

下面重点讲解animateTo函数.

[java] view plain copy
  1. public boolean animateTo(int target, int rate) {  
  2.     // Immediately jump to the target the first time.  
  3.     if (mFirstTime || rate <= 0) {   //当第一次调用animateTo, 或者rate小于等于0时直接设置目标亮度.  
  4.         if (mFirstTime || target != mCurrentValue) {  
  5.             mFirstTime = false;   //之后就不是第一次调用该函数  
  6.             mRate = 0;              //设置mRate为0  
  7.             mTargetValue = target;   //设置目标亮度为target  
  8.             mCurrentValue = target;  
  9.             mProperty.setValue(mObject, target);   //调用DisplayPowerState.SCREEN_BRIGHTNESS设置亮度值  
  10.             if (mAnimating) {  
  11.                 mAnimating = false;  
  12.                 cancelAnimationCallback();  
  13.             }  
  14.             if (mListener != null) {  
  15.                 mListener.onAnimationEnd();  //动画结束  
  16.             }  
  17.             return true;  
  18.         }  
  19.         return false;  
  20.     }  
  21.   
  22.     // Adjust the rate based on the closest target.  
  23.     // If a faster rate is specified, then use the new rate so that we converge  
  24.     // more rapidly based on the new request.  
  25.     // If a slower rate is specified, then use the new rate only if the current  
  26.     // value is somewhere in between the new and the old target meaning that  
  27.     // we will be ramping in a different direction to get there.  
  28.     // Otherwise, continue at the previous rate.  
  29.     if (!mAnimating  
  30.             || rate > mRate  
  31.             || (target <= mCurrentValue && mCurrentValue <= mTargetValue)  
  32.             || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) {  
  33.         mRate = rate;   //重新调节亮度速率  
  34.     }  
  35.   
  36.     final boolean changed = (mTargetValue != target);  //如果当前亮度值不等于目标亮度值,说明亮度改变了  
  37.     mTargetValue = target;    //重新设置mTargetValue  
  38.   
  39.     // Start animating.  开始动画  
  40.     if (!mAnimating && target != mCurrentValue) {    
  41.         mAnimating = true;  
  42.         mAnimatedValue = mCurrentValue;  
  43.         mLastFrameTimeNanos = System.nanoTime();  
  44.         postAnimationCallback();  
  45.     }  
  46.   
  47.     return changed;   
  48. }  
在postAnimationCallback中调用Choreographer的postCallback函数处理, 调用完成后回调回mAnimationCallback的run函数

[java] view plain copy
  1. private void postAnimationCallback() {  
  2.     mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);  
  3. }  
  4.   
  5. private final Runnable mAnimationCallback = new Runnable() {  
  6.     @Override // Choreographer callback  
  7.     public void run() {  
  8.         final long frameTimeNanos = mChoreographer.getFrameTimeNanos();  
  9.         final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)  
  10.                 * 0.000000001f;  
  11.         mLastFrameTimeNanos = frameTimeNanos;  //记录最后一次的frameTimeNanos  
  12.   
  13.         // Advance the animated value towards the target at the specified rate  
  14.         // and clamp to the target. This gives us the new current value but  
  15.         // we keep the animated value around to allow for fractional increments  
  16.         // towards the target.  
  17.         final float scale = ValueAnimator.getDurationScale();  
  18.         if (scale == 0) {  
  19.             // Animation off.  
  20.             mAnimatedValue = mTargetValue;   //让scale为0时, 表示动画停止了, 将mAnimatedValue设置为目标亮度  
  21.         } else {  
  22.             final float amount = timeDelta * mRate / scale;  //计算每一次需要变化的亮度值  
  23.             if (mTargetValue > mCurrentValue) {  
  24.                 mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue);  //亮屏,每次增加亮度amount,不超过目标亮度  
  25.             } else {  
  26.                 mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); //暗屏, 每次减少amount个亮度, 不超过目标亮度  
  27.             }  
  28.         }  
  29.         final int oldCurrentValue = mCurrentValue;  
  30.         mCurrentValue = Math.round(mAnimatedValue);  //获取当前要达到的亮度值  
  31.   
  32.         if (oldCurrentValue != mCurrentValue) {  
  33.             mProperty.setValue(mObject, mCurrentValue);  //调用DisplayPowerState.SCREEN_BRIGHTNESS设置亮度值  
  34.         }  
  35.   
  36.         if (mTargetValue != mCurrentValue) {  
  37.             postAnimationCallback();   //如果还没有达到目标亮度,就会继续调用postAnimationCallback循环设置亮度值  
  38.         } else {  
  39.             mAnimating = false;  
  40.             if (mListener != null) {  
  41.                 mListener.onAnimationEnd();  //否则,亮度动画结束  
  42.             }  
  43.         }  
  44.     }  
  45. };  
DisplayPowerState.SCREEN_BRIGHTNESS的setValue函数是在DisplayPowerState中实现的.

[java] view plain copy
  1. public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS =  
  2.         new IntProperty<DisplayPowerState>("screenBrightness") {  
  3.     @Override  
  4.     public void setValue(DisplayPowerState object, int value) {  
  5.         object.setScreenBrightness(value);  //调用DisplayPowerState的setScreenBrightness函数,设置亮度值  
  6.     }  
  7.   
  8.     @Override  
  9.     public Integer get(DisplayPowerState object) {  
  10.         return object.getScreenBrightness();  
  11.     }  
  12. };  
  13.   
  14. public void setScreenBrightness(int brightness) {  
  15.     if (mScreenBrightness != brightness) {  
  16.         if (DEBUG) {  
  17.             Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);  
  18.         }  
  19.   
  20.         mScreenBrightness = brightness;  //设置全局的亮度值  
  21.         if (mScreenState != Display.STATE_OFF) {  
  22.             mScreenReady = false;  
  23.             scheduleScreenUpdate();   //如果不是灭屏状态,更新屏幕状态  
  24.         }  
  25.     }  
  26. }  
scheduleScreenUpdate函数最终通过Handler发送mScreenUpdateRunnable对象来更新亮度值. 从run函数中可以看出只有当mColorFadeLevel > 0f时才能给brightness设置亮度值, 所以说当windows没有绘制完成时就算mScreenBrightness有值不为0, 但是brightness仍然为0不能点亮屏幕.

[java] view plain copy
  1. private final Runnable mScreenUpdateRunnable = new Runnable() {  
  2.     @Override  
  3.     public void run() {  
  4.         mScreenUpdatePending = false;  
  5.   
  6.         int brightness = mScreenState != Display.STATE_OFF  
  7.                 && mColorFadeLevel > 0f ? mScreenBrightness : 0;    //判断设置亮度值  
  8.         if (mPhotonicModulator.setState(mScreenState, brightness)) {  
  9.             if (DEBUG) {  
  10.                 Slog.d(TAG, "Screen ready");  
  11.             }  
  12.             mScreenReady = true;  
  13.             invokeCleanListenerIfNeeded();  
  14.         } else {  
  15.             if (DEBUG) {  
  16.                 Slog.d(TAG, "Screen not ready");  
  17.             }  
  18.         }  
  19.     }  
  20. };  
之后的流程就与设置设置状态的流程相同了, 调用DisplayManagerService中DisplayBlanker的requestDisplayState函数.

[java] view plain copy
  1. DisplayBlanker blanker = new DisplayBlanker() {  
  2.     @Override  
  3.     public void requestDisplayState(int state, int brightness) {  
  4.         // The order of operations is important for legacy reasons.  
  5.         if (state == Display.STATE_OFF) {  
  6.             requestGlobalDisplayStateInternal(state, brightness);  
  7.         }  
  8.   
  9.         callbacks.onDisplayStateChange(state);      
  10.   
  11.         if (state != Display.STATE_OFF) {  
  12.             requestGlobalDisplayStateInternal(state, brightness);  //亮屏调用设置状态,亮度  
  13.         }  
  14.     }  
  15. };  
[java] view plain copy
  1. private void requestGlobalDisplayStateInternal(int state, int brightness) {  
  2.     if (state == Display.STATE_UNKNOWN) {  
  3.         state = Display.STATE_ON;  
  4.     }  
  5.     if (state == Display.STATE_OFF) {  
  6.         brightness = PowerManager.BRIGHTNESS_OFF;  //灭屏设置屏幕亮度为0  
  7.     } else if (brightness < 0) {  
  8.         brightness = PowerManager.BRIGHTNESS_DEFAULT;  //屏幕亮度小于0,设置为默认亮度  
  9.     } else if (brightness > PowerManager.BRIGHTNESS_ON) {  
  10.         brightness = PowerManager.BRIGHTNESS_ON;    //屏幕亮度大于255设置最大亮度值255  
  11.     }  
  12.   
  13.     synchronized (mTempDisplayStateWorkQueue) {  
  14.         try {  
  15.             // Update the display state within the lock.  
  16.             // Note that we do not need to schedule traversals here although it  
  17.             // may happen as a side-effect of displays changing state.  
  18.             synchronized (mSyncRoot) {  
  19.                 if (mGlobalDisplayState == state  
  20.                         && mGlobalDisplayBrightness == brightness) {  
  21.                     return// no change     亮度与状态都没有改变就return  
  22.                 }  
  23.   
  24.                 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("  
  25.                         + Display.stateToString(state)  
  26.                         + ", brightness=" + brightness + ")");  
  27.                 mGlobalDisplayState = state;  
  28.                 mGlobalDisplayBrightness = brightness;  
  29.                 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);   //应用全局状态  
  30.             }  
  31.   
  32.             // Setting the display power state can take hundreds of milliseconds  
  33.             // to complete so we defer the most expensive part of the work until  
  34.             // after we have exited the critical section to avoid blocking other  
  35.             // threads for a long time.  
  36.             for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {  
  37.                 mTempDisplayStateWorkQueue.get(i).run();  //运行mTempDisplayStateWorkQueue队列中的runnable  
  38.             }  
  39.             Trace.traceEnd(Trace.TRACE_TAG_POWER);  
  40.         } finally {  
  41.             mTempDisplayStateWorkQueue.clear();  
  42.         }  
  43.     }  
  44. }  
在applyGlobalDisplayStateLocked函数中获取所有的devices, 调用对应设备的requestDisplayStateLocked函数更新请求状态. 启动devices为LocalDisplayAdapter, 就会调用到该类的requestDisplayStateLocked获得runnable.
[java] view plain copy
  1. private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {  
  2.     final int count = mDisplayDevices.size();  
  3.     for (int i = 0; i < count; i++) {   //遍历devices  
  4.         DisplayDevice device = mDisplayDevices.get(i);  
  5.         Runnable runnable = updateDisplayStateLocked(device);  //获得devices中的runnable  
  6.         if (runnable != null) {  
  7.             workQueue.add(runnable);  //将runnable加入workQueue队列, 即mTempDisplayStateWorkQueue队列  
  8.         }  
  9.     }  
  10. }  
  11.   
  12. private Runnable updateDisplayStateLocked(DisplayDevice device) {  
  13.     // Blank or unblank the display immediately to match the state requested  
  14.     // by the display power controller (if known).  
  15.     DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();  //获取devices信息  
  16.     if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {  
  17.         return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); //调用requestDisplayStateLocked函数  
  18.     }  
  19.     return null;  
  20. }  

在requestDisplayStateLocked中主要的任务就是创建一个runnable返回到DisplayManagerService中,并且等待回调run函数.

[java] view plain copy
  1. @Override  
  2. public Runnable requestDisplayStateLocked(final int state, final int brightness) {  
  3.     // Assume that the brightness is off if the display is being turned off.  
  4.     assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;  
  5.   
  6.     final boolean stateChanged = (mState != state);  //状态是否改变  
  7.     final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;  //亮度值是否改变  
  8.     if (stateChanged || brightnessChanged) {  //如果亮度值或者亮度状态发生改变就重新设置对应值  
  9.         final int displayId = mBuiltInDisplayId;  
  10.         final IBinder token = getDisplayTokenLocked();  
  11.         final int oldState = mState;  
  12.   
  13.         if (stateChanged) {   //设置亮度时.状态已经设置好,无变化  
  14.             mState = state;  
  15.             updateDeviceInfoLocked();  
  16.         }  
  17.   
  18.         if (brightnessChanged) {  
  19.             mBrightness = brightness;  //设置mBrightness  
  20.         }  
  21.   
  22.         // Defer actually setting the display state until after we have exited  
  23.         // the critical section since it can take hundreds of milliseconds  
  24.         // to complete.  
  25.         return new Runnable() {    //新建一个runnable返回  
  26.             @Override  
  27.             public void run() {  //在DisplayManagerService中调用run函数  
  28.                 // Exit a suspended state before making any changes.    
  29.                 int currentState = oldState;  
  30.                 if (Display.isSuspendedState(oldState)    //判断设置是否还是在suspend状态  
  31.                         || oldState == Display.STATE_UNKNOWN) {  
  32.                     if (!Display.isSuspendedState(state)) {  
  33.                         setDisplayState(state);  
  34.                         currentState = state;  
  35.                     } else if (state == Display.STATE_DOZE_SUSPEND  
  36.                             || oldState == Display.STATE_DOZE_SUSPEND) {  
  37.                         setDisplayState(Display.STATE_DOZE);  
  38.                         currentState = Display.STATE_DOZE;  
  39.                     } else {  
  40.                         return// old state and new state is off  
  41.                     }  
  42.                 }  
  43.   
  44.                 // Apply brightness changes given that we are in a non-suspended state.  
  45.                 if (brightnessChanged) {  
  46.                     if (isPowerDebug()) {  
  47.                         Slog.d(TAG, "set display brightness=" + brightness);  
  48.                     }  
  49.                     setDisplayBrightness(brightness);    //设置屏幕亮度  
  50.                 }  
  51.   
  52.                 // Enter the final desired state, possibly suspended.  
  53.                 if (state != currentState) {  
  54.                     if(isPowerDebug()) {  
  55.                         Slog.d(TAG, "set display state=" + state);  
  56.                     }  
  57.                     setDisplayState(state);  
  58.                 }  
  59.             }  
[java] view plain copy
  1.             private void setDisplayBrightness(int brightness) {  
  2.                 if (DEBUG) {  
  3.                     Slog.d(TAG, "setDisplayBrightness("  
  4.                             + "id=" + displayId + ", brightness=" + brightness + ")");  
  5.                 }  
  6.   
  7.                 Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("  
  8.                         + "id=" + displayId + ", brightness=" + brightness + ")");  
  9.                 try {  
  10.                     mBacklight.setBrightness(brightness);   //调用LightService设置亮度  
  11.                 } finally {  
  12.                     Trace.traceEnd(Trace.TRACE_TAG_POWER);  
  13.                 }  
  14.             }  
  15.         };  
  16.     }  
  17.     return null;  
  18. }  
[java] view plain copy
  1. @Override  
  2. public void setBrightness(int brightness) {  
  3.     setBrightness(brightness, BRIGHTNESS_MODE_USER);   //亮度模式默认为BRIGHTNESS_MODE_USER  
  4. }  
  5.   
  6. @Override  
  7. public void setBrightness(int brightness, int brightnessMode) {  
  8.     synchronized (this) {  
  9.         int color = brightness & 0x000000ff;  
  10.         color = 0xff000000 | (color << 16) | (color << 8) | color;   //设置光颜色  
  11.         setLightLocked(color, LIGHT_FLASH_NONE, 00, brightnessMode);  
  12.     }  
  13. }  
  14. private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {  
  15.     if (!LightsUtilsFactory.getInstance().isBatteryOpenWhenNotificationCome(mId, color)){  
  16.         if (!mLocked && (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS ||  
  17.                 mBrightnessMode != brightnessMode)) {  
  18.             if (DEBUG || isDebugNotifyLight()) Slog.v(TAG, "setLight #" + mId + ": color=#"  
  19.                     + Integer.toHexString(color) + ": brightnessMode=" + brightnessMode);  
  20.             mLastColor = mColor;  
  21.             mColor = color;  
  22.             mMode = mode;  
  23.             mOnMS = onMS;  
  24.             mOffMS = offMS;  
  25.             mLastBrightnessMode = mBrightnessMode;  
  26.             mBrightnessMode = brightnessMode;  
  27.             Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"  
  28.                     + Integer.toHexString(color) + ")");  
  29.             try {  
  30.                 setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);  //调用jni层设置亮度  
  31.             } finally {  
  32.                 Trace.traceEnd(Trace.TRACE_TAG_POWER);  
  33.             }  
  34.         }  
  35.     }  
  36. }  
通过JNI调用com_android_server_lights_LightsService.cpp的setLight_native函数
[java] view plain copy
  1. static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, jlong ptr,  
  2.         jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint brightnessMode)  
  3. {  
  4.     Devices* devices = (Devices*)ptr;  
  5.     light_state_t state;  
  6.   
  7.     if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {  
  8.         return ;  
  9.     }  
  10.   
  11.     uint32_t version = devices->lights[light]->common.version;  
  12.   
  13.     memset(&state, 0, sizeof(light_state_t));  
  14.   
  15.     if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {  
  16.         if (light != LIGHT_INDEX_BACKLIGHT) {  
  17.             ALOGE("Cannot set low-persistence mode for non-backlight device.");  
  18.             return;  
  19.         }  
  20.         if (version < LIGHTS_DEVICE_API_VERSION_2_0) {  
  21.             // HAL impl has not been upgraded to support this.  
  22.             return;  
  23.         }  
  24.     } else {  
  25.         // Only set non-brightness settings when not in low-persistence mode  
  26.         state.color = colorARGB;  
  27.         state.flashMode = flashMode;  
  28.         state.flashOnMS = onMS;  
  29.         state.flashOffMS = offMS;  
  30.     }  
  31.   
  32.     state.brightnessMode = brightnessMode;  
  33.   
  34.     {  
  35.         ALOGD_IF_SLOW(50"Excessive delay setting light");   //当设置亮度耗时大于50ms,就会输出该行log.  
  36.         devices->lights[light]->set_light(devices->lights[light], &state);  
  37.     }  
  38. }  
之后调用BSP向亮度节点写入亮度值. 从而点亮屏幕.


灭屏流程分析

灭屏总览


                   

在点击power键灭屏过程中,主要流程就是input对按键事件的传输,传送到上层处理。在PhoneWindowManager中判断是否为灭屏事件, 之后就是在power中进行对亮屏状态的处理,计算一系列的数值,并且与AMS,WMS等模块进行交互,最后调用底层LCD进行最终的设备状态与亮度的设置。灭屏流程与亮屏流程有很多共同流程,在这里只讲解灭屏的独特流程。
                            
当wakefulness状态发生改变,AMS收到通知。如果亮屏操作,AMS就会通过函数comeOutOfSleepIfNeedLocked调用到ActivityStackSupervisor中,将sleep超时消息移除,如果抓的有partial锁,就将其释放,最后将在栈顶的activity显示出来。
当亮屏时通过InputManagerService将当前屏幕状态传入JNI中进行记录,当再次发生power键事件可以方便确认该事件是需要亮屏还是灭屏。
灭屏时首先在Notifier中通过PhoneWindowManager来通知keyguard系统开始灭屏。
灭屏动画
在PowerManagerService中获得屏幕的请求状态为OFF,即设置state为Display.STATE_OFF,在这里将performScreenOffTransition为true。

[java] view plain copy
  1. case DisplayPowerRequest.POLICY_OFF:  
  2.     state = Display.STATE_OFF;  
  3.     performScreenOffTransition = true;  
  4.     break;  
调用animateScreenStateChange进行处理屏幕状态。
[java] view plain copy
  1. // Animate the screen state change unless already animating.  
  2. // The transition may be deferred, so after this point we will use the  
  3. // actual state instead of the desired one.  
  4. animateScreenStateChange(state, performScreenOffTransition);  
  5. state = mPowerState.getScreenState();  
如果目标亮度不为STATE_ON,STATE_DOZE,STATE_DOZE_SUSPEND屏幕就要去睡眠了。
[java] view plain copy
  1. // Want screen off.  
  2. mPendingScreenOff = true;  
  3. if (mPowerState.getColorFadeLevel() == 0.0f) {  
  4.     // Turn the screen off.  
  5.     // A black surface is already hiding the contents of the screen.  
  6.     setScreenState(Display.STATE_OFF);  
  7.     mPendingScreenOff = false;  
  8.     mPowerState.dismissColorFadeResources();  
  9. else if (performScreenOffTransition  
  10.         && mPowerState.prepareColorFade(mContext,  
  11.                 mColorFadeFadesConfig ?  
  12.                         ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)  
  13.         && mPowerState.getScreenState() != Display.STATE_OFF) {  
  14.     // Perform the screen off animation.  
  15.     mColorFadeOffAnimator.start();  
  16. else {  
  17.     // Skip the screen off animation and add a black surface to hide the  
  18.     // contents of the screen.  
  19.     mColorFadeOffAnimator.end();  
  20. }  
在这里就要判断ColorFadeLevel是不是0.0,由于亮屏时将ColorFadeLevel设置为1.0所以走else语句,如果performScreenOffTransition为true并且将ColorFade准备好了就开始灭屏动画将ColorFadeLevel从1.0渐变为0.0。但是前面知道将performScreenOffTransition设置为了false,所以就没有了灭屏动画,直接将ColorFadeLevel设置为0.0。之后就调用setScreenState设置状态。
发送灭屏广播
                              

power是通过WindowManagerPolicy与PhoneWindowManager进行交互,当屏幕在finishedGoingToSleep时需要通知window进行更新手势监听,更新方向监听,更新锁屏超时时间。之后发送灭屏广播通知关心灭屏事件的模块。

到此为止亮灭屏流程讲解完毕.

阅读全文
0 0
原创粉丝点击