前言: 在apk里使用下面方法来进行亮度调节遇到了问题,当亮度小于10后屏幕会变为最亮;
Window localWindow = getWindow();
WindowManager.LayoutParams params = localWindow.getAttributes();
params.screenBrightness = 9 / 255.0F;
localWindow.setAttributes(params);
首先调用
Window.setAttribute
在源码里调用了
public void setAttributes(WindowManager.LayoutParams a) {
mWindowAttributes.copyFrom(a);
dispatchWindowAttributesChanged(mWindowAttributes);
}
接着调用了
dispatchWindowAttributesChanged
这个方法的实现是
protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
if (mCallback != null) {
mCallback.onWindowAttributesChanged(attrs);
}
}
调用了mCallback,这个类里的Callback是个抽象类
public interface Callback {
public void onWindowAttributesChanged(WindowManager.LayoutParams attrs);
}
找这个类的实现类Activity
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback,
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
// Update window manager if: we have a view, that view is
// attached to its parent (which will be a RootView), and
// this activity is not embedded.
if (mParent == null) {
View decor = mDecor;
if (decor != null && decor.getParent() != null) {
getWindowManager().updateViewLayout(decor, params);
if (mContentCaptureManager != null) {
mContentCaptureManager.updateWindowAttributes(params);
}
}
}
}
在这里的方法的实现显示
接着找
getWindowManager().updateViewLayout(decor, params);
找到了这个类的实现类
public final class WindowManagerImpl implements WindowManager {
@UnsupportedAppUsage
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
最后的实现方法是
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
......
root.setLayoutParams(wparams, false);
}
}
在ViewRootImpl中
void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
......
scheduleTraversals();
}
}
最后调用了scheduleTracersals();
@UnsupportedAppUsage
void scheduleTraversals() {
.......
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
......
}
}
这个执行了mTraversalRunnable这个线程;
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
这个线程执行了doTracersal这个方法
void doTraversal() {
......
performTraversals();
.......
}
}
这里执行了performTraversal这个方法执行了
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
.......
int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
mTmpFrame, mTmpRect, mTmpRect, mTmpRect, mPendingBackDropFrame,
mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mSurfaceSize, mBlastSurfaceControl);
.......
这个方法中调用了mWIndowsSession的
int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
mTmpFrame, mTmpRect, mTmpRect, mTmpRect, mPendingBackDropFrame,
mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mSurfaceSize, mBlastSurfaceControl);
接着找到这个session的实现类
@Override
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
.......
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
outFrame, outContentInsets, outVisibleInsets,
outStableInsets, outBackdropFrame, cutout,
mergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls,
outSurfaceSize, outBLASTSurfaceControl);
.....;
}
这里调用了WIndowsManagerService里的relayoutWIndows这个方法
这个方法里有个
displayContent.sendNewConfiguration();
之后调用了
void sendNewConfiguration() {
......
mWmService.mWindowPlacerLocked.performSurfacePlacement();
}
}
在这里调用了
mWmService.mWindowPlacerLocked.performSurfacePlacement();
final void performSurfacePlacement(boolean force) {
......
mTraversalScheduled = false;
performSurfacePlacementLoop();
}
private void performSurfacePlacementLoop() {
......
mService.mRoot.performSurfacePlacement();
......
}
在这里调用了
mService.mRoot.performSurfacePlacement();
这个类里RootWindowContainer调用了
void performSurfacePlacement() {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
try {
performSurfacePlacementNoTrace();
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
在
performSurfacePlacementNoTrace();
对亮度进行了重写并发送了消息
int brightnessFloatAsIntBits = Float.floatToIntBits(brightnessOverride);
// Post these on a handler such that we don't call into power manager service while
// holding the window manager lock to avoid lock contention with power manager lock.
mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightnessFloatAsIntBits,
0).sendToTarget();
对消息进行了处理
private final class MyHandler extends Handler {
......
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SET_SCREEN_BRIGHTNESS_OVERRIDE:
mWmService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
Float.intBitsToFloat(msg.arg1));
break;
......
}
}
我们发送的是ovwreide
mWmService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
Float.intBitsToFloat(msg.arg1));
调用了这个方法 接着就找到了PowerManagerService.java这个类
public void setScreenBrightnessOverrideFromWindowManager(float screenBrightness) {
if (screenBrightness < PowerManager.BRIGHTNESS_MIN
|| screenBrightness > PowerManager.BRIGHTNESS_MAX) {
screenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
setScreenBrightnessOverrideFromWindowManagerInternal(screenBrightness);
}
这个方法对传来的值进行了判断,对不符合标准的赋值为
PowerManager.BRIGHTNESS_INVALID_FLOAT
之后执行了
setScreenBrightnessOverrideFromWindowManagerInternal(screenBrightness);
最后会执行到
private boolean updateDisplayPowerStateLocked(int dirty) {
......
} else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
autoBrightness = false;
screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
} else {
autoBrightness = (mScreenBrightnessModeSetting ==
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
这里有个isValidBrightness继续对值进行了判断
private static boolean isValidBrightness(float value) {
return value >= PowerManager.BRIGHTNESS_MIN && value <= PowerManager.BRIGHTNESS_MAX;
}
不满足条件的会继续在else里赋值为
screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
总结:
在亮度调节时,如果超出范围,会赋值为PowerManager.BRIGHTNESS_INVALID_FLOAT,会不生效,默认会和屏幕亮度相同 。所以在进行亮度调节时尽量在给定的范围内调节。