am c1bb8620: am a77a37c4: Merge "Fix doze jank by removing a fullscreen layer of overdraw" into lmp-mr1-dev
* commit 'c1bb86200dd995229ec6a3956f21065a8e4a425f': Fix doze jank by removing a fullscreen layer of overdraw
This commit is contained in:
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -23,10 +23,7 @@ import android.animation.PropertyValuesHolder;
|
|||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.LayoutDirection;
|
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.VelocityTracker;
|
import android.view.VelocityTracker;
|
||||||
@@ -63,8 +60,6 @@ public class NotificationPanelView extends PanelView implements
|
|||||||
private static final float HEADER_RUBBERBAND_FACTOR = 2.05f;
|
private static final float HEADER_RUBBERBAND_FACTOR = 2.05f;
|
||||||
private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
|
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;
|
public static final long DOZE_ANIMATION_DURATION = 700;
|
||||||
|
|
||||||
private KeyguardAffordanceHelper mAfforanceHelper;
|
private KeyguardAffordanceHelper mAfforanceHelper;
|
||||||
@@ -1824,11 +1819,9 @@ public class NotificationPanelView extends PanelView implements
|
|||||||
if (dozing == mDozing) return;
|
if (dozing == mDozing) return;
|
||||||
mDozing = dozing;
|
mDozing = dozing;
|
||||||
if (mDozing) {
|
if (mDozing) {
|
||||||
setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0xff, false /*animate*/);
|
|
||||||
mKeyguardStatusBar.setVisibility(View.INVISIBLE);
|
mKeyguardStatusBar.setVisibility(View.INVISIBLE);
|
||||||
mKeyguardBottomArea.setVisibility(View.INVISIBLE);
|
mKeyguardBottomArea.setVisibility(View.INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0, animate);
|
|
||||||
mKeyguardBottomArea.setVisibility(View.VISIBLE);
|
mKeyguardBottomArea.setVisibility(View.VISIBLE);
|
||||||
mKeyguardStatusBar.setVisibility(View.VISIBLE);
|
mKeyguardStatusBar.setVisibility(View.VISIBLE);
|
||||||
if (animate) {
|
if (animate) {
|
||||||
@@ -1843,52 +1836,6 @@ public class NotificationPanelView extends PanelView implements
|
|||||||
return mDozing;
|
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) {
|
public void setShadeEmpty(boolean shadeEmpty) {
|
||||||
mShadeEmpty = shadeEmpty;
|
mShadeEmpty = shadeEmpty;
|
||||||
updateEmptyShadeView();
|
updateEmptyShadeView();
|
||||||
|
|||||||
@@ -414,6 +414,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
|
|
||||||
private ViewMediatorCallback mKeyguardViewMediatorCallback;
|
private ViewMediatorCallback mKeyguardViewMediatorCallback;
|
||||||
private ScrimController mScrimController;
|
private ScrimController mScrimController;
|
||||||
|
private DozeScrimController mDozeScrimController;
|
||||||
|
|
||||||
private final Runnable mAutohide = new Runnable() {
|
private final Runnable mAutohide = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -741,6 +742,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
mScrimController = new ScrimController(scrimBehind, scrimInFront, mScrimSrcModeEnabled);
|
mScrimController = new ScrimController(scrimBehind, scrimInFront, mScrimSrcModeEnabled);
|
||||||
mScrimController.setBackDropView(mBackdrop);
|
mScrimController.setBackDropView(mBackdrop);
|
||||||
mStatusBarView.setScrimController(mScrimController);
|
mStatusBarView.setScrimController(mScrimController);
|
||||||
|
mDozeScrimController = new DozeScrimController(mScrimController, context);
|
||||||
|
|
||||||
mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
|
mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
|
||||||
mHeader.setActivityStarter(this);
|
mHeader.setActivityStarter(this);
|
||||||
@@ -3677,13 +3679,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
|
if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNotificationPanel.setDozing(mDozing, mScrimController.isPulsing() /*animate*/);
|
mNotificationPanel.setDozing(mDozing, mDozeScrimController.isPulsing() /*animate*/);
|
||||||
if (mDozing) {
|
if (mDozing) {
|
||||||
mStackScroller.setDark(true, false /*animate*/);
|
mStackScroller.setDark(true, false /*animate*/);
|
||||||
} else {
|
} else {
|
||||||
mStackScroller.setDark(false, false /*animate*/);
|
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) {
|
public void updateStackScrollerState(boolean goingToFullShade) {
|
||||||
@@ -4060,7 +4063,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void wakeUpIfDozing(long time, boolean fromTouch) {
|
public void wakeUpIfDozing(long time, boolean fromTouch) {
|
||||||
if (mDozing && mScrimController.isPulsing()) {
|
if (mDozing && mDozeScrimController.isPulsing()) {
|
||||||
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||||
pm.wakeUp(time);
|
pm.wakeUp(time);
|
||||||
if (fromTouch) {
|
if (fromTouch) {
|
||||||
@@ -4175,7 +4178,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handlePulseWhileDozing(@NonNull PulseCallback callback) {
|
private void handlePulseWhileDozing(@NonNull PulseCallback callback) {
|
||||||
mScrimController.pulse(callback);
|
mDozeScrimController.pulse(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleStopDozing() {
|
private void handleStopDozing() {
|
||||||
|
|||||||
@@ -19,20 +19,15 @@ package com.android.systemui.statusbar.phone;
|
|||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
import android.view.animation.PathInterpolator;
|
|
||||||
|
|
||||||
import com.android.systemui.R;
|
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.BackDropView;
|
||||||
import com.android.systemui.statusbar.ScrimView;
|
import com.android.systemui.statusbar.ScrimView;
|
||||||
|
|
||||||
@@ -41,9 +36,6 @@ import com.android.systemui.statusbar.ScrimView;
|
|||||||
* security method gets shown).
|
* security method gets shown).
|
||||||
*/
|
*/
|
||||||
public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
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;
|
public static final long ANIMATION_DURATION = 220;
|
||||||
|
|
||||||
private static final float SCRIM_BEHIND_ALPHA = 0.62f;
|
private static final float SCRIM_BEHIND_ALPHA = 0.62f;
|
||||||
@@ -55,7 +47,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
private final ScrimView mScrimBehind;
|
private final ScrimView mScrimBehind;
|
||||||
private final ScrimView mScrimInFront;
|
private final ScrimView mScrimInFront;
|
||||||
private final UnlockMethodCache mUnlockMethodCache;
|
private final UnlockMethodCache mUnlockMethodCache;
|
||||||
private final DozeParameters mDozeParameters;
|
|
||||||
|
|
||||||
private boolean mKeyguardShowing;
|
private boolean mKeyguardShowing;
|
||||||
private float mFraction;
|
private float mFraction;
|
||||||
@@ -70,15 +61,15 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
private long mAnimationDelay;
|
private long mAnimationDelay;
|
||||||
private Runnable mOnAnimationFinished;
|
private Runnable mOnAnimationFinished;
|
||||||
private boolean mAnimationStarted;
|
private boolean mAnimationStarted;
|
||||||
private boolean mDozing;
|
|
||||||
private boolean mPulsingOut;
|
|
||||||
private DozeHost.PulseCallback mPulseCallback;
|
|
||||||
private final Interpolator mInterpolator = new DecelerateInterpolator();
|
private final Interpolator mInterpolator = new DecelerateInterpolator();
|
||||||
private final Interpolator mLinearOutSlowInInterpolator;
|
private final Interpolator mLinearOutSlowInInterpolator;
|
||||||
private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT;
|
|
||||||
private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN;
|
|
||||||
private BackDropView mBackDropView;
|
private BackDropView mBackDropView;
|
||||||
private boolean mScrimSrcEnabled;
|
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) {
|
public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, boolean scrimSrcEnabled) {
|
||||||
mScrimBehind = scrimBehind;
|
mScrimBehind = scrimBehind;
|
||||||
@@ -87,7 +78,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
|
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
|
||||||
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
|
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
|
||||||
android.R.interpolator.linear_out_slow_in);
|
android.R.interpolator.linear_out_slow_in);
|
||||||
mDozeParameters = new DozeParameters(context);
|
|
||||||
mScrimSrcEnabled = scrimSrcEnabled;
|
mScrimSrcEnabled = scrimSrcEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,60 +124,27 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
scheduleUpdate();
|
scheduleUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDozing(boolean dozing, boolean animate) {
|
public void setDozing(boolean dozing) {
|
||||||
if (mDozing == dozing) return;
|
|
||||||
mDozing = dozing;
|
mDozing = dozing;
|
||||||
if (!mDozing) {
|
|
||||||
cancelPulsing();
|
|
||||||
mAnimateChange = animate;
|
|
||||||
}
|
|
||||||
scheduleUpdate();
|
scheduleUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** When dozing, fade screen contents in and out using the front scrim. */
|
public void setDozeInFrontAlpha(float alpha) {
|
||||||
public void pulse(@NonNull DozeHost.PulseCallback callback) {
|
mDozeInFrontAlpha = alpha;
|
||||||
if (callback == null) {
|
updateScrimColor(mScrimInFront);
|
||||||
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;
|
|
||||||
mScrimInFront.post(mPulseIn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPulsing() {
|
public void setDozeBehindAlpha(float alpha) {
|
||||||
return mPulseCallback != null;
|
mDozeBehindAlpha = alpha;
|
||||||
|
updateScrimColor(mScrimBehind);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelPulsing() {
|
public float getDozeBehindAlpha() {
|
||||||
if (DEBUG) Log.d(TAG, "Cancel pulsing");
|
return mDozeBehindAlpha;
|
||||||
|
|
||||||
if (mPulseCallback != null) {
|
|
||||||
mScrimInFront.removeCallbacks(mPulseIn);
|
|
||||||
mScrimInFront.removeCallbacks(mPulseOut);
|
|
||||||
pulseFinished();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pulseStarted() {
|
public float getDozeInFrontAlpha() {
|
||||||
if (mPulseCallback != null) {
|
return mDozeInFrontAlpha;
|
||||||
mPulseCallback.onPulseStarted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pulseFinished() {
|
|
||||||
mPulsingOut = false;
|
|
||||||
if (mPulseCallback != null) {
|
|
||||||
mPulseCallback.onPulseFinished();
|
|
||||||
mPulseCallback = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleUpdate() {
|
private void scheduleUpdate() {
|
||||||
@@ -223,12 +180,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
} else if (mBouncerShowing) {
|
} else if (mBouncerShowing) {
|
||||||
setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA);
|
setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA);
|
||||||
setScrimBehindColor(0f);
|
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 {
|
} else {
|
||||||
float fraction = Math.max(0, Math.min(mFraction, 1));
|
float fraction = Math.max(0, Math.min(mFraction, 1));
|
||||||
setScrimInFrontColor(0f);
|
setScrimInFrontColor(0f);
|
||||||
@@ -272,26 +223,46 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
((ValueAnimator) runningAnim).cancel();
|
((ValueAnimator) runningAnim).cancel();
|
||||||
scrim.setTag(TAG_KEY_ANIM, null);
|
scrim.setTag(TAG_KEY_ANIM, null);
|
||||||
}
|
}
|
||||||
int color = Color.argb((int) (alpha * 255), 0, 0, 0);
|
|
||||||
if (mAnimateChange) {
|
if (mAnimateChange) {
|
||||||
startScrimAnimation(scrim, color);
|
startScrimAnimation(scrim, alpha);
|
||||||
} else {
|
} else {
|
||||||
scrim.setScrimColor(color);
|
setCurrentScrimAlpha(scrim, alpha);
|
||||||
|
updateScrimColor(scrim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startScrimAnimation(final ScrimView scrim, int targetColor) {
|
private float getDozeAlpha(View scrim) {
|
||||||
int current = Color.alpha(scrim.getScrimColor());
|
return scrim == mScrimBehind ? mDozeBehindAlpha : mDozeInFrontAlpha;
|
||||||
int target = Color.alpha(targetColor);
|
}
|
||||||
if (current == target) {
|
|
||||||
return;
|
private float getCurrentScrimAlpha(View scrim) {
|
||||||
|
return scrim == mScrimBehind ? mCurrentBehindAlpha : mCurrentInFrontAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCurrentScrimAlpha(View scrim, float alpha) {
|
||||||
|
if (scrim == mScrimBehind) {
|
||||||
|
mCurrentBehindAlpha = alpha;
|
||||||
|
} else {
|
||||||
|
mCurrentInFrontAlpha = alpha;
|
||||||
}
|
}
|
||||||
ValueAnimator anim = ValueAnimator.ofInt(current, target);
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startScrimAnimation(final ScrimView scrim, float target) {
|
||||||
|
float current = getCurrentScrimAlpha(scrim);
|
||||||
|
ValueAnimator anim = ValueAnimator.ofFloat(current, target);
|
||||||
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
int value = (int) animation.getAnimatedValue();
|
float alpha = (float) animation.getAnimatedValue();
|
||||||
scrim.setScrimColor(Color.argb(value, 0, 0, 0));
|
setCurrentScrimAlpha(scrim, alpha);
|
||||||
|
updateScrimColor(scrim);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
anim.setInterpolator(getInterpolator());
|
anim.setInterpolator(getInterpolator());
|
||||||
@@ -313,15 +284,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Interpolator getInterpolator() {
|
private Interpolator getInterpolator() {
|
||||||
if (mAnimateKeyguardFadingOut) {
|
return mAnimateKeyguardFadingOut ? mLinearOutSlowInInterpolator : mInterpolator;
|
||||||
return mLinearOutSlowInInterpolator;
|
|
||||||
} else if (isPulsing() && !mPulsingOut) {
|
|
||||||
return mPulseInInterpolator;
|
|
||||||
} else if (isPulsing()) {
|
|
||||||
return mPulseOutInterpolator;
|
|
||||||
} else {
|
|
||||||
return mInterpolator;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -342,56 +305,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
|
|||||||
return true;
|
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) {
|
public void setBackDropView(BackDropView backDropView) {
|
||||||
mBackDropView = backDropView;
|
mBackDropView = backDropView;
|
||||||
mBackDropView.setOnVisibilityChangedRunnable(new Runnable() {
|
mBackDropView.setOnVisibilityChangedRunnable(new Runnable() {
|
||||||
|
|||||||
Reference in New Issue
Block a user