当前位置:   article > 正文

【Android】开机亮度问题_android开机默认亮度

android开机默认亮度

修改Android开机动画结束后到加载Launcher页面时android加载条出现亮度变化问题
一开始从上层入手,怀疑有app或者窗口对其进行了修改

追踪代码方法

//打印堆栈信息查看调用者
android.util.Log.i(TAG,"updateDisplayPowerStateLocked() ",new Throwable());
  • 1
  • 2

传统方式

一般的亮度修改,要么是调用Window中的方法进行修改,要么是写入系统值中,所以第一阶段想到该方案
1.Window.setAttributes方法修改亮度

frameworks\base\core\java\android\view\Window.java
  • 1

对该文件中setAttributes方法打印Log

public void setAttributes(WindowManager.LayoutParams a) {
        mWindowAttributes.copyFrom(a);
        dispatchWindowAttributesChanged(mWindowAttributes);
    }
  • 1
  • 2
  • 3
  • 4

2.应用设置亮度时Settings.System.SCREEN_BRIGHTNESS值,所以决定在Settings中对属性值进行putInt时打印Log

\frameworks\base\core\java\android\provider
  • 1

通过追加日志的方式来获取谁调用、设置了亮度

public static boolean putInt(ContentResolver cr, String name, int value) {
            return putString(cr, name, Integer.toString(value));
        }
  • 1
  • 2
  • 3

但对于开机亮度值的改变,以上两处地方皆没有进行修改,所以得出结论与上层应用无关,将目光放置到framework层,怀疑为系统对其进行了修改,所以第二阶段在framework中追踪代码。

背光渐变

网上搜索了一下相关的问题,有查看到MTK背光问题处理,于是乎顺着文章定位到DisplayPowerController

frameworks\base\services\core\java\com\android\server\display\DisplayPowerController.java
  • 1

其中的animateScreenBrightness()函数,作用是处理开机时亮度渐变,定位到调用该方法的函数updatePowerState()

private void updatePowerState() {
	...
	if (initialRampSkip || hasBrightnessBuckets
                      || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
                  animateScreenBrightness(brightness, 0);
              } else {
                  animateScreenBrightness(brightness,
                          slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
              }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

根据网上方法将else中的animateScreenBrightness改成与if一致

然而得到的结果只是将亮度渐变时间变快,仍旧会有亮度的变化,只是时间快慢问题,没有找到根源

framework中修改方案

虽然对DisplayPowerController中的animateScreenBrightness进行修改后没有效果,但是通过对updatePowerState打印堆栈信息,最终定位到DisplayManagerService.java、PowerManagerService.java两个文件当中,当然,由于要找到根源,所以也涉及到了LightsService.java这个文件

PowerManagerService.java

updateDisplayPowerStateLocked

核心函数

private boolean updateDisplayPowerStateLocked(int dirty) {
	...
	if (!mBootCompleted) {
		// Keep the brightness steady during boot. This requires the
        // bootloader brightness and the default brightness to be identical.
        autoBrightness = false;
        screenBrightnessOverride = mScreenBrightnessSettingDefault;
        } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
        	autoBrightness = false;
            screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
        } else {
            autoBrightness = (mScreenBrightnessModeSetting == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
        	screenBrightnessOverride = -1;
        }
        //Update display power request
        mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
        ...
        mDisplayRead = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,mRequestWaitForNegativeProximity);//调用DisplayManagerService
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

DisplayManagerService.java

在该文件中有一个重要的变量:mGlobalDisplayBrightness,顾名思义,全局亮度值

//定义
private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
//第一次赋值
mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
  • 1
  • 2
  • 3
  • 4

因为在第一次赋值时调用了pm进行赋值,所以传给下层的亮度值为系统默认值,而非用户设置值,从而导致开机加载完毕,加载桌面时出现亮度变化

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) {
        //第一次传亮度值,采取默认值传递
            return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
        }
        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

LocalDisplayAdapter.java

在开机时,添加设备阶段,就注册且绑定了LocalDisplayAdapter,在DisplayManagerService中对其进行引用,调用其requestDisplayStateLocked方法

@Override
public Runnable requestDisplayStateLocked(final int state, final int brightness) {
	...
	return new Runnable(){
		...
		private void setDisplayBrightness(int brightness) {
			...
			try{
			mBacklight.setBrightness(brightness);
			}
		}	
	};
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

LightsService.java

private final class LightImpl extends Light {
	...
	@Override
	//为LocalDisplayAdapter所调用
	public void setBrightness(int brightness) {
		setBrightness(brightness,BRIGHTNESS_MODE_USER);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
@Override
public void setBrightness(int brightness, int brightnessMode) {
	synchronized(this) {
		...
		setLightLocked(color,LIGHT_FLASH_NONE,0,0,brightnessMode);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
private void setLightsLocked(int color, int mode, int onMS, int offMS, int brightnessMode){
	...
	if (!mInitialized || color != mColor || mode != mMode || onMS != mOnMS || bambchanged || offMS != mOffMS || mBrightnessMode != brightnessMode){
		...
		try{
			//该处是上层调用native函数,将值传给驱动层
			setLight_native(mId,color,mode,onMS,offMS,brightnessMode);
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

原本是想在DisplayManagerService中对用户设置的亮度值进行获取再设置,但是在此java文件中添加System.getInt或者getIntForUser,刷机时都会报错,导致开不了机

所以想到两种方案
一是修改系统默认值,使得第一次开机亮度最大化
二是在修改完后写入到metazone中,在驱动层开机时进行读取

由于只想修改上层而不动驱动,所以采取了第一种方法,但是该方法仍存在问题

最终解决方案

将SettingsProvider中的默认值进行修改,修改完之后,刷机验证,正常
通过日志知道,在没有更改任何条件的情况下,值会从255渐变到102,所以也就意味着一开始的值设定的就是40%,即102

<!-- Default screen brightness, from 0 to 255.  102 is 40%. -->
    <integer name="def_screen_brightness">255</integer>
  • 1
  • 2

遗留问题

虽然修改了默认值,在开机的情况下已经不会在出现该亮度变化的问题,但是在测试时发现,如果将android亮度调节至最暗,再次开机会出现由最亮到最暗的动画过渡,其实这种现象是属于一方案代码修改后的正常变化范围

然而所要达到的效果是开机过程中不再有任何的亮度变化,所以就需要在开机第一时间将亮度设置为用户设置的值,在修改整个问题的过程中,其实一直在kernel层的接收亮度文件中进行修改,但通过追加日志发现,该处与framework层修改默认值的效果一致,即不能完全将整个开机过程的亮度进行囊括

后来查阅MTK资料,发现在arm2中已经进行了修改,也就是达到了开关背光一致性,即关机前设置的亮度,会在开机的那一刻就设置同等的亮度值,在整个开机过程中不会再有变化

发现是要通过写入metazone,供设备在开机时读取metazone来实现该功能

其实在没有深入arm2时,也考虑到是否可以通过写入metazone来确保开机时就保证亮度一致,但由于一直卡在kernel层,导致写入metazone也无法实现,因为通过串口日志以及adb对比,在kernel\drivers\misc\mediatek\leds\的leds.c文件中,亮度值的设定实际上就是开机动画完成后到加载Launcher前的一个亮度设置

所以综上,我调节的系统并没有实现开关背光一致性功能,后续也通过追踪代码,对arm2中display目录下的mt_led.c中代码进行比对,确实存在开机将亮度拉到最大值的函数设定,从而破坏了开关背光一致性功能

对c不是很熟悉,但是理清了一下思路:
1、在开机的时候,系统还未启动,所以系统服务中的一些设定是不管用的,要在开机的时候就读取到亮度值,只有写入到metazone中
2、顺着思路找到arm2开机文件设置亮度的地方,看看是否实现了读取保存的亮度值

通过以上两点找到对应的led文件,果然,去除掉了读取metazone部分,且值固定为最大值,即无论你关机前设置的亮度是多少,都会在开机的时候通通拉到最高

mt_led.c

mt65xx_backlight_on(void)
void mt65xx_backlight_on(void)
{
	unsigned int First_SetBacklight = 1;
	if(First_SetBacklight == 1) {
		First_SetBacklight = 0;
		mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, LED_FULL);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/642996
推荐阅读
相关标签
  

闽ICP备14008679号