Loading packages/SystemUI/res/layout/controls_dialog_pin.xml +0 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="48dp" android:hint="@string/controls_pin_instructions" android:inputType="numberPassword" /> <CheckBox android:id="@+id/controls_pin_use_alpha" Loading packages/SystemUI/res/values/strings.xml +9 −0 Original line number Diff line number Diff line Loading @@ -2714,6 +2714,8 @@ <string name="controls_pin_use_alphanumeric">PIN contains letters or symbols</string> <!-- Controls PIN entry dialog, title [CHAR LIMIT=30] --> <string name="controls_pin_verify">Verify <xliff:g id="device" example="Backdoor lock">%s</xliff:g></string> <!-- Controls PIN entry dialog, title when 1st attempt failed [CHAR LIMIT=30] --> <string name="controls_pin_wrong">Wrong PIN</string> <!-- Controls PIN entry dialog, waiting to verify [CHAR LIMIT=30] --> <string name="controls_pin_verifying">Verifying\u2026</string> <!-- Controls PIN entry dialog, text hint [CHAR LIMIT=30] --> Loading @@ -2737,6 +2739,13 @@ <!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] --> <string name="controls_error_timeout">Inactive, check app</string> <!-- Error message indicating that an unspecified error occurred while getting the status, and a retry will be attempted [CHAR LIMIT=30] --> <string name="controls_error_retryable">Error, retrying\u2026</string> <!-- Error message indicating that the control is no longer available in the application [CHAR LIMIT=30] --> <string name="controls_error_removed">Device removed</string> <!-- Error message indicating that an unspecified error occurred while getting the status [CHAR LIMIT=30] --> <string name="controls_error_generic">Can\u2019t load status</string> <!-- Error message indicating that a control action failed [CHAR_LIMIT=30] --> <string name="controls_error_failed">Error, try again</string> <!-- Stateless control message informing the user that a routine has started [CHAR_LIMIT=30] --> Loading packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt +19 −3 Original line number Diff line number Diff line Loading @@ -47,16 +47,31 @@ object ChallengeDialogs { * [ControlAction#RESPONSE_CHALLENGE_PIN] responses, decided by the useAlphaNumeric * parameter. */ fun createPinDialog(cvh: ControlViewHolder, useAlphaNumeric: Boolean): Dialog? { fun createPinDialog( cvh: ControlViewHolder, useAlphaNumeric: Boolean, useRetryStrings: 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, STYLE).apply { val res = cvh.context.resources setTitle(res.getString(R.string.controls_pin_verify, cvh.title.getText())) val (title, instructions) = if (useRetryStrings) { Pair( res.getString(R.string.controls_pin_wrong), R.string.controls_pin_instructions_retry ) } else { Pair( res.getString(R.string.controls_pin_verify, cvh.title.getText()), R.string.controls_pin_instructions ) } val builder = AlertDialog.Builder(cvh.context, STYLE).apply { setTitle(title) setView(R.layout.controls_dialog_pin) setPositiveButton( android.R.string.ok, Loading @@ -81,6 +96,7 @@ object ChallengeDialogs { } setOnShowListener(DialogInterface.OnShowListener { _ -> val editText = requireViewById<EditText>(R.id.controls_pin_input) editText.setHint(instructions) val useAlphaCheckBox = requireViewById<CheckBox>(R.id.controls_pin_use_alpha) useAlphaCheckBox.setChecked(useAlphaNumeric) setInputType(editText, useAlphaCheckBox.isChecked()) Loading packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +37 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.controls.ui import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.app.Dialog import android.content.Context import android.graphics.drawable.ClipDrawable import android.graphics.drawable.GradientDrawable Loading Loading @@ -82,6 +83,8 @@ class ControlViewHolder( var cancelUpdate: Runnable? = null var behavior: Behavior? = null var lastAction: ControlAction? = null private var lastChallengeDialog: Dialog? = null val deviceType: Int get() = cws.control?.let { it.getDeviceType() } ?: cws.ci.deviceType var dimmed: Boolean = false Loading Loading @@ -140,7 +143,37 @@ class ControlViewHolder( } fun actionResponse(@ControlAction.ResponseResult response: Int) { // TODO: b/150931809 - handle response codes // OK responses signal normal behavior, and the app will provide control updates val failedAttempt = lastChallengeDialog != null when (response) { ControlAction.RESPONSE_OK -> lastChallengeDialog = null ControlAction.RESPONSE_UNKNOWN -> { lastChallengeDialog = null setTransientStatus(context.resources.getString(R.string.controls_error_failed)) } ControlAction.RESPONSE_FAIL -> { lastChallengeDialog = null setTransientStatus(context.resources.getString(R.string.controls_error_failed)) } ControlAction.RESPONSE_CHALLENGE_PIN -> { lastChallengeDialog = ChallengeDialogs.createPinDialog(this, false, failedAttempt) lastChallengeDialog?.show() } ControlAction.RESPONSE_CHALLENGE_PASSPHRASE -> { lastChallengeDialog = ChallengeDialogs.createPinDialog(this, true, failedAttempt) lastChallengeDialog?.show() } ControlAction.RESPONSE_CHALLENGE_ACK -> { lastChallengeDialog = ChallengeDialogs.createConfirmationDialog(this) lastChallengeDialog?.show() } } } fun dismiss() { lastChallengeDialog?.dismiss() lastChallengeDialog = null } fun setTransientStatus(tempStatus: String) { Loading @@ -166,7 +199,9 @@ class ControlViewHolder( deviceType: Int ): KClass<out Behavior> { return when { status == Control.STATUS_UNKNOWN -> UnknownBehavior::class status == Control.STATUS_UNKNOWN -> StatusBehavior::class status == Control.STATUS_ERROR -> StatusBehavior::class status == Control.STATUS_NOT_FOUND -> StatusBehavior::class deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class template is ToggleTemplate -> ToggleBehavior::class template is StatelessTemplate -> TouchBehavior::class Loading packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +6 −22 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ObjectAnimator import android.app.AlertDialog import android.app.Dialog import android.content.ComponentName import android.content.Context import android.content.DialogInterface Loading @@ -32,7 +31,6 @@ import android.graphics.drawable.LayerDrawable import android.os.Process import android.os.Vibrator import android.service.controls.Control import android.service.controls.actions.ControlAction import android.util.Log import android.util.TypedValue import android.view.ContextThemeWrapper Loading Loading @@ -101,7 +99,6 @@ class ControlsUiControllerImpl @Inject constructor ( private lateinit var parent: ViewGroup private lateinit var lastItems: List<SelectionItem> private var popup: ListPopupWindow? = null private var activeDialog: Dialog? = null private var hidden = true private lateinit var dismissGlobalActions: Runnable Loading Loading @@ -537,7 +534,11 @@ class ControlsUiControllerImpl @Inject constructor ( Log.d(ControlsUiController.TAG, "hide()") hidden = true popup?.dismissImmediate() activeDialog?.dismiss() controlViewsById.forEach { it.value.dismiss() } ControlActionCoordinator.closeDialog() controlsController.get().unsubscribe() Loading @@ -551,7 +552,6 @@ class ControlsUiControllerImpl @Inject constructor ( } override fun onRefreshState(componentName: ComponentName, controls: List<Control>) { Log.d(ControlsUiController.TAG, "onRefreshState()") controls.forEach { c -> controlsById.get(ControlKey(componentName, c.getControlId()))?.let { Log.d(ControlsUiController.TAG, "onRefreshState() for id: " + c.getControlId()) Loading @@ -569,23 +569,7 @@ class ControlsUiControllerImpl @Inject constructor ( override fun onActionResponse(componentName: ComponentName, controlId: String, response: Int) { val key = ControlKey(componentName, controlId) uiExecutor.execute { controlViewsById.get(key)?.let { cvh -> when (response) { ControlAction.RESPONSE_CHALLENGE_PIN -> { 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) } } controlViewsById.get(key)?.actionResponse(response) } } Loading Loading
packages/SystemUI/res/layout/controls_dialog_pin.xml +0 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="48dp" android:hint="@string/controls_pin_instructions" android:inputType="numberPassword" /> <CheckBox android:id="@+id/controls_pin_use_alpha" Loading
packages/SystemUI/res/values/strings.xml +9 −0 Original line number Diff line number Diff line Loading @@ -2714,6 +2714,8 @@ <string name="controls_pin_use_alphanumeric">PIN contains letters or symbols</string> <!-- Controls PIN entry dialog, title [CHAR LIMIT=30] --> <string name="controls_pin_verify">Verify <xliff:g id="device" example="Backdoor lock">%s</xliff:g></string> <!-- Controls PIN entry dialog, title when 1st attempt failed [CHAR LIMIT=30] --> <string name="controls_pin_wrong">Wrong PIN</string> <!-- Controls PIN entry dialog, waiting to verify [CHAR LIMIT=30] --> <string name="controls_pin_verifying">Verifying\u2026</string> <!-- Controls PIN entry dialog, text hint [CHAR LIMIT=30] --> Loading @@ -2737,6 +2739,13 @@ <!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] --> <string name="controls_error_timeout">Inactive, check app</string> <!-- Error message indicating that an unspecified error occurred while getting the status, and a retry will be attempted [CHAR LIMIT=30] --> <string name="controls_error_retryable">Error, retrying\u2026</string> <!-- Error message indicating that the control is no longer available in the application [CHAR LIMIT=30] --> <string name="controls_error_removed">Device removed</string> <!-- Error message indicating that an unspecified error occurred while getting the status [CHAR LIMIT=30] --> <string name="controls_error_generic">Can\u2019t load status</string> <!-- Error message indicating that a control action failed [CHAR_LIMIT=30] --> <string name="controls_error_failed">Error, try again</string> <!-- Stateless control message informing the user that a routine has started [CHAR_LIMIT=30] --> Loading
packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt +19 −3 Original line number Diff line number Diff line Loading @@ -47,16 +47,31 @@ object ChallengeDialogs { * [ControlAction#RESPONSE_CHALLENGE_PIN] responses, decided by the useAlphaNumeric * parameter. */ fun createPinDialog(cvh: ControlViewHolder, useAlphaNumeric: Boolean): Dialog? { fun createPinDialog( cvh: ControlViewHolder, useAlphaNumeric: Boolean, useRetryStrings: 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, STYLE).apply { val res = cvh.context.resources setTitle(res.getString(R.string.controls_pin_verify, cvh.title.getText())) val (title, instructions) = if (useRetryStrings) { Pair( res.getString(R.string.controls_pin_wrong), R.string.controls_pin_instructions_retry ) } else { Pair( res.getString(R.string.controls_pin_verify, cvh.title.getText()), R.string.controls_pin_instructions ) } val builder = AlertDialog.Builder(cvh.context, STYLE).apply { setTitle(title) setView(R.layout.controls_dialog_pin) setPositiveButton( android.R.string.ok, Loading @@ -81,6 +96,7 @@ object ChallengeDialogs { } setOnShowListener(DialogInterface.OnShowListener { _ -> val editText = requireViewById<EditText>(R.id.controls_pin_input) editText.setHint(instructions) val useAlphaCheckBox = requireViewById<CheckBox>(R.id.controls_pin_use_alpha) useAlphaCheckBox.setChecked(useAlphaNumeric) setInputType(editText, useAlphaCheckBox.isChecked()) Loading
packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +37 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.controls.ui import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.app.Dialog import android.content.Context import android.graphics.drawable.ClipDrawable import android.graphics.drawable.GradientDrawable Loading Loading @@ -82,6 +83,8 @@ class ControlViewHolder( var cancelUpdate: Runnable? = null var behavior: Behavior? = null var lastAction: ControlAction? = null private var lastChallengeDialog: Dialog? = null val deviceType: Int get() = cws.control?.let { it.getDeviceType() } ?: cws.ci.deviceType var dimmed: Boolean = false Loading Loading @@ -140,7 +143,37 @@ class ControlViewHolder( } fun actionResponse(@ControlAction.ResponseResult response: Int) { // TODO: b/150931809 - handle response codes // OK responses signal normal behavior, and the app will provide control updates val failedAttempt = lastChallengeDialog != null when (response) { ControlAction.RESPONSE_OK -> lastChallengeDialog = null ControlAction.RESPONSE_UNKNOWN -> { lastChallengeDialog = null setTransientStatus(context.resources.getString(R.string.controls_error_failed)) } ControlAction.RESPONSE_FAIL -> { lastChallengeDialog = null setTransientStatus(context.resources.getString(R.string.controls_error_failed)) } ControlAction.RESPONSE_CHALLENGE_PIN -> { lastChallengeDialog = ChallengeDialogs.createPinDialog(this, false, failedAttempt) lastChallengeDialog?.show() } ControlAction.RESPONSE_CHALLENGE_PASSPHRASE -> { lastChallengeDialog = ChallengeDialogs.createPinDialog(this, true, failedAttempt) lastChallengeDialog?.show() } ControlAction.RESPONSE_CHALLENGE_ACK -> { lastChallengeDialog = ChallengeDialogs.createConfirmationDialog(this) lastChallengeDialog?.show() } } } fun dismiss() { lastChallengeDialog?.dismiss() lastChallengeDialog = null } fun setTransientStatus(tempStatus: String) { Loading @@ -166,7 +199,9 @@ class ControlViewHolder( deviceType: Int ): KClass<out Behavior> { return when { status == Control.STATUS_UNKNOWN -> UnknownBehavior::class status == Control.STATUS_UNKNOWN -> StatusBehavior::class status == Control.STATUS_ERROR -> StatusBehavior::class status == Control.STATUS_NOT_FOUND -> StatusBehavior::class deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class template is ToggleTemplate -> ToggleBehavior::class template is StatelessTemplate -> TouchBehavior::class Loading
packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +6 −22 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ObjectAnimator import android.app.AlertDialog import android.app.Dialog import android.content.ComponentName import android.content.Context import android.content.DialogInterface Loading @@ -32,7 +31,6 @@ import android.graphics.drawable.LayerDrawable import android.os.Process import android.os.Vibrator import android.service.controls.Control import android.service.controls.actions.ControlAction import android.util.Log import android.util.TypedValue import android.view.ContextThemeWrapper Loading Loading @@ -101,7 +99,6 @@ class ControlsUiControllerImpl @Inject constructor ( private lateinit var parent: ViewGroup private lateinit var lastItems: List<SelectionItem> private var popup: ListPopupWindow? = null private var activeDialog: Dialog? = null private var hidden = true private lateinit var dismissGlobalActions: Runnable Loading Loading @@ -537,7 +534,11 @@ class ControlsUiControllerImpl @Inject constructor ( Log.d(ControlsUiController.TAG, "hide()") hidden = true popup?.dismissImmediate() activeDialog?.dismiss() controlViewsById.forEach { it.value.dismiss() } ControlActionCoordinator.closeDialog() controlsController.get().unsubscribe() Loading @@ -551,7 +552,6 @@ class ControlsUiControllerImpl @Inject constructor ( } override fun onRefreshState(componentName: ComponentName, controls: List<Control>) { Log.d(ControlsUiController.TAG, "onRefreshState()") controls.forEach { c -> controlsById.get(ControlKey(componentName, c.getControlId()))?.let { Log.d(ControlsUiController.TAG, "onRefreshState() for id: " + c.getControlId()) Loading @@ -569,23 +569,7 @@ class ControlsUiControllerImpl @Inject constructor ( override fun onActionResponse(componentName: ComponentName, controlId: String, response: Int) { val key = ControlKey(componentName, controlId) uiExecutor.execute { controlViewsById.get(key)?.let { cvh -> when (response) { ControlAction.RESPONSE_CHALLENGE_PIN -> { 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) } } controlViewsById.get(key)?.actionResponse(response) } } Loading