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

Commit 56ee4125 authored by Sandy Pan's avatar Sandy Pan
Browse files

Invoke pin recovery setup activity after setup supervision

TODO: update test for setupSupervisionActivity once its added.

Bug: 408450426
Test: SupervisionMainSwitchPreferenceTest
Flag: android.app.supervision.flags.enable_supervision_pin_recovery_screen
Change-Id: Idf944003132f8a92e5a81d915179e2ad5af61b2c
parent f9a68cff
Loading
Loading
Loading
Loading
+55 −11
Original line number Diff line number Diff line
@@ -19,11 +19,14 @@ import android.Manifest.permission.CREATE_USERS
import android.Manifest.permission.INTERACT_ACROSS_USERS
import android.Manifest.permission.INTERACT_ACROSS_USERS_FULL
import android.Manifest.permission.MANAGE_USERS
import android.app.Activity
import android.app.ActivityManager
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD
import android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY
import android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW
import android.app.supervision.SupervisionManager
import android.app.supervision.flags.Flags
import android.content.Intent
import android.os.Bundle
import android.os.UserHandle
@@ -38,13 +41,17 @@ import com.android.settingslib.supervision.SupervisionLog
/**
 * This activity starts the flow for setting up device supervision.
 *
 * Three things are required for device supervision: a supervising profile must be created, a lock
 * must be set up for this profile, and `SupervisionManager.isSupervisionEnabled()` must be set.
 * This activity handles the first two, while the third is managed by
 * `SupervisionMainSwitchPreference`.
 * The flow involves three essential steps:
 * 1. Creating a dedicated supervising user profile.
 * 2. Setting up a secure lock (e.g., PIN, password) for this profile.
 * 3. Enabling device supervision using `SupervisionManager.isSupervisionEnabled()`.
 *
 * Returns `Activity.RESULT_OK` if all steps of setup succeed, and `Activity.RESULT_CANCELED` if
 * any step fails, or the user does not finish setting up the lock for the supervising profile.
 * After completing these steps, the activity prompts the user to set up PIN recovery. The result of
 * the PIN recovery setup does not affect the activity's overall result.
 *
 * The activity returns:
 * - `Activity.RESULT_OK` if steps 1-3 are successful.
 * - `Activity.RESULT_CANCELED` if any of steps 1-3 fail, or if the user cancels lock setup.
 *
 * Usage:
 * 1. Start this activity using `startActivityForResult()`.
@@ -94,7 +101,8 @@ class SetupSupervisionActivity : FragmentActivity() {
    private fun startChooseLockActivity(userHandle: UserHandle) {
        // TODO(b/389712273) Intent directly to PIN selection screen to avoid giving the user
        //  the options for password/pattern during the initial setup flow
        val intent = Intent(ACTION_SET_NEW_PASSWORD).apply {
        val intent =
            Intent(ACTION_SET_NEW_PASSWORD).apply {
                putExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_LOW)
                putExtra(EXTRA_KEY_FINGERPRINT_ENROLLMENT_ONLY, true)
            }
@@ -104,6 +112,14 @@ class SetupSupervisionActivity : FragmentActivity() {
    @RequiresPermission(anyOf = [INTERACT_ACROSS_USERS_FULL, MANAGE_USERS])
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {
            REQUEST_CODE_SET_SUPERVISION_LOCK -> handleSetLockResult(resultCode)
            REQUEST_CODE_SET_PIN_RECOVERY -> handlePinRecoveryResult(resultCode)
        }
    }

    private fun handleSetLockResult(resultCode: Int) {
        val supervisionHelper = SupervisionHelper.getInstance(this)
        val supervisingUser = supervisionHelper.getSupervisingUserHandle()
        if (supervisingUser == null) {
@@ -121,10 +137,38 @@ class SetupSupervisionActivity : FragmentActivity() {
            finish()
            return
        }

        // Enable device supervision
        val supervisionManager = getSystemService(SupervisionManager::class.java)
        supervisionManager?.setSupervisionEnabled(true)

        // Start PIN recovery setup
        startPinRecoveryActivity()
    }

    private fun handlePinRecoveryResult(resultCode: Int) {
        if (resultCode == Activity.RESULT_CANCELED) {
            Log.i(SupervisionLog.TAG, "PIN recovery setup was skipped by the user.")
        }
        setResult(RESULT_OK)
        finish()
    }

    private fun startPinRecoveryActivity() {
        // prompt user to setup pin recovery if flag is enabled
        if (!Flags.enableSupervisionPinRecoveryScreen()) {
            Log.d(SupervisionLog.TAG, "PIN recovery setup is not enabled.")
            setResult(RESULT_OK)
            finish()
        }

        val intent =
            Intent(this, SupervisionPinRecoveryActivity::class.java).apply {
                action = SupervisionPinRecoveryActivity.ACTION_SETUP
            }
        startActivityForResult(intent, REQUEST_CODE_SET_PIN_RECOVERY, null)
    }

    @RequiresPermission(anyOf = [INTERACT_ACROSS_USERS_FULL, MANAGE_USERS])
    private fun tryStopProfile(supervisingUser: UserHandle, activityManager: ActivityManager) {
        if (!activityManager.stopProfile(supervisingUser)) {
@@ -134,6 +178,6 @@ class SetupSupervisionActivity : FragmentActivity() {

    companion object {
        private const val REQUEST_CODE_SET_SUPERVISION_LOCK = 0
        private const val REQUEST_CODE_SET_PIN_RECOVERY = 1
    }

}
+6 −5
Original line number Diff line number Diff line
@@ -89,7 +89,8 @@ class SupervisionMainSwitchPreference(
            supervisionMainSwitchStorage.getBoolean(KEY)!!,
        )

        val preferenceKeys = buildList<String> {
        val preferenceKeys =
            buildList<String> {
                mainSwitchPreference?.parent?.forEachRecursively {
                    if (it.parent?.key == SupervisionDashboardScreen.SUPERVISION_DYNAMIC_GROUP_1) {
                        add(it.key)
+4 −6
Original line number Diff line number Diff line
@@ -35,17 +35,15 @@ import com.android.settingslib.supervision.SupervisionLog
class SupervisionPinRecoveryActivity : FragmentActivity() {
    // ActivityResultLaunchers
    private val contract = ActivityResultContracts.StartActivityForResult()
    private val confirmPinLauncher: ActivityResultLauncher<Intent> by lazy {
    private val confirmPinLauncher: ActivityResultLauncher<Intent> =
        registerForActivityResult(contract) { result -> onPinConfirmed(result.resultCode) }
    }
    private val verificationLauncher: ActivityResultLauncher<Intent> by lazy {

    private val verificationLauncher: ActivityResultLauncher<Intent> =
        registerForActivityResult(contract) { result ->
            onVerification(result.resultCode, result.data)
        }
    }
    private val setPinLauncher: ActivityResultLauncher<Intent> by lazy {
    private val setPinLauncher: ActivityResultLauncher<Intent> =
        registerForActivityResult(contract) { result -> onPinSet(result.resultCode) }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)