Display 亮度调节

亮度调节

亮度调节分两种,一种自动亮度调节,一种手动亮度调节,调用的入口在Settings和SystemUI当中,

SytemUI手动调节亮度方式如下

    //非自动背光下的调节
    else if (!mAutomatic) {
            final int val = value + mMinimumBacklight;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val);
            }
            //利用aidl调用PowManangerService的内部类BinderService处理背光调节的请求(val的值在0-255之间)
            setBrightness(val);
            if (!tracking) {
                AsyncTask.execute(new Runnable() {
                        public void run() {
                           //把调节的亮度更新到数据库,存取的值为(0-255)
                            Settings.System.putIntForUser(mContext.getContentResolver(),
                                    Settings.System.SCREEN_BRIGHTNESS, val,
                                    UserHandle.USER_CURRENT);
                        }
                    });
            }
        } else {
			//自动背光开关打开的情况下调节进度条
            final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1;
            //利用aidl调用PowManangerService的内部类BinderService处理背光调节的请求(adj的值在 -1,1之间)
            setBrightnessAdj(adj);
            if (!tracking) {
                AsyncTask.execute(new Runnable() {
                    public void run() {
                      //把调节的亮度更新到数据库,存取的值为(-1 - 1)
                        Settings.System.putFloatForUser(mContext.getContentResolver(),
                                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj,
                                UserHandle.USER_CURRENT);
                    }
                });
            }
        }

1.先通过Binder进程间通信与PowManangerService的内部类BinderService进行交互,然后更新Settings数据库
把亮度值存到Settings数据库当中
2.自动背光关闭情况下,手动可调节的范围0-255,自动开关打开情况下,手动可调节范围 -1 - 1;

  • setBrightness(val) 方法的实现
   private void setBrightness(int brightness) {
        try {
			//通过IPC进程间通信调用内部类BinderService的接口函数
            mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
        } catch (RemoteException ex) {
        }
    }
  • setBrightnessAdj(adj);
    private void setBrightnessAdj(float adj) {
        try {
			//通过IPC进程间通信调用内部类BinderService的接口函数
            mPower.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(adj);
        } catch (RemoteException ex) {
        }
    }

继续分析PowerManagerService中的setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternalChj方法

   @Override // Binder call
   public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideChj(int dispalyId,float adj) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.DEVICE_POWER, null);
       final long ident = Binder.clearCallingIdentity();
       try {
             setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternalChj(dispalyId,adj);
        } finally {
             Binder.restoreCallingIdentity(ident);
        }
   }

接着调用setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternalChj方法,方法实现如下:

    private void setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternalChj(int displayId,float adj) {
        synchronized (mLock) {
            // Note: This condition handles NaN because NaN is not equal to any other
            // value, including itself.
            if (displayId == DEFAULT_DISPLAY){
                if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverride != adj) {
                    mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = adj;
                    mDirty |= DIRTY_SETTINGS;
                    updatePowerStateLocked();
                }
            } else if (displayId == SECOND_DISPLAY){
                if (mTemporaryScreenAutoBrightnessAdjustmentSettingOverrideSecondDisplay != adj) {
                    mTemporaryScreenAutoBrightnessAdjustmentSettingOverrideSecondDisplay = adj;
                    mDirty |= DIRTY_SETTINGS;
                    updatePowerStateLocked();
                }
            }

        }
    }
  • 1.经过一系列的调用最终都会调到PowerManagerService的setTemporaryScreenAutoBrightnessAdjustmentSettingOverrideInternalChj方法当中
  • 2.针对不同屏幕设置不同的亮度(mTemporaryScreenAutoBrightnessAdjustmentSettingOverrideSecondDisplay),displayId代表屏幕Id值(0代表中控,1代表副屏幕,2代表仪表,3代表空调)
  • 3.最终都会调用到updatePowerStateLocked方法当中

播放视频下的亮度调节设置

在播放视频时,可以通过上下滑动来调整屏幕的亮度,但是,退出播放视频以后,又恢复到原来的亮度,其调用接口在PowerManagerService的setScreenBrightnessOverrideFromWindowManagerChj方法

        @Override
       public void setScreenBrightnessOverrideFromWindowManagerChj(int screenBrightness,int displayId){
           if (screenBrightness < PowerManager.BRIGHTNESS_DEFAULT
                   || screenBrightness > PowerManager.BRIGHTNESS_ON) {
               screenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
           }
           setScreenBrightnessOverrideFromWindowManagerInternal(screenBrightness,displayId);
       }
    private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness,int displayId) {
       synchronized (mLock) {
           if (displayId == DEFAULT_DISPLAY){
               if (mScreenBrightnessOverrideFromWindowManager != brightness) {
                   mScreenBrightnessOverrideFromWindowManager = brightness;
                   mDirty |= DIRTY_SETTINGS;
                   updatePowerStateLocked();
               }
           }else if (displayId == SECOND_DISPLAY){
               if (mScreenBrightnessOverrideSecondFromWindowManager != brightness) {
                   mScreenBrightnessOverrideSecondFromWindowManager = brightness;
                   mDirty |= DIRTY_SETTINGS;
                   updatePowerStateLocked();
               }
           }

       }
   }

1.针对不同的屏幕适配不同的亮度,这里只针对中屏幕和副屏幕亮度做调节,因为只有中控和副屏才可以播放视频。

2.最终也会调用到updatePowerStateLocked方法当中

在updatePowerStateLocked会调用updateDisplayPowerStateLocked方法处理屏幕的亮灭以及亮度调节的逻辑
所以我们直接看updateDisplayStateLocked方法解析


private boolean updateDisplayPowerStateLocked(int dirty) {
       final boolean oldDisplayReady = mDisplayReady;
       if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
               | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
               | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |
               DIRTY_QUIESCENT)) != 0) {
           mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();

           // Determine appropriate screen brightness and auto-brightness adjustments.
           //用来决定中控屏幕使用自动亮度还是手动设置亮度
           boolean brightnessSetByUser = true;
           boolean brightnessSetByUserSecondDisplay = true;
           // 需要设置的亮度值(中控),默认为config.xml中config_screenBrightnessSettingDefault的值
           int screenBrightness = mScreenBrightnessSettingDefault;
           // 需要设置的亮度值(副屏),默认为config.xml中config_screenBrightnessSettingDefault的值
           int screenBrightnessSecondDisplay = mScreenBrightnessSettingDefault;
           //需要设置的亮度值(仪表),默认为config.xml中config_screenBrightnessSettingDefault的值
           int screenBrightnessIpc = mScreenBrightnessSettingDefault;
           //需要设置的亮度值(空调),默认为config.xml中config_screenBrightnessSettingDefault的值
           int screenBrightnessCcp = mScreenBrightnessSettingDefault;
           //自动背光调节的比例值(中控)
           float screenAutoBrightnessAdjustment = 0.0f;
            //自动背光调节的比例值(副屏)
           float screenAutoBrightnessAdjustmentSecondDisplay = 0.0f;
           //是否打开自动背光开关,在Settings设置打开,该值为true,否则为false
           boolean autoBrightness = (mScreenBrightnessModeSetting ==
                   Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
           boolean autoBrightnessSecondDisplay = autoBrightness;
           //系统服务未启动完成情况下,设置以下各项都为false
           if (!mBootCompleted) {
               // Keep the brightness steady during boot. This requires the
               // bootloader brightness and the default brightness to be identical.
               autoBrightness = false;
               brightnessSetByUser = false;
               autoBrightnessSecondDisplay = false;
               brightnessSetByUserSecondDisplay = false;
               //VR模式下的设置
           } else if (mIsVrModeEnabled) {
               screenBrightness = mScreenBrightnessForVrSetting;
               autoBrightness = false;
               //当主屏或者副屏正在播放视频
           } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)
                   || isValidBrightness(mScreenBrightnessOverrideSecondFromWindowManager)) {
               if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)){
                   screenBrightness = mScreenBrightnessOverrideFromWindowManager;
                   autoBrightness = false;
                   brightnessSetByUser = false;

               }else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)){
                   screenBrightness = mTemporaryScreenBrightnessSettingOverride;
                   screenBrightnessIpc = mTemporaryScreenBrightnessSettingOverride;
                   screenBrightnessCcp = mTemporaryScreenBrightnessSettingOverride;
               } else if ((isValidBrightness(mScreenBrightnessSetting))){
                   screenBrightness = mScreenBrightnessSetting;
                   screenBrightnessIpc = mScreenBrightnessSetting;
                   screenBrightnessCcp = mScreenBrightnessSetting;
               }
               if (isValidBrightness(mScreenBrightnessOverrideSecondFromWindowManager)){
                   screenBrightnessSecondDisplay = mScreenBrightnessOverrideSecondFromWindowManager;
                   autoBrightnessSecondDisplay  = false;
                   brightnessSetByUserSecondDisplay = false;
               }else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverrideSecondDisplay)
                       || isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
                   screenBrightnessSecondDisplay = mTemporaryScreenBrightnessSettingOverrideSecondDisplay;
                   if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)){
                       screenBrightnessCcp = mTemporaryScreenBrightnessSettingOverride;
                       screenBrightnessIpc = mTemporaryScreenBrightnessSettingOverride;
                   }

               }else if (isValidBrightness(mScreenBrightnessSettingSecondDisplay)
                       || isValidBrightness(mScreenBrightnessSetting)) {
                   if (isValidBrightness(mScreenBrightnessSetting)){
                       screenBrightnessIpc = mScreenBrightnessSetting;
                       screenBrightnessCcp = mScreenBrightnessSetting;
                   }
                   screenBrightnessSecondDisplay = mScreenBrightnessSettingSecondDisplay;
               }
               //SystemUI中的调节
           } else if ((isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) ||
                       (isValidBrightness(mTemporaryScreenBrightnessSettingOverrideSecondDisplay))) {
               screenBrightness = mTemporaryScreenBrightnessSettingOverride;
               screenBrightnessSecondDisplay = mTemporaryScreenBrightnessSettingOverrideSecondDisplay;
               screenBrightnessIpc = mTemporaryScreenBrightnessSettingOverride;
               screenBrightnessCcp = mTemporaryScreenBrightnessSettingOverride;
               //Settings中的调节 //Settings.System.SCREEN_BRIGHTNESS的值,即保存在数据库中的亮度值,亮度值设置完成后,都会进行保存
           } else if ((isValidBrightness(mScreenBrightnessSetting)) ||
                       (isValidBrightness(mScreenBrightnessSettingSecondDisplay))) {
               screenBrightness = mScreenBrightnessSetting;
               screenBrightnessSecondDisplay = mScreenBrightnessSettingSecondDisplay;
               screenBrightnessIpc = mScreenBrightnessSetting;
               screenBrightnessCcp = mScreenBrightnessSetting;
           }
   		//自动背光开关打开(主控),手动调节亮度,设置亮度调节的比例值
           if (autoBrightness) {
               screenBrightness = mScreenBrightnessSettingDefault;
               if (isValidAutoBrightnessAdjustment(
                       mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
                   screenAutoBrightnessAdjustment =
                           mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
               } else if (isValidAutoBrightnessAdjustment(
                       mScreenAutoBrightnessAdjustmentSetting)) {
                   screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
               }
           }
   		//自动背光打开(副屏),调节亮度,设置亮度调节的比例值
           if (autoBrightnessSecondDisplay) {
               screenBrightnessSecondDisplay = mScreenBrightnessSettingDefault;
               if (isValidAutoBrightnessAdjustment(
                       mTemporaryScreenAutoBrightnessAdjustmentSettingOverrideSecondDisplay)) {
                   screenAutoBrightnessAdjustmentSecondDisplay =
                           mTemporaryScreenAutoBrightnessAdjustmentSettingOverrideSecondDisplay;
               } else if (isValidAutoBrightnessAdjustment(
                       mScreenAutoBrightnessAdjustmentSettingSecondDisplay)) {
                   screenAutoBrightnessAdjustmentSecondDisplay = mScreenAutoBrightnessAdjustmentSettingSecondDisplay;
               }
           }
   		
           screenBrightness = Math.max(Math.min(screenBrightness,
                   mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
           screenAutoBrightnessAdjustment = Math.max(Math.min(
                   screenAutoBrightnessAdjustment, 1.0f), -1.0f);

           screenBrightnessSecondDisplay = Math.max(Math.min(screenBrightnessSecondDisplay,
                   mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
           screenAutoBrightnessAdjustmentSecondDisplay = Math.max(Math.min(
                   screenAutoBrightnessAdjustmentSecondDisplay, 1.0f), -1.0f);

           screenBrightnessIpc = Math.max(Math.min(screenBrightnessIpc,
                   mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
           screenBrightnessCcp =Math.max(Math.min(screenBrightnessCcp,
                   mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);

           // Update display power request.
           mDisplayPowerRequest.screenBrightness = screenBrightness;
           mDisplayPowerRequest.screenBrightnessSecondDisplay = screenBrightnessSecondDisplay;
           mDisplayPowerRequest.screenBrightnessCcp = screenBrightnessCcp;
           mDisplayPowerRequest.screenBrightnessIpc = screenBrightnessIpc;
           mDisplayPowerRequest.screenAutoBrightnessAdjustment =
                   screenAutoBrightnessAdjustment;
           mDisplayPowerRequest.screenAutoBrightnessAdjustment = screenAutoBrightnessAdjustment;
           mDisplayPowerRequest.screenAutoBrightnessAdjustmentSecondDisplay =
                   screenAutoBrightnessAdjustmentSecondDisplay;
           mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
           mDisplayPowerRequest.brightnessSetByUserSecondDisplay = brightnessSetByUserSecondDisplay;
           mDisplayPowerRequest.useAutoBrightness = autoBrightness;
           mDisplayPowerRequest.useAutoBrightnessSecondDisplay = autoBrightnessSecondDisplay;
           mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
           mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();

           updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);

           if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
               mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
               if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND
                       && (mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
                   mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
               }
               mDisplayPowerRequest.dozeScreenBrightness =
                       mDozeScreenBrightnessOverrideFromDreamManager;
           } else {
               mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
               mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
           }

           mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
                   mRequestWaitForNegativeProximity);
           mRequestWaitForNegativeProximity = false;

           if ((dirty & DIRTY_QUIESCENT) != 0) {
               sQuiescent = false;
           }
       return mDisplayReady && !oldDisplayReady;
   }

四屏幕调节的逻辑,

  • 1.手动调节的时候,无论自动背光开关打开或关闭,都会跟随中控的亮度变化而变换,(即,手动调节中控的亮度条,4个屏幕设置亮度一致)
  • 2.自动背光自动调节亮度上三屏幕一致,使用仪表中的光感Sensor数据(中控,副屏,仪表亮度保持一致),空调屏幕自动背光自动调节单独由空调屏幕的光感Sensor控制
  • 3.把请求的数据封装到mDisplayPowerRequest对象里,交给DisplayManagerService中requestPowerState去处理,最终会调用到DispalyPowerController.java
    中的updatePowerState方法中
  • 4.以上亮度设置值,优先级为:自动调节亮度 > 视频播放时设置亮度 > Settings、SystemUI中设置亮度(因为autoBrightness时将screenBrightness重置了)。

DispalyPowerController : updatePowerState()

  private void updatePowerState() {
        // Update the power state request.
        final boolean mustNotify;
        boolean mustInitialize = false;
        boolean autoBrightnessAdjustmentChanged = false;//自动背光打开,有没有手动调节亮度,初始值设置为false(中控)
        boolean autoBrightnessAdjustmentSecondChanged = false;//自动背光打开,有没有手动调节亮度,初始值设置为false(副屏)
        //自动背光中控控制器
        AutomaticBrightnessController automaticBrightnessController = getAutomaticBrightnessController(DEFAULT_DISPLAY);
        //自动背光副屏控制器
        AutomaticBrightnessController automaticBrightnessControllerSecondDisplay = getAutomaticBrightnessController(SECOND_DISPLAY);
        //自动背光空调控制器
        AutomaticBrightnessController automaticCCPBrightnessController = getAutomaticBrightnessController(CCP_DISPLAY);
        //自动背光仪表控制器
        AutomaticBrightnessController automaticIPCBrightnessController = getAutomaticBrightnessController(IPC_DISPLAY);

        if (DEBUG) {
            Slog.d(TAG, "updatePowerState: original no displayId");
        }

        synchronized (mLock) {
            mPendingUpdatePowerStateLocked = false;
            if (mPendingRequestLocked == null) {
                return; // wait until first actual power request
            }
			//开机第一次重启会走这边的逻辑.重新创建DisplayPowerRequest对象
            if (mPowerRequest == null) {
                mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
                mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
                mPendingWaitForNegativeProximityLocked = false;
                mPendingRequestChangedLocked = false;
                mustInitialize = true;
                //从PowerManagerService中获取DisplayPowerRequest对象
            } else if (mPendingRequestChangedLocked) {
                autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
                        != mPendingRequestLocked.screenAutoBrightnessAdjustment);
                autoBrightnessAdjustmentSecondChanged = (mPowerRequest.screenAutoBrightnessAdjustmentSecondDisplay
                        != mPendingRequestLocked.screenAutoBrightnessAdjustmentSecondDisplay );
                mPowerRequest.copyFrom(mPendingRequestLocked);
                mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
                mPendingWaitForNegativeProximityLocked = false;
                mPendingRequestChangedLocked = false;
                mDisplayReadyLocked = false;
            }

            mustNotify = !mDisplayReadyLocked;
        }

        // Initialize things the first time the power state is changed.
        if (mustInitialize) {
            initialize();
        }

        // Compute the basic display state using the policy.
        // We might override this below based on other factors.
        int state;
        //初始化亮度值
        int brightness = PowerManager.BRIGHTNESS_DEFAULT;
        int brightnessSecondDisplay = PowerManager.BRIGHTNESS_DEFAULT;
        int brightnessIpc = PowerManager.BRIGHTNESS_DEFAULT;
        int brightnessCcp = PowerManager.BRIGHTNESS_DEFAULT;

        // Configure auto-brightness.
        //检测是是否开启自动亮度调节
        boolean autoCCPIPCBrightnessEnabled = mZMQ.checkBrightnessAutomodeEnabled(CCP_DISPLAY);

        boolean performScreenOffTransition = false;
        //根据请求的Policy设置屏幕的状态
        switch (mPowerRequest.policy) {
            case DisplayPowerRequest.POLICY_OFF:
                state = Display.STATE_OFF;
                performScreenOffTransition = true;
                break;
            case DisplayPowerRequest.POLICY_DOZE:
                if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
                    state = mPowerRequest.dozeScreenState;
                } else {
                    state = Display.STATE_DOZE;
                }
                if (!mAllowAutoBrightnessWhileDozingConfig) {
                    brightness = mPowerRequest.dozeScreenBrightness;
                    brightnessSecondDisplay = mPowerRequest.dozeScreenBrightness;
                }
                break;
            case DisplayPowerRequest.POLICY_VR:
                state = Display.STATE_VR;
                break;
            case DisplayPowerRequest.POLICY_DIM:
            case DisplayPowerRequest.POLICY_BRIGHT:
            default:
                state = Display.STATE_ON;
                break;
        }
        assert(state != Display.STATE_UNKNOWN);

        // Apply the proximity sensor.
        //proximity sensor距离传感器,与打电话有关,后续分析.
        if (mProximitySensor != null) {
            if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true);
                if (!mScreenOffBecauseOfProximity
                        && mProximity == PROXIMITY_POSITIVE) {
                    mScreenOffBecauseOfProximity = true;
                    sendOnProximityPositiveWithWakelock();
                }
            } else if (mWaitingForNegativeProximity
                    && mScreenOffBecauseOfProximity
                    && mProximity == PROXIMITY_POSITIVE
                    && state != Display.STATE_OFF) {
                setProximitySensorEnabled(true);
            } else {
                setProximitySensorEnabled(false);
                mWaitingForNegativeProximity = false;
            }
            if (mScreenOffBecauseOfProximity
                    && mProximity != PROXIMITY_POSITIVE) {
                mScreenOffBecauseOfProximity = false;
                sendOnProximityNegativeWithWakelock();
            }
        } else {
            mWaitingForNegativeProximity = false;
        }
        if (mScreenOffBecauseOfProximity) {
            state = Display.STATE_OFF;
        }

        // 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.
        //获取屏幕状态,此时还未设置新的屏幕状态,因此是”旧”的
        final int oldState = mPowerState.getScreenState();
         //在这个方法中会进行屏幕状态、亮度的设置和处理亮灭屏动画
        animateScreenStateChange(state, performScreenOffTransition);
        state = mPowerState.getScreenState();

        // Use zero brightness when screen is off.
        //根据状态设置是否灭屏,如果是状态是灭屏状态,设置亮度值为0
        if (state == Display.STATE_OFF) {
            brightness = PowerManager.BRIGHTNESS_OFF;
            brightnessSecondDisplay = PowerManager.BRIGHTNESS_OFF;
        }

        // Configure auto-brightness.
        //配置自动亮度调节
        boolean autoBrightnessEnabled = false;
        boolean autoBrightnessEnabledSecondDisplay = false;

        if (automaticBrightnessController != null) {
            final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
                    && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
            autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                    && brightness < 0;
            /*if (mZMQ != null) {
                autoBrightnessEnabled |= mZMQ.checkBrightnessAutomodeEnabled(DEFAULT_DISPLAY);
            }*/
            //是否手动调节了亮度,自动开关打开情况下
            final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
                    && mPowerRequest.brightnessSetByUser;
            //配置自动亮度调节功能,后续分析        
            automaticBrightnessController.configure(autoBrightnessEnabled,
                    mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
                    userInitiatedChange);
        }
		//副屏幕的自动背光配置
        if (automaticBrightnessControllerSecondDisplay != null) {
            final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
                    && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
            autoBrightnessEnabledSecondDisplay = mPowerRequest.useAutoBrightnessSecondDisplay
                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                    && brightnessSecondDisplay < 0;
            /*if (mZMQ != null) {
                autoBrightnessEnabled |= mZMQ.checkBrightnessAutomodeEnabled(DEFAULT_DISPLAY);
            }*/
            final boolean userInitiatedChangeSecondDisplay = autoBrightnessAdjustmentSecondChanged
                    && mPowerRequest.brightnessSetByUserSecondDisplay;
            automaticBrightnessControllerSecondDisplay.configure(autoBrightnessEnabledSecondDisplay,
                    mPowerRequest.screenAutoBrightnessAdjustmentSecondDisplay, state != Display.STATE_ON,
                    userInitiatedChangeSecondDisplay);
        }
		//仪表屏幕的自动背光配置
        if (automaticIPCBrightnessController != null) {
            final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
                    && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
            autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                    && (state == Display.STATE_ON || autoBrightnessEnabledInDoze);
            final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
                    && mPowerRequest.brightnessSetByUser;
            automaticIPCBrightnessController.configure(autoBrightnessEnabled,
                    mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
                    userInitiatedChange);
        }


        // Apply brightness boost.
        // We do this here after configuring auto-brightness so that we don't
        // disable the light sensor during this temporary state.  That way when
        // boost ends we will be able to resume normal auto-brightness behavior
        // without any delay.
        //亮度增强相关(中控),设置亮度增强,
        if (mPowerRequest.boostScreenBrightness
                && brightness != PowerManager.BRIGHTNESS_OFF) {
            brightness = PowerManager.BRIGHTNESS_ON;
        }
		//亮度增强相关(副屏),设置亮度增强,
        if (mPowerRequest.boostScreenBrightness
                && brightnessSecondDisplay != PowerManager.BRIGHTNESS_OFF) {
            brightnessSecondDisplay = PowerManager.BRIGHTNESS_ON;
        }

        // Apply auto-brightness.
        //自动调节,如果是自动亮度设置缓慢亮度变化
        boolean slowChange = false;

		//设置自动亮度(因为上三屏亮度要保持一致,所以自动背光的亮度发生变化,这都会用仪表的亮度,规定用仪表的亮度曲线)
        if (brightnessIpc < 0) {
            if (autoCCPIPCBrightnessEnabled && !autoBrightnessAdjustmentChanged ) {
                brightnessIpc = automaticIPCBrightnessController.getAutomaticScreenBrightness();
            }
            if (brightnessIpc >= 0) {
                // Use current auto-brightness value and slowly adjust to changes.
                brightnessIpc = clampScreenBrightness(brightnessIpc);
                if (autoBrightnessEnabled && !autoBrightnessAdjustmentChanged){
                    brightness = brightnessIpc;
                    putScreenBrightnessSetting(brightness);
                }
                if (autoBrightnessEnabledSecondDisplay && !autoBrightnessAdjustmentSecondChanged){
                    brightnessSecondDisplay = brightnessIpc;
                    putSecondScreenBrightnessSetting(brightnessSecondDisplay);
                }
                if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
                    slowChange = true; // slowly adapt to auto-brightness
                }
                mAppliedAutoBrightness = true;
                mAppliedAutoBrightnessSecondDisplay = true;
                mIPCAppliedAutoBrightness = true;
            } else {
                mAppliedAutoBrightness = false;
                mAppliedAutoBrightnessSecondDisplay = false;
                mIPCAppliedAutoBrightness = false;
            }
        } else {
            mAppliedAutoBrightness = false;
            mAppliedAutoBrightnessSecondDisplay = false;
            mIPCAppliedAutoBrightness = false;
        }

       //空调屏幕的亮度调节变化
        if (brightnessCcp < 0) {
            if (autoCCPIPCBrightnessEnabled) {
				//当环境光变化,获取自动调节的亮度(后续讲自动亮度调节的逻辑)
                brightnessCcp = automaticCCPBrightnessController.getAutomaticScreenBrightness();
            }
            if (brightnessCcp >= 0) {
                // Use current auto-brightness value and slowly adjust to changes.
                brightnessCcp = clampScreenBrightness(brightnessCcp);
                if (mCCPAppliedAutoBrightness) {
                    slowChange = true; // slowly adapt to auto-brightness
                }
                mCCPAppliedAutoBrightness = true;
            } else {
                mCCPAppliedAutoBrightness = false;
            }
        } else {
            mCCPAppliedAutoBrightness = false;
        }

        // Use default brightness when dozing unless overridden.
        //Doze状态下配置Doze状态的亮度(中控)
        if (brightness < 0 && (state == Display.STATE_DOZE
                || state == Display.STATE_DOZE_SUSPEND)) {
            brightness = mScreenBrightnessDozeConfig;
        }
		//Doze状态下配置Doze状态的亮度(副屏幕)
        if (brightnessSecondDisplay < 0 && (state == Display.STATE_DOZE
                || state == Display.STATE_DOZE_SUSPEND)) {
            brightnessSecondDisplay = mScreenBrightnessDozeConfig;
        }

        // Apply manual brightness.
        // Use the current brightness setting from the request, which is expected
        // provide a nominal default value for the case where auto-brightness
        // is not ready yet.
        //自动背光关闭情况下,手动调节亮度值设置(中控)
        if (brightness < 0) {
            brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
        }
		//自动背光关闭情况下,手动调节亮度值设置(副屏)
        if (brightnessSecondDisplay < 0) {
            brightnessSecondDisplay = clampScreenBrightness(mPowerRequest.screenBrightnessSecondDisplay);
        }
		//自动背光关闭情况下,手动调节亮度值设置(仪表)
        if (brightnessIpc < 0){
            brightnessIpc = clampAbsoluteBrightness(mPowerRequest.screenBrightnessIpc);
        }
		//自动背光关闭情况下,手动调节亮度值设置(空调)
        if (brightnessCcp < 0){
            brightnessCcp = clampAbsoluteBrightness(mPowerRequest.screenBrightnessCcp);
        }

        Slog.d(TAG," brightness: "+brightness+" brightnessSecondDisplay: "+brightnessSecondDisplay+" brightnessIpc: "+brightnessIpc+" brightnessCcp: "+brightnessCcp);
        // Apply dimming by at least some minimum amount when user activity
        // timeout is about to expire.
        //设置暗屏的亮度
        if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
            if (brightness > mScreenBrightnessRangeMinimum) {
                brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
                        mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
            }
            if (brightnessSecondDisplay > mScreenBrightnessRangeMinimum) {
                brightnessSecondDisplay = Math.max(Math.min(brightnessSecondDisplay - SCREEN_DIM_MINIMUM_REDUCTION,
                        mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
            }
            if (!mAppliedDimming) {
                slowChange = false;
            }
            mAppliedDimming = true;
        } else if (mAppliedDimming) {
            slowChange = false;
            mAppliedDimming = false;
        }
		//如果当前是低电量模式,设置低电量模式的亮度
        // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
        // as long as it is above the minimum threshold.
        if (mPowerRequest.lowPowerMode) {
            if (brightness > mScreenBrightnessRangeMinimum) {
                final float brightnessFactor =
                        Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
                final int lowPowerBrightness = (int) (brightness * brightnessFactor);
                brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
            }
            if (brightnessSecondDisplay > mScreenBrightnessRangeMinimum) {
                final float brightnessFactorSecondDisplay =
                        Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
                final int lowPowerBrightness = (int) (brightnessSecondDisplay * brightnessFactorSecondDisplay);
                brightnessSecondDisplay = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
            }
            if (!mAppliedLowPower) {
                slowChange = false;
            }
            mAppliedLowPower = true;
        } else if (mAppliedLowPower) {
            slowChange = false;
            mAppliedLowPower = false;
        }
		//背光调节时候,设置调节的动画,看起来比较丝滑
        // Animate the screen brightness when the screen is on or dozing.
        // Skip the animation when the screen is off or suspended or transition to/from VR.
        if (!mPendingScreenOff) {
            if (mSkipScreenOnBrightnessRamp) {
                if (state == Display.STATE_ON) {
                    if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
                        mInitialAutoBrightness = brightness;
                        mInitialAutoBrightnessSecondDisplay = brightnessSecondDisplay;
                        mSkipRampState = RAMP_STATE_SKIP_INITIAL;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
                            && mUseSoftwareAutoBrightnessConfig
                            && (brightness != mInitialAutoBrightness
                            || brightnessSecondDisplay != mInitialAutoBrightnessSecondDisplay)) {
                        mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
                    } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
                        mSkipRampState = RAMP_STATE_SKIP_NONE;
                    }
                } else {
                    mSkipRampState = RAMP_STATE_SKIP_NONE;
                }
            }

            boolean wasOrWillBeInVr = (state == Display.STATE_VR || oldState == Display.STATE_VR);
            int brightnessIPCCCP = (((brightnessCcp&0xff)<<8)|(brightnessIpc&0xff));
            int chjbrightness = (((brightnessSecondDisplay&0xff)<<8)|(brightness&0xff));
            if ((state == Display.STATE_ON
                    && mSkipRampState == RAMP_STATE_SKIP_NONE
                    || state == Display.STATE_DOZE && !mBrightnessBucketsInDozeConfig)
                    && !wasOrWillBeInVr) {
                   // 更新仪表和空调的亮度
                updateIPCCCPBrightnessState(brightnessIPCCCP,slowChange);
                //进入动画调节,更新中控和副屏的亮度
                animateScreenBrightness(chjbrightness, slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
            } else {
                animateScreenBrightness(chjbrightness, 0);
            }
        }
		//后续逻辑和亮灭屏相关以后分析
        // Determine whether the display is ready for use in the newly requested state.
        // Note that we do not wait for the brightness ramp animation to complete before
        // reporting the display is ready because we only need to ensure the screen is in the
        // right power state even as it continues to converge on the desired brightness.
        final boolean ready = mPendingScreenOnUnblocker == null &&
                (!mColorFadeEnabled ||
                        (!mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted()))
                && mPowerState.waitUntilClean(mCleanListener);
        final boolean finished = ready
                && !mScreenBrightnessRampAnimator.isAnimating();

        // Notify policy about screen turned on.
        if (ready && state != Display.STATE_OFF
                && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
            setReportedScreenState(REPORTED_TO_POLICY_SCREEN_ON);
            mWindowManagerPolicy.screenTurnedOn();
        }

        // Grab a wake lock if we have unfinished business.
        if (!finished && !mUnfinishedBusiness) {
            if (DEBUG) {
                Slog.d(TAG, "Unfinished business...");
            }
            mCallbacks.acquireSuspendBlocker();
            mUnfinishedBusiness = true;
        }

        // Notify the power manager when ready.
        if (ready && mustNotify) {
            // Send state change.
            synchronized (mLock) {
                if (!mPendingRequestChangedLocked) {
                    mDisplayReadyLocked = true;

                    if (DEBUG) {
                        Slog.d(TAG, "Display ready!");
                    }
                }
            }
            sendOnStateChangedWithWakelock();
        }

        // Release the wake lock when we have no unfinished business.
        if (finished && mUnfinishedBusiness) {
            if (DEBUG) {
                Slog.d(TAG, "Finished business...");
            }
            mUnfinishedBusiness = false;
            mCallbacks.releaseSuspendBlocker();
        }

        // Record if dozing for future comparison.
        mDozing = state != Display.STATE_ON;
    }

这里简单做一个小结

  • 1.当要请求进入Doze状态时,如果配置了Doze下LightSensor不可用,则将亮度设置为dozeScreenBrightness,(针对中控和副屏)
  • 2.当要灭屏时候,设置灭屏亮度背光为0(针对中控和副屏)
  • 3.当设置亮度增强的功能时候,设置亮度值255(针对中控和副屏)
  • 4.以上3个条件都不满足,且开启了自动亮度调节功能,则获取自动调节的亮度(中控,副屏,仪表使用同一自动亮度,空调单独使用亮度)
  • 5.以上4个条件都不满足,且当前为Doze状态,则将亮度值设置为mScreenBrightnessDozeConfig;(针对中控和副屏)
  • 6.如果不满足以上5步,则使用手动调节的亮度,这些亮度值从PowerManagerService中获取(四屏幕使用同一亮度值)
  • 7.如果要请求进入DIM状态时,则需要将当前得到的亮度值-10,并和mScreenBrightnessDimConfig比较取最小,和mScreenBrightnessRangeMinimum比较取最大。(针对中控和副屏)
  • 8.如果当前处于低电量模式,则需要将当前得到的亮度值* 低电量模式下亮度缩放比例,然后和mScreenBrightnessRangeMinimum取最大(一般缩放值为0.5,即减半);(针对中控和副屏)

针对中控和副屏幕的亮度调节

animateScreenBrightness()

    private void animateScreenBrightness(int target, int rate) {
        if (DEBUG) {
            Slog.d(TAG, "Animating brightness: target=" + target  + ", rate=" + rate);
        }
		//target代表最终亮度,rate代表调节动画时调节的速率
        if (mScreenBrightnessRampAnimator.chjanimateTo(target, rate)) {
        /*if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {*/
            Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", target);
            try {
                mBatteryStats.noteScreenBrightness(target);
            } catch (RemoteException ex) {
                // same process
            }
        }
    }

在这个方法中,第一个参数是updatePowerState()中获得的最终亮度值,第二个参数则和亮度设置时的动画效果有关系,
如果设置为大于0的数,那么会在chjanimateTo()方法中根据这个数逐渐地设置亮度,如果设置为小于等于0,那么则不会有动画效果,直接将亮度值一次性设置。接下来
,说说亮度值设置时的动画相关的逻辑。

RampAnimator.chjanimateTo()

继续跟着上一段分析,mScreenBrightnessRampAnimator是一个RampAnimator对象,RampAnimator类是一个自定义动画类,
专门用于更新亮度,其原理是该类中有一个IntProperty对象作为该类的一个属性:

    public boolean chjanimateTo(int target, int rate) {
        // Immediately jump to the target the first time.
        //如果rate<=0,则直接通过mProperty.setValue(mObject, target)设置为目标亮度
        if (mFirstTime || rate <= 0) {
         
            if (mFirstTime || target != mCurrentValue) {
                mFirstTime = false;
                mRate = 0;
                mTargetValue = target;
                mCurrentValue = target;
                //rate<=0时直接设置
                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;

        // Start animating.
        if (!mAnimating && target != mCurrentValue) {
            mAnimating = true;
            mAnimatedValue = mCurrentValue;
            mAnimatedValueDefaultDisplay = (mCurrentValue&0xff);
            mAnimatedValueSecondDisplay = ((mCurrentValue>>8)&0xff);
            mLastFrameTimeNanos = System.nanoTime();
            postAnimationCallback();
        }
        return changed;
    }

1.如果rate<=0,那么直接调用mProperty.setValue(object,target)设置最终的亮度;如果rate>0,
那么会进入postAnimationCallback()方法,在这个方法中通过rate计算出每次设置的亮度值进行设置,直到设置到最终亮度为止。

2.mProperty.setValue(mObject, target);设置亮度值 ,那这个setValue调用的哪个类的方法呢?
我们先看mScreenBrightnessRampAnimator对象的创建

mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
        mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);

因此当执行mProperty.setValue(object,target)时,执行的是DisplayPowerState.SCREEN_BRIGHTNESS的setValue()方法,
进入DisplayPowerState中查看该对象:

public 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();
    }
};

在这里可以看出,当调用setValue()方法后,将调用object.setScreenBrightness(),
从实例化流程可知,object对象还是DisplayPowerState对象。继续setScreenBrightness()方法:


public void setScreenBrightness(int brightness) {
    if (mScreenBrightness != brightness) {
        mScreenBrightness = brightness;
        //对于屏幕状态为State_OFF,根据上面内容的分析,在设置屏幕状态之间就会设置将背光设置为0,此处不进行处理
        if (mScreenState != Display.STATE_OFF) {
            mScreenReady = false;
            scheduleScreenUpdate();
        }
    }
}

在这个方法中,如果当前屏幕状态不为STATE_OFF,即当前不是处于灭屏状态,则开始调用scheduleScreenUpdate()更新背光

private void scheduleScreenUpdate() {
    if (!mScreenUpdatePending) {
        mScreenUpdatePending = true;
        postScreenUpdateThreadSafe();
    }
}

postScreenUpdateThreadSafe方法

private void postScreenUpdateThreadSafe() {
    mHandler.removeCallbacks(mScreenUpdateRunnable);
    mHandler.post(mScreenUpdateRunnable);
}

通过mHandler异步调用mScreenUpdateRunnable,mScreenUpdateRunnable是一个Runnable实现
具体方法如下

private final Runnable mScreenUpdateRunnable = new Runnable() {
    @Override
    public void run() {
        //表示是否打算更新屏幕状态,该值在scheduleScreenUpdate()方法中设置为了true
        mScreenUpdatePending = false;
        //获取背光亮度值,如果屏幕状态为State_Off的话就是0,其他屏幕状态下都是设置的背光值
        int brightness = mScreenState != Display.STATE_OFF
                && mColorFadeLevel > 0f ? mScreenBrightness : 0;
        //如果该方法返回false,表示屏幕更新完成,否则表示还没有更新完成
        if (mPhotonicModulator.setState(mScreenState, brightness)) {
            if (DEBUG) {
                Slog.d(TAG, "Screen ready");
            }
            mScreenReady = true;//标记屏幕状态是否更新完成
            invokeCleanListenerIfNeeded();
        } else {
            if (DEBUG) {
                Slog.d(TAG, "Screen not ready");
            }
        }
    }
};
  • 1.先获取背光的亮度值
  • 2.调用mPhotonicModulator的setState去更新亮度值和屏幕状态
  • 3.根据setState方法的返回值来决定是否是屏幕状态更新完成

PhotonicModulator是一个Thread的子类,专门用于更新屏幕和背光亮度值的状态,因此,在DisplayPowerState中,更新屏幕和背光状态是在独立的线程中异步进行的。
现在,先来看看这个线程的setState()方法:

public boolean setState(int state, int backlight) {
    synchronized (mLock) {
        //屏幕状态是否改变,和之前的值做比较
        boolean stateChanged = state != mPendingState;
        //背光是否改变
        boolean backlightChanged = backlight != mPendingBacklight;
        //如果有其中之一改变,进入if中
        if (stateChanged || backlightChanged) {
            if (DEBUG) {
                Slog.d(TAG, "Requesting new screen state: state="
                        + Display.stateToString(state) + ", backlight=" + backlight);
            }
            //设置state值
            mPendingState = state;
            //设置将要更新的亮度值
            mPendingBacklight = backlight;
            //mStateChangeInProgress和mBacklightChangeInProgress分别表示当前屏幕状态和背光值
            //正在更新的过程中,changeInProgress表示其中之一是否正在更新的过程中
            boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
            mStateChangeInProgress = stateChanged || mStateChangeInProgress;
            mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
            //如果为false,则唤醒mPhotonicModulator线程,执行它的run()方法
            if (!changeInProgress) {
                mLock.notifyAll();//很关键的一个方法
            }
        }
        //如果该值为true,说明此时正在进行屏幕状态的改变,没有准备好。因此返回false
        return !mStateChangeInProgress;
    }
}

其中对mLock.notifyAll()这个逻辑再进行下分析,为何当changeInProgress为false的时候需要mLock.notifyAll()呢?
这是因为该线程启动后就是一个死循环,可以无线执行,但在死循环中进行了mLock.wait()操作,这里看看它的run()方法,如下:


@Override
public void run() {
    for (;;) {
        // Get pending change.
        final int state;
        final boolean stateChanged;
        final int backlight;
        final boolean backlightChanged;
        synchronized (mLock) {
            //通过全局变量给局部变量赋值
            state = mPendingState;
            //mActualState表示目前实际的状态值
            stateChanged = (state != mActualState);
            backlight = mPendingBacklight;
            //mActualBacklight表示目前实际的亮度值
            backlightChanged = (backlight != mActualBacklight);
            //stateChange为false表示此时屏幕状态已应用为需要设置的值了(已应用),则再次执行一遍
            //postScreenUpdateThreadSafe()方法,这次执行时,PhotonicMudulator.setScreen()将返回
            //true,表示屏幕更新完成
            if (!stateChanged) {
                // State changed applied, notify outer class.
                postScreenUpdateThreadSafe();
                mStateChangeInProgress = false;//表示更新屏幕已完成
            }
            //说明背光值也已经应用
            if (!backlightChanged) {
                //置为false,表示更新背光已完成,没有正在进行的改变操作
                mBacklightChangeInProgress = false;
            }
            //如果屏幕状态和背光值都应用完成,则让该线程进入等待状态
            if (!stateChanged && !backlightChanged) {
                try {
                    mLock.wait();
                } catch (InterruptedException ex) { }
                continue;
            }
           //设置实际状态值和背光值
            mActualState = state;
            mActualBacklight = backlight;
        }
        // Apply pending change.
        if (DEBUG) {
            Slog.d(TAG, "Updating screen state: state="
                    + Display.stateToString(state) + ", backlight=" + backlight);
        }
        //调用DisplayBlanker中去请求Display
        mBlanker.requestDisplayState(state, backlight);
    }
}

DisplayBlanker.requestPowerState()

DisplayBlanker是一个接口,它专门用来更新实际的屏幕显示状态以及亮度.在DisplayPowerController中,
DisplayBlanker由DisplayManagerService在实例化DisplayPowerController时作为参数传入,
DisplayPowerController中在实例化DisplayPowerState时又通过构造函数传给了DisplayPowerState,
因此,DisplayBlanker的实现还是在DMS中,我们进入DMS中看DisplayBlanker对象:

public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
        SensorManager sensorManager) {
    synchronized (mSyncRoot) {
        DisplayBlanker blanker = new DisplayBlanker() {
            @Override
            public void requestDisplayState(int state, int brightness) {
                // The order of operations is important for legacy reasons.
                //对于灭屏和非灭屏状态,调用callback的顺序不同
                if (state == Display.STATE_OFF) {
                    requestGlobalDisplayStateInternal(state, brightness);
                }
                //PMS中调用native层方法
                callbacks.onDisplayStateChange(state);
                if (state != Display.STATE_OFF) {
                    requestGlobalDisplayStateInternal(state, brightness);更新状态和亮度值
                }
            }
        };
        mDisplayPowerController = new DisplayPowerController(
                mContext, callbacks, handler, sensorManager, blanker);
    }
}

1.从代码中可以得知当状态亮屏时候,调用requestGlobalDisplayStateInternal更新亮度值
2.从以上逻辑来看先更新状态,后更新亮度(亮屏设置时)


 private void requestGlobalDisplayStateInternal(int state, int brightness) {
        int brightnessdefaultdisplay = (brightness&0xff); //中控亮度值
        int brightnessseconddisplay = ((brightness>>8)&0xff); //副屏亮度值
        if (state == Display.STATE_UNKNOWN) {
            state = Display.STATE_ON;
        }
        根据状态设置亮度值,亮度调节时,state为Display.STATE_ON
        if (state == Display.STATE_OFF) {
            brightnessdefaultdisplay = PowerManager.BRIGHTNESS_OFF;
        } else if (brightnessdefaultdisplay < 0) {
            brightnessdefaultdisplay = PowerManager.BRIGHTNESS_DEFAULT;
        } else if (brightnessdefaultdisplay > PowerManager.BRIGHTNESS_ON) {
            brightnessdefaultdisplay = PowerManager.BRIGHTNESS_ON;
        }

        if (state == Display.STATE_OFF) {
            brightnessseconddisplay = PowerManager.BRIGHTNESS_OFF;
        } else if (brightnessseconddisplay < 0) {
            brightnessseconddisplay = PowerManager.BRIGHTNESS_DEFAULT;
        } else if (brightnessseconddisplay > PowerManager.BRIGHTNESS_ON) {
            brightnessseconddisplay = PowerManager.BRIGHTNESS_ON;
        }

        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 == brightnessdefaultdisplay
                            && mGlobalDisplayBrightnessSecondDisplay == brightnessseconddisplay) {
                        return; // no change
                    }

                    Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
                            + Display.stateToString(state)
                            + ", brightness=" + brightness + ")");
                    Slog.d(TAG, "requestGlobalDisplayStateInternal mGlobalDisplayState = " + mGlobalDisplayState + " mGlobalDisplayBrightness" + mGlobalDisplayBrightness + " mGlobalDisplayBrightnessSecondDisplay" + mGlobalDisplayBrightnessSecondDisplay);
                    //更新全局亮度值
                    mGlobalDisplayState = state;
                    mGlobalDisplayBrightness = brightnessdefaultdisplay;
                    mGlobalDisplayBrightnessSecondDisplay = brightnessseconddisplay;
                    //调节亮度
                    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();
                }
                Trace.traceEnd(Trace.TRACE_TAG_POWER);
            } finally {
                mTempDisplayStateWorkQueue.clear();
            }
        }
    }

在这个方法中,设置了mGlobalDisplayState和mGlobalDisplayBrightness,这两个全局变量表示整体的显示状态和亮度,然后将这两值传给了下一个方法applyGlobalDisplayStateLocked(),继续分析该方法:

    private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
        final int count = mDisplayDevices.size();
        for (int i = 0; i < count; i++) {
            DisplayDevice device = mDisplayDevices.get(i);
            Slog.i(TAG, "applyGlobalDisplayStateLocked UniqueId = " + device.getUniqueId());
            Runnable runnable = updateDisplayStateLocked(device);
            if (runnable != null) {
                workQueue.add(runnable);
            }
        }
    }

在这个方法中,首先会遍历mDisplayDevices,它是表示当前所有显示设备的集合,然后更新每一个显示设备.什么是显示设备呢?目前有5种DisplayDevice:

  • 1.LocalDisplayDevice:中控屏幕就是一个显示设备;
  • 2.WifiDisplayDevice:无线投射,通过wifi将屏幕投射到其他物理屏幕上如TV上.
  • 3.VirtualDisplayDevice:虚拟设备
  • 4.LocalDisplayDevice:副屏幕也是一个显示设备
  • 5.空调和仪表也是显示设备,不过空调和仪表的逻辑不在这里(后续会分享)
    调用updateDisplayStateLocked会对中控和副屏幕做不同的处理

DisplayManagerService.updateDisplayStateLocked

    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();
        if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
            if (device.getUniqueId().equals("local:1")) {
                Slog.i(TAG, "updateDisplayStateLocked UniqueId = " + device.getUniqueId() + " mGlobalDisplayStateSecondDisplay = " + mGlobalDisplayState);
                return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightnessSecondDisplay);
            }
            if (((device.getUniqueId().equals("local:0"))) || (device.getUniqueId().equals("local:3"))) {
                Slog.i(TAG, "updateDisplayStateLocked UniqueId = " + device.getUniqueId() + " mGlobalDisplayState = " + mGlobalDisplayState);
                return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
            }
        }
        return null;
    }

首先根据DisplayDevice对象的getDisplayDeviceInfoLocked()方法获取了DisplayDeviceInfo对象,
然后根据DisplayDeviceInfo的flag进行决策,调用下一个方法并返回。DisplayDeviceInfo用于描述显示的物理设备特征,如尺寸、分别率等。

  • local:1 代表副屏, local:0代表中控

DisplayDevice是一个抽象类,其方法的实现在LocalDisplayDevice类中,因此我们看requestDisplayStateLocked方法实现直接去LocalDisplayDevice类查找
具体方法实现如下

      @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;
                }

                // Defer actually setting the display state until after we have exited
                // the critical section since it can take hundreds of milliseconds
                // to complete.
                 //返回该Runnable对象
                return new Runnable() {
                    @Override
                    public void run() {
                        // Exit a suspended state before making any changes.
                        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; // old state and new state is off
                            }
                        }

                        // If the state change was from or to VR, then we need to tell the light
                        // so that it can apply appropriate VR brightness settings. Also, update the
                        // brightness so the state is propogated to light.
                        boolean vrModeChange = false;
                        if ((state == Display.STATE_VR || currentState == Display.STATE_VR) &&
                                currentState != state) {
                            setVrMode(state == Display.STATE_VR);
                            vrModeChange = true;
                        }


                        // Apply brightness changes given that we are in a non-suspended state.
                        if (brightnessChanged || vrModeChange) {
                            setDisplayBrightness(brightness);
                        }

                        // Enter the final desired state, possibly suspended.
                        if (state != currentState) {
                            setDisplayState(state);
                        }
                    }


                    private void setDisplayState(int state) {
                  
                        try {
                            final int mode = getPowerModeForState(state);
                            SurfaceControl.setDisplayPowerMode(token, mode);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                    }

                    private void setDisplayBrightness(int brightness) {
                    
                        try {
							//设置中控屏幕的亮度
                            if (mBuiltInDisplayId == DEFAULT_DISPLAY)
                                mBacklight.setBrightness(brightness, true);
                                //设置副屏的亮度
                            if (mBuiltInDisplayId == SECOND_DISPLAY)
                                mBacklight.setBrightness(brightness, false);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "ScreenBrightness", brightness);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                    }
                };
            }
            return null;
        }

最终交给LightService去处理亮度的调节。后面我就不做分析了。下面整理亮度调节的时序图

在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值