Changes to support reducing noise in active unlock notifications.
1. Add additional trigger onUserMayRequestUnlock
- point existing trigger points from SystemUI to this
2. Argument added to onUserRequestedUnlock to indicate if user wants to
dismiss keyguard.
3. Callback for result of grantTrust calls.
- curently only calls back if device was unlocked as a result of the
call
See design: go/au-noise-reduction
Note: changes made to SystemUI are manually tested and may need
refactoring which is being skipped now to meet the API Freeze deadline.
Bug: 225231929
Test: atest TrustTests
Test: Manual interaction with wake & fingerprint sensor
CTS-Coverage-Bug: 213944235
Change-Id: I8d08229f09c9a1f2295b7eb464d12cad0c6b8303
diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp
index c9c6c5c..77f98e8 100644
--- a/tests/TrustTests/Android.bp
+++ b/tests/TrustTests/Android.bp
@@ -25,6 +25,8 @@
"androidx.test.rules",
"androidx.test.ext.junit",
"androidx.test.uiautomator",
+ "mockito-target-minus-junit4",
+ "servicestests-utils",
"truth-prebuilt",
],
libs: [
diff --git a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
index af7a98c..f864fed 100644
--- a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
+++ b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
@@ -16,6 +16,7 @@
package android.trust.test
+import android.service.trust.GrantTrustResult
import android.trust.BaseTrustAgentService
import android.trust.TrustTestActivity
import android.trust.test.lib.LockStateTrackingRule
@@ -25,11 +26,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
+import com.android.server.testutils.mock
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.runner.RunWith
+import org.mockito.Mockito.verifyZeroInteractions
/**
* Test for testing revokeTrust & grantTrust for non-renewable trust.
@@ -66,7 +69,7 @@
@Test
fun grantKeepsDeviceUnlocked() {
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 10000, 0)
+ trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 10000, 0) {}
uiDevice.sleep()
lockStateTrackingRule.assertUnlocked()
@@ -74,7 +77,7 @@
@Test
fun grantKeepsDeviceUnlocked_untilRevoked() {
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, 0)
+ trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, 0) {}
await()
uiDevice.sleep()
trustAgentRule.agent.revokeTrust()
@@ -82,6 +85,15 @@
lockStateTrackingRule.assertLocked()
}
+ @Test
+ fun grantDoesNotCallBack() {
+ val callback = mock<(GrantTrustResult) -> Unit>()
+ trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, 0, callback)
+ await()
+
+ verifyZeroInteractions(callback)
+ }
+
companion object {
private const val TAG = "GrantAndRevokeTrustTest"
private const val GRANT_MESSAGE = "granted by test"
diff --git a/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt b/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
index 14c227b..3c6d54d 100644
--- a/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
+++ b/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
@@ -16,16 +16,20 @@
package android.trust.test
+import android.service.trust.GrantTrustResult
+import android.service.trust.GrantTrustResult.STATUS_UNLOCKED_BY_GRANT
import android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE
import android.trust.BaseTrustAgentService
import android.trust.TrustTestActivity
import android.trust.test.lib.LockStateTrackingRule
import android.trust.test.lib.ScreenLockRule
import android.trust.test.lib.TrustAgentRule
+import android.util.Log
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
+import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -70,7 +74,8 @@
uiDevice.sleep()
lockStateTrackingRule.assertLocked()
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
uiDevice.wakeUp()
lockStateTrackingRule.assertLocked()
@@ -78,7 +83,8 @@
@Test
fun grantTrustUnlockedDevice_deviceLocksOnScreenOff() {
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
uiDevice.sleep()
lockStateTrackingRule.assertLocked()
@@ -86,20 +92,48 @@
@Test
fun grantTrustLockedDevice_grantTrustOnLockedDeviceUnlocksDevice() {
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
uiDevice.sleep()
lockStateTrackingRule.assertLocked()
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
uiDevice.wakeUp()
lockStateTrackingRule.assertUnlocked()
}
@Test
+ fun grantTrustLockedDevice_callsBackWhenUnlocked() {
+ Log.i(TAG, "Granting renewable trust while unlocked")
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
+ await(1000)
+
+ Log.i(TAG, "Locking device")
+ uiDevice.sleep()
+
+ lockStateTrackingRule.assertLocked()
+
+ Log.i(TAG, "Renewing trust and unlocking")
+ var result: GrantTrustResult? = null
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {
+ Log.i(TAG, "Callback received; status=${it.status}")
+ result = it
+ }
+ uiDevice.wakeUp()
+ lockStateTrackingRule.assertUnlocked()
+
+ assertThat(result?.status).isEqualTo(STATUS_UNLOCKED_BY_GRANT)
+ }
+
+ @Test
fun grantTrustLockedDevice_revokeTrustPreventsSubsequentUnlock() {
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
uiDevice.sleep()
lockStateTrackingRule.assertLocked()
@@ -109,7 +143,8 @@
uiDevice.wakeUp()
await(500)
- trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE)
+ trustAgentRule.agent.grantTrust(
+ GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
lockStateTrackingRule.assertLocked()
}
diff --git a/tests/TrustTests/src/android/trust/test/UserUnlockRequestTest.kt b/tests/TrustTests/src/android/trust/test/UserUnlockRequestTest.kt
index f8783fb..8bd8340 100644
--- a/tests/TrustTests/src/android/trust/test/UserUnlockRequestTest.kt
+++ b/tests/TrustTests/src/android/trust/test/UserUnlockRequestTest.kt
@@ -32,7 +32,7 @@
import org.junit.runner.RunWith
/**
- * Test for testing the user unlock trigger.
+ * Test for the user unlock triggers.
*
* atest TrustTests:UserUnlockRequestTest
*/
@@ -53,13 +53,32 @@
@Test
fun reportUserRequestedUnlock_propagatesToAgent() {
val oldCount = trustAgentRule.agent.onUserRequestedUnlockCallCount
- trustManager.reportUserRequestedUnlock(userId)
+ trustManager.reportUserRequestedUnlock(userId, false)
await()
assertThat(trustAgentRule.agent.onUserRequestedUnlockCallCount)
.isEqualTo(oldCount + 1)
}
+ @Test
+ fun reportUserRequestedUnlock_propagatesToAgentWithDismissKeyguard() {
+ trustManager.reportUserRequestedUnlock(userId, true)
+ await()
+
+ assertThat(trustAgentRule.agent.lastCallDismissKeyguard)
+ .isTrue()
+ }
+
+ @Test
+ fun reportUserMayRequestUnlock_propagatesToAgent() {
+ val oldCount = trustAgentRule.agent.onUserMayRequestUnlockCallCount
+ trustManager.reportUserMayRequestUnlock(userId)
+ await()
+
+ assertThat(trustAgentRule.agent.onUserMayRequestUnlockCallCount)
+ .isEqualTo(oldCount + 1)
+ }
+
companion object {
private const val TAG = "UserUnlockRequestTest"
private fun await() = Thread.sleep(250)
@@ -69,10 +88,20 @@
class UserUnlockRequestTrustAgent : BaseTrustAgentService() {
var onUserRequestedUnlockCallCount: Long = 0
private set
+ var onUserMayRequestUnlockCallCount: Long = 0
+ private set
+ var lastCallDismissKeyguard: Boolean = false
+ private set
- override fun onUserRequestedUnlock() {
- Log.i(TAG, "onUserRequestedUnlock")
+ override fun onUserRequestedUnlock(dismissKeyguard: Boolean) {
+ Log.i(TAG, "onUserRequestedUnlock($dismissKeyguard)")
onUserRequestedUnlockCallCount++
+ lastCallDismissKeyguard = dismissKeyguard
+ }
+
+ override fun onUserMayRequestUnlock() {
+ Log.i(TAG, "onUserMayRequestUnlock")
+ onUserMayRequestUnlockCallCount++
}
companion object {
diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
index 834f212..00f457b 100644
--- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
@@ -56,12 +56,22 @@
val maxWaits = 50
var waitCount = 0
+ // First verify we get the call in LockState via TrustListener
while ((lockState.locked == false) && waitCount < maxWaits) {
- Log.i(TAG, "phone still locked, wait 50ms more ($waitCount)")
+ Log.i(TAG, "phone still unlocked (TrustListener), wait 50ms more ($waitCount)")
Thread.sleep(50)
waitCount++
}
assertThat(lockState.locked).isTrue()
+
+ // TODO(b/225231929): refactor checks into one loop and re-use for assertUnlocked
+ // Then verify we get the window manager locked
+ while (!windowManager.isKeyguardLocked && waitCount < maxWaits) {
+ Log.i(TAG, "phone still unlocked (WindowManager), wait 50ms more ($waitCount)")
+ Thread.sleep(50)
+ waitCount++
+ }
+ assertThat(windowManager.isKeyguardLocked).isTrue()
}
fun assertUnlocked() {
diff --git a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
index 006525d..127653d 100644
--- a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
@@ -69,6 +69,17 @@
while (windowManager.isKeyguardLocked && waitCount < maxWaits) {
Log.i(TAG, "Keyguard still showing; attempting to dismiss and wait 50ms ($waitCount)")
windowManager.dismissKeyguard(null, null)
+
+ // Sometimes, bouncer gets shown due to a race, so we have to put display to sleep
+ // and wake it back up to get it to go away
+ if (waitCount >= 10 && waitCount % 5 == 0) {
+ Log.i(TAG, "Escalation: attempting screen off/on to get rid of bouncer (+500ms)")
+ uiDevice.sleep()
+ Thread.sleep(250)
+ uiDevice.wakeUp()
+ Thread.sleep(250)
+ }
+
Thread.sleep(50)
waitCount++
}