Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android屏幕亮度調節

Android屏幕亮度調節

編輯:關於Android編程

平時通過一個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);
                }
            }
        }
        ....
    }

}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved