网站首页 网站导航 课程中心
新闻中心
您所在的位置:Android培训 > 新闻中心 > 【Android培训】Android屏幕亮度调节

【Android培训】Android屏幕亮度调节

来源:中软卓越 日期:2018-05-04 15:03 人气:
标签:
中软国际教育集团Python+大数据课程入驻大武汉啦!!!
平时通过一个slider调节改变屏幕亮度,其实这个slider是systemui的东西,叫做BrightnessDialog

public class BrightnessDialog extends Activity {
    ....
    private BrightnessController mBrightnessController;
    @Override
      protected void onStart() {
        super.onStart();
        // mBrightnessController是BrightnessController类型的
        mBrightnessController.registerCallbacks();
    }
    ....
 
}

进一步会通过BrightnessController

public class BrightnessController implements ToggleSlider.Listener {
    ....
    public void registerCallbacks() {
        ....
        //
        mControl.setOnChangedListener(this);
    }
    ....
 
 
 
    @Override
    public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
            boolean stopTracking) {
        mTracking = tracking;
        updateIcon(mAutomatic);
        if (mExternalChange) return;
        // 如果不是自动亮度,即用户手动设置的亮度
        if (!mAutomatic) {
            final int val = value + mMinimumBacklight;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsLogger.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 {
            // 自动亮度,计算出自动亮度值,然后通过setBrightnessAdj进行设置
            final float adj = value / ((mMaximumBacklight - mMinimumBacklight) / 2f) - 1;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsLogger.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);
                    }
                });
            }
        }
        // 回调所有实现BrightnessStateChangeCallback接口的监听
        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
            cb.onBrightnessLevelChanged();
        }
    }
 
 
    private void setBrightness(int brightness) {
        try {
            // mPower是一个IPowerManager接口,最终实现是在PowerManagerService
            mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
        } catch (RemoteException ex) {
        }
    }
 
}

可以看到,在BrightnessController#onChanged 回调中,调用了自己的setBrightness方法,并且最终通过PowerManagerService#setTemporaryScreenBrightnessSettingOverride实现

PowerManagerService#setTemporaryScreenBrightnessSettingOverride

@Override // Binder call
public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
            // 检查当前调用是否有android.Manifest.permission.DEVICE_POWER权限,如果没有,则抛出SecurityException
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.DEVICE_POWER, null);
 
            final long ident = Binder.clearCallingIdentity();
            try {
                // 通过setTemporaryScreenBrightnessSettingOverrideInternal方法设置屏幕亮度
                setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
}
 
 
private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
        synchronized (mLock) {
            // 屏幕亮度发生改变的时候调用
            if (mTemporaryScreenBrightnessSettingOverride != brightness) {
                // 设置新的屏幕亮度,后面在更新屏幕亮度中会用到
                mTemporaryScreenBrightnessSettingOverride = brightness;
                mDirty |= DIRTY_SETTINGS;
                // 改变当前屏幕亮度
                updatePowerStateLocked();
            }
        }
}
 
 
 
 
private void updatePowerStateLocked() {
        ....
        try {
            // 设置屏幕显示
            boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
 
        } finally {
        }
        ....
}
 
 
private boolean updateDisplayPowerStateLocked(int dirty) {
        final boolean oldDisplayReady = mDisplayReady;
        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
                | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
                | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
            ....
            boolean autoBrightness = (mScreenBrightnessModeSetting ==
                    Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
            if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
                screenBrightness = mScreenBrightnessOverrideFromWindowManager;
                autoBrightness = false;
                brightnessSetByUser = false;
            } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
                // 用户自己设置的屏幕亮度值
                screenBrightness = mTemporaryScreenBrightnessSettingOverride;
            } else if (isValidBrightness(mScreenBrightnessSetting)) {
                screenBrightness = mScreenBrightnessSetting;
            }
            if (autoBrightness) { //如果是自动亮度
                ....
            }
            screenBrightness = Math.max(Math.min(screenBrightness,
                    mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
            // 将新的屏幕亮度值赋值给mDisplayPowerRequest.screenBrightness
            mDisplayPowerRequest.screenBrightness = screenBrightness;
 
            // 进一步通过mDisplayManagerInternal请求改变当前的power状态
            mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
                    mRequestWaitForNegativeProximity);
        }
        return mDisplayReady && !oldDisplayReady;
}

这里的mDisplayManagerInternal是什么呢,可以看到它是DisplayManagerInternal类,是一个抽象类

public abstract class DisplayManagerInternal {
 
}

那么它的实现在哪里?还记得我们手机开机的时候所有的系统服务都是由SystemServer来启动的,其中在startBootstrapServices中启动了DisplayManagerService

mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

接着DisplayManagerService#onStart会被执行

@Override
public void onStart() {
        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
 
        publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                true /*allowIsolated*/);
        // DisplayManagerInternal对应的是LocalService服务
        publishLocalService(DisplayManagerInternal.class, new LocalService());
}

从上面代码可以看出DisplayManagerInternal对应的是LocalService服务,LocalService是DisplayManagerService的一个内部类,继承自DisplayManagerInternal

private final class LocalService extends DisplayManagerInternal {
    
    @Override
        public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
                SensorManager sensorManager) {
            synchronized (mSyncRoot) {
                DisplayBlanker blanker = new DisplayBlanker() {
                    @Override
                    public void requestDisplayState(int state, int brightness, int brightnessMode) {
                        // The order of operations is important for legacy reasons.
                        if (state == Display.STATE_OFF) {
                            requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
                        }
 
                        callbacks.onDisplayStateChange(state);
 
                        if (state != Display.STATE_OFF) {
                            requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
                        }
                    }
                };
                mDisplayPowerController = new DisplayPowerController(
                        mContext, callbacks, handler, sensorManager, blanker);
            }
        }
 
 
    ....
    @Override
    public boolean requestPowerState(DisplayPowerRequest request,
                boolean waitForNegativeProximity) {
            // mDisplayPowerController是DisplayPowerController类型
            return mDisplayPowerController.requestPowerState(request,
                    waitForNegativeProximity);
    }
    ....
 
}

接着看下DisplayPowerController#requestPowerState方法:

public boolean requestPowerState(DisplayPowerRequest request,
            boolean waitForNegativeProximity) {
 
        synchronized (mLock) {
            boolean changed = false;
 
            ....
            if (changed && !mPendingRequestChangedLocked) {
                mPendingRequestChangedLocked = true;
                sendUpdatePowerStateLocked();
            }
 
            return mDisplayReadyLocked;
        }
}
 
 
 
private void sendUpdatePowerStateLocked() {
        if (!mPendingUpdatePowerStateLocked) {
            mPendingUpdatePowerStateLocked = true;
            Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
            msg.setAsynchronous(true);
            mHandler.sendMessage(msg);
        }
}

发送”MSG_UPDATE_POWER_STATE”消息,DisplayControllerHandler是DisplayPowerController的一个内部handler

private final class DisplayControllerHandler extends Handler {
        public DisplayControllerHandler(Looper looper) {
            super(looper, null, true /*async*/);
        }
 
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_POWER_STATE:
                    updatePowerState();
                    break;
                ....
            }
        }
}
 
private void updatePowerState() {
 
        ....
        // If need to set the screen brightness immediately,
        // set the brightness and the brightness mode here.
        if (mSetBrightnessImmediatelyAtNextRequest) {
            if (DEBUG) {
                Slog.d(TAG, "Setting the screen brightness immediately:"
                    + brightness);
            }
            mPowerState.setScreenBrightnessAndBrightnessMode(
                    brightness,
                    hardwareAutoBrightnessEnabled ?
                    Light.BRIGHTNESS_MODE_SENSOR : Light.BRIGHTNESS_MODE_USER);
        }
        ....
 
        if (!mPendingScreenOff) {
            if (!mSetBrightnessImmediatelyAtNextRequest
                && (state == Display.STATE_ON || state == Display.STATE_DOZE)) {
                // 动态调整屏幕亮度
                animateScreenBrightness(brightness,
                        slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
            } else {
                animateScreenBrightness(brightness, 0);
                mSetBrightnessImmediatelyAtNextRequest = false;
            }
        }
 
}
 
 
 
 
public void setScreenBrightnessAndBrightnessMode(int brightness, int brightnessMode) {
        if (mScreenBrightness != brightness || mBrightnessMode != brightnessMode) {
 
            mScreenBrightness = brightness;
            mBrightnessMode = brightnessMode;
            if (mScreenState != Display.STATE_OFF) {
                mScreenReady = false;
                scheduleScreenUpdate();
            }
        }
}
 
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;
 
            int brightness = mScreenState != Display.STATE_OFF
                    && mColorFadeLevel > 0f ? mScreenBrightness : 0;
            // 调用了setState方法,mPhotonicModulator是PhotonicModulator类型,是一个线程
            if (mPhotonicModulator.setState(mScreenState, brightness, mBrightnessMode)) {
                mScreenReady = true;
                invokeCleanListenerIfNeeded();
            } else {
 
            }
        }
};

看下PhotonicModulator线程

private final class PhotonicModulator extends Thread {
        private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off
        private final Object mLock = new Object();
        private boolean mChangeInProgress;
 
        public PhotonicModulator() {
            super("PhotonicModulator");
        }
 
        public boolean setState(int state, int backlight, int brightnessMode) {
            synchronized (mLock) {
                if (state != mPendingState || backlight != mPendingBacklight ||
                        brightnessMode != mPendingBrightnessMode) {
 
                    mPendingState = state;
                    mPendingBacklight = backlight;
                    mPendingBrightnessMode = brightnessMode;
 
                    if (!mChangeInProgress) {
                        mChangeInProgress = true;
                        // 当亮度发生改变完成以后,通过notifyAll唤醒处于等待的所有线程,包括自己,
                        // 此时就会继续走之前"mLock.wait();"下面的代码,通过mBlanker.requestDisplayState实现屏幕亮度变化
                        mLock.notifyAll();
                    }
                }
                return !mChangeInProgress;
            }
        }
 
          @Override
        public void run() {
            for (;;) {
                // Get pending change.
                final int state;
                final boolean stateChanged;
                final int backlight;
                final boolean backlightChanged;
                final int brightnessMode;
                final boolean brightnessModeChanged;
                synchronized (mLock) {
                    state = mPendingState;
                    stateChanged = (state != mActualState);
                    backlight = mPendingBacklight;
                    backlightChanged = (backlight != mActualBacklight);
                    brightnessMode = mPendingBrightnessMode;
                    brightnessModeChanged = (brightnessMode != mActualBrightnessMode);
                    if (!stateChanged && !backlightChanged && !brightnessModeChanged) {
                        // All changed applied, notify outer class and wait for more.
                        mChangeInProgress = false;
                        postScreenUpdateThreadSafe();
                        // 如果没有发生改变,则当前线程处于等待状态,下面的代码也是不会执行的
                        try {
                            mLock.wait();
                        } catch (InterruptedException ex) { }
                        continue;
                    }
                    mActualState = state;
                    mActualBacklight = backlight;
                    mActualBrightnessMode = brightnessMode;
                }
                // 通过mBlanker.requestDisplayState来实现页面亮度改变     
                mBlanker.requestDisplayState(state, backlight, brightnessMode);
            }
        }
}

这里,可以看到,在mScreenUpdateRunnable线程中调用了PhotonicModulator#setState来唤醒所有处于等待状态的线程,包括它自己,PhotonicModulator是在DisplayPowerState的构造方法中就已经启动了,
好了现在看下mBlanker.requestDisplayState,可是发现mBlanker对应的DisplayBlanker是一个接口,那么肯定有它的实现类:

public interface DisplayBlanker {
    void requestDisplayState(int state, int brightness, int brightnessMode);
}

DisplayBlanker是在DisplayManagerService#onStart中绑定LocalService时候构造的

private final class LocalService extends DisplayManagerInternal {
        @Override
        public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
                SensorManager sensorManager) {
            synchronized (mSyncRoot) {
                DisplayBlanker blanker = new DisplayBlanker() {
                    @Override
                    public void requestDisplayState(int state, int brightness, int brightnessMode) {
                        // The order of operations is important for legacy reasons.
                        if (state == Display.STATE_OFF) {
                            requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
                        }
                        // 调用了PowerManagerService中的onDisplayStateChange
                        callbacks.onDisplayStateChange(state); 
 
                        if (state != Display.STATE_OFF) {
                            requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
                        }
                    }
                };
                mDisplayPowerController = new DisplayPowerController(
                        mContext, callbacks, handler, sensorManager, blanker);
            }
        }
}
 
 
 
@Override
public void onDisplayStateChange(int state) {
            // This method is only needed to support legacy display blanking behavior
            // where the display's power state is coupled to suspend or to the power HAL.
            // The order of operations matters here.
            synchronized (mLock) {
                if (mDisplayState != state) {
                    mDisplayState = state;
                    if (state == Display.STATE_OFF) {
                        if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
                            setHalInteractiveModeLocked(false);
                        }
                        if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
                            setHalAutoSuspendModeLocked(true);
                        }
                    } else {
                        if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
                            setHalAutoSuspendModeLocked(false);
                        }
                        if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
                            setHalInteractiveModeLocked(true);
                        }
                    }
                }
            }
}

其中setHalInteractiveModeLocked是一个native函数,设置屏幕是否亮。
 
接着继续看下updatePowerState中animateScreenBrightness动态调整屏幕亮度的过程

private void animateScreenBrightness(int target, float rate) {
        if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {//泛型技术,最后调用了DisplayPowerState的setScreenBrightness函数
            try {
                mBatteryStats.noteScreenBrightness(target);
            } catch (RemoteException ex) {
                // same process
            }
        }
}

最终程序会走到LightsService$LightImpl类中

public class LightsService extends SystemService {
 
    private final class LightImpl extends Light {
 
        @Override
        public void setBrightnessForce(int brightness, int brightnessMode) {
            synchronized (this) {
                int color = brightness & 0x000000ff;
                color = 0xff000000 | (color << 16) | (color << 8) | color;
                setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode, true);
            }
        }
 
        ....
         private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode, boolean force) {
            if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS
                    || brightnessMode != mBrightnessMode || force) {
                mColor = color;
                mMode = mode;
                mOnMS = onMS;
                mOffMS = offMS;
                Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
                        + Integer.toHexString(color) + ")");
                mBrightnessMode = brightnessMode;
                try {
                    if (mAllowSetLight) {
                        // 设置当前屏幕亮度
                        setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
                    }
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_POWER);
                }
            }
        }
        ....
    }
 
}
 
免责声明:本文转载自网络,转载目的在于传递更多信息,版权归原作者所有,如涉及内容、版权和其它问题请联系我们进行删除。

 

中软卓越是中软国际有限公司投资的大型人才服务机构,是中软国际人才战略的核心组成部分之一,承担集团发展过程中人才储备和培养的任务,是软件及外包业务快速发展的重要人才支撑平台,是集团保持高速增长动力之一。

中软国际教育集团专注IT教育36年,一直秉承“用良心做教育”的理念,是中国移动互联网研发人才一体化服务的开拓者,全力打造移动互联网研发人才服务优质平台。

公司总部位于武汉,目前已在深圳、上海、郑州、广州、大连、武汉、成都、西安、杭州、重庆、长沙、合肥、无锡、南宁、厦门、南京、南昌等全国22个省成立了60多家分公司。拥有全国的移动互联网教学就业保障团队,做到了毕业学员业内高薪水,成为学员信赖的IT培训机构。

营业执照 版权所有©Copyright 2008-2017,武汉中软卓越科技有限公司 , All Rights Reserved. ICP备案号:15018648号-1

sitemap | 来校路线 | 分类导航 | 关于我们