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

Commit 9b0ece97 authored by Junchen Quan's avatar Junchen Quan Committed by Android (Google) Code Review
Browse files

Merge "[Device Supervision] Implement createConfirmSupervisionCredentialsIntent API" into main

parents 29526191 160b8bc1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ android_library {
        "aconfig_settings_flags",
        "aconfig_settingslib_flags",
        "android.app.flags-aconfig",
        "android.app.supervision.flags-aconfig",
        "android.provider.flags-aconfig",
        "android.security.flags-aconfig",
        "android.view.contentprotection.flags-aconfig",
+9 −0
Original line number Diff line number Diff line
@@ -2817,6 +2817,15 @@
            </intent-filter>
        </activity>

        <activity android:name=".supervision.ConfirmSupervisionCredentialsActivity"
            android:exported="true"
            android:featureFlag="android.app.supervision.flags.supervision_manager_apis">
            <intent-filter>
                <action android:name="android.app.supervision.action.CONFIRM_SUPERVISION_CREDENTIALS" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <activity android:name=".SetupRedactionInterstitial"
            android:enabled="false"
            android:exported="true"
+2 −0
Original line number Diff line number Diff line
@@ -14351,5 +14351,7 @@ Data usage charges may apply.</string>
    <!-- Title for web content filters browser category allow all sites option [CHAR LIMIT=60] -->
    <string name="supervision_web_content_filters_browser_allow_all_sites_title">Allow all sites</string>
    <!-- Generic content description that is attached to the preview illustration at the top of an Accessibility feature toggle page. [CHAR LIMIT=NONE] -->
    <!-- Title for supervision PIN verification screen [CHAR LIMIT=60] -->
    <string name="supervision_full_screen_pin_verification_title">Enter supervision PIN</string>
    <string name="accessibility_illustration_content_description"><xliff:g id="feature" example="Select to Speak">%1$s</xliff:g> animation</string>
</resources>
+101 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.supervision

import android.Manifest.permission.USE_BIOMETRIC
import android.app.Activity
import android.content.pm.PackageManager
import android.hardware.biometrics.BiometricManager
import android.hardware.biometrics.BiometricPrompt
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback
import android.os.Bundle
import android.os.CancellationSignal
import android.util.Log
import androidx.annotation.RequiresPermission
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.android.settings.R

/**
 * Activity for confirming supervision credentials using device credential authentication.
 *
 * This activity displays an authentication prompt to the user, requiring them to authenticate using
 * their device credentials (PIN, pattern, or password). It is specifically designed for verifying
 * credentials for supervision purposes.
 *
 * It returns `Activity.RESULT_OK` if authentication succeeds, and `Activity.RESULT_CANCELED` if
 * authentication fails or is canceled by the user.
 *
 * Usage:
 * 1. Start this activity using `startActivityForResult()`.
 * 2. Handle the result in `onActivityResult()`.
 *
 * Permissions:
 * - Requires `android.permission.USE_BIOMETRIC`.
 */
class ConfirmSupervisionCredentialsActivity : FragmentActivity() {
    private val mAuthenticationCallback =
        object : AuthenticationCallback() {
            override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                Log.w(TAG, "onAuthenticationError(errorCode=$errorCode, errString=$errString)")
                setResult(Activity.RESULT_CANCELED)
                finish()
            }

            override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) {
                setResult(Activity.RESULT_OK)
                finish()
            }

            override fun onAuthenticationFailed() {
                setResult(Activity.RESULT_CANCELED)
                finish()
            }
        }

    @RequiresPermission(USE_BIOMETRIC)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // TODO(b/392961554): Check if caller is the SYSTEM_SUPERVISION role holder. Call
        // RoleManager#getRoleHolders(SYSTEM_SUPERVISION) and check if getCallingPackage() is in the
        // list.
        if (checkCallingOrSelfPermission(USE_BIOMETRIC) == PackageManager.PERMISSION_GRANTED) {
            showBiometricPrompt()
        }
    }

    @RequiresPermission(USE_BIOMETRIC)
    fun showBiometricPrompt() {
        // TODO(b/392961554): adapts to new user profile type to trigger PIN verification dialog.
        val biometricPrompt =
            BiometricPrompt.Builder(this)
                .setTitle(getString(R.string.supervision_full_screen_pin_verification_title))
                .setConfirmationRequired(true)
                .setAllowedAuthenticators(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
                .build()
        biometricPrompt.authenticate(
            CancellationSignal(),
            ContextCompat.getMainExecutor(this),
            mAuthenticationCallback,
        )
    }

    companion object {
        // TODO(b/392961554): remove this tag and use shared tag after http://ag/31997167 is
        // submitted.
        const val TAG = "SupervisionSettings"
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ class SupervisionDashboardScreen : PreferenceScreenCreator {

    override fun getPreferenceHierarchy(context: Context) =
        preferenceHierarchy(context, this) {
            +SupervisionMainSwitchPreference()
            +SupervisionMainSwitchPreference(context)
            +TitlelessPreferenceGroup(SUPERVISION_DYNAMIC_GROUP_1) += {
                +SupervisionWebContentFiltersScreen.KEY
            }
Loading