Loading src/com/android/settings/supervision/SetupSupervisionActivity.kt +55 −11 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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()`. Loading Loading @@ -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) } Loading @@ -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) { Loading @@ -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)) { Loading @@ -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 } } src/com/android/settings/supervision/SupervisionMainSwitchPreference.kt +6 −5 Original line number Diff line number Diff line Loading @@ -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) Loading src/com/android/settings/supervision/SupervisionPinRecoveryActivity.kt +4 −6 Original line number Diff line number Diff line Loading @@ -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) Loading Loading
src/com/android/settings/supervision/SetupSupervisionActivity.kt +55 −11 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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()`. Loading Loading @@ -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) } Loading @@ -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) { Loading @@ -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)) { Loading @@ -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 } }
src/com/android/settings/supervision/SupervisionMainSwitchPreference.kt +6 −5 Original line number Diff line number Diff line Loading @@ -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) Loading
src/com/android/settings/supervision/SupervisionPinRecoveryActivity.kt +4 −6 Original line number Diff line number Diff line Loading @@ -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) Loading