1 /*
<lambda>null2  * Copyright (C) 2023 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 
17 package com.android.settings.biometrics.fingerprint2.ui.settings.fragment
18 
19 import android.app.Dialog
20 import android.app.admin.DevicePolicyManager
21 import android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_FINGERPRINT_LAST_DELETE_MESSAGE
22 import android.app.admin.DevicePolicyResources.UNDEFINED
23 import android.app.settings.SettingsEnums
24 import android.content.DialogInterface
25 import android.os.Bundle
26 import android.os.UserManager
27 import androidx.appcompat.app.AlertDialog
28 import com.android.settings.R
29 import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
30 import com.android.settings.core.instrumentation.InstrumentedDialogFragment
31 import kotlin.coroutines.resume
32 import kotlinx.coroutines.suspendCancellableCoroutine
33 
34 private const val KEY_IS_LAST_FINGERPRINT = "IS_LAST_FINGERPRINT"
35 
36 class FingerprintDeletionDialog : InstrumentedDialogFragment() {
37   private lateinit var fingerprintViewModel: FingerprintData
38   private var isLastFingerprint: Boolean = false
39   private lateinit var alertDialog: AlertDialog
40   lateinit var onClickListener: DialogInterface.OnClickListener
41   lateinit var onNegativeClickListener: DialogInterface.OnClickListener
42   lateinit var onCancelListener: DialogInterface.OnCancelListener
43 
44   override fun getMetricsCategory(): Int {
45     return SettingsEnums.DIALOG_FINGERPINT_EDIT
46   }
47 
48   override fun onCancel(dialog: DialogInterface) {
49     onCancelListener.onCancel(dialog)
50   }
51 
52   override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
53     val fp = requireArguments().get(KEY_FINGERPRINT) as android.hardware.fingerprint.Fingerprint
54     fingerprintViewModel = FingerprintData(fp.name.toString(), fp.biometricId, fp.deviceId)
55     isLastFingerprint = requireArguments().getBoolean(KEY_IS_LAST_FINGERPRINT)
56     val title = getString(R.string.fingerprint_delete_title, fingerprintViewModel.name)
57     var message = getString(R.string.fingerprint_v2_delete_message, fingerprintViewModel.name)
58     val context = requireContext()
59 
60     if (isLastFingerprint) {
61       val isProfileChallengeUser = UserManager.get(context).isManagedProfile(context.userId)
62       val messageId =
63         if (isProfileChallengeUser) {
64           WORK_PROFILE_FINGERPRINT_LAST_DELETE_MESSAGE
65         } else {
66           UNDEFINED
67         }
68       val defaultMessageId =
69         if (isProfileChallengeUser) {
70           R.string.fingerprint_last_delete_message_profile_challenge
71         } else {
72           R.string.fingerprint_last_delete_message
73         }
74       val devicePolicyManager = requireContext().getSystemService(DevicePolicyManager::class.java)
75       message =
76         devicePolicyManager?.resources?.getString(messageId) {
77           message + "\n\n" + context.getString(defaultMessageId)
78         } ?: ""
79     }
80 
81     alertDialog =
82       AlertDialog.Builder(requireActivity())
83         .setTitle(title)
84         .setMessage(message)
85         .setPositiveButton(
86           R.string.security_settings_fingerprint_enroll_dialog_delete,
87           onClickListener,
88         )
89         .setNegativeButton(R.string.cancel, onNegativeClickListener)
90         .create()
91     return alertDialog
92   }
93 
94   companion object {
95     private const val KEY_FINGERPRINT = "fingerprint"
96 
97     suspend fun showInstance(
98       fp: FingerprintData,
99       lastFingerprint: Boolean,
100       target: FingerprintSettingsV2Fragment,
101     ) = suspendCancellableCoroutine { continuation ->
102       val dialog = FingerprintDeletionDialog()
103       dialog.onClickListener = DialogInterface.OnClickListener { _, _ -> continuation.resume(true) }
104       dialog.onNegativeClickListener =
105         DialogInterface.OnClickListener { _, _ -> continuation.resume(false) }
106       dialog.onCancelListener = DialogInterface.OnCancelListener { continuation.resume(false) }
107 
108       continuation.invokeOnCancellation { dialog.dismiss() }
109       val bundle = Bundle()
110       bundle.putObject(
111         KEY_FINGERPRINT,
112         android.hardware.fingerprint.Fingerprint(fp.name, fp.fingerId, fp.deviceId),
113       )
114       bundle.putBoolean(KEY_IS_LAST_FINGERPRINT, lastFingerprint)
115       dialog.arguments = bundle
116       dialog.show(target.parentFragmentManager, FingerprintDeletionDialog::class.java.toString())
117     }
118   }
119 }
120