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

Commit 3dfd5c03 authored by Sandy Pan's avatar Sandy Pan Committed by Android (Google) Code Review
Browse files

Merge "Reset the supervising user when pin recovery occurs. This is the...

Merge "Reset the supervising user when pin recovery occurs. This is the short-term solution based on go/kf-ramen-pin-recovery." into main
parents d782e1ad e7c396dc
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -121,7 +121,12 @@ class SupervisionMainSwitchPreference(
        }
        if (resultCode == Activity.RESULT_OK) {
            val mainSwitchPreference = lifeCycleContext.requirePreference<MainSwitchPreference>(KEY)
            val newValue = !supervisionMainSwitchStorage.getBoolean(KEY)!!
            val newValue =
                if (requestCode == REQUEST_CODE_SET_UP_SUPERVISION) {
                    true
                } else {
                    !supervisionMainSwitchStorage.getBoolean(KEY)!!
                }
            mainSwitchPreference.setChecked(newValue)
            updateDependentPreferencesEnabledState(mainSwitchPreference, newValue)
            updateDependentPreferenceSummary(mainSwitchPreference)
+43 −7
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.settings.supervision

import android.Manifest
import android.app.Activity
import android.app.supervision.SupervisionManager
import android.app.supervision.SupervisionRecoveryInfo
@@ -23,13 +24,16 @@ import android.app.supervision.SupervisionRecoveryInfo.STATE_VERIFIED
import android.content.Intent
import android.os.Bundle
import android.os.PersistableBundle
import android.os.UserManager
import android.os.UserManager.USER_TYPE_PROFILE_SUPERVISING
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresPermission
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.FragmentActivity
import com.android.settings.R
import com.android.settings.password.ChooseLockPassword
import com.android.settingslib.supervision.SupervisionIntentProvider
import com.android.settingslib.supervision.SupervisionLog

@@ -163,10 +167,10 @@ class SupervisionPinRecoveryActivity : FragmentActivity() {
    }

    private fun onVerification(resultCode: Int, data: Intent?) {
        if (resultCode == Activity.RESULT_OK) {
        if (resultCode == RESULT_OK) {
            val action = intent.action
            when (action) {
                ACTION_RECOVERY -> startResetPinActivity() // Continue to set PIN after verification
                ACTION_RECOVERY -> startResetPinActivity() // reset PIN after verification
                ACTION_SETUP,
                ACTION_UPDATE,
                ACTION_SETUP_VERIFIED,
@@ -219,9 +223,15 @@ class SupervisionPinRecoveryActivity : FragmentActivity() {
    }

    /** Starts the reset supervision PIN activity for the supervising user. */
    @RequiresPermission(
        anyOf = [Manifest.permission.CREATE_USERS, Manifest.permission.MANAGE_USERS]
    )
    private fun startResetPinActivity() {
        // TODO(b/407064075): reset the user or use other activity to skip entering current PIN.
        val intent = Intent(this, ChooseLockPassword::class.java)
        if (!resetSupervisionUser()) {
            handleError("Failed to reset supervision user.")
            return
        }
        val intent = Intent(this, SupervisionCredentialProxyActivity::class.java)
        setPinLauncher.launch(intent)
    }

@@ -238,6 +248,32 @@ class SupervisionPinRecoveryActivity : FragmentActivity() {
        finish()
    }

    /**
     * Resets the supervision user by removing the existing one and creating a new one.
     *
     * This method first retrieves the current supervising user handle. If it exists, the user is
     * removed. Then, a new supervising user is created.
     *
     * @return True if the reset was successful, false otherwise.
     *
     * TODO(b/407064075): use better approach to reset the supervision user.
     */
    @RequiresPermission(
        anyOf = [Manifest.permission.CREATE_USERS, Manifest.permission.MANAGE_USERS]
    )
    private fun resetSupervisionUser(): Boolean {
        val userManager = getSystemService(UserManager::class.java)
        supervisingUserHandle?.let { userManager.removeUser(it) }
        val userInfo =
            userManager.createUser("Supervising", USER_TYPE_PROFILE_SUPERVISING, /* flags= */ 0)
        if (userInfo != null) {
            return true
        } else {
            Log.e(SupervisionLog.TAG, "Unable to create supervising profile.")
            return false
        }
    }

    companion object {
        // Action types for the PIN recovery activity.
        const val ACTION_SETUP = "android.app.supervision.action.SETUP_PIN_RECOVERY"
@@ -249,7 +285,7 @@ class SupervisionPinRecoveryActivity : FragmentActivity() {
            "android.app.supervision.action.POST_SETUP_VERIFY_PIN_RECOVERY"

        // Extra keys
        private const val EXTRA_RECOVERY_EMAIL = "recoveryEmail"
        private const val EXTRA_RECOVERY_ID = "recoveryId"
        @VisibleForTesting const val EXTRA_RECOVERY_EMAIL = "recoveryEmail"
        @VisibleForTesting const val EXTRA_RECOVERY_ID = "recoveryId"
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ import org.robolectric.shadows.ShadowPackageManager
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.BAKLAVA])
class SupervisionPinRecoveryActivityTest {
    // TODO(b/399484695): Add test cases to verify different scenarios.
    // TODO(b/414457269): Add test cases to verify different scenarios.

    private lateinit var activity: SupervisionPinRecoveryActivity
    private val context: Context = ApplicationProvider.getApplicationContext()