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

Commit 3b561c85 authored by Clara Thomas's avatar Clara Thomas Committed by Android (Google) Code Review
Browse files

Merge "Add EXTRA_FORCE_CONFIRMATION to bypass supervision auth session." into main

parents 6d1b9294 0fa05fa6
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -122,9 +122,11 @@ class ConfirmSupervisionCredentialsActivity : FragmentActivity() {
            getResultLauncher.launch(setupIntent)
            return
        }

        val authController = SupervisionAuthController.getInstance(this)
        if (!authController.isSessionActive(taskId)) {
        val forceConfirmation = intent.getBooleanExtra(EXTRA_FORCE_CONFIRMATION, false)
        if (
            forceConfirmation ||
                !SupervisionAuthController.getInstance(this).isSessionActive(taskId)
        ) {
            val activityManager = getSystemService(ActivityManager::class.java)
            if (!activityManager.startProfile(supervisingUser)) {
                errorHandler("Unable to start supervising user, cannot verify credentials.")
@@ -213,4 +215,9 @@ class ConfirmSupervisionCredentialsActivity : FragmentActivity() {
        setResult(RESULT_CANCELED)
        finish()
    }

    companion object {
        // If true, force confirmation of supervision credentials, regardless of active auth session
        @VisibleForTesting const val EXTRA_FORCE_CONFIRMATION = "force_confirmation"
    }
}
+48 −16
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.app.supervision.SupervisionManager
import android.app.supervision.SupervisionRecoveryInfo
import android.app.supervision.SupervisionRecoveryInfo.STATE_PENDING
import android.content.Context
import android.content.Intent
import android.content.pm.UserInfo
import android.hardware.biometrics.BiometricManager
import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton
@@ -34,6 +35,7 @@ import android.os.UserManager.USER_TYPE_PROFILE_SUPERVISING
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R
import com.android.settings.supervision.ConfirmSupervisionCredentialsActivity.Companion.EXTRA_FORCE_CONFIRMATION
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@@ -76,22 +78,7 @@ class ConfirmSupervisionCredentialsActivityTest {
    @Before
    fun setUp() {
        ShadowRoleManager.reset()

        // Note, we have to use ActivityController (instead of ActivityScenario) in order to access
        // the activity before it is created, so we can set up various mocked responses before they
        // are referenced in onCreate.
        mActivityController =
            Robolectric.buildActivity(ConfirmSupervisionCredentialsActivity::class.java)
        mActivity = mActivityController.get()

        shadowActivity = shadowOf(mActivity)
        shadowActivity.setCallingPackage(callingPackage)
        shadowKeyguardManager = shadowOf(mActivity.getSystemService(KeyguardManager::class.java))
        Shadow.extract<ShadowContextImpl>(mActivity.baseContext).apply {
            setSystemService(Context.ACTIVITY_SERVICE, mockActivityManager)
            setSystemService(Context.SUPERVISION_SERVICE, mockSupervisionManager)
            setSystemService(Context.USER_SERVICE, mockUserManager)
        }
        setUpActivity(forceConfirm = false)
        SupervisionAuthController.sInstance = null
    }

@@ -153,6 +140,25 @@ class ConfirmSupervisionCredentialsActivityTest {
        assertThat(shadowActivity.resultCode).isEqualTo(Activity.RESULT_OK)
    }

    @Test
    fun onCreate_authSessionActive_forceConfirmation_doesNotFinish() {
        ShadowRoleManager.addRoleHolder(ROLE_SYSTEM_SUPERVISION, callingPackage, currentUser)
        mockUserManager.stub { on { users } doReturn listOf(SUPERVISING_USER_INFO) }
        mockActivityManager.stub { on { startProfile(any()) } doReturn true }
        shadowKeyguardManager.setIsDeviceSecure(SUPERVISING_USER_ID, true)
        SupervisionAuthController.getInstance(context).startSession(mActivity.taskId)

        setUpActivity(forceConfirm = true)
        mActivityController.setup()

        assertThat(mActivity.isFinishing).isFalse()

        // Ensure that the supervising profile is started
        val userCaptor = argumentCaptor<UserHandle>()
        verify(mockActivityManager).startProfile(userCaptor.capture())
        assert(userCaptor.lastValue.identifier == SUPERVISING_USER_ID)
    }

    @Test
    @Config(sdk = [Build.VERSION_CODES.BAKLAVA])
    fun onCreate_callerIsSystemUid_doesNotFinish() {
@@ -212,6 +218,7 @@ class ConfirmSupervisionCredentialsActivityTest {
            .isInstanceOf(PromptContentViewWithMoreOptionsButton::class.java)
    }

    @Test
    fun getBiometricPrompt_recoveryInfoEmpty_noMoreOptionsButton() {
        whenever(mockSupervisionManager.supervisionRecoveryInfo).thenReturn(null)

@@ -225,6 +232,7 @@ class ConfirmSupervisionCredentialsActivityTest {
        assertThat(biometricPrompt.contentView).isNull()
    }

    @Test
    fun onAuthenticationSucceeded_startsAuthSession_returnsResultOK() {
        mockUserManager.stub { on { users } doReturn listOf(SUPERVISING_USER_INFO) }
        shadowKeyguardManager.setIsDeviceSecure(SUPERVISING_USER_ID, true)
@@ -236,6 +244,30 @@ class ConfirmSupervisionCredentialsActivityTest {
        assertThat(shadowActivity.resultCode).isEqualTo(Activity.RESULT_OK)
    }

    private fun setUpActivity(forceConfirm: Boolean) {
        // Note, we have to use ActivityController (instead of ActivityScenario) in order to access
        // the activity before it is created, so we can set up various mocked responses before they
        // are referenced in onCreate.
        if (forceConfirm) {
            val intent = Intent().putExtra(EXTRA_FORCE_CONFIRMATION, true)
            mActivityController =
                Robolectric.buildActivity(ConfirmSupervisionCredentialsActivity::class.java, intent)
        } else {
            mActivityController =
                Robolectric.buildActivity(ConfirmSupervisionCredentialsActivity::class.java)
        }
        mActivity = mActivityController.get()

        shadowActivity = shadowOf(mActivity)
        shadowActivity.setCallingPackage(callingPackage)
        shadowKeyguardManager = shadowOf(mActivity.getSystemService(KeyguardManager::class.java))
        Shadow.extract<ShadowContextImpl>(mActivity.baseContext).apply {
            setSystemService(Context.ACTIVITY_SERVICE, mockActivityManager)
            setSystemService(Context.SUPERVISION_SERVICE, mockSupervisionManager)
            setSystemService(Context.USER_SERVICE, mockUserManager)
        }
    }

    private companion object {
        const val SUPERVISING_USER_ID = 5
        val SUPERVISING_USER_INFO =