Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb30c904 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add timeouts to animations in UserSwitchingDialog." into udc-dev am: d3446e4e

parents 5a0fd1b2 d3446e4e
Loading
Loading
Loading
Loading
+56 −19
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import android.graphics.Shader;
import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
@@ -53,6 +55,8 @@ import com.android.internal.util.ObjectUtils;
import com.android.internal.util.UserIcons;
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
 * 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
    protected static final boolean DEBUG = true;

    private static final long DIALOG_SHOW_HIDE_ANIMATION_DURATION_MS = 300;
    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 mNewUser;
    private final String mSwitchingFromSystemUserMessage;
@@ -180,7 +189,7 @@ class UserSwitchingDialog extends Dialog {

    @Override
    public void show() {
        asyncTraceBegin("", 0);
        asyncTraceBegin("dialog", 0);
        super.show();
    }

@@ -188,7 +197,7 @@ class UserSwitchingDialog extends Dialog {
    public void dismiss() {
        super.dismiss();
        stopFreezingScreen();
        asyncTraceEnd("", 0);
        asyncTraceEnd("dialog", 0);
    }

    public void show(@NonNull Runnable onShown) {
@@ -217,20 +226,18 @@ class UserSwitchingDialog extends Dialog {
        if (!mNeedToFreezeScreen) {
            return;
        }
        if (DEBUG) Slog.d(TAG, "startFreezingScreen");
        Trace.traceBegin(TRACE_TAG, "startFreezingScreen");
        traceBegin("startFreezingScreen");
        mWindowManager.startFreezingScreen(0, 0);
        Trace.traceEnd(TRACE_TAG);
        traceEnd("startFreezingScreen");
    }

    private void stopFreezingScreen() {
        if (!mNeedToFreezeScreen) {
            return;
        }
        if (DEBUG) Slog.d(TAG, "stopFreezingScreen");
        Trace.traceBegin(TRACE_TAG, "stopFreezingScreen");
        traceBegin("stopFreezingScreen");
        mWindowManager.stopFreezingScreen();
        Trace.traceEnd(TRACE_TAG);
        traceEnd("stopFreezingScreen");
    }

    private void startShowAnimation(Runnable onAnimationEnd) {
@@ -238,13 +245,13 @@ class UserSwitchingDialog extends Dialog {
            onAnimationEnd.run();
            return;
        }
        asyncTraceBegin("-showAnimation", 1);
        startDialogAnimation(new AlphaAnimation(0, 1), () -> {
            asyncTraceEnd("-showAnimation", 1);
        asyncTraceBegin("showAnimation", 1);
        startDialogAnimation("show", new AlphaAnimation(0, 1), () -> {
            asyncTraceEnd("showAnimation", 1);

            asyncTraceBegin("-spinnerAnimation", 2);
            asyncTraceBegin("spinnerAnimation", 2);
            startProgressAnimation(() -> {
                asyncTraceEnd("-spinnerAnimation", 2);
                asyncTraceEnd("spinnerAnimation", 2);

                onAnimationEnd.run();
            });
@@ -257,9 +264,9 @@ class UserSwitchingDialog extends Dialog {
            onAnimationEnd.run();
            return;
        }
        asyncTraceBegin("-dismissAnimation", 3);
        startDialogAnimation(new AlphaAnimation(1, 0), () -> {
            asyncTraceEnd("-dismissAnimation", 3);
        asyncTraceBegin("dismissAnimation", 3);
        startDialogAnimation("dismiss", new AlphaAnimation(1, 0), () -> {
            asyncTraceEnd("dismissAnimation", 3);

            onAnimationEnd.run();
        });
@@ -271,10 +278,11 @@ class UserSwitchingDialog extends Dialog {
            onAnimationEnd.run();
            return;
        }
        final Runnable onAnimationEndWithTimeout = animationWithTimeout("spinner", onAnimationEnd);
        avd.registerAnimationCallback(new Animatable2.AnimationCallback() {
            @Override
            public void onAnimationEnd(Drawable drawable) {
                onAnimationEnd.run();
                onAnimationEndWithTimeout.run();
            }
        });
        avd.start();
@@ -291,12 +299,13 @@ class UserSwitchingDialog extends Dialog {
        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);
        if (mDisableAnimations || view == null) {
            onAnimationEnd.run();
            return;
        }
        final Runnable onAnimationEndWithTimeout = animationWithTimeout(name, onAnimationEnd);
        animation.setDuration(DIALOG_SHOW_HIDE_ANIMATION_DURATION_MS);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
@@ -306,7 +315,7 @@ class UserSwitchingDialog extends Dialog {

            @Override
            public void onAnimationEnd(Animation animation) {
                onAnimationEnd.run();
                onAnimationEndWithTimeout.run();
            }

            @Override
@@ -317,11 +326,39 @@ class UserSwitchingDialog extends Dialog {
        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) {
        if (DEBUG) Slog.d(TAG, "asyncTraceBegin-" + subTag);
        Trace.asyncTraceBegin(TRACE_TAG, TAG + subTag, mTraceCookie + subCookie);
    }

    private void asyncTraceEnd(String subTag, int 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);
    }
}