Loading src/com/android/settings/supervision/ConfirmSupervisionCredentialsActivity.kt +13 −11 Original line number Diff line number Diff line Loading @@ -15,10 +15,9 @@ */ package com.android.settings.supervision import android.Manifest.permission.USE_BIOMETRIC import android.Manifest.permission.USE_BIOMETRIC_INTERNAL import android.app.Activity import android.app.role.RoleManager import android.content.pm.PackageManager import android.hardware.biometrics.BiometricManager import android.hardware.biometrics.BiometricPrompt import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback Loading @@ -29,7 +28,6 @@ import android.os.Process import android.util.Log import androidx.annotation.OpenForTesting import androidx.annotation.RequiresPermission import androidx.annotation.VisibleForTesting import androidx.core.content.ContextCompat import androidx.fragment.app.FragmentActivity import com.android.settings.R Loading Loading @@ -76,35 +74,39 @@ open class ConfirmSupervisionCredentialsActivity : FragmentActivity() { } } @RequiresPermission(USE_BIOMETRIC) @RequiresPermission(USE_BIOMETRIC_INTERNAL) public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // TODO(b/392961554): adapts to new user profile type to trigger PIN verification dialog. if (!callerHasSupervisionRole() && !callerIsSystemUid()) { setResult(Activity.RESULT_CANCELED) finish() return } if (checkCallingOrSelfPermission(USE_BIOMETRIC) != PackageManager.PERMISSION_GRANTED) { showBiometricPrompt() } @RequiresPermission(USE_BIOMETRIC_INTERNAL) fun showBiometricPrompt() { val supervisingUserId = SupervisionHelper.getInstance(this).getSupervisingUserHandle()?.identifier if (supervisingUserId == null) { Log.w(SupervisionLog.TAG, "supervisingUserId is null") setResult(Activity.RESULT_CANCELED) finish() return } showBiometricPrompt() } @RequiresPermission(USE_BIOMETRIC) fun showBiometricPrompt() { val biometricPrompt = BiometricPrompt.Builder(this) .setTitle(getString(R.string.supervision_full_screen_pin_verification_title)) .setConfirmationRequired(true) .setAllowedAuthenticators(BiometricManager.Authenticators.DEVICE_CREDENTIAL) .build() biometricPrompt.authenticate( biometricPrompt.authenticateUser( CancellationSignal(), ContextCompat.getMainExecutor(this), mAuthenticationCallback, supervisingUserId, ) } Loading tests/robotests/src/com/android/settings/supervision/ConfirmSupervisionCredentialsActivityTest.kt +41 −15 Original line number Diff line number Diff line Loading @@ -17,9 +17,12 @@ package com.android.settings.supervision import android.app.Activity import android.app.role.RoleManager import android.content.pm.PackageManager import android.content.pm.UserInfo import android.os.Build import android.os.Process import android.os.UserManager import android.os.UserManager.USER_TYPE_PROFILE_SUPERVISING import android.os.UserManager.USER_TYPE_PROFILE_TEST import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading @@ -38,6 +41,7 @@ import org.robolectric.shadows.ShadowBinder @RunWith(RobolectricTestRunner::class) class ConfirmSupervisionCredentialsActivityTest { private val mockRoleManager = mock<RoleManager>() private val mockUserManager = mock<UserManager>() private lateinit var mActivity: ConfirmSupervisionCredentialsActivity Loading @@ -45,29 +49,21 @@ class ConfirmSupervisionCredentialsActivityTest { @Before fun setUp() { SupervisionHelper.sInstance = null mActivity = spy( Robolectric.buildActivity(ConfirmSupervisionCredentialsActivity::class.java).get() ) { on { getSystemService(RoleManager::class.java) } doReturn mockRoleManager on { getSystemService(UserManager::class.java) } doReturn mockUserManager on { callingPackage } doReturn callingPackage } } @Test fun onCreate_noRequiredPermission_finish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_DENIED) mActivity.onCreate(null) verify(mActivity).setResult(Activity.RESULT_CANCELED) verify(mActivity).finish() } @Test fun onCreate_callerHasSupervisionRole_doesNotFinish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) whenever(mockRoleManager.getRoleHolders(any())).thenReturn(listOf(callingPackage)) whenever(mockUserManager.users).thenReturn(listOf(SUPERVISING_USER_INFO)) mActivity.onCreate(null) Loading @@ -78,7 +74,6 @@ class ConfirmSupervisionCredentialsActivityTest { fun onCreate_callerNotHasSupervisionRole_finish() { val otherPackage = "com.example.other" whenever(mockRoleManager.getRoleHolders(any())).thenReturn(listOf(otherPackage)) whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) mActivity.onCreate(null) Loading @@ -89,8 +84,8 @@ class ConfirmSupervisionCredentialsActivityTest { @Test @Config(sdk = [Build.VERSION_CODES.BAKLAVA]) fun onCreate_callerIsSystemUid_doesNotFinish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) ShadowBinder.setCallingUid(Process.SYSTEM_UID) whenever(mockUserManager.users).thenReturn(listOf(SUPERVISING_USER_INFO)) mActivity.onCreate(null) Loading @@ -100,7 +95,6 @@ class ConfirmSupervisionCredentialsActivityTest { @Test @Config(sdk = [Build.VERSION_CODES.BAKLAVA]) fun onCreate_callerIsUnknownUid_finish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) ShadowBinder.setCallingUid(Process.NOBODY_UID) mActivity.onCreate(null) Loading @@ -108,4 +102,36 @@ class ConfirmSupervisionCredentialsActivityTest { verify(mActivity).setResult(Activity.RESULT_CANCELED) verify(mActivity).finish() } @Test fun onCreate_noSupervisingCredential_finish() { whenever(mockRoleManager.getRoleHolders(any())).thenReturn(listOf(callingPackage)) whenever(mockUserManager.users).thenReturn(listOf(TESTING_USER_INFO)) mActivity.onCreate(null) verify(mActivity).setResult(Activity.RESULT_CANCELED) verify(mActivity).finish() } private companion object { const val SUPERVISING_USER_ID = 5 val SUPERVISING_USER_INFO = UserInfo( SUPERVISING_USER_ID, /* name */ "supervising", /* iconPath */ "", /* flags */ 0, USER_TYPE_PROFILE_SUPERVISING, ) const val TESTING_USER_ID = 6 val TESTING_USER_INFO = UserInfo( TESTING_USER_ID, /* name */ "testing", /* iconPath */ "", /* flags */ 0, USER_TYPE_PROFILE_TEST, ) } } Loading
src/com/android/settings/supervision/ConfirmSupervisionCredentialsActivity.kt +13 −11 Original line number Diff line number Diff line Loading @@ -15,10 +15,9 @@ */ package com.android.settings.supervision import android.Manifest.permission.USE_BIOMETRIC import android.Manifest.permission.USE_BIOMETRIC_INTERNAL import android.app.Activity import android.app.role.RoleManager import android.content.pm.PackageManager import android.hardware.biometrics.BiometricManager import android.hardware.biometrics.BiometricPrompt import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback Loading @@ -29,7 +28,6 @@ import android.os.Process import android.util.Log import androidx.annotation.OpenForTesting import androidx.annotation.RequiresPermission import androidx.annotation.VisibleForTesting import androidx.core.content.ContextCompat import androidx.fragment.app.FragmentActivity import com.android.settings.R Loading Loading @@ -76,35 +74,39 @@ open class ConfirmSupervisionCredentialsActivity : FragmentActivity() { } } @RequiresPermission(USE_BIOMETRIC) @RequiresPermission(USE_BIOMETRIC_INTERNAL) public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // TODO(b/392961554): adapts to new user profile type to trigger PIN verification dialog. if (!callerHasSupervisionRole() && !callerIsSystemUid()) { setResult(Activity.RESULT_CANCELED) finish() return } if (checkCallingOrSelfPermission(USE_BIOMETRIC) != PackageManager.PERMISSION_GRANTED) { showBiometricPrompt() } @RequiresPermission(USE_BIOMETRIC_INTERNAL) fun showBiometricPrompt() { val supervisingUserId = SupervisionHelper.getInstance(this).getSupervisingUserHandle()?.identifier if (supervisingUserId == null) { Log.w(SupervisionLog.TAG, "supervisingUserId is null") setResult(Activity.RESULT_CANCELED) finish() return } showBiometricPrompt() } @RequiresPermission(USE_BIOMETRIC) fun showBiometricPrompt() { val biometricPrompt = BiometricPrompt.Builder(this) .setTitle(getString(R.string.supervision_full_screen_pin_verification_title)) .setConfirmationRequired(true) .setAllowedAuthenticators(BiometricManager.Authenticators.DEVICE_CREDENTIAL) .build() biometricPrompt.authenticate( biometricPrompt.authenticateUser( CancellationSignal(), ContextCompat.getMainExecutor(this), mAuthenticationCallback, supervisingUserId, ) } Loading
tests/robotests/src/com/android/settings/supervision/ConfirmSupervisionCredentialsActivityTest.kt +41 −15 Original line number Diff line number Diff line Loading @@ -17,9 +17,12 @@ package com.android.settings.supervision import android.app.Activity import android.app.role.RoleManager import android.content.pm.PackageManager import android.content.pm.UserInfo import android.os.Build import android.os.Process import android.os.UserManager import android.os.UserManager.USER_TYPE_PROFILE_SUPERVISING import android.os.UserManager.USER_TYPE_PROFILE_TEST import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading @@ -38,6 +41,7 @@ import org.robolectric.shadows.ShadowBinder @RunWith(RobolectricTestRunner::class) class ConfirmSupervisionCredentialsActivityTest { private val mockRoleManager = mock<RoleManager>() private val mockUserManager = mock<UserManager>() private lateinit var mActivity: ConfirmSupervisionCredentialsActivity Loading @@ -45,29 +49,21 @@ class ConfirmSupervisionCredentialsActivityTest { @Before fun setUp() { SupervisionHelper.sInstance = null mActivity = spy( Robolectric.buildActivity(ConfirmSupervisionCredentialsActivity::class.java).get() ) { on { getSystemService(RoleManager::class.java) } doReturn mockRoleManager on { getSystemService(UserManager::class.java) } doReturn mockUserManager on { callingPackage } doReturn callingPackage } } @Test fun onCreate_noRequiredPermission_finish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_DENIED) mActivity.onCreate(null) verify(mActivity).setResult(Activity.RESULT_CANCELED) verify(mActivity).finish() } @Test fun onCreate_callerHasSupervisionRole_doesNotFinish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) whenever(mockRoleManager.getRoleHolders(any())).thenReturn(listOf(callingPackage)) whenever(mockUserManager.users).thenReturn(listOf(SUPERVISING_USER_INFO)) mActivity.onCreate(null) Loading @@ -78,7 +74,6 @@ class ConfirmSupervisionCredentialsActivityTest { fun onCreate_callerNotHasSupervisionRole_finish() { val otherPackage = "com.example.other" whenever(mockRoleManager.getRoleHolders(any())).thenReturn(listOf(otherPackage)) whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) mActivity.onCreate(null) Loading @@ -89,8 +84,8 @@ class ConfirmSupervisionCredentialsActivityTest { @Test @Config(sdk = [Build.VERSION_CODES.BAKLAVA]) fun onCreate_callerIsSystemUid_doesNotFinish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) ShadowBinder.setCallingUid(Process.SYSTEM_UID) whenever(mockUserManager.users).thenReturn(listOf(SUPERVISING_USER_INFO)) mActivity.onCreate(null) Loading @@ -100,7 +95,6 @@ class ConfirmSupervisionCredentialsActivityTest { @Test @Config(sdk = [Build.VERSION_CODES.BAKLAVA]) fun onCreate_callerIsUnknownUid_finish() { whenever(mActivity.checkCallingOrSelfPermission(any())).thenReturn(PackageManager.PERMISSION_GRANTED) ShadowBinder.setCallingUid(Process.NOBODY_UID) mActivity.onCreate(null) Loading @@ -108,4 +102,36 @@ class ConfirmSupervisionCredentialsActivityTest { verify(mActivity).setResult(Activity.RESULT_CANCELED) verify(mActivity).finish() } @Test fun onCreate_noSupervisingCredential_finish() { whenever(mockRoleManager.getRoleHolders(any())).thenReturn(listOf(callingPackage)) whenever(mockUserManager.users).thenReturn(listOf(TESTING_USER_INFO)) mActivity.onCreate(null) verify(mActivity).setResult(Activity.RESULT_CANCELED) verify(mActivity).finish() } private companion object { const val SUPERVISING_USER_ID = 5 val SUPERVISING_USER_INFO = UserInfo( SUPERVISING_USER_ID, /* name */ "supervising", /* iconPath */ "", /* flags */ 0, USER_TYPE_PROFILE_SUPERVISING, ) const val TESTING_USER_ID = 6 val TESTING_USER_INFO = UserInfo( TESTING_USER_ID, /* name */ "testing", /* iconPath */ "", /* flags */ 0, USER_TYPE_PROFILE_TEST, ) } }