• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.settings.supervision
17 
18 import android.Manifest.permission.USE_BIOMETRIC
19 import android.app.Activity
20 import android.content.pm.PackageManager
21 import android.hardware.biometrics.BiometricManager
22 import android.hardware.biometrics.BiometricPrompt
23 import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback
24 import android.os.Bundle
25 import android.os.CancellationSignal
26 import android.util.Log
27 import androidx.annotation.RequiresPermission
28 import androidx.core.content.ContextCompat
29 import androidx.fragment.app.FragmentActivity
30 import com.android.settings.R
31 
32 /**
33  * Activity for confirming supervision credentials using device credential authentication.
34  *
35  * This activity displays an authentication prompt to the user, requiring them to authenticate using
36  * their device credentials (PIN, pattern, or password). It is specifically designed for verifying
37  * credentials for supervision purposes.
38  *
39  * It returns `Activity.RESULT_OK` if authentication succeeds, and `Activity.RESULT_CANCELED` if
40  * authentication fails or is canceled by the user.
41  *
42  * Usage:
43  * 1. Start this activity using `startActivityForResult()`.
44  * 2. Handle the result in `onActivityResult()`.
45  *
46  * Permissions:
47  * - Requires `android.permission.USE_BIOMETRIC`.
48  */
49 class ConfirmSupervisionCredentialsActivity : FragmentActivity() {
50     private val mAuthenticationCallback =
51         object : AuthenticationCallback() {
onAuthenticationErrornull52             override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
53                 Log.w(TAG, "onAuthenticationError(errorCode=$errorCode, errString=$errString)")
54                 setResult(Activity.RESULT_CANCELED)
55                 finish()
56             }
57 
onAuthenticationSucceedednull58             override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) {
59                 setResult(Activity.RESULT_OK)
60                 finish()
61             }
62 
onAuthenticationFailednull63             override fun onAuthenticationFailed() {
64                 setResult(Activity.RESULT_CANCELED)
65                 finish()
66             }
67         }
68 
69     @RequiresPermission(USE_BIOMETRIC)
onCreatenull70     override fun onCreate(savedInstanceState: Bundle?) {
71         super.onCreate(savedInstanceState)
72         // TODO(b/392961554): Check if caller is the SYSTEM_SUPERVISION role holder. Call
73         // RoleManager#getRoleHolders(SYSTEM_SUPERVISION) and check if getCallingPackage() is in the
74         // list.
75         if (checkCallingOrSelfPermission(USE_BIOMETRIC) == PackageManager.PERMISSION_GRANTED) {
76             showBiometricPrompt()
77         }
78     }
79 
80     @RequiresPermission(USE_BIOMETRIC)
showBiometricPromptnull81     fun showBiometricPrompt() {
82         // TODO(b/392961554): adapts to new user profile type to trigger PIN verification dialog.
83         val biometricPrompt =
84             BiometricPrompt.Builder(this)
85                 .setTitle(getString(R.string.supervision_full_screen_pin_verification_title))
86                 .setConfirmationRequired(true)
87                 .setAllowedAuthenticators(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
88                 .build()
89         biometricPrompt.authenticate(
90             CancellationSignal(),
91             ContextCompat.getMainExecutor(this),
92             mAuthenticationCallback,
93         )
94     }
95 
96     companion object {
97         // TODO(b/392961554): remove this tag and use shared tag after http://ag/31997167 is
98         // submitted.
99         const val TAG = "SupervisionSettings"
100     }
101 }
102