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

Commit 0281bb3c authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Controls UI - Add PIN dialog" into rvc-dev am: 3f164ee5 am: 020725c6 am: 675d9c32

Change-Id: I7f8b230e58e6dfdd8cf431bcf92d08149609396f
parents cb6d63a4 675d9c32
Loading
Loading
Loading
Loading
+36 −0
Original line number Original line Diff line number Diff line
<!--
  ~ Copyright (C) 2020 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.
  -->

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingLeft="?android:attr/dialogPreferredPadding"
    android:paddingRight="?android:attr/dialogPreferredPadding">
  <EditText
      android:id="@+id/controls_pin_input"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="@string/controls_pin_instructions"
      android:inputType="numberPassword" />
  <CheckBox
      android:id="@+id/controls_pin_use_alpha"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginTop="5dp"
      android:text="@string/controls_pin_use_alphanumeric" />
</LinearLayout>
+7 −0
Original line number Original line Diff line number Diff line
@@ -2646,4 +2646,11 @@
    <string name="controls_dialog_ok">Add to favorites</string>
    <string name="controls_dialog_ok">Add to favorites</string>
    <!-- Controls dialog message [CHAR LIMIT=NONE] -->
    <!-- Controls dialog message [CHAR LIMIT=NONE] -->
    <string name="controls_dialog_message"><xliff:g id="app" example="System UI">%s</xliff:g> suggested this control to add to your favorites.</string>
    <string name="controls_dialog_message"><xliff:g id="app" example="System UI">%s</xliff:g> suggested this control to add to your favorites.</string>

    <!-- Controls PIN entry dialog, switch to alphanumeric keyboard [CHAR LIMIT=100] -->
    <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 device PIN</string>
    <!-- Controls PIN entry dialog, text hint [CHAR LIMIT=30] -->
    <string name="controls_pin_instructions">Enter PIN</string>
</resources>
</resources>
+102 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 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.systemui.controls.ui

import android.app.AlertDialog
import android.app.Dialog
import android.content.DialogInterface
import android.service.controls.actions.BooleanAction
import android.service.controls.actions.CommandAction
import android.service.controls.actions.ControlAction
import android.service.controls.actions.FloatAction
import android.service.controls.actions.ModeAction
import android.text.InputType
import android.util.Log
import android.view.WindowManager
import android.widget.CheckBox
import android.widget.EditText

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}.
 */
object ChallengeDialogs {

    fun createPinDialog(cvh: ControlViewHolder): 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 {
            setTitle(R.string.controls_pin_verify)
            setView(R.layout.controls_dialog_pin)
            setPositiveButton(
                android.R.string.ok,
                DialogInterface.OnClickListener { dialog, _ ->
                    if (dialog is Dialog) {
                        dialog.requireViewById<EditText>(R.id.controls_pin_input)
                        val pin = dialog.requireViewById<EditText>(R.id.controls_pin_input)
                            .getText().toString()
                        cvh.action(addChallengeValue(lastAction, pin))
                        dialog.dismiss()
                    }
            })
            setNegativeButton(
                android.R.string.cancel,
                DialogInterface.OnClickListener { dialog, _ -> dialog.cancel() }
            )
        }
        return builder.create().apply {
            getWindow().apply {
                setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
                setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
            }
            setOnShowListener(DialogInterface.OnShowListener { _ ->
                val editText = requireViewById<EditText>(R.id.controls_pin_input)
                requireViewById<CheckBox>(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)
                    }
                }
                editText.requestFocus()
            })
        }
    }

    private fun addChallengeValue(action: ControlAction, challengeValue: String): ControlAction {
        val id = action.getTemplateId()
        return when (action) {
            is BooleanAction -> BooleanAction(id, action.getNewState(), challengeValue)
            is FloatAction -> FloatAction(id, action.getNewValue(), challengeValue)
            is CommandAction -> CommandAction(id, challengeValue)
            is ModeAction -> ModeAction(id, action.getNewMode(), challengeValue)
            else -> throw IllegalStateException("'action' is not a known type: $action")
        }
    }
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -27,7 +27,6 @@ import android.service.controls.templates.ControlTemplate
import android.service.controls.templates.TemperatureControlTemplate
import android.service.controls.templates.TemperatureControlTemplate
import android.service.controls.templates.ToggleRangeTemplate
import android.service.controls.templates.ToggleRangeTemplate
import android.service.controls.templates.ToggleTemplate
import android.service.controls.templates.ToggleTemplate
import android.util.Log
import android.view.View
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ImageView
@@ -57,6 +56,7 @@ class ControlViewHolder(
    lateinit var cws: ControlWithState
    lateinit var cws: ControlWithState
    var cancelUpdate: Runnable? = null
    var cancelUpdate: Runnable? = null
    var behavior: Behavior? = null
    var behavior: Behavior? = null
    var lastAction: ControlAction? = null


    init {
    init {
        val ld = layout.getBackground() as LayerDrawable
        val ld = layout.getBackground() as LayerDrawable
@@ -98,7 +98,6 @@ class ControlViewHolder(


    fun actionResponse(@ControlAction.ResponseResult response: Int) {
    fun actionResponse(@ControlAction.ResponseResult response: Int) {
        // TODO: b/150931809 - handle response codes
        // TODO: b/150931809 - handle response codes
        Log.d(ControlsUiController.TAG, "Received response code: $response")
    }
    }


    fun setTransientStatus(tempStatus: String) {
    fun setTransientStatus(tempStatus: String) {
@@ -115,6 +114,7 @@ class ControlViewHolder(
    }
    }


    fun action(action: ControlAction) {
    fun action(action: ControlAction) {
        lastAction = action
        controlsController.action(cws.componentName, cws.ci, action)
        controlsController.action(cws.componentName, cws.ci, action)
    }
    }


+14 −3
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.controls.ui


import android.accounts.Account
import android.accounts.Account
import android.accounts.AccountManager
import android.accounts.AccountManager
import android.app.Dialog
import android.content.ComponentName
import android.content.ComponentName
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
@@ -28,6 +29,7 @@ import android.graphics.drawable.LayerDrawable
import android.os.IBinder
import android.os.IBinder
import android.service.controls.Control
import android.service.controls.Control
import android.service.controls.TokenProvider
import android.service.controls.TokenProvider
import android.service.controls.actions.ControlAction
import android.util.Log
import android.util.Log
import android.view.ContextThemeWrapper
import android.view.ContextThemeWrapper
import android.view.LayoutInflater
import android.view.LayoutInflater
@@ -49,8 +51,8 @@ import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.management.ControlsProviderSelectorActivity
import com.android.systemui.controls.management.ControlsProviderSelectorActivity
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.R
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.R


import dagger.Lazy
import dagger.Lazy


@@ -152,7 +154,7 @@ class ControlsUiControllerImpl @Inject constructor (
    private lateinit var parent: ViewGroup
    private lateinit var parent: ViewGroup
    private lateinit var lastItems: List<SelectionItem>
    private lateinit var lastItems: List<SelectionItem>
    private var popup: ListPopupWindow? = null
    private var popup: ListPopupWindow? = null

    private var activeDialog: Dialog? = null
    private val addControlsItem: SelectionItem
    private val addControlsItem: SelectionItem


    init {
    init {
@@ -388,6 +390,7 @@ class ControlsUiControllerImpl @Inject constructor (
    override fun hide() {
    override fun hide() {
        Log.d(ControlsUiController.TAG, "hide()")
        Log.d(ControlsUiController.TAG, "hide()")
        popup?.dismiss()
        popup?.dismiss()
        activeDialog?.dismiss()


        controlsController.get().unsubscribe()
        controlsController.get().unsubscribe()
        context.unbindService(tokenProviderConnection)
        context.unbindService(tokenProviderConnection)
@@ -418,7 +421,15 @@ class ControlsUiControllerImpl @Inject constructor (
    override fun onActionResponse(componentName: ComponentName, controlId: String, response: Int) {
    override fun onActionResponse(componentName: ComponentName, controlId: String, response: Int) {
        val key = ControlKey(componentName, controlId)
        val key = ControlKey(componentName, controlId)
        uiExecutor.execute {
        uiExecutor.execute {
            controlViewsById.get(key)?.actionResponse(response)
            controlViewsById.get(key)?.let { cvh ->
                when (response) {
                    ControlAction.RESPONSE_CHALLENGE_PIN -> {
                        activeDialog = ChallengeDialogs.createPinDialog(cvh)
                        activeDialog?.show()
                    }
                    else -> cvh.actionResponse(response)
                }
            }
        }
        }
    }
    }