前提:使用的是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;
}