项目场景:
Rk3288 Android 8.1 自动调节亮度打开有异常.
问题描述
机器打开 "自动调节亮度"时, 屏幕亮度会随着 LightSensor 值变化,但是设置和导状态栏中的亮度值Bar均没有变化.
// Setting 中的值未改变.
private double getCurrentBrightness() {
if (isInVrMode()) {
final double value = (mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR,
mMaxBrightness);
return getPercentage(value, mMinVrBrightness, mMaxVrBrightness);
}
final int brightnessMode = (mContentResolver,
System.SCREEN_BRIGHTNESS_MODE, System.SCREEN_BRIGHTNESS_MODE_MANUAL);
if (brightnessMode == System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
final float value = (mContentResolver,
System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
// auto brightness is between -1 and 1
return getPercentage(value, -1, 1);
}
final double value = (mContentResolver, System.SCREEN_BRIGHTNESS,
mMinBrightness);
return getPercentage(value, mMinBrightness, mMaxBrightness);
}
// Settings 亮度Bar 未发生变化
private final Runnable mUpdateSliderRunnable = new Runnable() {
@Override
public void run() {
if (mIsVrModeEnabled) {
int value = ((),
.SCREEN_BRIGHTNESS_FOR_VR, mMaximumBacklight,
UserHandle.USER_CURRENT);
(MSG_UPDATE_SLIDER,
mMaximumBacklightForVr - mMinimumBacklightForVr,
value - mMinimumBacklightForVr).sendToTarget();
} else if (mAutomatic) {
float value = ((),
.SCREEN_AUTO_BRIGHTNESS_ADJ, 0,
UserHandle.USER_CURRENT);
(MSG_UPDATE_SLIDER, (int) BRIGHTNESS_ADJ_RESOLUTION,
(int) ((value + 1) * BRIGHTNESS_ADJ_RESOLUTION / 2f)).sendToTarget();
} else {
int value;
value = ((),
.SCREEN_BRIGHTNESS, mMaximumBacklight,
UserHandle.USER_CURRENT);
(MSG_UPDATE_SLIDER, mMaximumBacklight - mMinimumBacklight,
value - mMinimumBacklight).sendToTarget();
}
}
};
.SCREEN_AUTO_BRIGHTNESS_ADJ 值未发生变化.
原因分析:
自动亮度开启后 , 当屏幕亮度发生改变时,"/sys/class/backlight/backlight/brightness" 值会改变.
当亮度值改变时 会出现以下的LOG,
E/Lights Hal( 240): write_int failed to open /sys/class/backlight/rk28_bl/brightness
继而找到 \hardware\rockchip\liblights\ . 调用set_backlight_light()
#define BACKLIGHT_PATH1 "/sys/class/backlight/backlight/brightness" // for kernel 4.4 int set_backlight_light(struct light_device_t* dev, struct light_state_t const* state) { int err = 0; int brightness = rgb_to_brightness(state); pthread_mutex_lock(&g_lock); err = write_int(BACKLIGHT_PATH, brightness); if (err !=0) err = write_int(BACKLIGHT_PATH1, brightness); pthread_mutex_unlock(&g_lock); return 0; }
frameworks\base\services\core\java\com\android\server\lights\ 和 frameworks\base\services\core\java\com\android\server\lights\ setBrightness()
@Override public void setBrightness(int brightness) { setBrightness(brightness, BRIGHTNESS_MODE_USER); } @Override public void setBrightness(int brightness, int brightnessMode) { synchronized (this) { // LOW_PERSISTENCE cannot be manually set if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) { (TAG, "setBrightness with LOW_PERSISTENCE unexpected #" + mId + ": brightness=0x" + (brightness)); return; } int color = brightness & 0x000000ff; color = 0xff000000 | (color << 16) | (color << 8) | color; setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); } }
setBrightness() 这个方法只有在 frameworks\base\services\core\java\com\android\server\display\ 中调用.
public Runnable requestDisplayStateLocked(final int state, final int brightness) { /* 省略代码 */ private void setDisplayBrightness(int brightness) { if (DEBUG) { (TAG, "setDisplayBrightness(" + ", brightness=" + brightness + ")"); } (Trace.TRACE_TAG_POWER, "setDisplayBrightness(" + ", brightness=" + brightness + ")"); try { (brightness); (Trace.TRACE_TAG_POWER, "ScreenBrightness", brightness); } finally { (Trace.TRACE_TAG_POWER); } } }
再往上追代码 设置 "/sys/class/backlight/backlight/brightness" 节点是在 frameworks\base\services\core\java\com\android\server\ 中 requestGlobalDisplayStateInternal(int state, int brightness) 方法里. 这个类是由 调用的.
import ; import ; import ; // in requestGlobalDisplayStateInternal(int state, int brightness) // Add for LightSensor_ADJ by brightness Change in begin final float adj = brightness / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1; setBrightnessAdj(adj); (TAG, "-----requestGlobalDisplayStateInternal : ----adj " +adj); (new Runnable() { public void run() { ((), .SCREEN_AUTO_BRIGHTNESS_ADJ, adj); } }); // Add for LightSensor_ADJ by brightness Change end private void setBrightnessAdj(float adj) { try { (adj); } catch (RemoteException ex) { } }
在此设置后,即可在 LightSensor 改变 brightness 时,同步改变 .SCREEN_AUTO_BRIGHTNESS_ADJ 的值,继而实现动态改变Settings的值.
解决方案:
当屏幕亮度("/sys/class/backlight/backlight/brightness")变化时,.SCREEN_AUTO_BRIGHTNESS_ADJ 值应随之变化.
采用倒追法,完成的本项功能,逻辑尚不算是很清晰,若有大神,可以针对Android 9 以下指点不胜感激.