Bootstrap

android系统的亮度调节

前提:使用的是rk3588 android11

1.packages/apps/Settings里可以得知调节亮度调用的是

<intent android:action="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG" />

2.之后通过查找找到这个activity

<activity
            android:name=".settings.BrightnessDialog"
            android:label="@string/quick_settings_brightness_dialog_title"
            android:theme="@*android:style/Theme.DeviceDefault.QuickSettings.Dialog"
            android:finishOnCloseSystemDialogs="true"
            android:launchMode="singleInstance"
            android:excludeFromRecents="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

3.在这个oncreate里找到了

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Window window = getWindow();

        window.setGravity(Gravity.TOP);
        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        window.requestFeature(Window.FEATURE_NO_TITLE);

        View v = LayoutInflater.from(this).inflate(
                R.layout.quick_settings_brightness_dialog, null);
        setContentView(v);

        final ToggleSliderView slider = findViewById(R.id.brightness_slider);
        mBrightnessController = new BrightnessController(this, slider, mBroadcastDispatcher);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mBrightnessController.registerCallbacks();
        MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);
    }

调用了mBrightnessController这个类

@Override
    public void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic,
            int value, boolean stopTracking) {
        if (mExternalChange) return;

        if (mSliderAnimator != null) {
            mSliderAnimator.cancel();
        }

        final float minBacklight;
        final float maxBacklight;
        final int metric;
        final String settingToChange;

        if (mIsVrModeEnabled) {
            metric = MetricsEvent.ACTION_BRIGHTNESS_FOR_VR;
            minBacklight = mMinimumBacklightForVr;
            maxBacklight = mMaximumBacklightForVr;
            settingToChange = Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT;
        } else {
            metric = mAutomatic
                    ? MetricsEvent.ACTION_BRIGHTNESS_AUTO
                    : MetricsEvent.ACTION_BRIGHTNESS;
            minBacklight = mMinimumBacklight;
            maxBacklight = mMaximumBacklight;
            settingToChange = Settings.System.SCREEN_BRIGHTNESS_FLOAT;
        }
        final float valFloat = MathUtils.min(convertGammaToLinearFloat(value,
                minBacklight, maxBacklight),
                1.0f);
        if (stopTracking) {
            // TODO(brightnessfloat): change to use float value instead.
            MetricsLogger.action(mContext, metric,
                    BrightnessSynchronizer.brightnessFloatToInt(mContext, valFloat));

        }
        setBrightness(valFloat);
        if (!tracking) {
            AsyncTask.execute(new Runnable() {
                    public void run() {
                        Settings.System.putFloatForUser(mContext.getContentResolver(),
                                settingToChange, valFloat, UserHandle.USER_CURRENT);
                    }
                });
        }

        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
            cb.onBrightnessLevelChanged();
        }
    }

在发生改变时调用了setBrightness(valFloat);

private void setBrightness(float brightness) {
         Log.e("xsr", "setBrightness(float brightness) "+brightness );
        mDisplayManager.setTemporaryBrightness(brightness);
    }

这个方法又调用了mDisplayManager类

@Override // Binder call
        public void setTemporaryBrightness(float brightness) {
            mContext.enforceCallingOrSelfPermission(
                    Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
                    "Permission required to set the display's brightness");
            final long token = Binder.clearCallingIdentity();
            try {
                synchronized (mSyncRoot) {
                    mDisplayPowerController.setTemporaryBrightness(brightness);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

最后调用了 mDisplayPowerController.setTemporaryBrightness(brightness);

public void setTemporaryBrightness(float brightness) {
        Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,
                Float.floatToIntBits(brightness), 0 /*unused*/);
        msg.sendToTarget();
    }

在这里发送了消息,我们查看消息的处理过程

 

   public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_POWER_STATE:
                    updatePowerState();
                    break;

                case MSG_PROXIMITY_SENSOR_DEBOUNCED:
                    debounceProximitySensor();
                    break;

                case MSG_SCREEN_ON_UNBLOCKED:
                    if (mPendingScreenOnUnblocker == msg.obj) {
                        unblockScreenOn();
                        updatePowerState();
                    }
                    break;
                case MSG_SCREEN_OFF_UNBLOCKED:
                    if (mPendingScreenOffUnblocker == msg.obj) {
                        unblockScreenOff();
                        updatePowerState();
                    }
                    break;
                case MSG_CONFIGURE_BRIGHTNESS:
                    mBrightnessConfiguration = (BrightnessConfiguration)msg.obj;
                    updatePowerState();
                    break;

                case MSG_SET_TEMPORARY_BRIGHTNESS:
                    // TODO: Should we have a a timeout for the temporary brightness?
                    mTemporaryScreenBrightness = Float.intBitsToFloat(msg.arg1);
                    updatePowerState();
                    break;

                case MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT:
                    mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
                    updatePowerState();
                    break;

                case MSG_IGNORE_PROXIMITY:
                    ignoreProximitySensorUntilChangedInternal();
                    break;
            }
        }
    }

最后调用了updatePowerState,这个方法有点长,我们主要看下

            float animateValue = brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT
                    ? PowerManager.BRIGHTNESS_MIN : brightnessState;
            if (isValidBrightnessValue(animateValue)) {
                if (initialRampSkip || hasBrightnessBuckets
                        || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
                    animateScreenBrightness(animateValue, SCREEN_ANIMATION_RATE_MINIMUM);
                } else {
                    animateScreenBrightness(animateValue,
                            slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
                }
            }

通过动画过渡来设置亮度

    private void animateScreenBrightness(float target, float rate) {
        if (DEBUG) {
            Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
        }
        if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {
            Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target);
            // TODO(b/153319140) remove when we can get this from the above trace invocation
            SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target));
            try {
                // TODO(brightnessfloat): change BatteryStats to use float
                mBatteryStats.noteScreenBrightness(
                        BrightnessSynchronizer.brightnessFloatToInt(
                        mContext, target));
            } catch (RemoteException ex) {
                // same process
            }
        }
    }

这个代码通过animateTo来设置了亮度,成功了就执行里面的内容

之后我们就需要看

    public boolean animateTo(float target, float rate) {

        // Immediately jump to the target the first time.
        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;
        }

这里是通过mProperty.setValue(mObject, target);来设置的,这里的mProperty是

    public static final FloatProperty<DisplayPowerState> COLOR_FADE_LEVEL =
            new FloatProperty<DisplayPowerState>("electronBeamLevel") {
        @Override
        public void setValue(DisplayPowerState object, float value) {
            object.setColorFadeLevel(value);
        }

        @Override
        public Float get(DisplayPowerState object) {
            return object.getColorFadeLevel();
        }
    };

这里的object是个泛型,这里指的是DisplayPowerState

    public void setColorFadeLevel(float level) {
        if (mColorFadeLevel != level) {
            if (DEBUG) {
                Slog.d(TAG, "setColorFadeLevel: level=" + level);
            }

            mColorFadeLevel = level;
            if (mScreenState != Display.STATE_OFF) {
                mScreenReady = false;
                scheduleScreenUpdate(); // update backlight brightness
            }
            if (mColorFadePrepared) {
                mColorFadeReady = false;
                scheduleColorFadeDraw();
            }
        }
    }
    private void scheduleScreenUpdate() {
        if (!mScreenUpdatePending) {
            mScreenUpdatePending = true;
            postScreenUpdateThreadSafe();
        }
    }

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

我们看下这个线程

    private final Runnable mScreenUpdateRunnable = new Runnable() {
        @Override
        public void run() {
            mScreenUpdatePending = false;

            float brightnessState = mScreenState != Display.STATE_OFF
                    && mColorFadeLevel > 0f ? mScreenBrightness : PowerManager.BRIGHTNESS_OFF_FLOAT;
            if (mPhotonicModulator.setState(mScreenState, brightnessState)) {//用来设置亮度的方法
                if (DEBUG) {
                    Slog.d(TAG, "Screen ready");
                }
                mScreenReady = true;
                invokeCleanListenerIfNeeded();
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Screen not ready");
                }
            }
        }
    };

我们看下这个类的setState这个方法

    private final class PhotonicModulator extends Thread {
        private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off
        private static final float INITIAL_BACKLIGHT_FLOAT = PowerManager.BRIGHTNESS_INVALID_FLOAT;

        private final Object mLock = new Object();

        private int mPendingState = INITIAL_SCREEN_STATE;
        private float mPendingBacklight = INITIAL_BACKLIGHT_FLOAT;
        private int mActualState = INITIAL_SCREEN_STATE;
        private float mActualBacklight = INITIAL_BACKLIGHT_FLOAT;
        private boolean mStateChangeInProgress;
        private boolean mBacklightChangeInProgress;

        public PhotonicModulator() {
            super("PhotonicModulator");
        }

        public boolean setState(int state, float brightnessState) {
            synchronized (mLock) {
                boolean stateChanged = state != mPendingState;
                boolean backlightChanged = !BrightnessSynchronizer.floatEquals(
                        brightnessState, mPendingBacklight);
                if (stateChanged || backlightChanged) {
                    if (DEBUG) {
                        Slog.d(TAG, "Requesting new screen state: state="
                                + Display.stateToString(state) + ", backlight=" + brightnessState);
                    }

                    mPendingState = state;
                    mPendingBacklight = brightnessState;
                    boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
                    mStateChangeInProgress = stateChanged || mStateChangeInProgress;
                    mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;

                    if (!changeInProgress) {
                        mLock.notifyAll();
                    }
                }
                return !mStateChangeInProgress;
            }
        }

在这里设置后,这是个线程,会一直run,我们看下run的方法

@Override
        public void run() {
            for (;;) {
                // Get pending change.
                final int state;
                final boolean stateChanged;
                final float brightnessState;
                final boolean backlightChanged;
                synchronized (mLock) {
                    state = mPendingState;
                    stateChanged = (state != mActualState);
                    brightnessState = mPendingBacklight;
                    backlightChanged = !BrightnessSynchronizer.floatEquals(
                            brightnessState, mActualBacklight);
                    if (!stateChanged) {
                        // State changed applied, notify outer class.
                        postScreenUpdateThreadSafe();
                        mStateChangeInProgress = false;
                    }
                    if (!backlightChanged) {
                        mBacklightChangeInProgress = false;
                    }
                    if (!stateChanged && !backlightChanged) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException ex) { }
                        continue;
                    }
                    mActualState = state;
                    mActualBacklight = brightnessState;
                }

                // Apply pending change.
                if (DEBUG) {
                    Slog.d(TAG, "Updating screen state: state="
                            + Display.stateToString(state) + ", backlight=" + brightnessState);
                }
                mBlanker.requestDisplayState(state, brightnessState);
            }

最后调用了DisplayBlanker ,这是个接口

我们看他的实现类

                DisplayBlanker blanker = new DisplayBlanker() {
                    @Override
                    public void requestDisplayState(int state, float 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);
                        }
                    }
                };
                mDisplayPowerController = new DisplayPowerController(
                        mContext, callbacks, handler, sensorManager, blanker,
                        mDisplayDevices.get(Display.DEFAULT_DISPLAY));
                mSensorManager = sensorManager;
            }

            mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
        }

他调用了requestGlobalDisplayStateInternal

    private void requestGlobalDisplayStateInternal(int state, float brightnessState) {
        if (state == Display.STATE_UNKNOWN) {
            state = Display.STATE_ON;
        }
        if (state == Display.STATE_OFF) {
            brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
        } else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT
                && brightnessState < PowerManager.BRIGHTNESS_MIN) {
            brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        } else if (brightnessState > PowerManager.BRIGHTNESS_MAX) {
            brightnessState = PowerManager.BRIGHTNESS_MAX;
        }

        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 == brightnessState) {
                        return; // no change
                    }

                    Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
                            + Display.stateToString(state)
                            + ", brightness=" + brightnessState + ")");
                    mGlobalDisplayState = state;
                    mGlobalDisplayBrightness = brightnessState;
                    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();
            }
        }
    }

这里调用了mTempDisplayStateWorkQueue.get(i).run();来执行,我们看下有那些线程

    private 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) {
        // 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) {
            return device.requestDisplayStateLocked(
                    mGlobalDisplayState, mGlobalDisplayBrightness);
        }
        return null;
    }

 device的这个方法返回了null,

    public Runnable requestDisplayStateLocked(int state, float brightnessState) {

        return null;

    }

可能着个类是父类,子类有实现,我们就看下我们看下得到的device的类型是啥

DisplayDevice device = mDisplayDevices.get(i);

通过这个来得到device,我们看下device是如何添加的

    private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
        if (mDisplayDevices.contains(device)) {
            Slog.w(TAG, "Attempted to add already added display device: " + info);
            return;
        }

        Slog.i(TAG, "Display device added: " + info);
        device.mDebugLastLoggedDeviceInfo = info;

        mDisplayDevices.add(device);
        LogicalDisplay display = addLogicalDisplayLocked(device);
        Runnable work = updateDisplayStateLocked(device);
        if (work != null) {
            work.run();
        }
        sch

在这里添加的,我们看下哪里调用了这个。

    private void handleDisplayDeviceAdded(DisplayDevice device) {
        synchronized (mSyncRoot) {
            handleDisplayDeviceAddedLocked(device);
        }
    }

这个方法又是通过

    private final class DisplayAdapterListener implements DisplayAdapter.Listener {
        @Override
        public void onDisplayDeviceEvent(DisplayDevice device, int event) {
            switch (event) {
                case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
                    handleDisplayDeviceAdded(device);
                    break;

                case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
                    handleDisplayDeviceChanged(device);
                    break;

                case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
                    handleDisplayDeviceRemoved(device);
                    break;
            }
        }

在这里调用了这个方法

我们看下listener是在哪里注册的,并且是监听那个信号

    private void registerDefaultDisplayAdapters() {
        // Register default display adapters.
        synchronized (mSyncRoot) {
            // main display adapter
            registerDisplayAdapterLocked(new LocalDisplayAdapter(
                    mSyncRoot, mContext, mHandler, mDisplayAdapterListener));

            // Standalone VR devices rely on a virtual display as their primary display for
            // 2D UI. We register virtual display adapter along side the main display adapter
            // here so that it is ready by the time the system sends the home Intent for
            // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
            // the virtual display inside VR before any VR-specific apps even run.
            mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
                    mHandler, mDisplayAdapterListener);
            if (mVirtualDisplayAdapter != null) {
                registerDisplayAdapterLocked(mVirtualDisplayAdapter);
            }
        }
    }

在这个adapter适配器里我们找到了发送这个信号的

    private void tryConnectDisplayLocked(long physicalDisplayId) {
        final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
        if (displayToken != null) {
            SurfaceControl.DisplayInfo info = SurfaceControl.getDisplayInfo(displayToken);
            if (info == null) {
                Slog.w(TAG, "No valid info found for display device " + physicalDisplayId);
                return;
            }
            SurfaceControl.DisplayConfig[] configs = SurfaceControl.getDisplayConfigs(displayToken);
            if (configs == null) {
                // There are no valid configs for this device, so we can't use it
                Slog.w(TAG, "No valid configs found for display device " + physicalDisplayId);
                return;
            }
            int activeConfig = SurfaceControl.getActiveConfig(displayToken);
            if (activeConfig < 0) {
                // There is no active config, and for now we don't have the
                // policy to set one.
                Slog.w(TAG, "No active config found for display device " + physicalDisplayId);
                return;
            }
            int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);
            if (activeColorMode < 0) {
                // We failed to get the active color mode. We don't bail out here since on the next
                // configuration pass we'll go ahead and set it to whatever it was set to last (or
                // COLOR_MODE_NATIVE if this is the first configuration).
                Slog.w(TAG, "Unable to get active color mode for display device " +
                        physicalDisplayId);
                activeColorMode = Display.COLOR_MODE_INVALID;
            }
            SurfaceControl.DesiredDisplayConfigSpecs configSpecs =
                    SurfaceControl.getDesiredDisplayConfigSpecs(displayToken);
            int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
            Display.HdrCapabilities hdrCapabilities =
                    SurfaceControl.getHdrCapabilities(displayToken);
            LocalDisplayDevice device = mDevices.get(physicalDisplayId);
            if (device == null) {
                // Display was added.
                final boolean isDefaultDisplay = mDevices.size() == 0;
                device = new LocalDisplayDevice(displayToken, physicalDisplayId, info,
                        configs, activeConfig, configSpecs, colorModes, activeColorMode,
                        hdrCapabilities, isDefaultDisplay);
                mDevices.put(physicalDisplayId, device);
                sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
            } else if (device.updateDisplayProperties(configs, activeConfig,
                    configSpecs, colorModes, activeColorMode, hdrCapabilities)) {
                sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
            }
        } else {
            // The display is no longer available. Ignore the attempt to add it.
            // If it was connected but has already been disconnected, we'll get a
            // disconnect event that will remove it from mDevices.
        }
    }

通过这个来通知监听器加一个device  sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);

这个device的类型是LocalDisplayDevice,我们看下这个类

 private final class LocalDisplayDevice extends DisplayDevice {
        public Runnable requestDisplayStateLocked(final int state, final float brightnessState) {
            // Assume that the brightness is off if the display is being turned off.
            assert state != Display.STATE_OFF || BrightnessSynchronizer.floatEquals(
                    brightnessState, PowerManager.BRIGHTNESS_OFF_FLOAT);
            final boolean stateChanged = (mState != state);
            final boolean brightnessChanged = (!BrightnessSynchronizer.floatEquals(
                    mBrightnessState, brightnessState))
                    && mBacklight != null;
            if (stateChanged || brightnessChanged) {
                final long physicalDisplayId = mPhysicalDisplayId;
                final IBinder token = getDisplayTokenLocked();
                final int oldState = mState;

                if (stateChanged) {
                    mState = state;
                    updateDeviceInfoLocked();
                }

                if (brightnessChanged) {
                    mBrightnessState = brightnessState;
                }

                // 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() {
                    @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 if (state == Display.STATE_ON_SUSPEND
                                    || oldState == Display.STATE_ON_SUSPEND) {
                                setDisplayState(Display.STATE_ON);
                                currentState = Display.STATE_ON;
                            } 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(brightnessState);
                        }

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

                    private void setVrMode(boolean isVrEnabled) {
                        if (DEBUG) {
                            Slog.d(TAG, "setVrMode("
                                    + "id=" + physicalDisplayId
                                    + ", state=" + Display.stateToString(state) + ")");
                        }
                        if (mBacklight != null) {
                            mBacklight.setVrMode(isVrEnabled);
                        }
                    }

                    private void setDisplayState(int state) {
                        if (DEBUG) {
                            Slog.d(TAG, "setDisplayState("
                                    + "id=" + physicalDisplayId
                                    + ", state=" + Display.stateToString(state) + ")");
                        }

                        // We must tell sidekick to stop controlling the display before we
                        // can change its power mode, so do that first.
                        if (mSidekickActive) {
                            Trace.traceBegin(Trace.TRACE_TAG_POWER,
                                    "SidekickInternal#endDisplayControl");
                            try {
                                mSidekickInternal.endDisplayControl();
                            } finally {
                                Trace.traceEnd(Trace.TRACE_TAG_POWER);
                            }
                            mSidekickActive = false;
                        }
                        final int mode = getPowerModeForState(state);
                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
                                + "id=" + physicalDisplayId
                                + ", state=" + Display.stateToString(state) + ")");
                        try {
                            SurfaceControl.setDisplayPowerMode(token, mode);
                            Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                        // If we're entering a suspended (but not OFF) power state and we
                        // have a sidekick available, tell it now that it can take control.
                        if (Display.isSuspendedState(state) && state != Display.STATE_OFF
                                && mSidekickInternal != null && !mSidekickActive) {
                            Trace.traceBegin(Trace.TRACE_TAG_POWER,
                                    "SidekickInternal#startDisplayControl");
                            try {
                                mSidekickActive = mSidekickInternal.startDisplayControl(state);
                            } finally {
                                Trace.traceEnd(Trace.TRACE_TAG_POWER);
                            }
                        }
                    }

                    private void setDisplayBrightness(float brightness) {
                        if (DEBUG) {
                            Slog.d(TAG, "setDisplayBrightness("
                                    + "id=" + physicalDisplayId
                                    + ", brightness=" + brightness + ")");
                        }

                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
                                + "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
                        try {
                            if (isHalBrightnessRangeSpecified()) {
                                brightness = displayBrightnessToHalBrightness(
                                        BrightnessSynchronizer.brightnessFloatToIntRange(
                                                getContext(), brightness));
                            }
                            if (mBacklight != null) {
                                mBacklight.setBrightness(brightness);
                            }
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "ScreenBrightness",
                                    BrightnessSynchronizer.brightnessFloatToInt(
                                            getContext(), brightness));
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                    }

                    private boolean isHalBrightnessRangeSpecified() {
                        return !(mSystemBrightnessToNits == null || mNitsToHalBrightness == null);
                    }

                    /**
                     * Converts brightness range from the framework's brightness space to the
                     * Hal brightness space if the HAL brightness space has been provided via
                     * a display device configuration file.
                     */
                    private float displayBrightnessToHalBrightness(float brightness) {
                        if (!isHalBrightnessRangeSpecified()) {
                            return PowerManager.BRIGHTNESS_INVALID_FLOAT;
                        }

                        if (BrightnessSynchronizer.floatEquals(
                                brightness, PowerManager.BRIGHTNESS_OFF)) {
                            return PowerManager.BRIGHTNESS_OFF_FLOAT;
                        }

                        final float nits = mSystemBrightnessToNits.interpolate(brightness);
                        final float halBrightness = mNitsToHalBrightness.interpolate(nits);
                        return halBrightness;
                    }
                };
            }
            return null;
        }

}

这个类确实继承了displaydevice

然后执行这个runnable通过  setDisplayBrightness(brightnessState);来设置亮度

                    private void setDisplayBrightness(float brightness) {
                        if (DEBUG) {
                            Slog.d(TAG, "setDisplayBrightness("
                                    + "id=" + physicalDisplayId
                                    + ", brightness=" + brightness + ")");
                        }

                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
                                + "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
                        try {
                            if (isHalBrightnessRangeSpecified()) {
                                brightness = displayBrightnessToHalBrightness(
                                        BrightnessSynchronizer.brightnessFloatToIntRange(
                                                getContext(), brightness));
                            }
                            if (mBacklight != null) {
                                mBacklight.setBrightness(brightness);//通过这个来设置屏幕亮度
                            }
                            Trace.traceCounter(Trace.TRACE_TAG_POWER,
                                    "ScreenBrightness",
                                    BrightnessSynchronizer.brightnessFloatToInt(
                                            getContext(), brightness));
                        } finally {
                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
                        }
                    }

我们看下backLight的实现

                LightsManager lights = LocalServices.getService(LightsManager.class);
               LogicalLight mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
//LogicalLight 是个抽象类,需要找到实现类

    private final class LightImpl extends LogicalLight {
        private final IBinder mDisplayToken;
        private final int mSurfaceControlMaximumBrightness;

        private LightImpl(Context context, HwLight hwLight) {
            mHwLight = hwLight;
            mDisplayToken = SurfaceControl.getInternalDisplayToken();
            final boolean brightnessSupport = SurfaceControl.getDisplayBrightnessSupport(
                    mDisplayToken);
            if (DEBUG) {
                Slog.d(TAG, "Display brightness support: " + brightnessSupport);
            }
            int maximumBrightness = 0;
            if (brightnessSupport) {
                PowerManager pm = context.getSystemService(PowerManager.class);
                if (pm != null) {
                    maximumBrightness = pm.getMaximumScreenBrightnessSetting();
                }
            }
            mSurfaceControlMaximumBrightness = maximumBrightness;
        }

        @Override
        public void setBrightness(float brightness) {
            setBrightness(brightness, BRIGHTNESS_MODE_USER);
        }

          @Override
        public void setBrightness(float brightness, int brightnessMode) {
            if (Float.isNaN(brightness)) {
                Slog.w(TAG, "Brightness is not valid: " + brightness);
                return;
            }
            synchronized (this) {
                // LOW_PERSISTENCE cannot be manually set
                if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
                    Slog.w(TAG, "setBrightness with LOW_PERSISTENCE unexpected #" + mHwLight.id
                            + ": brightness=" + brightness);
                    return;
                }
                // Ideally, we'd like to set the brightness mode through the SF/HWC as well, but
                // right now we just fall back to the old path through Lights brightessMode is
                // anything but USER or the device shouldBeInLowPersistenceMode().
                if (brightnessMode == BRIGHTNESS_MODE_USER && !shouldBeInLowPersistenceMode()
                        && mSurfaceControlMaximumBrightness == 255) {
                    // New system
                    // TODO: the last check should be mSurfaceControlMaximumBrightness != 0; the
                    // reason we enforce 255 right now is to stay consistent with the old path. In
                    // the future, the framework should be refactored so that brightness is a float
                    // between 0.0f and 1.0f, and the actual number of supported brightness levels
                    // is determined in the device-specific implementation.
                    if (DEBUG) {
                        Slog.d(TAG, "Using new setBrightness path!");
                    }
                    SurfaceControl.setDisplayBrightness(mDisplayToken, brightness);
                } else {
                    // Old system
                    int brightnessInt = BrightnessSynchronizer.brightnessFloatToInt(
                            getContext(), brightness);
                    int color = brightnessInt & 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 (shouldBeInLowPersistenceMode()) {
                brightnessMode = BRIGHTNESS_MODE_LOW_PERSISTENCE;
            } else if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
                brightnessMode = mLastBrightnessMode;
            }

            if (!mInitialized || color != mColor || mode != mMode || onMS != mOnMS ||
                    offMS != mOffMS || mBrightnessMode != brightnessMode) {
                if (DEBUG) {
                    Slog.v(TAG, "setLight #" + mHwLight.id + ": color=#"
                            + Integer.toHexString(color) + ": brightnessMode=" + brightnessMode);
                }
                mInitialized = true;
                mLastColor = mColor;
                mColor = color;
                mMode = mode;
                mOnMS = onMS;
                mOffMS = offMS;
                mBrightnessMode = brightnessMode;
                setLightUnchecked(color, mode, onMS, offMS, brightnessMode);
            }
        }

        private void setLightUnchecked(int color, int mode, int onMS, int offMS,
                int brightnessMode) {
            Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLightState(" + mHwLight.id + ", 0x"
                    + Integer.toHexString(color) + ")");
            try {
                if (mVintfLights != null) {
                    HwLightState lightState = new HwLightState();
                    lightState.color = color;
                    lightState.flashMode = (byte) mode;
                    lightState.flashOnMs = onMS;
                    lightState.flashOffMs = offMS;
                    lightState.brightnessMode = (byte) brightnessMode;
                    mVintfLights.get().setLightState(mHwLight.id, lightState);
                } else {
                    setLight_native(mHwLight.id, color, mode, onMS, offMS, brightnessMode);
                }
            } catch (RemoteException | UnsupportedOperationException ex) {
                Slog.e(TAG, "Failed issuing setLightState", ex);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_POWER);
            }
        }

这个图可以看到我们的背光是通过添加服务来实现的,所以走上面的服务mVintfLights.get().setLightState(mHwLight.id, lightState);

我们看下这个类

   private static class VintfHalCache implements Supplier<ILights>, IBinder.DeathRecipient {
        @GuardedBy("this")
        private ILights mInstance = null;

        @Override
        public synchronized ILights get() {
            if (mInstance == null) {
                IBinder binder = Binder.allowBlocking(ServiceManager.waitForDeclaredService(
                        "android.hardware.light.ILights/default"));
                if (binder != null) {
                    mInstance = ILights.Stub.asInterface(binder);
                    try {
                        binder.linkToDeath(this, 0);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "Unable to register DeathRecipient for " + mInstance);
                    }
                }
            }
            return mInstance;
        }

        @Override
        public synchronized void binderDied() {
            mInstance = null;
        }
    }

    static native void setLight_native(int light, int color, int mode,
            int onMS, int offMS, int brightnessMode);
}

在这里得到了服务,然后我们就可以到hal中查找我们的服务了

ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
    ALOGV("Lights setting state for id=%d to color:%x", id, state.color);
    LightType type;
    int err = -1;
    std::vector<HwLight>::iterator it = _lights.begin();
    for (; it != _lights.end(); ++it) {
        if (it->id == id) {
            type = it->type;
            err = 0;
            break;
        }
    }
    if (err != 0) {
        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    }
    // Set lights.
    err = setLightFromType(type, state);
    if (err == 0) {
        return ndk::ScopedAStatus::ok();
    }
    return ndk::ScopedAStatus::fromServiceSpecificError(err);
}

这就是设置的方法了,他之后调用了setLightFromType

static int setLightFromType(LightType type, const HwLightState& state) {
    int err = 0;
    switch (type) {
        case LightType::BACKLIGHT:
        case LightType::BUTTONS: {
//在这里向backlight中写值
            int brightness = state2brightbess(state);
            err = write_int(getDriverPath(type), brightness);
            write_int(BACKLIGHT_PATH1, brightness);
            write_int(BACKLIGHT_PATH2, brightness);
            break;
        }
        case LightType::BATTERY:
        case LightType::NOTIFICATIONS:
        case LightType::ATTENTION: {
            int red, green, blue;
            int blink;
            int onMS, offMS;
            unsigned int colorRGB;
            std::string led_path(getDriverPath(type));

            switch (state.flashMode) {
                case FlashMode::TIMED: {
                    onMS = state.flashOnMs;
                    offMS = state.flashOffMs;
                    break;
                }
                case FlashMode::NONE:
                case FlashMode::HARDWARE:
                default: {
                    onMS = 0;
                    offMS = 0;
                    break;
                }
            }
            colorRGB = state.color;
            red = (colorRGB >> 16) & 0xFF;
            green = (colorRGB >> 8) & 0xFF;
            blue = colorRGB & 0xFF;
            if (onMS > 0 && offMS > 0) {
                if (onMS == offMS) blink = 2;
                else blink = 1;
            } else {
                blink = 0;
            }
            if (blink) {
                if (red) {
                    if (write_int((led_path + "/led_r/blink").c_str(), blink)) {
                        err = write_int((led_path + "/led_r/brightness").c_str(), 0);
                    }
                }
                if (green) {
                    if (write_int((led_path + "/led_g/blink").c_str(), blink)) {
                        err = write_int((led_path + "/led_g/brightness").c_str(), 0);
                    }
                }
                if (blue) {
                    if (write_int((led_path + "/led_b/blink").c_str(), blink)) {
                        err = write_int((led_path + "/led_b/brightness").c_str(), 0);
                    }
                }
            } else {
                err = write_int((led_path + "/led_r/brightness").c_str(), red);
                err = write_int((led_path + "/led_g/brightness").c_str(), green);
                err = write_int((led_path + "/led_b/brightness").c_str(), blue);
            }
            break;
        }
        default:
            break;
    }
    if (err != 0) {
        ALOGE("Failed to setLightState: %d", err);
        return err;
    }
    return 0;
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;