Merge "Added success lotties to BP for fp" into tm-qpr-dev am: 62b30d3e23
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19646757 Change-Id: Ia367e20b5c8f2a7ecba6a4a1cce0adecdc7731c6 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -92,7 +92,7 @@ open class AuthBiometricFingerprintIconController(
|
|||||||
STATE_ERROR -> true
|
STATE_ERROR -> true
|
||||||
STATE_AUTHENTICATING_ANIMATING_IN,
|
STATE_AUTHENTICATING_ANIMATING_IN,
|
||||||
STATE_AUTHENTICATING -> oldState == STATE_ERROR || oldState == STATE_HELP
|
STATE_AUTHENTICATING -> oldState == STATE_ERROR || oldState == STATE_HELP
|
||||||
STATE_AUTHENTICATED -> false
|
STATE_AUTHENTICATED -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,13 @@ open class AuthBiometricFingerprintIconController(
|
|||||||
R.raw.fingerprint_dialogue_fingerprint_to_error_lottie
|
R.raw.fingerprint_dialogue_fingerprint_to_error_lottie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STATE_AUTHENTICATED -> R.raw.fingerprint_dialogue_fingerprint_to_error_lottie
|
STATE_AUTHENTICATED -> {
|
||||||
|
if (oldState == STATE_ERROR || oldState == STATE_HELP) {
|
||||||
|
R.raw.fingerprint_dialogue_error_to_success_lottie
|
||||||
|
} else {
|
||||||
|
R.raw.fingerprint_dialogue_fingerprint_to_success_lottie
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> return null
|
else -> return null
|
||||||
}
|
}
|
||||||
return if (id != null) return id else null
|
return if (id != null) return id else null
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ open class AuthBiometricFingerprintView(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDelayAfterAuthenticatedDurationMs() = 0
|
override fun getDelayAfterAuthenticatedDurationMs() = 500
|
||||||
|
|
||||||
override fun getStateForAfterError() = STATE_AUTHENTICATING
|
override fun getStateForAfterError() = STATE_AUTHENTICATING
|
||||||
|
|
||||||
|
|||||||
@@ -468,6 +468,7 @@ public abstract class AuthBiometricView extends LinearLayout {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_AUTHENTICATED:
|
case STATE_AUTHENTICATED:
|
||||||
|
removePendingAnimations();
|
||||||
if (mSize != AuthDialog.SIZE_SMALL) {
|
if (mSize != AuthDialog.SIZE_SMALL) {
|
||||||
mConfirmButton.setVisibility(View.GONE);
|
mConfirmButton.setVisibility(View.GONE);
|
||||||
mNegativeButton.setVisibility(View.GONE);
|
mNegativeButton.setVisibility(View.GONE);
|
||||||
|
|||||||
@@ -41,11 +41,13 @@ import org.mockito.junit.MockitoJUnit
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
|
class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
|
||||||
|
|
||||||
@JvmField @Rule
|
@JvmField
|
||||||
|
@Rule
|
||||||
var mockitoRule = MockitoJUnit.rule()
|
var mockitoRule = MockitoJUnit.rule()
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var callback: AuthBiometricView.Callback
|
private lateinit var callback: AuthBiometricView.Callback
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var panelController: AuthPanelController
|
private lateinit var panelController: AuthPanelController
|
||||||
|
|
||||||
@@ -67,6 +69,7 @@ class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
|
|||||||
fun fingerprintSuccessDoesNotRequireExplicitConfirmation() {
|
fun fingerprintSuccessDoesNotRequireExplicitConfirmation() {
|
||||||
biometricView.onDialogAnimatedIn()
|
biometricView.onDialogAnimatedIn()
|
||||||
biometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT)
|
biometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT)
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
assertThat(biometricView.isAuthenticated).isTrue()
|
assertThat(biometricView.isAuthenticated).isTrue()
|
||||||
@@ -86,6 +89,7 @@ class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
|
|||||||
|
|
||||||
// icon acts as confirm button
|
// icon acts as confirm button
|
||||||
biometricView.mIconView.performClick()
|
biometricView.mIconView.performClick()
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
assertThat(biometricView.isAuthenticated).isTrue()
|
assertThat(biometricView.isAuthenticated).isTrue()
|
||||||
@@ -102,6 +106,7 @@ class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
|
|||||||
verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_ERROR)
|
verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_ERROR)
|
||||||
|
|
||||||
biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
|
biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
|
verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
|
||||||
|
|||||||
@@ -42,20 +42,23 @@ import org.mockito.junit.MockitoJUnit
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
||||||
|
|
||||||
@JvmField @Rule
|
@JvmField
|
||||||
|
@Rule
|
||||||
val mockitoRule = MockitoJUnit.rule()
|
val mockitoRule = MockitoJUnit.rule()
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var callback: AuthBiometricView.Callback
|
private lateinit var callback: AuthBiometricView.Callback
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var panelController: AuthPanelController
|
private lateinit var panelController: AuthPanelController
|
||||||
|
|
||||||
private lateinit var biometricView: AuthBiometricView
|
private lateinit var biometricView: AuthBiometricView
|
||||||
|
|
||||||
private fun createView(allowDeviceCredential: Boolean = false): AuthBiometricFingerprintView {
|
private fun createView(allowDeviceCredential: Boolean = false): AuthBiometricFingerprintView {
|
||||||
val view = R.layout.auth_biometric_fingerprint_view.asTestAuthBiometricView(
|
val view: AuthBiometricFingerprintView =
|
||||||
|
R.layout.auth_biometric_fingerprint_view.asTestAuthBiometricView(
|
||||||
mContext, callback, panelController, allowDeviceCredential = allowDeviceCredential
|
mContext, callback, panelController, allowDeviceCredential = allowDeviceCredential
|
||||||
) as AuthBiometricFingerprintView
|
)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
@@ -73,6 +76,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testOnAuthenticationSucceeded_noConfirmationRequired_sendsActionAuthenticated() {
|
fun testOnAuthenticationSucceeded_noConfirmationRequired_sendsActionAuthenticated() {
|
||||||
biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
|
biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
assertThat(biometricView.isAuthenticated).isTrue()
|
assertThat(biometricView.isAuthenticated).isTrue()
|
||||||
@@ -83,6 +87,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
fun testOnAuthenticationSucceeded_confirmationRequired_updatesDialogContents() {
|
fun testOnAuthenticationSucceeded_confirmationRequired_updatesDialogContents() {
|
||||||
biometricView.setRequireConfirmation(true)
|
biometricView.setRequireConfirmation(true)
|
||||||
biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
|
biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
// TODO: this should be tested in the subclasses
|
// TODO: this should be tested in the subclasses
|
||||||
@@ -104,6 +109,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testPositiveButton_sendsActionAuthenticated() {
|
fun testPositiveButton_sendsActionAuthenticated() {
|
||||||
biometricView.mConfirmButton.performClick()
|
biometricView.mConfirmButton.performClick()
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
|
verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
|
||||||
@@ -114,6 +120,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
fun testNegativeButton_beforeAuthentication_sendsActionButtonNegative() {
|
fun testNegativeButton_beforeAuthentication_sendsActionButtonNegative() {
|
||||||
biometricView.onDialogAnimatedIn()
|
biometricView.onDialogAnimatedIn()
|
||||||
biometricView.mNegativeButton.performClick()
|
biometricView.mNegativeButton.performClick()
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
verify(callback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE)
|
verify(callback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE)
|
||||||
@@ -126,6 +133,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
|
|
||||||
assertThat(biometricView.mNegativeButton.visibility).isEqualTo(View.GONE)
|
assertThat(biometricView.mNegativeButton.visibility).isEqualTo(View.GONE)
|
||||||
biometricView.mCancelButton.performClick()
|
biometricView.mCancelButton.performClick()
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
verify(callback).onAction(AuthBiometricView.Callback.ACTION_USER_CANCELED)
|
verify(callback).onAction(AuthBiometricView.Callback.ACTION_USER_CANCELED)
|
||||||
@@ -134,6 +142,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testTryAgainButton_sendsActionTryAgain() {
|
fun testTryAgainButton_sendsActionTryAgain() {
|
||||||
biometricView.mTryAgainButton.performClick()
|
biometricView.mTryAgainButton.performClick()
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
verify(callback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN)
|
verify(callback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN)
|
||||||
@@ -144,6 +153,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testOnErrorSendsActionError() {
|
fun testOnErrorSendsActionError() {
|
||||||
biometricView.onError(BiometricAuthenticator.TYPE_FACE, "testError")
|
biometricView.onError(BiometricAuthenticator.TYPE_FACE, "testError")
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
verify(callback).onAction(eq(AuthBiometricView.Callback.ACTION_ERROR))
|
verify(callback).onAction(eq(AuthBiometricView.Callback.ACTION_ERROR))
|
||||||
@@ -156,6 +166,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val message = "another error"
|
val message = "another error"
|
||||||
biometricView.onError(BiometricAuthenticator.TYPE_FACE, message)
|
biometricView.onError(BiometricAuthenticator.TYPE_FACE, message)
|
||||||
|
TestableLooper.get(this).moveTimeForward(1000)
|
||||||
waitForIdleSync()
|
waitForIdleSync()
|
||||||
|
|
||||||
assertThat(biometricView.isAuthenticating).isFalse()
|
assertThat(biometricView.isAuthenticating).isFalse()
|
||||||
@@ -178,6 +189,7 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
val view = View(mContext)
|
val view = View(mContext)
|
||||||
biometricView.setBackgroundView(view)
|
biometricView.setBackgroundView(view)
|
||||||
biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
|
biometricView.onAuthenticationSucceeded(BiometricAuthenticator.TYPE_FINGERPRINT)
|
||||||
|
waitForIdleSync()
|
||||||
view.performClick()
|
view.performClick()
|
||||||
|
|
||||||
verify(callback, never())
|
verify(callback, never())
|
||||||
@@ -225,14 +237,14 @@ class AuthBiometricFingerprintViewTest : SysuiTestCase() {
|
|||||||
biometricView.onSaveState(state)
|
biometricView.onSaveState(state)
|
||||||
assertThat(biometricView.mTryAgainButton.visibility).isEqualTo(View.GONE)
|
assertThat(biometricView.mTryAgainButton.visibility).isEqualTo(View.GONE)
|
||||||
assertThat(state.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY))
|
assertThat(state.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY))
|
||||||
.isEqualTo(View.GONE)
|
.isEqualTo(View.GONE)
|
||||||
assertThat(state.getInt(AuthDialog.KEY_BIOMETRIC_STATE))
|
assertThat(state.getInt(AuthDialog.KEY_BIOMETRIC_STATE))
|
||||||
.isEqualTo(AuthBiometricView.STATE_ERROR)
|
.isEqualTo(AuthBiometricView.STATE_ERROR)
|
||||||
assertThat(biometricView.mIndicatorView.visibility).isEqualTo(View.VISIBLE)
|
assertThat(biometricView.mIndicatorView.visibility).isEqualTo(View.VISIBLE)
|
||||||
assertThat(state.getBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING)).isTrue()
|
assertThat(state.getBoolean(AuthDialog.KEY_BIOMETRIC_INDICATOR_ERROR_SHOWING)).isTrue()
|
||||||
assertThat(biometricView.mIndicatorView.text).isEqualTo(failureMessage)
|
assertThat(biometricView.mIndicatorView.text).isEqualTo(failureMessage)
|
||||||
assertThat(state.getString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING))
|
assertThat(state.getString(AuthDialog.KEY_BIOMETRIC_INDICATOR_STRING))
|
||||||
.isEqualTo(failureMessage)
|
.isEqualTo(failureMessage)
|
||||||
|
|
||||||
// TODO: Test dialog size. Should move requireConfirmation to buildBiometricPromptBundle
|
// TODO: Test dialog size. Should move requireConfirmation to buildBiometricPromptBundle
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import java.lang.annotation.ElementType;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,6 +46,9 @@ public class TestableLooper {
|
|||||||
* catch crashes.
|
* catch crashes.
|
||||||
*/
|
*/
|
||||||
public static final boolean HOLD_MAIN_THREAD = false;
|
public static final boolean HOLD_MAIN_THREAD = false;
|
||||||
|
private static final Field MESSAGE_QUEUE_MESSAGES_FIELD;
|
||||||
|
private static final Field MESSAGE_NEXT_FIELD;
|
||||||
|
private static final Field MESSAGE_WHEN_FIELD;
|
||||||
|
|
||||||
private Looper mLooper;
|
private Looper mLooper;
|
||||||
private MessageQueue mQueue;
|
private MessageQueue mQueue;
|
||||||
@@ -54,6 +58,19 @@ public class TestableLooper {
|
|||||||
private Runnable mEmptyMessage;
|
private Runnable mEmptyMessage;
|
||||||
private TestLooperManager mQueueWrapper;
|
private TestLooperManager mQueueWrapper;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
|
||||||
|
MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
|
||||||
|
MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
|
||||||
|
MESSAGE_NEXT_FIELD.setAccessible(true);
|
||||||
|
MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
|
||||||
|
MESSAGE_WHEN_FIELD.setAccessible(true);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException("Failed to initialize TestableLooper", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TestableLooper(Looper l) throws Exception {
|
public TestableLooper(Looper l) throws Exception {
|
||||||
this(acquireLooperManager(l), l);
|
this(acquireLooperManager(l), l);
|
||||||
}
|
}
|
||||||
@@ -119,6 +136,33 @@ public class TestableLooper {
|
|||||||
while (processQueuedMessages() != 0) ;
|
while (processQueuedMessages() != 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void moveTimeForward(long milliSeconds) {
|
||||||
|
try {
|
||||||
|
Message msg = getMessageLinkedList();
|
||||||
|
while (msg != null) {
|
||||||
|
long updatedWhen = msg.getWhen() - milliSeconds;
|
||||||
|
if (updatedWhen < 0) {
|
||||||
|
updatedWhen = 0;
|
||||||
|
}
|
||||||
|
MESSAGE_WHEN_FIELD.set(msg, updatedWhen);
|
||||||
|
msg = (Message) MESSAGE_NEXT_FIELD.get(msg);
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("Access failed in TestableLooper: set - Message.when", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Message getMessageLinkedList() {
|
||||||
|
try {
|
||||||
|
MessageQueue queue = mLooper.getQueue();
|
||||||
|
return (Message) MESSAGE_QUEUE_MESSAGES_FIELD.get(queue);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Access failed in TestableLooper: get - MessageQueue.mMessages",
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int processQueuedMessages() {
|
private int processQueuedMessages() {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
mEmptyMessage = () -> { };
|
mEmptyMessage = () -> { };
|
||||||
|
|||||||
@@ -19,15 +19,19 @@ import static org.junit.Assert.assertNotEquals;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.inOrder;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InOrder;
|
||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -162,7 +166,7 @@ public class TestableLooperTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCorrectLooperExecution() throws Exception {
|
public void testCorrectLooperExecution() throws Exception {
|
||||||
boolean[] hasRun = new boolean[] { false };
|
boolean[] hasRun = new boolean[]{false};
|
||||||
Runnable r = () -> {
|
Runnable r = () -> {
|
||||||
assertEquals("Should run on main looper", Looper.getMainLooper(), Looper.myLooper());
|
assertEquals("Should run on main looper", Looper.getMainLooper(), Looper.myLooper());
|
||||||
hasRun[0] = true;
|
hasRun[0] = true;
|
||||||
@@ -177,4 +181,63 @@ public class TestableLooperTest {
|
|||||||
testableLooper.destroy();
|
testableLooper.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelayedDispatchNoTimeMove() {
|
||||||
|
Handler handler = spy(new Handler(mTestableLooper.getLooper()));
|
||||||
|
InOrder inOrder = inOrder(handler);
|
||||||
|
|
||||||
|
final Message messageA = handler.obtainMessage(1);
|
||||||
|
final Message messageB = handler.obtainMessage(2);
|
||||||
|
|
||||||
|
handler.sendMessageDelayed(messageA, 0);
|
||||||
|
handler.sendMessageDelayed(messageB, 0);
|
||||||
|
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
inOrder.verify(handler).dispatchMessage(messageA);
|
||||||
|
inOrder.verify(handler).dispatchMessage(messageB);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelayedMessageDoesntSend() {
|
||||||
|
Handler handler = spy(new Handler(mTestableLooper.getLooper()));
|
||||||
|
InOrder inOrder = inOrder(handler);
|
||||||
|
|
||||||
|
final Message messageA = handler.obtainMessage(1);
|
||||||
|
final Message messageB = handler.obtainMessage(2);
|
||||||
|
final Message messageC = handler.obtainMessage(3);
|
||||||
|
|
||||||
|
handler.sendMessageDelayed(messageA, 0);
|
||||||
|
handler.sendMessageDelayed(messageB, 0);
|
||||||
|
handler.sendMessageDelayed(messageC, 500);
|
||||||
|
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
inOrder.verify(handler).dispatchMessage(messageA);
|
||||||
|
inOrder.verify(handler).dispatchMessage(messageB);
|
||||||
|
verify(handler, never()).dispatchMessage(messageC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMessageSendsAfterDelay() {
|
||||||
|
Handler handler = spy(new Handler(mTestableLooper.getLooper()));
|
||||||
|
InOrder inOrder = inOrder(handler);
|
||||||
|
|
||||||
|
final Message messageA = handler.obtainMessage(1);
|
||||||
|
final Message messageB = handler.obtainMessage(2);
|
||||||
|
final Message messageC = handler.obtainMessage(3);
|
||||||
|
|
||||||
|
handler.sendMessageDelayed(messageA, 0);
|
||||||
|
handler.sendMessageDelayed(messageB, 0);
|
||||||
|
handler.sendMessageDelayed(messageC, 500);
|
||||||
|
|
||||||
|
mTestableLooper.moveTimeForward(500);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
inOrder.verify(handler).dispatchMessage(messageA);
|
||||||
|
inOrder.verify(handler).dispatchMessage(messageB);
|
||||||
|
inOrder.verify(handler).dispatchMessage(messageC);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user