基于Android P 背光流程
16lz
2021-01-23
一、SystemUI、Settings中手动调节
/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java@Overridepublic void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic, int value, boolean stopTracking) { final String setting; if (mIsVrModeEnabled) { setting = Settings.System.SCREEN_BRIGHTNESS_FOR_VR; } else { setting = Settings.System.SCREEN_BRIGHTNESS; } //获取亮度值 final int val = convertGammaToLinear(value, min, max); //设置亮度值 setBrightness(val); if (!tracking) { //在异步任务中将新的亮度值保存在SettingsProvider中 AsyncTask.execute(new Runnable() { public void run() { Settings.System.putIntForUser(mContext.getContentResolver(), setting, val, UserHandle.USER_CURRENT); } }); }}private void setBrightness(int brightness) { mDisplayManager.setTemporaryBrightness(brightness);}//frameworks/base/core/java/android/hardware/display/DisplayManager.javapublic void setTemporaryBrightness(int brightness) { mGlobal.setTemporaryBrightness(brightness);}//frameworks/base/core/java/android/hardware/display/DisplayManagerGlobal.javapublic void setTemporaryBrightness(int brightness) { try { mDm.setTemporaryBrightness(brightness); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); }}//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java@Override // Binder callpublic void setTemporaryBrightness(int brightness) { mContext.enforceCallingOrSelfPermission( Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, "Permission required to set the display's brightness"); final long token = Binder.clearCallingIdentity(); try { synchronized (mSyncRoot) { mDisplayPowerController.setTemporaryBrightness(brightness); } } finally { Binder.restoreCallingIdentity(token); }}/frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.javapublic void setTemporaryBrightness(int brightness) { Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS, brightness, 0 /*unused*/); msg.sendToTarget();}@Overridepublic void handleMessage(Message msg) { switch (msg.what) { case MSG_SET_TEMPORARY_BRIGHTNESS: // TODO: Should we have a a timeout for the temporary brightness? //将brightness赋值给了mTemporaryScreenBrightness mTemporaryScreenBrightness = msg.arg1; updatePowerState(); break; } }}private void updatePowerState() {// ...... //手动设置亮度是否改变 final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); if (userSetBrightnessChanged) { mTemporaryScreenBrightness = -1;}// ......// Apply manual brightness. if (brightness < 0) { brightness = clampScreenBrightness(mCurrentScreenBrightnessSetting); }// ...... // Use the temporary screen brightness if there isn't an override, either from // WindowManager or based on the display state. if (mTemporaryScreenBrightness > 0) { //使用手动设置的亮度 brightness = mTemporaryScreenBrightness; mAppliedTemporaryBrightness = true; } else { mAppliedTemporaryBrightness = false; } //........ if (!mPendingScreenOff) { final boolean isDisplayContentVisible = mColorFadeEnabled ? (mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f) : (state == Display.STATE_ON && mSkipRampState == RAMP_STATE_SKIP_NONE); if (initialRampSkip || hasBrightnessBuckets || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {//设置亮度值到底层驱动,调节背光值,不设置背光动画 animateScreenBrightness(brightness, 0); } else {//设置亮度值到底层驱动,调节背光值,根据slowChange设置快动画还是慢动画 animateScreenBrightness(brightness, slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast); } //......}private boolean updateUserSetScreenBrightness() { if (mPendingScreenBrightnessSetting < 0) { return false; } //add for bug BEG if (mPendingScreenBrightnessSetting > 0 && (mCurrentScreenBrightnessSetting == mTemporaryScreenBrightness)){ return true; } //add for bug END if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) { mPendingScreenBrightnessSetting = -1; return false; } mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting; mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting; mPendingScreenBrightnessSetting = -1; return true;}//监听SettingsProvider中Settings.System.SCREEN_BRIGHTNESS的值变化(对应systemUI,Settings中seekbar的拖动)private final class SettingsObserver extends ContentObserver { public SettingsObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, Uri uri) { handleSettingsChange(false /* userSwitch */); } }private void handleSettingsChange(boolean userSwitch) { mPendingScreenBrightnessSetting = getScreenBrightnessSetting(); sendUpdatePowerState();}private int getScreenBrightnessSetting() { final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessDefault, UserHandle.USER_CURRENT); return clampAbsoluteBrightness(brightness);}二、视频背光调节播放视频时,可以通过上下滑动界面来设置亮度,当退出播放界面时,又会恢复到原亮度,其调用接口正是PMS中的setScreenBrightnessOverrideFromWindowManager()方法。/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.javapublic void handleMessage(Message msg) { switch (msg.what) { case SET_SCREEN_BRIGHTNESS_OVERRIDE: //调用PMS相关接口 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager( msg.arg1); break; ...... } }}/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java@Overridepublic void setScreenBrightnessOverrideFromWindowManager(int screenBrightness) { if (screenBrightness < PowerManager.BRIGHTNESS_DEFAULT || screenBrightness > PowerManager.BRIGHTNESS_ON) { screenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } setScreenBrightnessOverrideFromWindowManagerInternal(screenBrightness);}private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) { synchronized (mLock) { //将亮度值设置给了mScreenBrightnessOverrideFromWindowManager变量 if (mScreenBrightnessOverrideFromWindowManager != brightness) { mScreenBrightnessOverrideFromWindowManager = brightness; mDirty |= DIRTY_SETTINGS; updatePowerStateLocked(); } }}private void updatePowerStateLocked() { if (!mSystemReady || mDirty == 0) { return; } if (!Thread.holdsLock(mLock)) { Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked"); } Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState"); try { // Phase 0: Basic state updates. updateIsPoweredLocked(mDirty); updateStayOnLocked(mDirty); updateScreenBrightnessBoostLocked(mDirty); // Phase 1: Update wakefulness. // Loop because the wake lock and user activity computations are influenced // by changes in wakefulness. final long now = SystemClock.uptimeMillis(); int dirtyPhase2 = 0; for (;;) { int dirtyPhase1 = mDirty; dirtyPhase2 |= dirtyPhase1; mDirty = 0; updateWakeLockSummaryLocked(dirtyPhase1); updateUserActivitySummaryLocked(now, dirtyPhase1); if (!updateWakefulnessLocked(dirtyPhase1)) { break; } } // Phase 2: Lock profiles that became inactive/not kept awake. updateProfilesLocked(now); // Phase 3: Update display power state. final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2); // Phase 4: Update dream state (depends on display ready signal). updateDreamLocked(dirtyPhase2, displayBecameReady); // Phase 5: Send notifications, if needed. finishWakefulnessChangeIfNeededLocked(); // Phase 6: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } }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 | DIRTY_VR_MODE_CHANGED |DIRTY_QUIESCENT)) != 0) { mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); // Determine appropriate screen brightness and auto-brightness adjustments. final boolean autoBrightness; final int screenBrightnessOverride; 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; mDisplayPowerRequest.useAutoBrightness = autoBrightness; mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked(); mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness(); updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest); if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager; if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0 && !mDrawWakeLockOverrideFromSidekick) { if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) { mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE; } if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) { mDisplayPowerRequest.dozeScreenState = Display.STATE_ON; } } mDisplayPowerRequest.dozeScreenBrightness = mDozeScreenBrightnessOverrideFromDreamManager; } else { mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN; mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity); mRequestWaitForNegativeProximity = false; if ((dirty & DIRTY_QUIESCENT) != 0) { sQuiescent = false; } } return mDisplayReady && !oldDisplayReady; }/frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.javapublic boolean requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity) { if (DEBUG) { Slog.d(TAG, "requestPowerState: " + request + ", waitForNegativeProximity=" + waitForNegativeProximity); } synchronized (mLock) { boolean changed = false; if (waitForNegativeProximity && !mPendingWaitForNegativeProximityLocked) { mPendingWaitForNegativeProximityLocked = true; changed = true; } if (mPendingRequestLocked == null) { mPendingRequestLocked = new DisplayPowerRequest(request); changed = true; } else if (!mPendingRequestLocked.equals(request)) { mPendingRequestLocked.copyFrom(request); changed = true; if (changed) { mDisplayReadyLocked = false; } if (changed && !mPendingRequestChangedLocked) { mPendingRequestChangedLocked = true; sendUpdatePowerStateLocked(); } return mDisplayReadyLocked; } }private void sendUpdatePowerStateLocked() { if (!mPendingUpdatePowerStateLocked) { mPendingUpdatePowerStateLocked = true; Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); mHandler.sendMessage(msg);} @Overridepublic void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_POWER_STATE: updatePowerState(); break; }}三、自动背光自动背光流程跟前面的介绍背光流程分叉口就在updatePowerState()。private void updatePowerState() {…if (mAutomaticBrightnessController != null) { hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints(); mAutomaticBrightnessController.configure(autoBrightnessEnabled, mBrightnessConfiguration, mLastUserSetScreenBrightness / (float)PowerManager.BRIGHTNESS_ON, userSetBrightnessChanged, autoBrightnessAdjustment, autoBrightnessAdjustmentChanged, mPowerRequest.policy); } // Apply auto-brightness. boolean slowChange = false; if (brightness < 0) { float newAutoBrightnessAdjustment = autoBrightnessAdjustment; if (autoBrightnessEnabled) { brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness(); newAutoBrightnessAdjustment = mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); } if (brightness >= 0) { // Use current auto-brightness value and slowly adjust to changes. brightness = clampScreenBrightness(brightness); if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { slowChange = true; // slowly adapt to auto-brightness } putScreenBrightnessSetting(brightness); mAppliedAutoBrightness = true; } else { mAppliedAutoBrightness = false; } if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) { putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment); } } else { mAppliedAutoBrightness = false; }…if (!mPendingScreenOff) { final boolean isDisplayContentVisible = mColorFadeEnabled ? (mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f) : (state == Display.STATE_ON && mSkipRampState == RAMP_STATE_SKIP_NONE); if (initialRampSkip || hasBrightnessBuckets || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) { animateScreenBrightness(brightness, 0); } else { animateScreenBrightness(brightness, slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast); }…}public void configure(boolean enable, @Nullable BrightnessConfiguration configuration, float brightness, boolean userChangedBrightness, float adjustment, boolean userChangedAutoBrightnessAdjustment, int displayPolicy) { boolean dozing = (displayPolicy == DisplayPowerRequest.POLICY_DOZE); boolean changed = setBrightnessConfiguration(configuration); changed |= setDisplayPolicy(displayPolicy); if (userChangedAutoBrightnessAdjustment) { changed |= setAutoBrightnessAdjustment(adjustment); } if (userChangedBrightness && enable) { changed |= setScreenBrightnessByUser(brightness); } final boolean userInitiatedChange = userChangedBrightness || userChangedAutoBrightnessAdjustment; if (userInitiatedChange && enable && !dozing) { prepareBrightnessAdjustmentSample(); }//注册/解除注册LightSensor,即开启自动调节亮度且非Doze状态下才可用 changed |= setLightSensorEnabled(enable && !dozing);//changed为true则说明自动调节亮度状态发生改变或自动亮度调整值发生改变,则更新亮度 if (changed) { updateAutoBrightness(false /*sendUpdate*/); } }private boolean setLightSensorEnabled(boolean enable) { if (enable) { if (!mLightSensorEnabled) { mLightSensorEnabled = true; mLightSensorEnableTime = SystemClock.uptimeMillis(); mCurrentLightSensorRate = mInitialLightSensorRate; mSensorManager.registerListener(mLightSensorListener, mLightSensor, mCurrentLightSensorRate * 1000, mHandler); return true; } } else if (mLightSensorEnabled) { mLightSensorEnabled = false; mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; mRecentLightSamples = 0; mAmbientLightRingBuffer.clear(); mCurrentLightSensorRate = -1; mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX); mSensorManager.unregisterListener(mLightSensorListener); } return false; }private final SensorEventListener mLightSensorListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { if (mLightSensorEnabled) { final long time = SystemClock.uptimeMillis(); final float lux = event.values[0]; handleLightSensorEvent(time, lux); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Not used. } };private void handleLightSensorEvent(long time, float lux) { Trace.traceCounter(Trace.TRACE_TAG_POWER, "ALS", (int) lux); mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX); if (mAmbientLightRingBuffer.size() == 0) { adjustLightSensorRate(mNormalLightSensorRate); } applyLightSensorMeasurement(time, lux); updateAmbientLux(time);}private void applyLightSensorMeasurement(long time, float lux) { mRecentLightSamples++;//删除距离当前mAmbientLightHorizon(10s)秒的数据 //LSensor500ms上报一次值,因此存储10s内可存储21组数据 mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);//添加此次数据 mAmbientLightRingBuffer.push(time, lux); mLastObservedLux = lux; mLastObservedLuxTime = time; }private void updateAmbientLux() { long time = SystemClock.uptimeMillis(); mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon); updateAmbientLux(time); }private void updateAmbientLux(long time) { if (!mAmbientLuxValid) { final long timeWhenSensorWarmedUp = mLightSensorWarmUpTimeConfig + mLightSensorEnableTime; if (time < timeWhenSensorWarmedUp) { mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, timeWhenSensorWarmedUp); return; } setAmbientLux(calculateAmbientLux(time,AMBIENT_LIGHT_SHORT_HORIZON_MILLIS)); mAmbientLuxValid = true; updateAutoBrightness(true); } long nextBrightenTransition = nextAmbientLightBrighteningTransition(time); long nextDarkenTransition = nextAmbientLightDarkeningTransition(time); float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS); float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS); if ((slowAmbientLux >= mBrighteningLuxThreshold && fastAmbientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time) ||(slowAmbientLux <= mDarkeningLuxThreshold && fastAmbientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time)) { setAmbientLux(fastAmbientLux); updateAutoBrightness(true); nextBrightenTransition = nextAmbientLightBrighteningTransition(time); nextDarkenTransition = nextAmbientLightDarkeningTransition(time); } long nextTransitionTime = Math.min(nextDarkenTransition, nextBrightenTransition); nextTransitionTime = nextTransitionTime > time ? nextTransitionTime : time + mNormalLightSensorRate; mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime); }private void updateAutoBrightness(boolean sendUpdate) { if (!mAmbientLuxValid) { return; } float value = mBrightnessMapper.getBrightness(mAmbientLux); int newScreenAutoBrightness = clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); if (mScreenAutoBrightness != newScreenAutoBrightness) { mScreenAutoBrightness = newScreenAutoBrightness; if (sendUpdate) { mCallbacks.updateBrightness(); } } }public int getAutomaticScreenBrightness() { if (!mAmbientLuxValid) { return -1; } if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) { return (int) (mScreenAutoBrightness * mDozeScaleFactor); } return mScreenAutoBrightness; }/frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java@Overridepublic void updateBrightness() { sendUpdatePowerState(); }private void sendUpdatePowerState() { synchronized (mLock) { sendUpdatePowerStateLocked(); } }private void sendUpdatePowerStateLocked() { if (!mPendingUpdatePowerStateLocked) { mPendingUpdatePowerStateLocked = true; Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); mHandler.sendMessage(msg); } }//最后又是重新调用updatepowerstate()去更新背光值到底层
上面各种背光流程,我们都已经将具体流程介绍了一遍,最后得将在他们各个模式下的背光值设置到底层驱动中,而取的值,则要看当前是属于那种模式下,使用animateScreenBrightness()改变屏幕亮度。
if (initialRampSkip || hasBrightnessBuckets || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {//直接设置亮度值,不需要亮度动画 animateScreenBrightness(brightness, 0); } else {//设置亮度值,根据slowChange设置快速或慢速动画 animateScreenBrightness(brightness, ? mBrightnessRampRateSlow : mBrightnessRampRateFast); }private void animateScreenBrightness(int target, int rate) { if (DEBUG) { Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate); } if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", target); try { mBatteryStats.noteScreenBrightness(target); } catch (RemoteException ex) { // same process } } }/frameworks/base/services/core/java/com/android/server/display/RampAnimator.javapublic boolean animateTo(int target, int rate) { // Immediately jump to the target the first time. if (mFirstTime || rate <= 0) { if (mFirstTime || target != mCurrentValue) { mFirstTime = false; mRate = 0; mTargetValue = target; mCurrentValue = target; mProperty.setValue(mObject, target); if (mAnimating) { mAnimating = false; cancelAnimationCallback(); } if (mListener != null) { mListener.onAnimationEnd(); } return true; } return false; } if (!mAnimating || rate > mRate || (target <= mCurrentValue && mCurrentValue <= mTargetValue) || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) { mRate = rate; } final boolean changed = (mTargetValue != target); mTargetValue = target; // Start animating. if (!mAnimating && target != mCurrentValue) { mAnimating = true; mAnimatedValue = mCurrentValue; mLastFrameTimeNanos = System.nanoTime(); postAnimationCallback(); } return changed;}private void postAnimationCallback() { mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, mAnimationCallback, null); }private final Runnable mAnimationCallback = new Runnable() { @Override // Choreographer callback public void run() { final long frameTimeNanos = mChoreographer.getFrameTimeNanos(); final float timeDelta = (frameTimeNanos - mLastFrameTimeNanos)* 0.000000001f; mLastFrameTimeNanos = frameTimeNanos; final float scale = ValueAnimator.getDurationScale(); if (scale == 0) { // Animation off. mAnimatedValue = mTargetValue; } else { final float amount = timeDelta * mRate / scale; if (mTargetValue > mCurrentValue) { mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue); } else { mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); } } final int oldCurrentValue = mCurrentValue; mCurrentValue = Math.round(mAnimatedValue); if (oldCurrentValue != mCurrentValue) { mProperty.setValue(mObject, mCurrentValue); } if (mTargetValue != mCurrentValue) { postAnimationCallback(); } else { mAnimating = false; if (mListener != null) { mListener.onAnimationEnd(); } } }};public RampAnimator(T object, IntProperty property) { mObject = object; mProperty = property; mChoreographer = Choreographer.getInstance(); }/frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java mScreenBrightnessRampAnimator = new RampAnimator( mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);/frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.javapublic static final IntProperty SCREEN_BRIGHTNESS = new IntProperty("screenBrightness") { @Override public void setValue(DisplayPowerState object, int value) { object.setScreenBrightness(value); } @Override public Integer get(DisplayPowerState object) { return object.getScreenBrightness(); } };public void setScreenBrightness(int brightness) { if (mScreenBrightness != brightness) { mScreenBrightness = brightness; 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; if (mPhotonicModulator.setState(mScreenState, brightness)) { if (DEBUG) { Slog.d(TAG, "Screen ready"); } mScreenReady = true; invokeCleanListenerIfNeeded(); } else { if (DEBUG) { Slog.d(TAG, "Screen not ready"); } } } };public boolean setState(int state, int backlight) { synchronized (mLock) { boolean stateChanged = state != mPendingState; boolean backlightChanged = backlight != mPendingBacklight; mPendingState = state; mPendingBacklight = backlight; boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress; mStateChangeInProgress = stateChanged || mStateChangeInProgress; mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress; if (!changeInProgress) { mLock.notifyAll(); } } return !mStateChangeInProgress; } }@Overridepublic void run() { for (;;) { // Get pending change. final int state; final boolean stateChanged; final int backlight; final boolean backlightChanged; synchronized (mLock) { state = mPendingState; stateChanged = (state != mActualState); backlight = mPendingBacklight; backlightChanged = (backlight != mActualBacklight); if (!stateChanged) { postScreenUpdateThreadSafe(); mStateChangeInProgress = false; } if (!backlightChanged) { mBacklightChangeInProgress = false; } if (!stateChanged && !backlightChanged) { try { mLock.wait(); } catch (InterruptedException ex) { } continue; } mActualState = state; mActualBacklight = backlight; } mBlanker.requestDisplayState(state, backlight); } }}/frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.javapublic void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager) { synchronized (mSyncRoot) { DisplayBlanker blanker = new DisplayBlanker() { @Override public void requestDisplayState(int state, int brightness) { // The order of operations is important for legacy reasons. //对于灭屏和非灭屏状态,调用callback的顺序不同 if (state == Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); } //PMS中调用native层方法 callbacks.onDisplayStateChange(state); if (state != Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); } } }; mDisplayPowerController = new DisplayPowerController( mContext, callbacks, handler, sensorManager, blanker); }}private void requestGlobalDisplayStateInternal(int state, int brightness) { if (state == Display.STATE_UNKNOWN) { state = Display.STATE_ON; } if (state == Display.STATE_OFF) { brightness = PowerManager.BRIGHTNESS_OFF; } else if (brightness < 0) { brightness = PowerManager.BRIGHTNESS_DEFAULT; } else if (brightness > PowerManager.BRIGHTNESS_ON) { brightness = PowerManager.BRIGHTNESS_ON; } synchronized (mTempDisplayStateWorkQueue) { try { synchronized (mSyncRoot) { if (mGlobalDisplayState == state && mGlobalDisplayBrightness == brightness) { return; // no change } Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState(" + Display.stateToString(state) + ", brightness=" + brightness + ")"); mGlobalDisplayState = state; mGlobalDisplayBrightness = brightness; applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); } for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) { mTempDisplayStateWorkQueue.get(i).run(); } Trace.traceEnd(Trace.TRACE_TAG_POWER); } finally { mTempDisplayStateWorkQueue.clear(); } } }private void applyGlobalDisplayStateLocked(List workQueue) { final int count = mDisplayDevices.size(); for (int i = 0; i < count; i++) { DisplayDevice device = mDisplayDevices.get(i); Runnable runnable = updateDisplayStateLocked(device); if (runnable != null) { workQueue.add(runnable); } } }private Runnable updateDisplayStateLocked(DisplayDevice device) { DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); } return null; }/frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java@Overridepublic Runnable requestDisplayStateLocked(final int state, final int brightness) { assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF; final boolean stateChanged = (mState != state); final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null; if (stateChanged || brightnessChanged) { final int displayId = mBuiltInDisplayId; final IBinder token = getDisplayTokenLocked(); final int oldState = mState; if (stateChanged) { mState = state; updateDeviceInfoLocked(); } if (brightnessChanged) { mBrightness = brightness; } return new Runnable() { @Override public void run() { int currentState = oldState; if (Display.isSuspendedState(oldState) || oldState == Display.STATE_UNKNOWN) { if (!Display.isSuspendedState(state)) { setDisplayState(state); currentState = state; } else if (state == Display.STATE_DOZE_SUSPEND || oldState == Display.STATE_DOZE_SUSPEND) { setDisplayState(Display.STATE_DOZE); currentState = Display.STATE_DOZE; } else if (state == Display.STATE_ON_SUSPEND || oldState == Display.STATE_ON_SUSPEND) { setDisplayState(Display.STATE_ON); currentState = Display.STATE_ON; } else { return; } } boolean vrModeChange = false; if ((state == Display.STATE_VR || currentState == Display.STATE_VR) && currentState != state) { setVrMode(state == Display.STATE_VR); vrModeChange = true; } if (brightnessChanged || vrModeChange) { setDisplayBrightness(brightness); } if (state != currentState) { setDisplayState(state); } } private void setVrMode(boolean isVrEnabled) { mBacklight.setVrMode(isVrEnabled); } private void setDisplayState(int state) { if (mSidekickActive) { Trace.traceBegin(Trace.TRACE_TAG_POWER, "SidekickInternal#endDisplayControl"); try { mSidekickInternal.endDisplayControl(); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } mSidekickActive = false; } final int mode = getPowerModeForState(state); Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState(" + "id=" + displayId + ", state=" + Display.stateToString(state) + ")"); try { SurfaceControl.setDisplayPowerMode(token, mode); Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } if (Display.isSuspendedState(state) && state != Display.STATE_OFF && mSidekickInternal != null && !mSidekickActive) { Trace.traceBegin(Trace.TRACE_TAG_POWER, "SidekickInternal#startDisplayControl"); try { mSidekickActive = mSidekickInternal.startDisplayControl(state); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } } private void setDisplayBrightness(int brightness) { Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("+ "id=" + displayId + ", brightness=" + brightness + ")"); try { mBacklight.setBrightness(brightness); Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenBrightness", brightness); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } }; } return null; }/frameworks/base/services/core/java/com/android/server/lights/LightsService.java@Overridepublic void setBrightness(int brightness, int brightnessMode) { synchronized (this) { // LOW_PERSISTENCE cannot be manually set if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) { return; } int color = brightness & 0x000000ff; color = 0xff000000 | (color << 16) | (color << 8) | color; setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); } }private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) { if (shouldBeInLowPersistenceMode()) { brightnessMode = BRIGHTNESS_MODE_LOW_PERSISTENCE; } else if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) { brightnessMode = mLastBrightnessMode; } if (!mInitialized || color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS || mBrightnessMode != brightnessMode) { mInitialized = true; mLastColor = mColor; mColor = color; mMode = mode; mOnMS = onMS; mOffMS = offMS; mBrightnessMode = brightnessMode; Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x" + Integer.toHexString(color) + ")"); try { setLight_native(mId, color, mode, onMS, offMS, brightnessMode); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } }static native void setLight_native(int light, int color, int mode, int onMS, int offMS, int brightnessMode);}/frameworks/base/services/core/jni/com_android_server_lights_LightsService.cppstatic void setLight_native( JNIEnv* /* env */, jobject /* clazz */, jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint brightnessMode) { if (!validate(light, flashMode, brightnessMode)) { return; } sp hal = LightHal::associate(); if (hal == nullptr) { return; } Type type = static_cast(light); LightState state = constructState( colorARGB, flashMode, onMS, offMS, brightnessMode); { android::base::Timer t;//将背光值传递到HAL层,设置到驱动文件中 Return ret = hal->setLight(type, state); processReturn(ret, type, state); if (t.duration() > 50ms) ALOGD("Excessive delay setting light"); }}
更多相关文章
- Android动画效果生动有趣的通知NiftyNotification(Android Toast
- Android中的动画详解系列【4】——Activity之间切换动画
- Android 用网络图片做帧动画
- item点击波纹动画
- Property Animation属性动画,还用补间动画你就out了
- Android几种动画的总结(MaterialAnimations)
- 【Android】如何调节屏幕亮度,关闭屏幕
- Android动画