Merge "Add timeouts to animations in UserSwitchingDialog." into udc-dev am: d3446e4eb8
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22967258 Change-Id: Iab492af11b41ef8867b1e0f3d04da3fa9331e479 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -33,6 +33,8 @@ import android.graphics.Shader;
|
|||||||
import android.graphics.drawable.Animatable2;
|
import android.graphics.drawable.Animatable2;
|
||||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -53,6 +55,8 @@ import com.android.internal.util.ObjectUtils;
|
|||||||
import com.android.internal.util.UserIcons;
|
import com.android.internal.util.UserIcons;
|
||||||
import com.android.server.wm.WindowManagerService;
|
import com.android.server.wm.WindowManagerService;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog to show during the user switch. This dialog shows target user's name and their profile
|
* Dialog to show during the user switch. This dialog shows target user's name and their profile
|
||||||
* picture with a circular spinner animation around it if the animations for this dialog are not
|
* picture with a circular spinner animation around it if the animations for this dialog are not
|
||||||
@@ -64,9 +68,14 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
|
|
||||||
// User switching doesn't happen that frequently, so it doesn't hurt to have it always on
|
// User switching doesn't happen that frequently, so it doesn't hurt to have it always on
|
||||||
protected static final boolean DEBUG = true;
|
protected static final boolean DEBUG = true;
|
||||||
|
|
||||||
private static final long DIALOG_SHOW_HIDE_ANIMATION_DURATION_MS = 300;
|
private static final long DIALOG_SHOW_HIDE_ANIMATION_DURATION_MS = 300;
|
||||||
private final boolean mDisableAnimations;
|
private final boolean mDisableAnimations;
|
||||||
|
|
||||||
|
// Time to wait for the onAnimationEnd() callbacks before moving on
|
||||||
|
private static final int ANIMATION_TIMEOUT_MS = 1000;
|
||||||
|
private final Handler mHandler = new Handler(Looper.myLooper());
|
||||||
|
|
||||||
protected final UserInfo mOldUser;
|
protected final UserInfo mOldUser;
|
||||||
protected final UserInfo mNewUser;
|
protected final UserInfo mNewUser;
|
||||||
private final String mSwitchingFromSystemUserMessage;
|
private final String mSwitchingFromSystemUserMessage;
|
||||||
@@ -180,7 +189,7 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show() {
|
public void show() {
|
||||||
asyncTraceBegin("", 0);
|
asyncTraceBegin("dialog", 0);
|
||||||
super.show();
|
super.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +197,7 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
public void dismiss() {
|
public void dismiss() {
|
||||||
super.dismiss();
|
super.dismiss();
|
||||||
stopFreezingScreen();
|
stopFreezingScreen();
|
||||||
asyncTraceEnd("", 0);
|
asyncTraceEnd("dialog", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(@NonNull Runnable onShown) {
|
public void show(@NonNull Runnable onShown) {
|
||||||
@@ -217,20 +226,18 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
if (!mNeedToFreezeScreen) {
|
if (!mNeedToFreezeScreen) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DEBUG) Slog.d(TAG, "startFreezingScreen");
|
traceBegin("startFreezingScreen");
|
||||||
Trace.traceBegin(TRACE_TAG, "startFreezingScreen");
|
|
||||||
mWindowManager.startFreezingScreen(0, 0);
|
mWindowManager.startFreezingScreen(0, 0);
|
||||||
Trace.traceEnd(TRACE_TAG);
|
traceEnd("startFreezingScreen");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopFreezingScreen() {
|
private void stopFreezingScreen() {
|
||||||
if (!mNeedToFreezeScreen) {
|
if (!mNeedToFreezeScreen) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DEBUG) Slog.d(TAG, "stopFreezingScreen");
|
traceBegin("stopFreezingScreen");
|
||||||
Trace.traceBegin(TRACE_TAG, "stopFreezingScreen");
|
|
||||||
mWindowManager.stopFreezingScreen();
|
mWindowManager.stopFreezingScreen();
|
||||||
Trace.traceEnd(TRACE_TAG);
|
traceEnd("stopFreezingScreen");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startShowAnimation(Runnable onAnimationEnd) {
|
private void startShowAnimation(Runnable onAnimationEnd) {
|
||||||
@@ -238,13 +245,13 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
onAnimationEnd.run();
|
onAnimationEnd.run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
asyncTraceBegin("-showAnimation", 1);
|
asyncTraceBegin("showAnimation", 1);
|
||||||
startDialogAnimation(new AlphaAnimation(0, 1), () -> {
|
startDialogAnimation("show", new AlphaAnimation(0, 1), () -> {
|
||||||
asyncTraceEnd("-showAnimation", 1);
|
asyncTraceEnd("showAnimation", 1);
|
||||||
|
|
||||||
asyncTraceBegin("-spinnerAnimation", 2);
|
asyncTraceBegin("spinnerAnimation", 2);
|
||||||
startProgressAnimation(() -> {
|
startProgressAnimation(() -> {
|
||||||
asyncTraceEnd("-spinnerAnimation", 2);
|
asyncTraceEnd("spinnerAnimation", 2);
|
||||||
|
|
||||||
onAnimationEnd.run();
|
onAnimationEnd.run();
|
||||||
});
|
});
|
||||||
@@ -257,9 +264,9 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
onAnimationEnd.run();
|
onAnimationEnd.run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
asyncTraceBegin("-dismissAnimation", 3);
|
asyncTraceBegin("dismissAnimation", 3);
|
||||||
startDialogAnimation(new AlphaAnimation(1, 0), () -> {
|
startDialogAnimation("dismiss", new AlphaAnimation(1, 0), () -> {
|
||||||
asyncTraceEnd("-dismissAnimation", 3);
|
asyncTraceEnd("dismissAnimation", 3);
|
||||||
|
|
||||||
onAnimationEnd.run();
|
onAnimationEnd.run();
|
||||||
});
|
});
|
||||||
@@ -271,10 +278,11 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
onAnimationEnd.run();
|
onAnimationEnd.run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final Runnable onAnimationEndWithTimeout = animationWithTimeout("spinner", onAnimationEnd);
|
||||||
avd.registerAnimationCallback(new Animatable2.AnimationCallback() {
|
avd.registerAnimationCallback(new Animatable2.AnimationCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Drawable drawable) {
|
public void onAnimationEnd(Drawable drawable) {
|
||||||
onAnimationEnd.run();
|
onAnimationEndWithTimeout.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
avd.start();
|
avd.start();
|
||||||
@@ -291,12 +299,13 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startDialogAnimation(Animation animation, Runnable onAnimationEnd) {
|
private void startDialogAnimation(String name, Animation animation, Runnable onAnimationEnd) {
|
||||||
final View view = findViewById(R.id.content);
|
final View view = findViewById(R.id.content);
|
||||||
if (mDisableAnimations || view == null) {
|
if (mDisableAnimations || view == null) {
|
||||||
onAnimationEnd.run();
|
onAnimationEnd.run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final Runnable onAnimationEndWithTimeout = animationWithTimeout(name, onAnimationEnd);
|
||||||
animation.setDuration(DIALOG_SHOW_HIDE_ANIMATION_DURATION_MS);
|
animation.setDuration(DIALOG_SHOW_HIDE_ANIMATION_DURATION_MS);
|
||||||
animation.setAnimationListener(new Animation.AnimationListener() {
|
animation.setAnimationListener(new Animation.AnimationListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -306,7 +315,7 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animation animation) {
|
public void onAnimationEnd(Animation animation) {
|
||||||
onAnimationEnd.run();
|
onAnimationEndWithTimeout.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -317,11 +326,39 @@ class UserSwitchingDialog extends Dialog {
|
|||||||
view.startAnimation(animation);
|
view.startAnimation(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Runnable animationWithTimeout(String name, Runnable onAnimationEnd) {
|
||||||
|
final AtomicBoolean isFirst = new AtomicBoolean(true);
|
||||||
|
final Runnable onAnimationEndOrTimeout = () -> {
|
||||||
|
if (isFirst.getAndSet(false)) {
|
||||||
|
mHandler.removeCallbacksAndMessages(null);
|
||||||
|
onAnimationEnd.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mHandler.postDelayed(() -> {
|
||||||
|
Slog.w(TAG, name + " animation not completed in " + ANIMATION_TIMEOUT_MS + " ms");
|
||||||
|
onAnimationEndOrTimeout.run();
|
||||||
|
}, ANIMATION_TIMEOUT_MS);
|
||||||
|
|
||||||
|
return onAnimationEndOrTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
private void asyncTraceBegin(String subTag, int subCookie) {
|
private void asyncTraceBegin(String subTag, int subCookie) {
|
||||||
|
if (DEBUG) Slog.d(TAG, "asyncTraceBegin-" + subTag);
|
||||||
Trace.asyncTraceBegin(TRACE_TAG, TAG + subTag, mTraceCookie + subCookie);
|
Trace.asyncTraceBegin(TRACE_TAG, TAG + subTag, mTraceCookie + subCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void asyncTraceEnd(String subTag, int subCookie) {
|
private void asyncTraceEnd(String subTag, int subCookie) {
|
||||||
Trace.asyncTraceEnd(TRACE_TAG, TAG + subTag, mTraceCookie + subCookie);
|
Trace.asyncTraceEnd(TRACE_TAG, TAG + subTag, mTraceCookie + subCookie);
|
||||||
|
if (DEBUG) Slog.d(TAG, "asyncTraceEnd-" + subTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void traceBegin(String msg) {
|
||||||
|
if (DEBUG) Slog.d(TAG, "traceBegin-" + msg);
|
||||||
|
Trace.traceBegin(TRACE_TAG, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void traceEnd(String msg) {
|
||||||
|
Trace.traceEnd(TRACE_TAG);
|
||||||
|
if (DEBUG) Slog.d(TAG, "traceEnd-" + msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user