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

Commit 194582ca authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AOD/LS - Animate bottom view text indicator"

parents 199b4799 d82e7c4c
Loading
Loading
Loading
Loading
+76 −9
Original line number Diff line number Diff line
@@ -16,18 +16,32 @@

package com.android.systemui.statusbar.phone;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Interpolators;

import java.util.LinkedList;

/**
 * A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open").
 */
public class KeyguardIndicationTextView extends TextView {

    private CharSequence mText = "";
    private static final int FADE_OUT_MILLIS = 200;
    private static final int FADE_IN_MILLIS = 250;
    private static final long MSG_DURATION_MILLIS = 600;
    private long mNextAnimationTime = 0;
    private boolean mAnimationsEnabled = true;
    private LinkedList<CharSequence> mMessages = new LinkedList<>();

    public KeyguardIndicationTextView(Context context) {
        super(context);
@@ -52,15 +66,68 @@ public class KeyguardIndicationTextView extends TextView {
     * @param text The text to show.
     */
    public void switchIndication(CharSequence text) {
        if (text == null) text = "";

        CharSequence lastPendingMessage = mMessages.peekLast();
        if (TextUtils.equals(lastPendingMessage, text)
                || (lastPendingMessage == null && TextUtils.equals(text, getText()))) {
            return;
        }
        mMessages.add(text);

        Animator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f);
        fadeOut.setDuration(getFadeOutMillis());
        fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);

        final CharSequence nextText = text;
        fadeOut.addListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd(Animator animator) {
                    setText(mMessages.poll());
                }
            });

        final AnimatorSet animSet = new AnimatorSet();
        final AnimatorSet.Builder animSetBuilder = animSet.play(fadeOut);

        // Make sure each animation is visible for a minimum amount of time, while not worrying
        // about fading in blank text
        long timeInMillis = System.currentTimeMillis();
        long delay = Math.max(0, mNextAnimationTime - timeInMillis);
        setNextAnimationTime(timeInMillis + delay + getFadeOutMillis());

        if (!text.equals("")) {
            setNextAnimationTime(mNextAnimationTime + MSG_DURATION_MILLIS);

            ObjectAnimator fadeIn = ObjectAnimator.ofFloat(this, View.ALPHA, 1f);
            fadeIn.setDuration(getFadeInMillis());
            fadeIn.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
            animSetBuilder.before(fadeIn);
        }

        animSet.setStartDelay(delay);
        animSet.start();
    }

    @VisibleForTesting
    public void setAnimationsEnabled(boolean enabled) {
        mAnimationsEnabled = enabled;
    }

    private long getFadeInMillis() {
        if (mAnimationsEnabled) return FADE_IN_MILLIS;
        return 0L;
    }

    private long getFadeOutMillis() {
        if (mAnimationsEnabled) return FADE_OUT_MILLIS;
        return 0L;
    }

        // TODO: Animation, make sure that we will show one indication long enough.
        if (TextUtils.isEmpty(text)) {
            mText = "";
            setVisibility(View.INVISIBLE);
        } else if (!TextUtils.equals(text, mText)) {
            mText = text;
            setVisibility(View.VISIBLE);
            setText(mText);
    private void setNextAnimationTime(long time) {
        if (mAnimationsEnabled) {
            mNextAnimationTime = time;
        } else {
            mNextAnimationTime = 0L;
        }
    }

+7 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.wakelock.WakeLockFake;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -131,6 +132,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
        MockitoAnnotations.initMocks(this);
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mTextView = new KeyguardIndicationTextView(mContext);
        mTextView.setAnimationsEnabled(false);

        mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
        mContext.addMockSystemService(UserManager.class, mUserManager);
@@ -153,6 +155,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
        mWakeLockBuilder.setWakeLock(mWakeLock);
    }

    @After
    public void tearDown() throws Exception {
        mTextView.setAnimationsEnabled(true);
    }

    private void createController() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
+7 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,13 +41,18 @@ public class KeyguardIndicationTextViewTest extends SysuiTestCase {
    @Before
    public void setup() {
        mKeyguardIndicationTextView = new KeyguardIndicationTextView(mContext);
        mKeyguardIndicationTextView.setAnimationsEnabled(false);
    }

    @After
    public void tearDown() {
        mKeyguardIndicationTextView.setAnimationsEnabled(true);
    }

    @Test
    public void switchIndication_null_hideIndication() {
        mKeyguardIndicationTextView.switchIndication(null /* text */);

        assertThat(mKeyguardIndicationTextView.getVisibility()).isEqualTo(View.INVISIBLE);
        assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("");
    }

@@ -54,7 +60,6 @@ public class KeyguardIndicationTextViewTest extends SysuiTestCase {
    public void switchIndication_emptyText_hideIndication() {
        mKeyguardIndicationTextView.switchIndication("" /* text */);

        assertThat(mKeyguardIndicationTextView.getVisibility()).isEqualTo(View.INVISIBLE);
        assertThat(mKeyguardIndicationTextView.getText()).isEqualTo("");
    }