P 上背光调节:

https://blog.csdn.net/FightFightFight/article/details/85797336

 

 

frameworks\base\packages\SystemUI\AndroidManifest.xml

 

                        

 

 

 

frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessDialog.java

 

/** A dialog that provides controls for adjusting the screen brightness. */public class BrightnessDialog extends Activity {    private BrightnessController mBrightnessController;    @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);        setContentView(R.layout.quick_settings_brightness_dialog);        final ImageView icon = (ImageView) findViewById(R.id.brightness_icon_on);        final ToggleSlider slider = (ToggleSlider) findViewById(R.id.brightness_slider);        mBrightnessController = new BrightnessController(this, icon, slider);    }    @Override    protected void onStart() {        super.onStart();        mBrightnessController.registerCallbacks();        MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);    }    @Override    protected void onStop() {        super.onStop();        MetricsLogger.hidden(this, MetricsEvent.BRIGHTNESS_DIALOG);        mBrightnessController.unregisterCallbacks();    }

}

 

// BrightnessController 实现了ToggleSlider监听的类,其内部对象类是赋值传入的slider,从而与ToggleSlider 关联起来

// mBrightnessController.registerCallbacks(); 将BrightnessController 设置为slider 的监听器,同时设置对数据库的监BrightnessController

 

frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessController.java

 

public class BrightnessController implements ToggleSlider.Listener {
public interface BrightnessStateChangeCallback {    public void onBrightnessLevelChanged();  }/** ContentObserver to watch brightness **/private class BrightnessObserver extends ContentObserver {
    private final Uri BRIGHTNESS_MODE_URI =            Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE);    private final Uri BRIGHTNESS_URI =            Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);    private final Uri BRIGHTNESS_ADJ_URI =            Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ);
 

 

  }

 

public void registerCallbacks() {    if (mListening) {        return;    }    mBrightnessObserver.startObserving();    mUserTracker.startTracking();    // Update the slider and mode before attaching the listener so we don't    // receive the onChanged notifications for the initial values.    updateMode();    updateSlider();    mControl.setOnChangedListener(this);    mListening = true;}

 

 

 

}

 

// 当注册数据库监听器与ToggleSlider的监听器后,如果数据库改变,onChange 就会更新ToggleSlider ,如果ToggleSlider  改变了,这回调用其onChange函数,这个时候会更新数据库项,反过来由于数据库项变了,就会更新ToggleSlider  到对应的进度位置。

 

 

frameworks\base\packages\SystemUI\src\com\android\systemui\settings\ToggleSlider.java

 

 
mToggle = (CompoundButton) findViewById(R.id.toggle); mToggle.setOnCheckedChangeListener(mCheckListener); mSlider = (ToggleSeekBar) findViewById(R.id.slider); mSlider.setOnSeekBarChangeListener(mSeekListener);

 

 

 

private final OnCheckedChangeListener mCheckListener = new OnCheckedChangeListener() {    @Override    public void onCheckedChanged(CompoundButton toggle, boolean checked) {        mSlider.setEnabled(!checked);        if (mListener != null) {            mListener.onChanged(                    ToggleSlider.this, mTracking, checked, mSlider.getProgress(), false);        }        if (mMirror != null) {            mMirror.mToggle.setChecked(checked);        }    }};
private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {    @Override    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {        if (mListener != null) {            mListener.onChanged(                    ToggleSlider.this, mTracking, mToggle.isChecked(), progress, false);        }    }

 

 

 

 

ToggleSlider 是由多个控件组成的,这里一个是check控件、一个是进度条控件,并分别绑定对应的监听器。

 

 

 

private ToggleSlider mMirror;private BrightnessMirrorController mMirrorController;

ToggleSlider  这两个成员用于下拉设置中设置与隐藏亮度进度条。

 

 

 

public void setMirror(ToggleSlider toggleSlider) {    mMirror = toggleSlider;    if (mMirror != null) {        mMirror.setChecked(mToggle.isChecked());        mMirror.setMax(mSlider.getMax());        mMirror.setValue(mSlider.getProgress());    }}public void setMirrorController(BrightnessMirrorController c) {    mMirrorController = c;}

 

 

 

这里将 mToggle、mSlider 值设置到 mMirror

 

 

frameworks\base\packages\SystemUI\src\com\android\systemui\qs\QSPanel.java
 
 
public void setBrightnessMirror(BrightnessMirrorController c) { mBrightnessMirrorController = c; ToggleSlider brightnessSlider = (ToggleSlider) findViewById(R.id.brightness_slider); ToggleSlider mirror = (ToggleSlider) c.getMirror().findViewById(R.id.brightness_slider); brightnessSlider.setMirror(mirror); brightnessSlider.setMirrorController(c); } 
 
 
frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBar.java
 
mQSPanel.setBrightnessMirror(mBrightnessMirrorController);

这里 mBrightnessMirrorController控制 ToggleSlider mirror其在下拉菜单中的显示与隐藏,而其值由 mToggle、mSlider 的值设置。

 
 
 
 
frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessController.java
 
public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value, boolean stopTracking) { updateIcon(mAutomatic); if (mExternalChange) return; if (!mAutomatic) { final int val = value + mMinimumBacklight; if (stopTracking) { MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val); } setBrightness(val); if (!tracking) { AsyncTask.execute(new Runnable() { public void run() { Settings.System.putIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, val, UserHandle.USER_CURRENT); } }); } } else { final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1; if (stopTracking) { MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_AUTO, value); } setBrightnessAdj(adj); if (!tracking) { AsyncTask.execute(new Runnable() { public void run() { Settings.System.putFloatForUser(mContext.getContentResolver(), Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj, UserHandle.USER_CURRENT); } }); } } for (BrightnessStateChangeCallback cb : mChangeCallbacks) { cb.onBrightnessLevelChanged(); } }

 

 

 

mAutomaticAvailable = context.getResources().getBoolean( com.android.internal.R.bool.config_automatic_brightness_available);
 
自动亮度是否支持,设置Settings.System.SCREEN_BRIGHTNESS_MODE
 
public static final String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode";
支持则设置为Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC ,否则设置为 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL
 
这里监听进度条改变,并记录到数据库中,并调用PMS设置亮度
 
 
private class BrightnessObserver extends ContentObserver { private final Uri BRIGHTNESS_MODE_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); private final Uri BRIGHTNESS_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); private final Uri BRIGHTNESS_ADJ_URI = Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ);   public BrightnessObserver(Handler handler) { super(handler); } @Override  public void onChange(boolean selfChange) { onChange(selfChange, null); } @Override  public void onChange(boolean selfChange, Uri uri) { if (selfChange) return; try { mExternalChange = true; if (BRIGHTNESS_MODE_URI.equals(uri)) { updateMode(); updateSlider();

 

 

 

同时systemUI 中BrightnessController会注册监听器监听数据库改变从而改变进度条的位置
 
 
 
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
 
关闭自动背光:
 
 
setBrightness(val);-》

mPower.setTemporaryScreenBrightnessSettingOverride(brightness);设置 mTemporaryScreenBrightnessSettingOverride 为当前进度条值,同时会设置 Settings.System.SCREEN_BRIGHTNESS 值为val,但是这个时候值是一样的,所以

SCREEN_BRIGHTNESS 不会变化,紧接着会再次调用这个函数,设置的值为用户点击位置的值,从而马上更新SCREEN_BRIGHTNESS ,
这个时候PMS 监听数据库值Settings.System.SCREEN_BRIGHTNESS 改变,并执行以下
 
mScreenBrightnessSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
 
if (oldScreenBrightnessSetting != mScreenBrightnessSetting) { mTemporaryScreenBrightnessSettingOverride = -1; }
 
mDirty |= DIRTY_SETTINGS;
updatePowerStateLocked();   //这个时候亮度值不一样,从而调节亮度。

 

 

 

当用户点击进度条到不同位置时,
1、进度条会调用setBrightness(val),但是值还是当前进度条的值。这样会调用如下方法:
 
setBrightness(val); //设置 mTemporaryScreenBrightnessSettingOverride 为当前进度条的值。
 
mDirty |= DIRTY_SETTINGS; //设置标记,这样才会调用updatePowerStateLocked(); updatePowerStateLocked(); //更新设置屏膜亮度,但是由于设置的为当前进度条的值,即前后亮度一致,所以这次并不会改变屏膜亮度。
2、这个时候进度条更新到用户设置的值,这个时候会重复1、
3、PMS中监听到SCREEN_BRIGHTNESS 数据库改变,从而将mTemporaryScreenAutoBrightnessAdjustmentSettingOverride 改为 -1,这个时候从数据库中
读取的 SCREEN_BRIGHTNESS 更上次保存的不一样,从而调用
 
mDirty |= DIRTY_SETTINGS;
 
updatePowerStateLocked();
将亮度调到用户设置的亮度值。
 
 
 
 
如果打开自动背光:与手动一样
阶段1
 
setBrightnessAdj(adj); --》
 
mPower.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(adj);-》
 
mDirty |= DIRTY_SETTINGS; updatePowerStateLocked(); // 这个时候并没有改变亮度,用于设置的是当前进度条的值

 

阶段2

 

 
设置mTemporaryScreenAutoBrightnessAdjustmentSettingOverride 为adj,同时设置 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ
这个时候会监听数据库值 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ
final float oldScreenAutoBrightnessAdjustmentSetting =        mScreenAutoBrightnessAdjustmentSetting;mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,        Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,        UserHandle.USER_CURRENT);if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {    mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;}

 

//监听

 

 
private final class SettingsObserver extends ContentObserver { public SettingsObserver(Handler handler) { super(handler); } @Override  public void onChange(boolean selfChange, Uri uri) { synchronized (mLock) { handleSettingsChangedLocked(); } } }

 

 

 

private void handleSettingsChangedLocked() { updateSettingsLocked(); updatePowerStateLocked(); }
 
 
 
阶段1

 

 
setBrightnessAdj(adj); --》
 
mPower.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(adj);-》
mDirty |= DIRTY_SETTINGS;updatePowerStateLocked();

 

--》

 

// Phase 2: Update display power state.boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);

这个时候 有 DIRTY_SETTINGS  并且 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride 是有效值,否则取

mScreenAutoBrightnessAdjustmentSetting

 

 

这里赋值mDisplayPowerRequest

 

// Update display power request.mDisplayPowerRequest.screenBrightness = screenBrightness;           ---屏膜亮度mDisplayPowerRequest.screenAutoBrightnessAdjustment =               ---自动进度条值,现在是mTemporaryScreenAutoBrightnessAdjustmentSettingOverride         screenAutoBrightnessAdjustment;mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;mDisplayPowerRequest.useAutoBrightness = autoBrightness;            ---自动调节值mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;

 

 

 

 

mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,        mRequestWaitForNegativeProximity);

 

 

 

实现在

frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java

 

public boolean requestPowerState(DisplayPowerRequest request,        boolean waitForNegativeProximity) {    return mDisplayPowerController.requestPowerState(request,            waitForNegativeProximity);}

 

 

 

这个时候判断 mPendingRequestLocked 与 request可以知道是否changed,从而是否调用sendUpdatePowerStateLocked,并进入请求标识mPendingRequestChangedLocked

 

if (changed && !mPendingRequestChangedLocked) {    mPendingRequestChangedLocked = true;    sendUpdatePowerStateLocked();}

 

 

if (changed) {    mDisplayReadyLocked = false;             ---如果changed没准备好}

 

 

 

==》

 

private void sendUpdatePowerStateLocked() {    if (!mPendingUpdatePowerStateLocked) {        mPendingUpdatePowerStateLocked = true;        Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);        msg.setAsynchronous(true);        mHandler.sendMessage(msg);    }}
 
进入请求mPendingUpdatePowerStateLocked 

 

 

 

 

@Overridepublic 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_PROTECT_LOW_DIMMING:            handleProtectLowDimming();            break;    }}

 

 

 

==》

 

updatePowerState();
synchronized (mLock) {    mPendingUpdatePowerStateLocked = false;    if (mPendingRequestLocked == null) {        return; // wait until first actual power request    }    if (mPowerRequest == null) {        mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);        mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;        mPendingWaitForNegativeProximityLocked = false;        mPendingRequestChangedLocked = false;        mustInitialize = true;    } else if (mPendingRequestChangedLocked) {        autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment                != mPendingRequestLocked.screenAutoBrightnessAdjustment);        mPowerRequest.copyFrom(mPendingRequestLocked);        mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;        mPendingWaitForNegativeProximityLocked = false;        mPendingRequestChangedLocked = false;        mDisplayReadyLocked = false;    }

 

 

 

 

这个时候构造 mPowerRequest 

 

 

 

 


updateAutoBrightness()
根据光感应出一个值(算法),由这个值算出一个屏膜亮度newScreenAutoBrightness,
并与mScreenAutoBrightness比较,如果不一样就会updateBrightness


自动背光亮度mScreenAutoBrightness
mAppliedAutoBrightness
mScreenBrightness


手动模式
这个时候进度条对应的值是亮度值  SCREEN_BRIGHTNESS     0~255 

自动模式下的亮度
这个时候进度条对应的值是[-1,1],即缩放比例mScreenAutoBrightnessAdjustment,根据这个比例来得到一个亮度值

自动模式下的自动动背光调节
自动背光传感器会自动感应光强度,并通过算法获得一个亮度值mScreenAutoBrightness,与当前屏膜亮度mScreenBrightness比较,
变化则会自动调节屏膜亮度。或者这个时候调节进度条会导致mScreenAutoBrightnessAdjustment变化,从而调节亮度。

问题:
1、手动与自动切换时,会出现进度条不一样,并且也会出些亮度不一样
---这是由于手动模式对应的是上一次SCREEN_BRIGHTNESS ,而自动模式对应的是上一次mScreenAutoBrightnessAdjustment,这两个
值没有必然联系,仅仅记录了上一次对应的亮度的位置及亮度,从而出现这种现象。

2、自动模式,会出现亮度变化但是进度条不变
---这是由于自动背光传感器及对应的算法会根据环境算出一个亮度mScreenAutoBrightness,从而跟目前亮度比较发生变化就会调节到
mScreenAutoBrightness亮度,但是不会影响mScreenAutoBrightnessAdjustment值,所以进度条不变化,亮度变化。如果这个时候
调节进度条会导致mScreenAutoBrightnessAdjustment变化,从而根据mScreenAutoBrightnessAdjustment重新调节亮度。

问题1、 修改
可以在手动与自动切换时将mScreenAutoBrightnessAdjustment与mScreenBrightness关联起来,做到切换时只是进度条改变,屏膜的亮度不变。

 

 

 

见http://www.ithao123.cn/content-11140655.html

 

 

 

http://blog.csdn.net/kitty_landon/article/details/64128140

更多相关文章

  1. Android获取并设置Activity的亮度
  2. Android(安卓)数据库SQLite的使用简单Demo
  3. android 数据存储技术
  4. Android基础练习
  5. 随记:安装数据库的时候需要配置YUM(本地+桥接)
  6. Android中数据存取
  7. Android使用SQLite数据库的简单实例

随机推荐

  1. Android加载SVG实现交互式地图绘制
  2. Windows下通过虚拟机搭建android的linux
  3. Android之实现点击波纹效果
  4. Android adb shell命令大全
  5. android数据库操作出现的 android.databa
  6. Android的EditText控件常用属性
  7. Android架构实例分析之注册hello HAL的JN
  8. android 四种启动模式
  9. 剖析andriod联系人
  10. android:launchMode="singleTask" intent