在前面兩部分已經(jīng)對繪制windows與設置設備狀態(tài)進行了詳細講解. 之后接著就該對亮度值進行設置, 實現(xiàn)亮屏動作了.
在DisplayPowerController中的animateScreenBrightness函數(shù)通過亮度漸變動畫來將亮度設置到目標亮度.
[java]?view plain
?copy??private?static?final?int?BRIGHTNESS_RAMP_RATE_SLOW?=?40;?????????????mBrightnessRampRateFast?=?resources.getInteger(??????????????com.android.internal.R.integer.config_brightness_ramp_rate_fast);???????????????????????if?(!mPendingScreenOff)?{??????????if?(state?==?Display.STATE_ON?||?state?==?Display.STATE_DOZE)?{??????????????animateScreenBrightness(brightness,????????????????????????????slowChange???BRIGHTNESS_RAMP_RATE_SLOW?:?mBrightnessRampRateFast);??????????}?else?{??????????????animateScreenBrightness(brightness,?0);?????????????}??????}??在animateScreenBrightness函數(shù)中調(diào)用動畫mScreenBrightnessRampAnimator對亮度值處理, 而mScreenBrightnessRampAnimator是在initialize()函數(shù)中進行初始化的, 在構(gòu)造函數(shù)中將DisplayPowerState和DisplayPowerState.SCREEN_BRIGHTNESS傳輸過去.
[java]?view plain
?copy??private?void?initialize()?{??????????????????mScreenBrightnessRampAnimator?=?new?RampAnimator<DisplayPowerState>(????????????????????mPowerState,?DisplayPowerState.SCREEN_BRIGHTNESS);??????????mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);?????????}????????private?void?animateScreenBrightness(int?target,?int?rate)?{??????????if?(DEBUG)?{??????????????Slog.d(TAG,?"Animating?brightness:?target="?+?target?+",?rate="?+?rate);??????????}??????????if?(mScreenBrightnessRampAnimator.animateTo(target,?rate))?{??????????????????try?{??????????????????mBatteryStats.noteScreenBrightness(target);??????????????}?catch?(RemoteException?ex)?{????????????????????????????????}??????????}??????}??在RampAnimator的構(gòu)造函數(shù)中將DisplayPowerState賦值給mObject,?DisplayPowerState.SCREEN_BRIGHTNESS賦值給mProperty, 并且創(chuàng)建mChoreographer實例.
[java]?view plain
?copypublic?RampAnimator(T?object,?IntProperty<T>?property)?{??????mObject?=?object;??????mProperty?=?property;??????mChoreographer?=?Choreographer.getInstance();??}??下面重點講解animateTo函數(shù).
[java]?view plain
?copypublic?boolean?animateTo(int?target,?int?rate)?{????????????if?(mFirstTime?||?rate?<=?0)?{?????????????if?(mFirstTime?||?target?!=?mCurrentValue)?{??????????????mFirstTime?=?false;?????????????????mRate?=?0;????????????????????????????mTargetValue?=?target;?????????????????mCurrentValue?=?target;??????????????mProperty.setValue(mObject,?target);?????????????????if?(mAnimating)?{??????????????????mAnimating?=?false;??????????????????cancelAnimationCallback();??????????????}??????????????if?(mListener?!=?null)?{??????????????????mListener.onAnimationEnd();????????????????}??????????????return?true;??????????}??????????return?false;??????}??????????????????????????????????????????????????if?(!mAnimating??????????????||?rate?>?mRate??????????????||?(target?<=?mCurrentValue?&&?mCurrentValue?<=?mTargetValue)??????????????||?(mTargetValue?<=?mCurrentValue?&&?mCurrentValue?<=?target))?{??????????mRate?=?rate;?????????}????????final?boolean?changed?=?(mTargetValue?!=?target);????????mTargetValue?=?target;??????????????????if?(!mAnimating?&&?target?!=?mCurrentValue)?{????????????mAnimating?=?true;??????????mAnimatedValue?=?mCurrentValue;??????????mLastFrameTimeNanos?=?System.nanoTime();??????????postAnimationCallback();??????}????????return?changed;???}??在postAnimationCallback中調(diào)用Choreographer的postCallback函數(shù)處理, 調(diào)用完成后回調(diào)回mAnimationCallback的run函數(shù)
[java]?view plain
?copyprivate?void?postAnimationCallback()?{??????mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION,?mAnimationCallback,?null);??}????private?final?Runnable?mAnimationCallback?=?new?Runnable()?{??????@Override???????public?void?run()?{??????????final?long?frameTimeNanos?=?mChoreographer.getFrameTimeNanos();??????????final?float?timeDelta?=?(frameTimeNanos?-?mLastFrameTimeNanos)??????????????????*?0.000000001f;??????????mLastFrameTimeNanos?=?frameTimeNanos;??????????????????????????????????????????????????????final?float?scale?=?ValueAnimator.getDurationScale();??????????if?(scale?==?0)?{????????????????????????????mAnimatedValue?=?mTargetValue;?????????????}?else?{??????????????final?float?amount?=?timeDelta?*?mRate?/?scale;????????????????if?(mTargetValue?>?mCurrentValue)?{??????????????????mAnimatedValue?=?Math.min(mAnimatedValue?+?amount,?mTargetValue);????????????????}?else?{??????????????????mAnimatedValue?=?Math.max(mAnimatedValue?-?amount,?mTargetValue);???????????????}??????????}??????????final?int?oldCurrentValue?=?mCurrentValue;??????????mCurrentValue?=?Math.round(mAnimatedValue);??????????????if?(oldCurrentValue?!=?mCurrentValue)?{??????????????mProperty.setValue(mObject,?mCurrentValue);????????????}????????????if?(mTargetValue?!=?mCurrentValue)?{??????????????postAnimationCallback();?????????????}?else?{??????????????mAnimating?=?false;??????????????if?(mListener?!=?null)?{??????????????????mListener.onAnimationEnd();????????????????}??????????}??????}??};??DisplayPowerState.SCREEN_BRIGHTNESS的setValue函數(shù)是在DisplayPowerState中實現(xiàn)的.
[java]?view plain
?copypublic?static?final?IntProperty<DisplayPowerState>?SCREEN_BRIGHTNESS?=??????????new?IntProperty<DisplayPowerState>("screenBrightness")?{??????@Override??????public?void?setValue(DisplayPowerState?object,?int?value)?{??????????object.setScreenBrightness(value);????????}????????@Override??????public?Integer?get(DisplayPowerState?object)?{??????????return?object.getScreenBrightness();??????}??};????public?void?setScreenBrightness(int?brightness)?{??????if?(mScreenBrightness?!=?brightness)?{??????????if?(DEBUG)?{??????????????Slog.d(TAG,?"setScreenBrightness:?brightness="?+?brightness);??????????}????????????mScreenBrightness?=?brightness;????????????if?(mScreenState?!=?Display.STATE_OFF)?{??????????????mScreenReady?=?false;??????????????scheduleScreenUpdate();?????????????}??????}??}??scheduleScreenUpdate函數(shù)最終通過Handler發(fā)送mScreenUpdateRunnable對象來更新亮度值. 從run函數(shù)中可以看出只有當mColorFadeLevel > 0f時才能給brightness設置亮度值, 所以說當windows沒有繪制完成時就算mScreenBrightness有值不為0, 但是brightness仍然為0不能點亮屏幕.
[java]?view plain
?copyprivate?final?Runnable?mScreenUpdateRunnable?=?new?Runnable()?{??????@Override??????public?void?run()?{??????????mScreenUpdatePending?=?false;????????????int?brightness?=?mScreenState?!=?Display.STATE_OFF??????????????????&&?mColorFadeLevel?>?0f???mScreenBrightness?:?0;??????????????if?(mPhotonicModulator.setState(mScreenState,?brightness))?{??????????????if?(DEBUG)?{??????????????????Slog.d(TAG,?"Screen?ready");??????????????}??????????????mScreenReady?=?true;??????????????invokeCleanListenerIfNeeded();??????????}?else?{??????????????if?(DEBUG)?{??????????????????Slog.d(TAG,?"Screen?not?ready");??????????????}??????????}??????}??};??之后的流程就與設置設置狀態(tài)的流程相同了, 調(diào)用DisplayManagerService中DisplayBlanker的requestDisplayState函數(shù).
[java]?view plain
?copyDisplayBlanker?blanker?=?new?DisplayBlanker()?{??????@Override??????public?void?requestDisplayState(int?state,?int?brightness)?{????????????????????if?(state?==?Display.STATE_OFF)?{??????????????requestGlobalDisplayStateInternal(state,?brightness);??????????}????????????callbacks.onDisplayStateChange(state);????????????????if?(state?!=?Display.STATE_OFF)?{??????????????requestGlobalDisplayStateInternal(state,?brightness);????????????}??????}??};??[java]?view plain
?copyprivate?void?requestGlobalDisplayStateInternal(int?state,?int?brightness)?{??????if?(state?==?Display.STATE_UNKNOWN)?{??????????state?=?Display.STATE_ON;??????}??????if?(state?==?Display.STATE_OFF)?{??????????brightness?=?PowerManager.BRIGHTNESS_OFF;????????}?else?if?(brightness?<?0)?{??????????brightness?=?PowerManager.BRIGHTNESS_DEFAULT;????????}?else?if?(brightness?>?PowerManager.BRIGHTNESS_ON)?{??????????brightness?=?PowerManager.BRIGHTNESS_ON;??????????}????????synchronized?(mTempDisplayStateWorkQueue)?{??????????try?{????????????????????????????????????????????????????????synchronized?(mSyncRoot)?{??????????????????if?(mGlobalDisplayState?==?state??????????????????????????&&?mGlobalDisplayBrightness?==?brightness)?{??????????????????????return;???????????????????}????????????????????Trace.traceBegin(Trace.TRACE_TAG_POWER,?"requestGlobalDisplayState("??????????????????????????+?Display.stateToString(state)??????????????????????????+?",?brightness="?+?brightness?+?")");??????????????????mGlobalDisplayState?=?state;??????????????????mGlobalDisplayBrightness?=?brightness;??????????????????applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);?????????????????}????????????????????????????????????????????????????????????????????????for?(int?i?=?0;?i?<?mTempDisplayStateWorkQueue.size();?i++)?{??????????????????mTempDisplayStateWorkQueue.get(i).run();????????????????}??????????????Trace.traceEnd(Trace.TRACE_TAG_POWER);??????????}?finally?{??????????????mTempDisplayStateWorkQueue.clear();??????????}??????}??}??在applyGlobalDisplayStateLocked函數(shù)中獲取所有的devices, 調(diào)用對應設備的requestDisplayStateLocked函數(shù)更新請求狀態(tài). 啟動devices為LocalDisplayAdapter, 就會調(diào)用到該類的requestDisplayStateLocked獲得runnable.
[java]?view plain
?copyprivate?void?applyGlobalDisplayStateLocked(List<Runnable>?workQueue)?{??????final?int?count?=?mDisplayDevices.size();??????for?(int?i?=?0;?i?<?count;?i++)?{?????????????DisplayDevice?device?=?mDisplayDevices.get(i);??????????Runnable?runnable?=?updateDisplayStateLocked(device);????????????if?(runnable?!=?null)?{??????????????workQueue.add(runnable);????????????}??????}??}????private?Runnable?updateDisplayStateLocked(DisplayDevice?device)?{??????????????????DisplayDeviceInfo?info?=?device.getDisplayDeviceInfoLocked();????????if?((info.flags?&?DisplayDeviceInfo.FLAG_NEVER_BLANK)?==?0)?{??????????return?device.requestDisplayStateLocked(mGlobalDisplayState,?mGlobalDisplayBrightness);???????}??????return?null;??}??在requestDisplayStateLocked中主要的任務就是創(chuàng)建一個runnable返回到DisplayManagerService中,并且等待回調(diào)run函數(shù).
[java]?view plain
?copy@Override??public?Runnable?requestDisplayStateLocked(final?int?state,?final?int?brightness)?{????????????assert?state?!=?Display.STATE_OFF?||?brightness?==?PowerManager.BRIGHTNESS_OFF;????????final?boolean?stateChanged?=?(mState?!=?state);????????final?boolean?brightnessChanged?=?(mBrightness?!=?brightness)?&&?mBacklight?!=?null;????????if?(stateChanged?||?brightnessChanged)?{????????????final?int?displayId?=?mBuiltInDisplayId;??????????final?IBinder?token?=?getDisplayTokenLocked();??????????final?int?oldState?=?mState;????????????if?(stateChanged)?{?????????????????mState?=?state;??????????????updateDeviceInfoLocked();??????????}????????????if?(brightnessChanged)?{??????????????mBrightness?=?brightness;????????????}??????????????????????????????????????????return?new?Runnable()?{??????????????????@Override??????????????public?void?run()?{??????????????????????????????????????int?currentState?=?oldState;??????????????????if?(Display.isSuspendedState(oldState)??????????????????????????????||?oldState?==?Display.STATE_UNKNOWN)?{??????????????????????if?(!Display.isSuspendedState(state))?{??????????????????????????setDisplayState(state);??????????????????????????currentState?=?state;??????????????????????}?else?if?(state?==?Display.STATE_DOZE_SUSPEND??????????????????????????????||?oldState?==?Display.STATE_DOZE_SUSPEND)?{??????????????????????????setDisplayState(Display.STATE_DOZE);??????????????????????????currentState?=?Display.STATE_DOZE;??????????????????????}?else?{??????????????????????????return;???????????????????????}??????????????????}??????????????????????????????????????if?(brightnessChanged)?{??????????????????????if?(isPowerDebug())?{??????????????????????????Slog.d(TAG,?"set?display?brightness="?+?brightness);??????????????????????}??????????????????????setDisplayBrightness(brightness);??????????????????????}??????????????????????????????????????if?(state?!=?currentState)?{??????????????????????if(isPowerDebug())?{??????????????????????????Slog.d(TAG,?"set?display?state="?+?state);??????????????????????}??????????????????????setDisplayState(state);??????????????????}??????????????}??[java]?view plain
?copy????????????private?void?setDisplayBrightness(int?brightness)?{??????????????????if?(DEBUG)?{??????????????????????Slog.d(TAG,?"setDisplayBrightness("??????????????????????????????+?"id="?+?displayId?+?",?brightness="?+?brightness?+?")");??????????????????}????????????????????Trace.traceBegin(Trace.TRACE_TAG_POWER,?"setDisplayBrightness("??????????????????????????+?"id="?+?displayId?+?",?brightness="?+?brightness?+?")");??????????????????try?{??????????????????????mBacklight.setBrightness(brightness);?????????????????????}?finally?{??????????????????????Trace.traceEnd(Trace.TRACE_TAG_POWER);??????????????????}??????????????}??????????};??????}??????return?null;??}??[java]?view plain
?copy@Override??public?void?setBrightness(int?brightness)?{??????setBrightness(brightness,?BRIGHTNESS_MODE_USER);?????}????@Override??public?void?setBrightness(int?brightness,?int?brightnessMode)?{??????synchronized?(this)?{??????????int?color?=?brightness?&?0x000000ff;??????????color?=?0xff000000?|?(color?<<?16)?|?(color?<<?8)?|?color;?????????????setLightLocked(color,?LIGHT_FLASH_NONE,?0,?0,?brightnessMode);??????}??}??private?void?setLightLocked(int?color,?int?mode,?int?onMS,?int?offMS,?int?brightnessMode)?{??????if?(!LightsUtilsFactory.getInstance().isBatteryOpenWhenNotificationCome(mId,?color)){??????????if?(!mLocked?&&?(color?!=?mColor?||?mode?!=?mMode?||?onMS?!=?mOnMS?||?offMS?!=?mOffMS?||??????????????????mBrightnessMode?!=?brightnessMode))?{??????????????if?(DEBUG?||?isDebugNotifyLight())?Slog.v(TAG,?"setLight?#"?+?mId?+?":?color=#"??????????????????????+?Integer.toHexString(color)?+?":?brightnessMode="?+?brightnessMode);??????????????mLastColor?=?mColor;??????????????mColor?=?color;??????????????mMode?=?mode;??????????????mOnMS?=?onMS;??????????????mOffMS?=?offMS;??????????????mLastBrightnessMode?=?mBrightnessMode;??????????????mBrightnessMode?=?brightnessMode;??????????????Trace.traceBegin(Trace.TRACE_TAG_POWER,?"setLight("?+?mId?+?",?0x"??????????????????????+?Integer.toHexString(color)?+?")");??????????????try?{??????????????????setLight_native(mNativePointer,?mId,?color,?mode,?onMS,?offMS,?brightnessMode);????????????????}?finally?{??????????????????Trace.traceEnd(Trace.TRACE_TAG_POWER);??????????????}??????????}??????}??}??通過JNI調(diào)用com_android_server_lights_LightsService.cpp的setLight_native函數(shù)
[java]?view plain
?copystatic?void?setLight_native(JNIEnv*?,?jobject?,?jlong?ptr,??????????jint?light,?jint?colorARGB,?jint?flashMode,?jint?onMS,?jint?offMS,?jint?brightnessMode)??{??????Devices*?devices?=?(Devices*)ptr;??????light_state_t?state;????????if?(light?<?0?||?light?>=?LIGHT_COUNT?||?devices->lights[light]?==?NULL)?{??????????return?;??????}????????uint32_t?version?=?devices->lights[light]->common.version;????????memset(&state,?0,?sizeof(light_state_t));????????if?(brightnessMode?==?BRIGHTNESS_MODE_LOW_PERSISTENCE)?{??????????if?(light?!=?LIGHT_INDEX_BACKLIGHT)?{??????????????ALOGE("Cannot?set?low-persistence?mode?for?non-backlight?device.");??????????????return;??????????}??????????if?(version?<?LIGHTS_DEVICE_API_VERSION_2_0)?{????????????????????????????return;??????????}??????}?else?{????????????????????state.color?=?colorARGB;??????????state.flashMode?=?flashMode;??????????state.flashOnMS?=?onMS;??????????state.flashOffMS?=?offMS;??????}????????state.brightnessMode?=?brightnessMode;????????{??????????ALOGD_IF_SLOW(50,?"Excessive?delay?setting?light");?????????????devices->lights[light]->set_light(devices->lights[light],?&state);??????}??}??之后調(diào)用BSP向亮度節(jié)點寫入亮度值. 從而點亮屏幕.
滅屏流程分析
滅屏總覽
? ? ? ? ? ? ? ? ? ?
在點擊power鍵滅屏過程中,主要流程就是input對按鍵事件的傳輸,傳送到上層處理。在PhoneWindowManager中判斷是否為滅屏事件, 之后就是在power中進行對亮屏狀態(tài)的處理,計算一系列的數(shù)值,并且與AMS,WMS等模塊進行交互,最后調(diào)用底層LCD進行最終的設備狀態(tài)與亮度的設置。滅屏流程與亮屏流程有很多共同流程,在這里只講解滅屏的獨特流程。
? ? ? ? ? ? ? ? ? ? ? ? ? ??
當wakefulness狀態(tài)發(fā)生改變,AMS收到通知。如果亮屏操作,AMS就會通過函數(shù)comeOutOfSleepIfNeedLocked調(diào)用到ActivityStackSupervisor中,將sleep超時消息移除,如果抓的有partial鎖,就將其釋放,最后將在棧頂?shù)腶ctivity顯示出來。
當亮屏時通過InputManagerService將當前屏幕狀態(tài)傳入JNI中進行記錄,當再次發(fā)生power鍵事件可以方便確認該事件是需要亮屏還是滅屏。
滅屏時首先在Notifier中通過PhoneWindowManager來通知keyguard系統(tǒng)開始滅屏。
滅屏動畫
在PowerManagerService中獲得屏幕的請求狀態(tài)為OFF,即設置state為Display.STATE_OFF,在這里將performScreenOffTransition為true。
[java]?view plain
?copycase?DisplayPowerRequest.POLICY_OFF:??????state?=?Display.STATE_OFF;??????performScreenOffTransition?=?true;??????break;??調(diào)用animateScreenStateChange進行處理屏幕狀態(tài)。
[java]?view plain
?copy??????animateScreenStateChange(state,?performScreenOffTransition);??state?=?mPowerState.getScreenState();??如果目標亮度不為STATE_ON,STATE_DOZE,STATE_DOZE_SUSPEND屏幕就要去睡眠了。
[java]?view plain
?copy??mPendingScreenOff?=?true;??if?(mPowerState.getColorFadeLevel()?==?0.0f)?{??????????????????setScreenState(Display.STATE_OFF);??????mPendingScreenOff?=?false;??????mPowerState.dismissColorFadeResources();??}?else?if?(performScreenOffTransition??????????&&?mPowerState.prepareColorFade(mContext,??????????????????mColorFadeFadesConfig????????????????????????????ColorFade.MODE_FADE?:?ColorFade.MODE_COOL_DOWN)??????????&&?mPowerState.getScreenState()?!=?Display.STATE_OFF)?{????????????mColorFadeOffAnimator.start();??}?else?{??????????????????mColorFadeOffAnimator.end();??}??在這里就要判斷ColorFadeLevel是不是0.0,由于亮屏時將ColorFadeLevel設置為1.0所以走else語句,如果performScreenOffTransition為true并且將ColorFade準備好了就開始滅屏動畫將ColorFadeLevel從1.0漸變?yōu)?.0。但是前面知道將performScreenOffTransition設置為了false,所以就沒有了滅屏動畫,直接將ColorFadeLevel設置為0.0。之后就調(diào)用setScreenState設置狀態(tài)。
發(fā)送滅屏廣播? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
power是通過WindowManagerPolicy與PhoneWindowManager進行交互,當屏幕在finishedGoingToSleep時需要通知window進行更新手勢監(jiān)聽,更新方向監(jiān)聽,更新鎖屏超時時間。之后發(fā)送滅屏廣播通知關心滅屏事件的模塊。
到此為止亮滅屏流程講解完畢.
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 https://blog.csdn.net/fu_kevin0606/article/details/54427641
總結(jié)
以上是生活随笔為你收集整理的Android7.0 PowerManagerService亮灭屏分析(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。