diff --git a/core/java/android/service/controls/actions/ControlAction.java b/core/java/android/service/controls/actions/ControlAction.java index 37a75f0e9e5af..10f526d6565ca 100644 --- a/core/java/android/service/controls/actions/ControlAction.java +++ b/core/java/android/service/controls/actions/ControlAction.java @@ -136,7 +136,8 @@ public abstract class ControlAction { /** * Response code for the {@code consumer} in * {@link ControlsProviderService#performControlAction} indicating that in order for the action - * to be performed, acknowledgment from the user is required. + * to be performed, acknowledgment from the user is required. Any non-empty string returned + * from {@link #getChallengeValue} shall be treated as a positive acknowledgment. */ public static final @ResponseResult int RESPONSE_CHALLENGE_ACK = 3; /** diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt index 15c2a0afe8191..a7a41033bb5d5 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt @@ -34,24 +34,29 @@ import com.android.systemui.R /** * Creates all dialogs for challengeValues that can occur from a call to - * {@link ControlsProviderService#performControlAction}. The types of challenge - * responses are listed in {@link ControlAction.ResponseResult}. + * [ControlsProviderService#performControlAction]. The types of challenge responses are listed in + * [ControlAction.ResponseResult]. */ object ChallengeDialogs { - fun createPinDialog(cvh: ControlViewHolder): Dialog? { + private const val WINDOW_TYPE = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY + private const val STYLE = android.R.style.Theme_DeviceDefault_Dialog_Alert + + /** + * AlertDialogs to handle [ControlAction#RESPONSE_CHALLENGE_PIN] and + * [ControlAction#RESPONSE_CHALLENGE_PIN] responses, decided by the useAlphaNumeric + * parameter. + */ + fun createPinDialog(cvh: ControlViewHolder, useAlphaNumeric: Boolean): Dialog? { val lastAction = cvh.lastAction if (lastAction == null) { Log.e(ControlsUiController.TAG, "PIN Dialog attempted but no last action is set. Will not show") return null } - val builder = AlertDialog.Builder( - cvh.context, - android.R.style.Theme_DeviceDefault_Dialog_Alert - ).apply { + val builder = AlertDialog.Builder(cvh.context, STYLE).apply { val res = cvh.context.resources - setTitle(res.getString(R.string.controls_pin_verify, *arrayOf(cvh.title.getText()))) + setTitle(res.getString(R.string.controls_pin_verify, cvh.title.getText())) setView(R.layout.controls_dialog_pin) setPositiveButton( android.R.string.ok, @@ -71,25 +76,64 @@ object ChallengeDialogs { } return builder.create().apply { getWindow().apply { - setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY) + setType(WINDOW_TYPE) setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) } setOnShowListener(DialogInterface.OnShowListener { _ -> val editText = requireViewById(R.id.controls_pin_input) - requireViewById(R.id.controls_pin_use_alpha).setOnClickListener { v -> - if ((v as CheckBox).isChecked) { - editText.setInputType( - InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD) - } else { - editText.setInputType( - InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD) - } + val useAlphaCheckBox = requireViewById(R.id.controls_pin_use_alpha) + useAlphaCheckBox.setChecked(useAlphaNumeric) + setInputType(editText, useAlphaCheckBox.isChecked()) + requireViewById(R.id.controls_pin_use_alpha).setOnClickListener { _ -> + setInputType(editText, useAlphaCheckBox.isChecked()) } editText.requestFocus() }) } } + /** + * AlertDialogs to handle [ControlAction#RESPONSE_CHALLENGE_ACK] response type. + */ + fun createConfirmationDialog(cvh: ControlViewHolder): Dialog? { + val lastAction = cvh.lastAction + if (lastAction == null) { + Log.e(ControlsUiController.TAG, + "Confirmation Dialog attempted but no last action is set. Will not show") + return null + } + val builder = AlertDialog.Builder(cvh.context, STYLE).apply { + val res = cvh.context.resources + setMessage(res.getString( + R.string.controls_confirmation_message, cvh.title.getText())) + setPositiveButton( + android.R.string.ok, + DialogInterface.OnClickListener { dialog, _ -> + cvh.action(addChallengeValue(lastAction, "true")) + dialog.dismiss() + }) + setNegativeButton( + android.R.string.cancel, + DialogInterface.OnClickListener { dialog, _ -> dialog.cancel() } + ) + } + return builder.create().apply { + getWindow().apply { + setType(WINDOW_TYPE) + } + } + } + + private fun setInputType(editText: EditText, useTextInput: Boolean) { + if (useTextInput) { + editText.setInputType( + InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD) + } else { + editText.setInputType( + InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD) + } + } + private fun addChallengeValue(action: ControlAction, challengeValue: String): ControlAction { val id = action.getTemplateId() return when (action) { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index b0db4370f38db..05a0c45c2e15d 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -442,7 +442,15 @@ class ControlsUiControllerImpl @Inject constructor ( controlViewsById.get(key)?.let { cvh -> when (response) { ControlAction.RESPONSE_CHALLENGE_PIN -> { - activeDialog = ChallengeDialogs.createPinDialog(cvh) + activeDialog = ChallengeDialogs.createPinDialog(cvh, false) + activeDialog?.show() + } + ControlAction.RESPONSE_CHALLENGE_PASSPHRASE -> { + activeDialog = ChallengeDialogs.createPinDialog(cvh, true) + activeDialog?.show() + } + ControlAction.RESPONSE_CHALLENGE_ACK -> { + activeDialog = ChallengeDialogs.createConfirmationDialog(cvh) activeDialog?.show() } else -> cvh.actionResponse(response)