Android7.0 PowerManagerService亮灭屏分析(三)
在前面两部分已经对绘制windows与设置设备状态进行了详细讲解. 之后接着就该对亮度值进行设置, 实现亮屏动作了.
在DisplayPowerController中的animateScreenBrightness函数通过亮度渐变动画来将亮度设置到目标亮度.
- // Brightness animation ramp rate in brightness units per second.
- private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40; //亮度渐变动画较慢的速率, 每秒变化40个亮度单位
- mBrightnessRampRateFast = resources.getInteger(
- com.android.internal.R.integer.config_brightness_ramp_rate_fast); //从配置文件中获取较快的亮度速率
- // Animate the screen brightness when the screen is on or dozing.
- // Skip the animation when the screen is off or suspended.
- if (!mPendingScreenOff) {
- if (state == Display.STATE_ON || state == Display.STATE_DOZE) {
- animateScreenBrightness(brightness, //当亮屏或doze状态时有亮度渐变动画
- slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : mBrightnessRampRateFast);
- } else {
- animateScreenBrightness(brightness, 0); //灭屏时没有亮度渐变动画,直接将亮度设置为0
- }
- }
- private void initialize() {
- //....
- mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( //泛型为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) {
- // same process
- }
- }
- }
在RampAnimator的构造函数中将DisplayPowerState赋值给mObject, DisplayPowerState.SCREEN_BRIGHTNESS赋值给mProperty, 并且创建mChoreographer实例.
- public RampAnimator(T object, IntProperty<T> property) {
- mObject = object;
- mProperty = property;
- mChoreographer = Choreographer.getInstance();
- }
下面重点讲解animateTo函数.
- public boolean animateTo(int target, int rate) {
- // Immediately jump to the target the first time.
- if (mFirstTime || rate <= 0) { //当第一次调用animateTo, 或者rate小于等于0时直接设置目标亮度.
- if (mFirstTime || target != mCurrentValue) {
- mFirstTime = false; //之后就不是第一次调用该函数
- mRate = 0; //设置mRate为0
- mTargetValue = target; //设置目标亮度为target
- mCurrentValue = target;
- mProperty.setValue(mObject, target); //调用DisplayPowerState.SCREEN_BRIGHTNESS设置亮度值
- if (mAnimating) {
- mAnimating = false;
- cancelAnimationCallback();
- }
- if (mListener != null) {
- mListener.onAnimationEnd(); //动画结束
- }
- return true;
- }
- return false;
- }
- // Adjust the rate based on the closest target.
- // If a faster rate is specified, then use the new rate so that we converge
- // more rapidly based on the new request.
- // If a slower rate is specified, then use the new rate only if the current
- // value is somewhere in between the new and the old target meaning that
- // we will be ramping in a different direction to get there.
- // Otherwise, continue at the previous rate.
- if (!mAnimating
- || rate > mRate
- || (target <= mCurrentValue && mCurrentValue <= mTargetValue)
- || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) {
- mRate = rate; //重新调节亮度速率
- }
- final boolean changed = (mTargetValue != target); //如果当前亮度值不等于目标亮度值,说明亮度改变了
- mTargetValue = target; //重新设置mTargetValue
- // Start animating. 开始动画
- if (!mAnimating && target != mCurrentValue) {
- mAnimating = true;
- mAnimatedValue = mCurrentValue;
- mLastFrameTimeNanos = System.nanoTime();
- postAnimationCallback();
- }
- return changed;
- }
- private void postAnimationCallback() {
- mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);
- }
- private final Runnable mAnimationCallback = new Runnable() {
- @Override // Choreographer callback
- public void run() {
- final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
- final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)
- * 0.000000001f;
- mLastFrameTimeNanos = frameTimeNanos; //记录最后一次的frameTimeNanos
- // Advance the animated value towards the target at the specified rate
- // and clamp to the target. This gives us the new current value but
- // we keep the animated value around to allow for fractional increments
- // towards the target.
- final float scale = ValueAnimator.getDurationScale();
- if (scale == 0) {
- // Animation off.
- mAnimatedValue = mTargetValue; //让scale为0时, 表示动画停止了, 将mAnimatedValue设置为目标亮度
- } else {
- final float amount = timeDelta * mRate / scale; //计算每一次需要变化的亮度值
- if (mTargetValue > mCurrentValue) {
- mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue); //亮屏,每次增加亮度amount,不超过目标亮度
- } else {
- mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); //暗屏, 每次减少amount个亮度, 不超过目标亮度
- }
- }
- final int oldCurrentValue = mCurrentValue;
- mCurrentValue = Math.round(mAnimatedValue); //获取当前要达到的亮度值
- if (oldCurrentValue != mCurrentValue) {
- mProperty.setValue(mObject, mCurrentValue); //调用DisplayPowerState.SCREEN_BRIGHTNESS设置亮度值
- }
- if (mTargetValue != mCurrentValue) {
- postAnimationCallback(); //如果还没有达到目标亮度,就会继续调用postAnimationCallback循环设置亮度值
- } else {
- mAnimating = false;
- if (mListener != null) {
- mListener.onAnimationEnd(); //否则,亮度动画结束
- }
- }
- }
- };
- public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS =
- new IntProperty<DisplayPowerState>("screenBrightness") {
- @Override
- public void setValue(DisplayPowerState object, int value) {
- object.setScreenBrightness(value); //调用DisplayPowerState的setScreenBrightness函数,设置亮度值
- }
- @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(); //如果不是灭屏状态,更新屏幕状态
- }
- }
- }
- private 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");
- }
- }
- }
- };
- DisplayBlanker blanker = new DisplayBlanker() {
- @Override
- public void requestDisplayState(int state, int brightness) {
- // The order of operations is important for legacy reasons.
- if (state == Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state, brightness);
- }
- callbacks.onDisplayStateChange(state);
- if (state != Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state, brightness); //亮屏调用设置状态,亮度
- }
- }
- };
- private void requestGlobalDisplayStateInternal(int state, int brightness) {
- if (state == Display.STATE_UNKNOWN) {
- state = Display.STATE_ON;
- }
- if (state == Display.STATE_OFF) {
- brightness = PowerManager.BRIGHTNESS_OFF; //灭屏设置屏幕亮度为0
- } else if (brightness < 0) {
- brightness = PowerManager.BRIGHTNESS_DEFAULT; //屏幕亮度小于0,设置为默认亮度
- } else if (brightness > PowerManager.BRIGHTNESS_ON) {
- brightness = PowerManager.BRIGHTNESS_ON; //屏幕亮度大于255设置最大亮度值255
- }
- synchronized (mTempDisplayStateWorkQueue) {
- try {
- // Update the display state within the lock.
- // Note that we do not need to schedule traversals here although it
- // may happen as a side-effect of displays changing state.
- synchronized (mSyncRoot) {
- if (mGlobalDisplayState == state
- && mGlobalDisplayBrightness == brightness) {
- return; // no change 亮度与状态都没有改变就return
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
- + Display.stateToString(state)
- + ", brightness=" + brightness + ")");
- mGlobalDisplayState = state;
- mGlobalDisplayBrightness = brightness;
- applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); //应用全局状态
- }
- // Setting the display power state can take hundreds of milliseconds
- // to complete so we defer the most expensive part of the work until
- // after we have exited the critical section to avoid blocking other
- // threads for a long time.
- for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
- mTempDisplayStateWorkQueue.get(i).run(); //运行mTempDisplayStateWorkQueue队列中的runnable
- }
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- } finally {
- mTempDisplayStateWorkQueue.clear();
- }
- }
- }
- private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
- final int count = mDisplayDevices.size();
- for (int i = 0; i < count; i++) { //遍历devices
- DisplayDevice device = mDisplayDevices.get(i);
- Runnable runnable = updateDisplayStateLocked(device); //获得devices中的runnable
- if (runnable != null) {
- workQueue.add(runnable); //将runnable加入workQueue队列, 即mTempDisplayStateWorkQueue队列
- }
- }
- }
- private Runnable updateDisplayStateLocked(DisplayDevice device) {
- // Blank or unblank the display immediately to match the state requested
- // by the display power controller (if known).
- DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); //获取devices信息
- if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
- return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); //调用requestDisplayStateLocked函数
- }
- return null;
- }
在requestDisplayStateLocked中主要的任务就是创建一个runnable返回到DisplayManagerService中,并且等待回调run函数.
- @Override
- public Runnable requestDisplayStateLocked(final int state, final int brightness) {
- // Assume that the brightness is off if the display is being turned off.
- 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; //设置mBrightness
- }
- // Defer actually setting the display state until after we have exited
- // the critical section since it can take hundreds of milliseconds
- // to complete.
- return new Runnable() { //新建一个runnable返回
- @Override
- public void run() { //在DisplayManagerService中调用run函数
- // Exit a suspended state before making any changes.
- int currentState = oldState;
- if (Display.isSuspendedState(oldState) //判断设置是否还是在suspend状态
- || 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; // old state and new state is off
- }
- }
- // Apply brightness changes given that we are in a non-suspended state.
- if (brightnessChanged) {
- if (isPowerDebug()) {
- Slog.d(TAG, "set display brightness=" + brightness);
- }
- setDisplayBrightness(brightness); //设置屏幕亮度
- }
- // Enter the final desired state, possibly suspended.
- if (state != currentState) {
- if(isPowerDebug()) {
- Slog.d(TAG, "set display state=" + state);
- }
- setDisplayState(state);
- }
- }
- 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); //调用LightService设置亮度
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
- };
- }
- return null;
- }
- @Override
- public void setBrightness(int brightness) {
- setBrightness(brightness, BRIGHTNESS_MODE_USER); //亮度模式默认为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); //调用jni层设置亮度
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
- }
- }
- static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, 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) {
- // HAL impl has not been upgraded to support this.
- return;
- }
- } else {
- // Only set non-brightness settings when not in low-persistence mode
- state.color = colorARGB;
- state.flashMode = flashMode;
- state.flashOnMS = onMS;
- state.flashOffMS = offMS;
- }
- state.brightnessMode = brightnessMode;
- {
- ALOGD_IF_SLOW(50, "Excessive delay setting light"); //当设置亮度耗时大于50ms,就会输出该行log.
- devices->lights[light]->set_light(devices->lights[light], &state);
- }
- }
灭屏流程分析
灭屏总览
在点击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。
- case DisplayPowerRequest.POLICY_OFF:
- state = Display.STATE_OFF;
- performScreenOffTransition = true;
- break;
- // Animate the screen state change unless already animating.
- // The transition may be deferred, so after this point we will use the
- // actual state instead of the desired one.
- animateScreenStateChange(state, performScreenOffTransition);
- state = mPowerState.getScreenState();
- // Want screen off.
- mPendingScreenOff = true;
- if (mPowerState.getColorFadeLevel() == 0.0f) {
- // Turn the screen off.
- // A black surface is already hiding the contents of the screen.
- 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) {
- // Perform the screen off animation.
- mColorFadeOffAnimator.start();
- } else {
- // Skip the screen off animation and add a black surface to hide the
- // contents of the screen.
- mColorFadeOffAnimator.end();
- }
发送灭屏广播
power是通过WindowManagerPolicy与PhoneWindowManager进行交互,当屏幕在finishedGoingToSleep时需要通知window进行更新手势监听,更新方向监听,更新锁屏超时时间。之后发送灭屏广播通知关心灭屏事件的模块。
到此为止亮灭屏流程讲解完毕.
在前面两部分已经对绘制windows与设置设备状态进行了详细讲解. 之后接着就该对亮度值进行设置, 实现亮屏动作了.
在DisplayPowerController中的animateScreenBrightness函数通过亮度渐变动画来将亮度设置到目标亮度.
- // Brightness animation ramp rate in brightness units per second.
- private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40; //亮度渐变动画较慢的速率, 每秒变化40个亮度单位
- mBrightnessRampRateFast = resources.getInteger(
- com.android.internal.R.integer.config_brightness_ramp_rate_fast); //从配置文件中获取较快的亮度速率
- // Animate the screen brightness when the screen is on or dozing.
- // Skip the animation when the screen is off or suspended.
- if (!mPendingScreenOff) {
- if (state == Display.STATE_ON || state == Display.STATE_DOZE) {
- animateScreenBrightness(brightness, //当亮屏或doze状态时有亮度渐变动画
- slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : mBrightnessRampRateFast);
- } else {
- animateScreenBrightness(brightness, 0); //灭屏时没有亮度渐变动画,直接将亮度设置为0
- }
- }
- private void initialize() {
- //....
- mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( //泛型为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) {
- // same process
- }
- }
- }
在RampAnimator的构造函数中将DisplayPowerState赋值给mObject, DisplayPowerState.SCREEN_BRIGHTNESS赋值给mProperty, 并且创建mChoreographer实例.
- public RampAnimator(T object, IntProperty<T> property) {
- mObject = object;
- mProperty = property;
- mChoreographer = Choreographer.getInstance();
- }
下面重点讲解animateTo函数.
- public boolean animateTo(int target, int rate) {
- // Immediately jump to the target the first time.
- if (mFirstTime || rate <= 0) { //当第一次调用animateTo, 或者rate小于等于0时直接设置目标亮度.
- if (mFirstTime || target != mCurrentValue) {
- mFirstTime = false; //之后就不是第一次调用该函数
- mRate = 0; //设置mRate为0
- mTargetValue = target; //设置目标亮度为target
- mCurrentValue = target;
- mProperty.setValue(mObject, target); //调用DisplayPowerState.SCREEN_BRIGHTNESS设置亮度值
- if (mAnimating) {
- mAnimating = false;
- cancelAnimationCallback();
- }
- if (mListener != null) {
- mListener.onAnimationEnd(); //动画结束
- }
- return true;
- }
- return false;
- }
- // Adjust the rate based on the closest target.
- // If a faster rate is specified, then use the new rate so that we converge
- // more rapidly based on the new request.
- // If a slower rate is specified, then use the new rate only if the current
- // value is somewhere in between the new and the old target meaning that
- // we will be ramping in a different direction to get there.
- // Otherwise, continue at the previous rate.
- if (!mAnimating
- || rate > mRate
- || (target <= mCurrentValue && mCurrentValue <= mTargetValue)
- || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) {
- mRate = rate; //重新调节亮度速率
- }
- final boolean changed = (mTargetValue != target); //如果当前亮度值不等于目标亮度值,说明亮度改变了
- mTargetValue = target; //重新设置mTargetValue
- // Start animating. 开始动画
- if (!mAnimating && target != mCurrentValue) {
- mAnimating = true;
- mAnimatedValue = mCurrentValue;
- mLastFrameTimeNanos = System.nanoTime();
- postAnimationCallback();
- }
- return changed;
- }
- private void postAnimationCallback() {
- mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null);
- }
- private final Runnable mAnimationCallback = new Runnable() {
- @Override // Choreographer callback
- public void run() {
- final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
- final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)
- * 0.000000001f;
- mLastFrameTimeNanos = frameTimeNanos; //记录最后一次的frameTimeNanos
- // Advance the animated value towards the target at the specified rate
- // and clamp to the target. This gives us the new current value but
- // we keep the animated value around to allow for fractional increments
- // towards the target.
- final float scale = ValueAnimator.getDurationScale();
- if (scale == 0) {
- // Animation off.
- mAnimatedValue = mTargetValue; //让scale为0时, 表示动画停止了, 将mAnimatedValue设置为目标亮度
- } else {
- final float amount = timeDelta * mRate / scale; //计算每一次需要变化的亮度值
- if (mTargetValue > mCurrentValue) {
- mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue); //亮屏,每次增加亮度amount,不超过目标亮度
- } else {
- mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); //暗屏, 每次减少amount个亮度, 不超过目标亮度
- }
- }
- final int oldCurrentValue = mCurrentValue;
- mCurrentValue = Math.round(mAnimatedValue); //获取当前要达到的亮度值
- if (oldCurrentValue != mCurrentValue) {
- mProperty.setValue(mObject, mCurrentValue); //调用DisplayPowerState.SCREEN_BRIGHTNESS设置亮度值
- }
- if (mTargetValue != mCurrentValue) {
- postAnimationCallback(); //如果还没有达到目标亮度,就会继续调用postAnimationCallback循环设置亮度值
- } else {
- mAnimating = false;
- if (mListener != null) {
- mListener.onAnimationEnd(); //否则,亮度动画结束
- }
- }
- }
- };
- public static final IntProperty<DisplayPowerState> SCREEN_BRIGHTNESS =
- new IntProperty<DisplayPowerState>("screenBrightness") {
- @Override
- public void setValue(DisplayPowerState object, int value) {
- object.setScreenBrightness(value); //调用DisplayPowerState的setScreenBrightness函数,设置亮度值
- }
- @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(); //如果不是灭屏状态,更新屏幕状态
- }
- }
- }
- private 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");
- }
- }
- }
- };
- DisplayBlanker blanker = new DisplayBlanker() {
- @Override
- public void requestDisplayState(int state, int brightness) {
- // The order of operations is important for legacy reasons.
- if (state == Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state, brightness);
- }
- callbacks.onDisplayStateChange(state);
- if (state != Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state, brightness); //亮屏调用设置状态,亮度
- }
- }
- };
- private void requestGlobalDisplayStateInternal(int state, int brightness) {
- if (state == Display.STATE_UNKNOWN) {
- state = Display.STATE_ON;
- }
- if (state == Display.STATE_OFF) {
- brightness = PowerManager.BRIGHTNESS_OFF; //灭屏设置屏幕亮度为0
- } else if (brightness < 0) {
- brightness = PowerManager.BRIGHTNESS_DEFAULT; //屏幕亮度小于0,设置为默认亮度
- } else if (brightness > PowerManager.BRIGHTNESS_ON) {
- brightness = PowerManager.BRIGHTNESS_ON; //屏幕亮度大于255设置最大亮度值255
- }
- synchronized (mTempDisplayStateWorkQueue) {
- try {
- // Update the display state within the lock.
- // Note that we do not need to schedule traversals here although it
- // may happen as a side-effect of displays changing state.
- synchronized (mSyncRoot) {
- if (mGlobalDisplayState == state
- && mGlobalDisplayBrightness == brightness) {
- return; // no change 亮度与状态都没有改变就return
- }
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
- + Display.stateToString(state)
- + ", brightness=" + brightness + ")");
- mGlobalDisplayState = state;
- mGlobalDisplayBrightness = brightness;
- applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); //应用全局状态
- }
- // Setting the display power state can take hundreds of milliseconds
- // to complete so we defer the most expensive part of the work until
- // after we have exited the critical section to avoid blocking other
- // threads for a long time.
- for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
- mTempDisplayStateWorkQueue.get(i).run(); //运行mTempDisplayStateWorkQueue队列中的runnable
- }
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- } finally {
- mTempDisplayStateWorkQueue.clear();
- }
- }
- }
- private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
- final int count = mDisplayDevices.size();
- for (int i = 0; i < count; i++) { //遍历devices
- DisplayDevice device = mDisplayDevices.get(i);
- Runnable runnable = updateDisplayStateLocked(device); //获得devices中的runnable
- if (runnable != null) {
- workQueue.add(runnable); //将runnable加入workQueue队列, 即mTempDisplayStateWorkQueue队列
- }
- }
- }
- private Runnable updateDisplayStateLocked(DisplayDevice device) {
- // Blank or unblank the display immediately to match the state requested
- // by the display power controller (if known).
- DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); //获取devices信息
- if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
- return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); //调用requestDisplayStateLocked函数
- }
- return null;
- }
在requestDisplayStateLocked中主要的任务就是创建一个runnable返回到DisplayManagerService中,并且等待回调run函数.
- @Override
- public Runnable requestDisplayStateLocked(final int state, final int brightness) {
- // Assume that the brightness is off if the display is being turned off.
- 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; //设置mBrightness
- }
- // Defer actually setting the display state until after we have exited
- // the critical section since it can take hundreds of milliseconds
- // to complete.
- return new Runnable() { //新建一个runnable返回
- @Override
- public void run() { //在DisplayManagerService中调用run函数
- // Exit a suspended state before making any changes.
- int currentState = oldState;
- if (Display.isSuspendedState(oldState) //判断设置是否还是在suspend状态
- || 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; // old state and new state is off
- }
- }
- // Apply brightness changes given that we are in a non-suspended state.
- if (brightnessChanged) {
- if (isPowerDebug()) {
- Slog.d(TAG, "set display brightness=" + brightness);
- }
- setDisplayBrightness(brightness); //设置屏幕亮度
- }
- // Enter the final desired state, possibly suspended.
- if (state != currentState) {
- if(isPowerDebug()) {
- Slog.d(TAG, "set display state=" + state);
- }
- setDisplayState(state);
- }
- }
- 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); //调用LightService设置亮度
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
- };
- }
- return null;
- }
- @Override
- public void setBrightness(int brightness) {
- setBrightness(brightness, BRIGHTNESS_MODE_USER); //亮度模式默认为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); //调用jni层设置亮度
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
- }
- }
- static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, 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) {
- // HAL impl has not been upgraded to support this.
- return;
- }
- } else {
- // Only set non-brightness settings when not in low-persistence mode
- state.color = colorARGB;
- state.flashMode = flashMode;
- state.flashOnMS = onMS;
- state.flashOffMS = offMS;
- }
- state.brightnessMode = brightnessMode;
- {
- ALOGD_IF_SLOW(50, "Excessive delay setting light"); //当设置亮度耗时大于50ms,就会输出该行log.
- devices->lights[light]->set_light(devices->lights[light], &state);
- }
- }
灭屏流程分析
灭屏总览
在点击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。
- case DisplayPowerRequest.POLICY_OFF:
- state = Display.STATE_OFF;
- performScreenOffTransition = true;
- break;
- // Animate the screen state change unless already animating.
- // The transition may be deferred, so after this point we will use the
- // actual state instead of the desired one.
- animateScreenStateChange(state, performScreenOffTransition);
- state = mPowerState.getScreenState();
- // Want screen off.
- mPendingScreenOff = true;
- if (mPowerState.getColorFadeLevel() == 0.0f) {
- // Turn the screen off.
- // A black surface is already hiding the contents of the screen.
- 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) {
- // Perform the screen off animation.
- mColorFadeOffAnimator.start();
- } else {
- // Skip the screen off animation and add a black surface to hide the
- // contents of the screen.
- mColorFadeOffAnimator.end();
- }
发送灭屏广播
power是通过WindowManagerPolicy与PhoneWindowManager进行交互,当屏幕在finishedGoingToSleep时需要通知window进行更新手势监听,更新方向监听,更新锁屏超时时间。之后发送灭屏广播通知关心灭屏事件的模块。
到此为止亮灭屏流程讲解完毕.