Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java 0 → 100644 +260 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.util.Log; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; /** * Controller which handles all the doze animations of the scrims. */ public class DozeScrimController { private static final String TAG = "DozeScrimController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final DozeParameters mDozeParameters; private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT; private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN; private final Interpolator mDozeAnimationInterpolator; private final Handler mHandler = new Handler(); private final ScrimController mScrimController; private boolean mDozing; private DozeHost.PulseCallback mPulseCallback; private Animator mInFrontAnimator; private Animator mBehindAnimator; private float mInFrontTarget; private float mBehindTarget; public DozeScrimController(ScrimController scrimController, Context context) { mScrimController = scrimController; mDozeParameters = new DozeParameters(context); mDozeAnimationInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); } public void setDozing(boolean dozing, boolean animate) { if (mDozing == dozing) return; mDozing = dozing; if (mDozing) { abortAnimations(); mScrimController.setDozeBehindAlpha(1f); mScrimController.setDozeInFrontAlpha(1f); } else { cancelPulsing(); if (animate) { startScrimAnimation(false /* inFront */, 0f /* target */, NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator); startScrimAnimation(true /* inFront */, 0f /* target */, NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator); } else { abortAnimations(); mScrimController.setDozeBehindAlpha(0f); mScrimController.setDozeInFrontAlpha(0f); } } } /** When dozing, fade screen contents in and out using the front scrim. */ public void pulse(@NonNull DozeHost.PulseCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback must not be null"); } if (!mDozing || mPulseCallback != null) { // Pulse suppressed. callback.onPulseFinished(); return; } // Begin pulse. Note that it's very important that the pulse finished callback // be invoked when we're done so that the caller can drop the pulse wakelock. mPulseCallback = callback; mHandler.post(mPulseIn); } public boolean isPulsing() { return mPulseCallback != null; } private void cancelPulsing() { if (DEBUG) Log.d(TAG, "Cancel pulsing"); if (mPulseCallback != null) { mHandler.removeCallbacks(mPulseIn); mHandler.removeCallbacks(mPulseOut); pulseFinished(); } } private void pulseStarted() { if (mPulseCallback != null) { mPulseCallback.onPulseStarted(); } } private void pulseFinished() { if (mPulseCallback != null) { mPulseCallback.onPulseFinished(); mPulseCallback = null; } } private void abortAnimations() { if (mInFrontAnimator != null) { mInFrontAnimator.cancel(); } if (mBehindAnimator != null) { mBehindAnimator.cancel(); } } private void startScrimAnimation(final boolean inFront, float target, long duration, Interpolator interpolator) { startScrimAnimation(inFront, target, duration, interpolator, 0 /* delay */, null /* endRunnable */); } private void startScrimAnimation(final boolean inFront, float target, long duration, Interpolator interpolator, long delay, final Runnable endRunnable) { Animator current = getCurrentAnimator(inFront); if (current != null) { float currentTarget = getCurrentTarget(inFront); if (currentTarget == target) { return; } current.cancel(); } ValueAnimator anim = ValueAnimator.ofFloat(getDozeAlpha(inFront), target); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float value = (float) animation.getAnimatedValue(); setDozeAlpha(inFront, value); } }); anim.setInterpolator(interpolator); anim.setDuration(duration); anim.setStartDelay(delay); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { setCurrentAnimator(inFront, null); if (endRunnable != null) { endRunnable.run(); } } }); anim.start(); setCurrentAnimator(inFront, anim); setCurrentTarget(inFront, target); } private float getCurrentTarget(boolean inFront) { return inFront ? mInFrontTarget : mBehindTarget; } private void setCurrentTarget(boolean inFront, float target) { if (inFront) { mInFrontTarget = target; } else { mBehindTarget = target; } } private Animator getCurrentAnimator(boolean inFront) { return inFront ? mInFrontAnimator : mBehindAnimator; } private void setCurrentAnimator(boolean inFront, Animator animator) { if (inFront) { mInFrontAnimator = animator; } else { mBehindAnimator = animator; } } private void setDozeAlpha(boolean inFront, float alpha) { if (inFront) { mScrimController.setDozeInFrontAlpha(alpha); } else { mScrimController.setDozeBehindAlpha(alpha); } } private float getDozeAlpha(boolean inFront) { return inFront ? mScrimController.getDozeInFrontAlpha() : mScrimController.getDozeBehindAlpha(); } private final Runnable mPulseIn = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing); if (!mDozing) return; DozeLog.tracePulseStart(); startScrimAnimation(true /* inFront */, 0f, mDozeParameters.getPulseInDuration(), mPulseInInterpolator, mDozeParameters.getPulseInDelay(), mPulseInFinished); // Signal that the pulse is ready to turn the screen on and draw. pulseStarted(); } }; private final Runnable mPulseInFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing); if (!mDozing) return; mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration()); } }; private final Runnable mPulseOut = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing); if (!mDozing) return; startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(), mPulseOutInterpolator, 0 /* delay */, mPulseOutFinished); } }; private final Runnable mPulseOutFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out finished"); DozeLog.tracePulseFinish(); // Signal that the pulse is all finished so we can turn the screen off now. pulseFinished(); } }; } packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +0 −53 Original line number Diff line number Diff line Loading @@ -23,10 +23,7 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; import android.util.LayoutDirection; import android.util.MathUtils; import android.view.MotionEvent; import android.view.VelocityTracker; Loading Loading @@ -63,8 +60,6 @@ public class NotificationPanelView extends PanelView implements private static final float HEADER_RUBBERBAND_FACTOR = 2.05f; private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f; private static final int DOZE_BACKGROUND_COLOR = 0xff000000; private static final int TAG_KEY_ANIM = R.id.scrim; public static final long DOZE_ANIMATION_DURATION = 700; private KeyguardAffordanceHelper mAfforanceHelper; Loading Loading @@ -1824,11 +1819,9 @@ public class NotificationPanelView extends PanelView implements if (dozing == mDozing) return; mDozing = dozing; if (mDozing) { setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0xff, false /*animate*/); mKeyguardStatusBar.setVisibility(View.INVISIBLE); mKeyguardBottomArea.setVisibility(View.INVISIBLE); } else { setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0, animate); mKeyguardBottomArea.setVisibility(View.VISIBLE); mKeyguardStatusBar.setVisibility(View.VISIBLE); if (animate) { Loading @@ -1843,52 +1836,6 @@ public class NotificationPanelView extends PanelView implements return mDozing; } private void setBackgroundColorAlpha(int rgb, int targetAlpha, boolean animate) { int currentAlpha = getBackgroundAlpha(this); if (currentAlpha == targetAlpha) { return; } final int r = Color.red(rgb); final int g = Color.green(rgb); final int b = Color.blue(rgb); Object runningAnim = getTag(TAG_KEY_ANIM); if (runningAnim instanceof ValueAnimator) { ((ValueAnimator) runningAnim).cancel(); } if (!animate) { setBackgroundColor(Color.argb(targetAlpha, r, g, b)); return; } ValueAnimator anim = ValueAnimator.ofInt(currentAlpha, targetAlpha); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); setBackgroundColor(Color.argb(value, r, g, b)); } }); anim.setInterpolator(mDozeAnimationInterpolator); anim.setDuration(DOZE_ANIMATION_DURATION); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { setTag(TAG_KEY_ANIM, null); } }); anim.start(); setTag(TAG_KEY_ANIM, anim); } private static int getBackgroundAlpha(View view) { if (view.getBackground() instanceof ColorDrawable) { ColorDrawable drawable = (ColorDrawable) view.getBackground(); return Color.alpha(drawable.getColor()); } else { return 0; } } public void setShadeEmpty(boolean shadeEmpty) { mShadeEmpty = shadeEmpty; updateEmptyShadeView(); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +7 −4 Original line number Diff line number Diff line Loading @@ -414,6 +414,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private ViewMediatorCallback mKeyguardViewMediatorCallback; private ScrimController mScrimController; private DozeScrimController mDozeScrimController; private final Runnable mAutohide = new Runnable() { @Override Loading Loading @@ -741,6 +742,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScrimController = new ScrimController(scrimBehind, scrimInFront, mScrimSrcModeEnabled); mScrimController.setBackDropView(mBackdrop); mStatusBarView.setScrimController(mScrimController); mDozeScrimController = new DozeScrimController(mScrimController, context); mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header); mHeader.setActivityStarter(this); Loading Loading @@ -3677,13 +3679,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) { return; } mNotificationPanel.setDozing(mDozing, mScrimController.isPulsing() /*animate*/); mNotificationPanel.setDozing(mDozing, mDozeScrimController.isPulsing() /*animate*/); if (mDozing) { mStackScroller.setDark(true, false /*animate*/); } else { mStackScroller.setDark(false, false /*animate*/); } mScrimController.setDozing(mDozing, mScrimController.isPulsing() /*animate*/); mScrimController.setDozing(mDozing); mDozeScrimController.setDozing(mDozing, mDozeScrimController.isPulsing() /* animate */); } public void updateStackScrollerState(boolean goingToFullShade) { Loading Loading @@ -4060,7 +4063,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void wakeUpIfDozing(long time, boolean fromTouch) { if (mDozing && mScrimController.isPulsing()) { if (mDozing && mDozeScrimController.isPulsing()) { PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); pm.wakeUp(time); if (fromTouch) { Loading Loading @@ -4175,7 +4178,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void handlePulseWhileDozing(@NonNull PulseCallback callback) { mScrimController.pulse(callback); mDozeScrimController.pulse(callback); } private void handleStopDozing() { Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +48 −135 Original line number Diff line number Diff line Loading @@ -19,20 +19,15 @@ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.content.Context; import android.graphics.Color; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver; import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import com.android.systemui.R; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.ScrimView; Loading @@ -41,9 +36,6 @@ import com.android.systemui.statusbar.ScrimView; * security method gets shown). */ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private static final String TAG = "ScrimController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); public static final long ANIMATION_DURATION = 220; private static final float SCRIM_BEHIND_ALPHA = 0.62f; Loading @@ -55,7 +47,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private final ScrimView mScrimBehind; private final ScrimView mScrimInFront; private final UnlockMethodCache mUnlockMethodCache; private final DozeParameters mDozeParameters; private boolean mKeyguardShowing; private float mFraction; Loading @@ -70,15 +61,15 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private long mAnimationDelay; private Runnable mOnAnimationFinished; private boolean mAnimationStarted; private boolean mDozing; private boolean mPulsingOut; private DozeHost.PulseCallback mPulseCallback; private final Interpolator mInterpolator = new DecelerateInterpolator(); private final Interpolator mLinearOutSlowInInterpolator; private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT; private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN; private BackDropView mBackDropView; private boolean mScrimSrcEnabled; private boolean mDozing; private float mDozeInFrontAlpha; private float mDozeBehindAlpha; private float mCurrentInFrontAlpha; private float mCurrentBehindAlpha; public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, boolean scrimSrcEnabled) { mScrimBehind = scrimBehind; Loading @@ -87,7 +78,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { mUnlockMethodCache = UnlockMethodCache.getInstance(context); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); mDozeParameters = new DozeParameters(context); mScrimSrcEnabled = scrimSrcEnabled; } Loading Loading @@ -134,60 +124,27 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { scheduleUpdate(); } public void setDozing(boolean dozing, boolean animate) { if (mDozing == dozing) return; public void setDozing(boolean dozing) { mDozing = dozing; if (!mDozing) { cancelPulsing(); mAnimateChange = animate; } scheduleUpdate(); } /** When dozing, fade screen contents in and out using the front scrim. */ public void pulse(@NonNull DozeHost.PulseCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback must not be null"); public void setDozeInFrontAlpha(float alpha) { mDozeInFrontAlpha = alpha; updateScrimColor(mScrimInFront); } if (!mDozing || mPulseCallback != null) { // Pulse suppressed. callback.onPulseFinished(); return; public void setDozeBehindAlpha(float alpha) { mDozeBehindAlpha = alpha; updateScrimColor(mScrimBehind); } // Begin pulse. Note that it's very important that the pulse finished callback // be invoked when we're done so that the caller can drop the pulse wakelock. mPulseCallback = callback; mScrimInFront.post(mPulseIn); public float getDozeBehindAlpha() { return mDozeBehindAlpha; } public boolean isPulsing() { return mPulseCallback != null; } private void cancelPulsing() { if (DEBUG) Log.d(TAG, "Cancel pulsing"); if (mPulseCallback != null) { mScrimInFront.removeCallbacks(mPulseIn); mScrimInFront.removeCallbacks(mPulseOut); pulseFinished(); } } private void pulseStarted() { if (mPulseCallback != null) { mPulseCallback.onPulseStarted(); } } private void pulseFinished() { mPulsingOut = false; if (mPulseCallback != null) { mPulseCallback.onPulseFinished(); mPulseCallback = null; } public float getDozeInFrontAlpha() { return mDozeInFrontAlpha; } private void scheduleUpdate() { Loading Loading @@ -223,12 +180,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { } else if (mBouncerShowing) { setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA); setScrimBehindColor(0f); } else if (mDozing && isPulsing() && !mPulsingOut) { setScrimInFrontColor(0); setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD); } else if (mDozing) { setScrimInFrontColor(1); setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD); } else { float fraction = Math.max(0, Math.min(mFraction, 1)); setScrimInFrontColor(0f); Loading Loading @@ -272,26 +223,46 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { ((ValueAnimator) runningAnim).cancel(); scrim.setTag(TAG_KEY_ANIM, null); } int color = Color.argb((int) (alpha * 255), 0, 0, 0); if (mAnimateChange) { startScrimAnimation(scrim, color); startScrimAnimation(scrim, alpha); } else { setCurrentScrimAlpha(scrim, alpha); updateScrimColor(scrim); } } private float getDozeAlpha(View scrim) { return scrim == mScrimBehind ? mDozeBehindAlpha : mDozeInFrontAlpha; } private float getCurrentScrimAlpha(View scrim) { return scrim == mScrimBehind ? mCurrentBehindAlpha : mCurrentInFrontAlpha; } private void setCurrentScrimAlpha(View scrim, float alpha) { if (scrim == mScrimBehind) { mCurrentBehindAlpha = alpha; } else { scrim.setScrimColor(color); mCurrentInFrontAlpha = alpha; } } private void startScrimAnimation(final ScrimView scrim, int targetColor) { int current = Color.alpha(scrim.getScrimColor()); int target = Color.alpha(targetColor); if (current == target) { return; private void updateScrimColor(ScrimView scrim) { float alpha1 = getCurrentScrimAlpha(scrim); float alpha2 = getDozeAlpha(scrim); float alpha = 1 - (1 - alpha1) * (1 - alpha2); scrim.setScrimColor(Color.argb((int) (alpha * 255), 0, 0, 0)); } ValueAnimator anim = ValueAnimator.ofInt(current, target); private void startScrimAnimation(final ScrimView scrim, float target) { float current = getCurrentScrimAlpha(scrim); ValueAnimator anim = ValueAnimator.ofFloat(current, target); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); scrim.setScrimColor(Color.argb(value, 0, 0, 0)); float alpha = (float) animation.getAnimatedValue(); setCurrentScrimAlpha(scrim, alpha); updateScrimColor(scrim); } }); anim.setInterpolator(getInterpolator()); Loading @@ -313,15 +284,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { } private Interpolator getInterpolator() { if (mAnimateKeyguardFadingOut) { return mLinearOutSlowInInterpolator; } else if (isPulsing() && !mPulsingOut) { return mPulseInInterpolator; } else if (isPulsing()) { return mPulseOutInterpolator; } else { return mInterpolator; } return mAnimateKeyguardFadingOut ? mLinearOutSlowInInterpolator : mInterpolator; } @Override Loading @@ -342,56 +305,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { return true; } private final Runnable mPulseIn = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing); if (!mDozing) return; DozeLog.tracePulseStart(); mDurationOverride = mDozeParameters.getPulseInDuration(); mAnimationDelay = mDozeParameters.getPulseInDelay(); mAnimateChange = true; mOnAnimationFinished = mPulseInFinished; scheduleUpdate(); // Signal that the pulse is ready to turn the screen on and draw. pulseStarted(); } }; private final Runnable mPulseInFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing); if (!mDozing) return; mScrimInFront.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration()); } }; private final Runnable mPulseOut = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing); if (!mDozing) return; mDurationOverride = mDozeParameters.getPulseOutDuration(); mAnimateChange = true; mOnAnimationFinished = mPulseOutFinished; mPulsingOut = true; scheduleUpdate(); } }; private final Runnable mPulseOutFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out finished"); DozeLog.tracePulseFinish(); // Signal that the pulse is all finished so we can turn the screen off now. pulseFinished(); } }; public void setBackDropView(BackDropView backDropView) { mBackDropView = backDropView; mBackDropView.setOnVisibilityChangedRunnable(new Runnable() { Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java 0 → 100644 +260 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.util.Log; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; /** * Controller which handles all the doze animations of the scrims. */ public class DozeScrimController { private static final String TAG = "DozeScrimController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final DozeParameters mDozeParameters; private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT; private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN; private final Interpolator mDozeAnimationInterpolator; private final Handler mHandler = new Handler(); private final ScrimController mScrimController; private boolean mDozing; private DozeHost.PulseCallback mPulseCallback; private Animator mInFrontAnimator; private Animator mBehindAnimator; private float mInFrontTarget; private float mBehindTarget; public DozeScrimController(ScrimController scrimController, Context context) { mScrimController = scrimController; mDozeParameters = new DozeParameters(context); mDozeAnimationInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); } public void setDozing(boolean dozing, boolean animate) { if (mDozing == dozing) return; mDozing = dozing; if (mDozing) { abortAnimations(); mScrimController.setDozeBehindAlpha(1f); mScrimController.setDozeInFrontAlpha(1f); } else { cancelPulsing(); if (animate) { startScrimAnimation(false /* inFront */, 0f /* target */, NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator); startScrimAnimation(true /* inFront */, 0f /* target */, NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator); } else { abortAnimations(); mScrimController.setDozeBehindAlpha(0f); mScrimController.setDozeInFrontAlpha(0f); } } } /** When dozing, fade screen contents in and out using the front scrim. */ public void pulse(@NonNull DozeHost.PulseCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback must not be null"); } if (!mDozing || mPulseCallback != null) { // Pulse suppressed. callback.onPulseFinished(); return; } // Begin pulse. Note that it's very important that the pulse finished callback // be invoked when we're done so that the caller can drop the pulse wakelock. mPulseCallback = callback; mHandler.post(mPulseIn); } public boolean isPulsing() { return mPulseCallback != null; } private void cancelPulsing() { if (DEBUG) Log.d(TAG, "Cancel pulsing"); if (mPulseCallback != null) { mHandler.removeCallbacks(mPulseIn); mHandler.removeCallbacks(mPulseOut); pulseFinished(); } } private void pulseStarted() { if (mPulseCallback != null) { mPulseCallback.onPulseStarted(); } } private void pulseFinished() { if (mPulseCallback != null) { mPulseCallback.onPulseFinished(); mPulseCallback = null; } } private void abortAnimations() { if (mInFrontAnimator != null) { mInFrontAnimator.cancel(); } if (mBehindAnimator != null) { mBehindAnimator.cancel(); } } private void startScrimAnimation(final boolean inFront, float target, long duration, Interpolator interpolator) { startScrimAnimation(inFront, target, duration, interpolator, 0 /* delay */, null /* endRunnable */); } private void startScrimAnimation(final boolean inFront, float target, long duration, Interpolator interpolator, long delay, final Runnable endRunnable) { Animator current = getCurrentAnimator(inFront); if (current != null) { float currentTarget = getCurrentTarget(inFront); if (currentTarget == target) { return; } current.cancel(); } ValueAnimator anim = ValueAnimator.ofFloat(getDozeAlpha(inFront), target); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float value = (float) animation.getAnimatedValue(); setDozeAlpha(inFront, value); } }); anim.setInterpolator(interpolator); anim.setDuration(duration); anim.setStartDelay(delay); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { setCurrentAnimator(inFront, null); if (endRunnable != null) { endRunnable.run(); } } }); anim.start(); setCurrentAnimator(inFront, anim); setCurrentTarget(inFront, target); } private float getCurrentTarget(boolean inFront) { return inFront ? mInFrontTarget : mBehindTarget; } private void setCurrentTarget(boolean inFront, float target) { if (inFront) { mInFrontTarget = target; } else { mBehindTarget = target; } } private Animator getCurrentAnimator(boolean inFront) { return inFront ? mInFrontAnimator : mBehindAnimator; } private void setCurrentAnimator(boolean inFront, Animator animator) { if (inFront) { mInFrontAnimator = animator; } else { mBehindAnimator = animator; } } private void setDozeAlpha(boolean inFront, float alpha) { if (inFront) { mScrimController.setDozeInFrontAlpha(alpha); } else { mScrimController.setDozeBehindAlpha(alpha); } } private float getDozeAlpha(boolean inFront) { return inFront ? mScrimController.getDozeInFrontAlpha() : mScrimController.getDozeBehindAlpha(); } private final Runnable mPulseIn = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing); if (!mDozing) return; DozeLog.tracePulseStart(); startScrimAnimation(true /* inFront */, 0f, mDozeParameters.getPulseInDuration(), mPulseInInterpolator, mDozeParameters.getPulseInDelay(), mPulseInFinished); // Signal that the pulse is ready to turn the screen on and draw. pulseStarted(); } }; private final Runnable mPulseInFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing); if (!mDozing) return; mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration()); } }; private final Runnable mPulseOut = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing); if (!mDozing) return; startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(), mPulseOutInterpolator, 0 /* delay */, mPulseOutFinished); } }; private final Runnable mPulseOutFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out finished"); DozeLog.tracePulseFinish(); // Signal that the pulse is all finished so we can turn the screen off now. pulseFinished(); } }; }
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +0 −53 Original line number Diff line number Diff line Loading @@ -23,10 +23,7 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; import android.util.LayoutDirection; import android.util.MathUtils; import android.view.MotionEvent; import android.view.VelocityTracker; Loading Loading @@ -63,8 +60,6 @@ public class NotificationPanelView extends PanelView implements private static final float HEADER_RUBBERBAND_FACTOR = 2.05f; private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f; private static final int DOZE_BACKGROUND_COLOR = 0xff000000; private static final int TAG_KEY_ANIM = R.id.scrim; public static final long DOZE_ANIMATION_DURATION = 700; private KeyguardAffordanceHelper mAfforanceHelper; Loading Loading @@ -1824,11 +1819,9 @@ public class NotificationPanelView extends PanelView implements if (dozing == mDozing) return; mDozing = dozing; if (mDozing) { setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0xff, false /*animate*/); mKeyguardStatusBar.setVisibility(View.INVISIBLE); mKeyguardBottomArea.setVisibility(View.INVISIBLE); } else { setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0, animate); mKeyguardBottomArea.setVisibility(View.VISIBLE); mKeyguardStatusBar.setVisibility(View.VISIBLE); if (animate) { Loading @@ -1843,52 +1836,6 @@ public class NotificationPanelView extends PanelView implements return mDozing; } private void setBackgroundColorAlpha(int rgb, int targetAlpha, boolean animate) { int currentAlpha = getBackgroundAlpha(this); if (currentAlpha == targetAlpha) { return; } final int r = Color.red(rgb); final int g = Color.green(rgb); final int b = Color.blue(rgb); Object runningAnim = getTag(TAG_KEY_ANIM); if (runningAnim instanceof ValueAnimator) { ((ValueAnimator) runningAnim).cancel(); } if (!animate) { setBackgroundColor(Color.argb(targetAlpha, r, g, b)); return; } ValueAnimator anim = ValueAnimator.ofInt(currentAlpha, targetAlpha); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); setBackgroundColor(Color.argb(value, r, g, b)); } }); anim.setInterpolator(mDozeAnimationInterpolator); anim.setDuration(DOZE_ANIMATION_DURATION); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { setTag(TAG_KEY_ANIM, null); } }); anim.start(); setTag(TAG_KEY_ANIM, anim); } private static int getBackgroundAlpha(View view) { if (view.getBackground() instanceof ColorDrawable) { ColorDrawable drawable = (ColorDrawable) view.getBackground(); return Color.alpha(drawable.getColor()); } else { return 0; } } public void setShadeEmpty(boolean shadeEmpty) { mShadeEmpty = shadeEmpty; updateEmptyShadeView(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +7 −4 Original line number Diff line number Diff line Loading @@ -414,6 +414,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private ViewMediatorCallback mKeyguardViewMediatorCallback; private ScrimController mScrimController; private DozeScrimController mDozeScrimController; private final Runnable mAutohide = new Runnable() { @Override Loading Loading @@ -741,6 +742,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScrimController = new ScrimController(scrimBehind, scrimInFront, mScrimSrcModeEnabled); mScrimController.setBackDropView(mBackdrop); mStatusBarView.setScrimController(mScrimController); mDozeScrimController = new DozeScrimController(mScrimController, context); mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header); mHeader.setActivityStarter(this); Loading Loading @@ -3677,13 +3679,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) { return; } mNotificationPanel.setDozing(mDozing, mScrimController.isPulsing() /*animate*/); mNotificationPanel.setDozing(mDozing, mDozeScrimController.isPulsing() /*animate*/); if (mDozing) { mStackScroller.setDark(true, false /*animate*/); } else { mStackScroller.setDark(false, false /*animate*/); } mScrimController.setDozing(mDozing, mScrimController.isPulsing() /*animate*/); mScrimController.setDozing(mDozing); mDozeScrimController.setDozing(mDozing, mDozeScrimController.isPulsing() /* animate */); } public void updateStackScrollerState(boolean goingToFullShade) { Loading Loading @@ -4060,7 +4063,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void wakeUpIfDozing(long time, boolean fromTouch) { if (mDozing && mScrimController.isPulsing()) { if (mDozing && mDozeScrimController.isPulsing()) { PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); pm.wakeUp(time); if (fromTouch) { Loading Loading @@ -4175,7 +4178,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void handlePulseWhileDozing(@NonNull PulseCallback callback) { mScrimController.pulse(callback); mDozeScrimController.pulse(callback); } private void handleStopDozing() { Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +48 −135 Original line number Diff line number Diff line Loading @@ -19,20 +19,15 @@ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.content.Context; import android.graphics.Color; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver; import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import com.android.systemui.R; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.ScrimView; Loading @@ -41,9 +36,6 @@ import com.android.systemui.statusbar.ScrimView; * security method gets shown). */ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private static final String TAG = "ScrimController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); public static final long ANIMATION_DURATION = 220; private static final float SCRIM_BEHIND_ALPHA = 0.62f; Loading @@ -55,7 +47,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private final ScrimView mScrimBehind; private final ScrimView mScrimInFront; private final UnlockMethodCache mUnlockMethodCache; private final DozeParameters mDozeParameters; private boolean mKeyguardShowing; private float mFraction; Loading @@ -70,15 +61,15 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private long mAnimationDelay; private Runnable mOnAnimationFinished; private boolean mAnimationStarted; private boolean mDozing; private boolean mPulsingOut; private DozeHost.PulseCallback mPulseCallback; private final Interpolator mInterpolator = new DecelerateInterpolator(); private final Interpolator mLinearOutSlowInInterpolator; private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT; private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN; private BackDropView mBackDropView; private boolean mScrimSrcEnabled; private boolean mDozing; private float mDozeInFrontAlpha; private float mDozeBehindAlpha; private float mCurrentInFrontAlpha; private float mCurrentBehindAlpha; public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, boolean scrimSrcEnabled) { mScrimBehind = scrimBehind; Loading @@ -87,7 +78,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { mUnlockMethodCache = UnlockMethodCache.getInstance(context); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); mDozeParameters = new DozeParameters(context); mScrimSrcEnabled = scrimSrcEnabled; } Loading Loading @@ -134,60 +124,27 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { scheduleUpdate(); } public void setDozing(boolean dozing, boolean animate) { if (mDozing == dozing) return; public void setDozing(boolean dozing) { mDozing = dozing; if (!mDozing) { cancelPulsing(); mAnimateChange = animate; } scheduleUpdate(); } /** When dozing, fade screen contents in and out using the front scrim. */ public void pulse(@NonNull DozeHost.PulseCallback callback) { if (callback == null) { throw new IllegalArgumentException("callback must not be null"); public void setDozeInFrontAlpha(float alpha) { mDozeInFrontAlpha = alpha; updateScrimColor(mScrimInFront); } if (!mDozing || mPulseCallback != null) { // Pulse suppressed. callback.onPulseFinished(); return; public void setDozeBehindAlpha(float alpha) { mDozeBehindAlpha = alpha; updateScrimColor(mScrimBehind); } // Begin pulse. Note that it's very important that the pulse finished callback // be invoked when we're done so that the caller can drop the pulse wakelock. mPulseCallback = callback; mScrimInFront.post(mPulseIn); public float getDozeBehindAlpha() { return mDozeBehindAlpha; } public boolean isPulsing() { return mPulseCallback != null; } private void cancelPulsing() { if (DEBUG) Log.d(TAG, "Cancel pulsing"); if (mPulseCallback != null) { mScrimInFront.removeCallbacks(mPulseIn); mScrimInFront.removeCallbacks(mPulseOut); pulseFinished(); } } private void pulseStarted() { if (mPulseCallback != null) { mPulseCallback.onPulseStarted(); } } private void pulseFinished() { mPulsingOut = false; if (mPulseCallback != null) { mPulseCallback.onPulseFinished(); mPulseCallback = null; } public float getDozeInFrontAlpha() { return mDozeInFrontAlpha; } private void scheduleUpdate() { Loading Loading @@ -223,12 +180,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { } else if (mBouncerShowing) { setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA); setScrimBehindColor(0f); } else if (mDozing && isPulsing() && !mPulsingOut) { setScrimInFrontColor(0); setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD); } else if (mDozing) { setScrimInFrontColor(1); setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD); } else { float fraction = Math.max(0, Math.min(mFraction, 1)); setScrimInFrontColor(0f); Loading Loading @@ -272,26 +223,46 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { ((ValueAnimator) runningAnim).cancel(); scrim.setTag(TAG_KEY_ANIM, null); } int color = Color.argb((int) (alpha * 255), 0, 0, 0); if (mAnimateChange) { startScrimAnimation(scrim, color); startScrimAnimation(scrim, alpha); } else { setCurrentScrimAlpha(scrim, alpha); updateScrimColor(scrim); } } private float getDozeAlpha(View scrim) { return scrim == mScrimBehind ? mDozeBehindAlpha : mDozeInFrontAlpha; } private float getCurrentScrimAlpha(View scrim) { return scrim == mScrimBehind ? mCurrentBehindAlpha : mCurrentInFrontAlpha; } private void setCurrentScrimAlpha(View scrim, float alpha) { if (scrim == mScrimBehind) { mCurrentBehindAlpha = alpha; } else { scrim.setScrimColor(color); mCurrentInFrontAlpha = alpha; } } private void startScrimAnimation(final ScrimView scrim, int targetColor) { int current = Color.alpha(scrim.getScrimColor()); int target = Color.alpha(targetColor); if (current == target) { return; private void updateScrimColor(ScrimView scrim) { float alpha1 = getCurrentScrimAlpha(scrim); float alpha2 = getDozeAlpha(scrim); float alpha = 1 - (1 - alpha1) * (1 - alpha2); scrim.setScrimColor(Color.argb((int) (alpha * 255), 0, 0, 0)); } ValueAnimator anim = ValueAnimator.ofInt(current, target); private void startScrimAnimation(final ScrimView scrim, float target) { float current = getCurrentScrimAlpha(scrim); ValueAnimator anim = ValueAnimator.ofFloat(current, target); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); scrim.setScrimColor(Color.argb(value, 0, 0, 0)); float alpha = (float) animation.getAnimatedValue(); setCurrentScrimAlpha(scrim, alpha); updateScrimColor(scrim); } }); anim.setInterpolator(getInterpolator()); Loading @@ -313,15 +284,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { } private Interpolator getInterpolator() { if (mAnimateKeyguardFadingOut) { return mLinearOutSlowInInterpolator; } else if (isPulsing() && !mPulsingOut) { return mPulseInInterpolator; } else if (isPulsing()) { return mPulseOutInterpolator; } else { return mInterpolator; } return mAnimateKeyguardFadingOut ? mLinearOutSlowInInterpolator : mInterpolator; } @Override Loading @@ -342,56 +305,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { return true; } private final Runnable mPulseIn = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing); if (!mDozing) return; DozeLog.tracePulseStart(); mDurationOverride = mDozeParameters.getPulseInDuration(); mAnimationDelay = mDozeParameters.getPulseInDelay(); mAnimateChange = true; mOnAnimationFinished = mPulseInFinished; scheduleUpdate(); // Signal that the pulse is ready to turn the screen on and draw. pulseStarted(); } }; private final Runnable mPulseInFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing); if (!mDozing) return; mScrimInFront.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration()); } }; private final Runnable mPulseOut = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing); if (!mDozing) return; mDurationOverride = mDozeParameters.getPulseOutDuration(); mAnimateChange = true; mOnAnimationFinished = mPulseOutFinished; mPulsingOut = true; scheduleUpdate(); } }; private final Runnable mPulseOutFinished = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "Pulse out finished"); DozeLog.tracePulseFinish(); // Signal that the pulse is all finished so we can turn the screen off now. pulseFinished(); } }; public void setBackDropView(BackDropView backDropView) { mBackDropView = backDropView; mBackDropView.setOnVisibilityChangedRunnable(new Runnable() { Loading