Merge "Home Controls: Add settings dialog" into tm-dev
This commit is contained in:
@@ -16,4 +16,4 @@
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,12.5zM1,21L12,2l11,19zM11,15h2v-5h-2zM12,18q0.425,0 0.713,-0.288Q13,17.425 13,17t-0.287,-0.712Q12.425,16 12,16t-0.713,0.288Q11,16.575 11,17t0.287,0.712Q11.575,18 12,18zM4.45,19h15.1L12,6z"/>
|
||||
</vector>
|
||||
</vector>
|
||||
@@ -2105,6 +2105,19 @@
|
||||
<!-- Controls tile secondary label when device is locked and user does not want access to controls from lockscreen [CHAR LIMIT=20] -->
|
||||
<string name="controls_tile_locked">Device locked</string>
|
||||
|
||||
<!-- Title of the dialog to show and control devices from lock screen [CHAR LIMIT=NONE] -->
|
||||
<string name="controls_settings_show_controls_dialog_title">Show and control devices from lock screen?</string>
|
||||
<!-- Message of the dialog to show and control devices from lock screen [CHAR LIMIT=NONE] -->
|
||||
<string name="controls_settings_show_controls_dialog_message">You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes any time in Settings.</string>
|
||||
<!-- Title of the dialog to control certain devices from lock screen without auth [CHAR LIMIT=NONE] -->
|
||||
<string name="controls_settings_trivial_controls_dialog_title">Control devices from lock screen?</string>
|
||||
<!-- Message of the dialog to control certain devices from lock screen without auth [CHAR LIMIT=NONE] -->
|
||||
<string name="controls_settings_trivial_controls_dialog_message">You can control some devices without unlocking your phone or tablet.\n\nYour device app determines which devices can be controlled in this way.</string>
|
||||
<!-- Neutral button title of the controls dialog [CHAR LIMIT=NONE] -->
|
||||
<string name="controls_settings_dialog_neutral_button">No thanks</string>
|
||||
<!-- Positive button title of the controls dialog [CHAR LIMIT=NONE] -->
|
||||
<string name="controls_settings_dialog_positive_button">Yes</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] -->
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.controls.ui
|
||||
|
||||
import android.annotation.AnyThread
|
||||
import android.annotation.MainThread
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
@@ -27,7 +28,7 @@ import android.database.ContentObserver
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.VibrationEffect
|
||||
import android.provider.Settings
|
||||
import android.provider.Settings.Secure
|
||||
import android.service.controls.Control
|
||||
import android.service.controls.actions.BooleanAction
|
||||
import android.service.controls.actions.CommandAction
|
||||
@@ -35,12 +36,17 @@ import android.service.controls.actions.FloatAction
|
||||
import android.util.Log
|
||||
import android.view.HapticFeedbackConstants
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.broadcast.BroadcastSender
|
||||
import com.android.systemui.controls.ControlsMetricsLogger
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserContextProvider
|
||||
import com.android.systemui.statusbar.VibratorHelper
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog
|
||||
import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_FILE
|
||||
import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_SETTINGS_DIALOG_ATTEMPTS
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
@@ -60,6 +66,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
private val controlsMetricsLogger: ControlsMetricsLogger,
|
||||
private val vibrator: VibratorHelper,
|
||||
private val secureSettings: SecureSettings,
|
||||
private val userContextProvider: UserContextProvider,
|
||||
@Main mainHandler: Handler
|
||||
) : ControlActionCoordinator {
|
||||
private var dialog: Dialog? = null
|
||||
@@ -68,22 +75,33 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
private val isLocked: Boolean
|
||||
get() = !keyguardStateController.isUnlocked()
|
||||
private var mAllowTrivialControls: Boolean = secureSettings.getInt(
|
||||
Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
|
||||
Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
|
||||
private var mShowDeviceControlsInLockscreen: Boolean = secureSettings.getInt(
|
||||
Secure.LOCKSCREEN_SHOW_CONTROLS, 0) != 0
|
||||
override lateinit var activityContext: Context
|
||||
|
||||
companion object {
|
||||
private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
|
||||
private const val MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG = 2
|
||||
}
|
||||
|
||||
init {
|
||||
val lockScreenShowControlsUri =
|
||||
secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)
|
||||
secureSettings.getUriFor(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)
|
||||
val showControlsUri =
|
||||
secureSettings.getUriFor(Secure.LOCKSCREEN_SHOW_CONTROLS)
|
||||
val controlsContentObserver = object : ContentObserver(mainHandler) {
|
||||
override fun onChange(selfChange: Boolean, uri: Uri?) {
|
||||
super.onChange(selfChange, uri)
|
||||
if (uri == lockScreenShowControlsUri) {
|
||||
mAllowTrivialControls = secureSettings.getInt(
|
||||
Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
|
||||
when (uri) {
|
||||
lockScreenShowControlsUri -> {
|
||||
mAllowTrivialControls = secureSettings.getInt(
|
||||
Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
|
||||
}
|
||||
showControlsUri -> {
|
||||
mShowDeviceControlsInLockscreen = secureSettings
|
||||
.getInt(Secure.LOCKSCREEN_SHOW_CONTROLS, 0) != 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,6 +109,10 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
lockScreenShowControlsUri,
|
||||
false /* notifyForDescendants */, controlsContentObserver
|
||||
)
|
||||
secureSettings.registerContentObserver(
|
||||
showControlsUri,
|
||||
false /* notifyForDescendants */, controlsContentObserver
|
||||
)
|
||||
}
|
||||
|
||||
override fun closeDialogs() {
|
||||
@@ -107,9 +129,9 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
cvh.layout.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
|
||||
cvh.action(BooleanAction(templateId, !isChecked))
|
||||
},
|
||||
true /* blockable */
|
||||
),
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
true /* blockable */,
|
||||
cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -127,9 +149,9 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
cvh.action(CommandAction(templateId))
|
||||
}
|
||||
},
|
||||
blockable
|
||||
),
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
blockable /* blockable */,
|
||||
cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -147,9 +169,9 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
createAction(
|
||||
cvh.cws.ci.controlId,
|
||||
{ cvh.action(FloatAction(templateId, newValue)) },
|
||||
false /* blockable */
|
||||
),
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
false /* blockable */,
|
||||
cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -166,15 +188,16 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
showDetail(cvh, it.getAppIntent())
|
||||
}
|
||||
},
|
||||
false /* blockable */
|
||||
),
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
false /* blockable */,
|
||||
cvh.cws.control?.isAuthRequired ?: true /* authIsRequired */
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun runPendingAction(controlId: String) {
|
||||
if (isLocked) return
|
||||
if (pendingAction?.controlId == controlId) {
|
||||
showSettingsDialogIfNeeded(pendingAction!!)
|
||||
pendingAction?.invoke()
|
||||
pendingAction = null
|
||||
}
|
||||
@@ -185,12 +208,6 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
actionsInProgress.remove(controlId)
|
||||
}
|
||||
|
||||
@VisibleForTesting()
|
||||
fun isAuthRequired(cvh: ControlViewHolder, allowTrivialControls: Boolean): Boolean {
|
||||
val isAuthRequired = cvh.cws.control?.isAuthRequired ?: true
|
||||
return isAuthRequired || !allowTrivialControls
|
||||
}
|
||||
|
||||
private fun shouldRunAction(controlId: String) =
|
||||
if (actionsInProgress.add(controlId)) {
|
||||
uiExecutor.executeDelayed({
|
||||
@@ -203,7 +220,9 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
|
||||
@AnyThread
|
||||
@VisibleForTesting
|
||||
fun bouncerOrRun(action: Action, authRequired: Boolean) {
|
||||
fun bouncerOrRun(action: Action) {
|
||||
val authRequired = action.authIsRequired || !mAllowTrivialControls
|
||||
|
||||
if (keyguardStateController.isShowing() && authRequired) {
|
||||
if (isLocked) {
|
||||
broadcastSender.closeSystemDialogs()
|
||||
@@ -217,6 +236,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
true
|
||||
}, { pendingAction = null }, true /* afterKeyguardGone */)
|
||||
} else {
|
||||
showSettingsDialogIfNeeded(action)
|
||||
action.invoke()
|
||||
}
|
||||
}
|
||||
@@ -251,11 +271,88 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
fun createAction(controlId: String, f: () -> Unit, blockable: Boolean) =
|
||||
Action(controlId, f, blockable)
|
||||
private fun showSettingsDialogIfNeeded(action: Action) {
|
||||
if (action.authIsRequired) {
|
||||
return
|
||||
}
|
||||
val prefs = userContextProvider.userContext.getSharedPreferences(
|
||||
PREFS_CONTROLS_FILE, Context.MODE_PRIVATE)
|
||||
val attempts = prefs.getInt(PREFS_SETTINGS_DIALOG_ATTEMPTS, 0)
|
||||
if (attempts >= MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG ||
|
||||
(mShowDeviceControlsInLockscreen && mAllowTrivialControls)) {
|
||||
return
|
||||
}
|
||||
val builder = AlertDialog
|
||||
.Builder(activityContext, R.style.Theme_SystemUI_Dialog)
|
||||
.setIcon(R.drawable.ic_warning)
|
||||
.setOnCancelListener {
|
||||
if (attempts < MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
|
||||
prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS, attempts + 1)
|
||||
.commit()
|
||||
}
|
||||
true
|
||||
}
|
||||
.setNeutralButton(R.string.controls_settings_dialog_neutral_button) { _, _ ->
|
||||
if (attempts != MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
|
||||
prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS,
|
||||
MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG)
|
||||
.commit()
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
inner class Action(val controlId: String, val f: () -> Unit, val blockable: Boolean) {
|
||||
if (mShowDeviceControlsInLockscreen) {
|
||||
dialog = builder
|
||||
.setTitle(R.string.controls_settings_trivial_controls_dialog_title)
|
||||
.setMessage(R.string.controls_settings_trivial_controls_dialog_message)
|
||||
.setPositiveButton(R.string.controls_settings_dialog_positive_button) { _, _ ->
|
||||
if (attempts != MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
|
||||
prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS,
|
||||
MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG)
|
||||
.commit()
|
||||
}
|
||||
secureSettings.putInt(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 1)
|
||||
true
|
||||
}
|
||||
.create()
|
||||
} else {
|
||||
dialog = builder
|
||||
.setTitle(R.string.controls_settings_show_controls_dialog_title)
|
||||
.setMessage(R.string.controls_settings_show_controls_dialog_message)
|
||||
.setPositiveButton(R.string.controls_settings_dialog_positive_button) { _, _ ->
|
||||
if (attempts != MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) {
|
||||
prefs.edit().putInt(PREFS_SETTINGS_DIALOG_ATTEMPTS,
|
||||
MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG)
|
||||
.commit()
|
||||
}
|
||||
secureSettings.putInt(Secure.LOCKSCREEN_SHOW_CONTROLS, 1)
|
||||
secureSettings.putInt(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 1)
|
||||
true
|
||||
}
|
||||
.create()
|
||||
}
|
||||
|
||||
SystemUIDialog.registerDismissListener(dialog)
|
||||
SystemUIDialog.setDialogSize(dialog)
|
||||
|
||||
dialog?.create()
|
||||
dialog?.show()
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
fun createAction(
|
||||
controlId: String,
|
||||
f: () -> Unit,
|
||||
blockable: Boolean,
|
||||
authIsRequired: Boolean
|
||||
) = Action(controlId, f, blockable, authIsRequired)
|
||||
|
||||
inner class Action(
|
||||
val controlId: String,
|
||||
val f: () -> Unit,
|
||||
val blockable: Boolean,
|
||||
val authIsRequired: Boolean
|
||||
) {
|
||||
fun invoke() {
|
||||
if (!blockable || shouldRunAction(controlId)) {
|
||||
f.invoke()
|
||||
|
||||
@@ -68,6 +68,7 @@ public class DeviceControlsControllerImpl @Inject constructor(
|
||||
|
||||
internal const val PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted"
|
||||
internal const val PREFS_CONTROLS_FILE = "controls_prefs"
|
||||
internal const val PREFS_SETTINGS_DIALOG_ATTEMPTS = "show_settings_attempts"
|
||||
private const val SEEDING_MAX = 2
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.controls.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.database.ContentObserver
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
@@ -26,13 +28,14 @@ import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.broadcast.BroadcastSender
|
||||
import com.android.systemui.controls.ControlsMetricsLogger
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserContextProvider
|
||||
import com.android.systemui.statusbar.VibratorHelper
|
||||
import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
import com.android.wm.shell.TaskViewFactory
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@@ -42,6 +45,7 @@ import org.mockito.Mockito
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.Mockito.anyBoolean
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.reset
|
||||
import org.mockito.Mockito.spy
|
||||
@@ -74,6 +78,8 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
private lateinit var secureSettings: SecureSettings
|
||||
@Mock
|
||||
private lateinit var mainHandler: Handler
|
||||
@Mock
|
||||
private lateinit var userContextProvider: UserContextProvider
|
||||
|
||||
companion object {
|
||||
fun <T> any(): T = Mockito.any<T>()
|
||||
@@ -91,6 +97,8 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
`when`(secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
|
||||
.thenReturn(Settings.Secure
|
||||
.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
|
||||
`when`(secureSettings.getInt(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0))
|
||||
.thenReturn(1)
|
||||
|
||||
coordinator = spy(ControlActionCoordinatorImpl(
|
||||
mContext,
|
||||
@@ -103,15 +111,27 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
metricsLogger,
|
||||
vibratorHelper,
|
||||
secureSettings,
|
||||
mainHandler))
|
||||
userContextProvider,
|
||||
mainHandler
|
||||
))
|
||||
|
||||
val userContext = mock(Context::class.java)
|
||||
val pref = mock(SharedPreferences::class.java)
|
||||
`when`(userContextProvider.userContext).thenReturn(userContext)
|
||||
`when`(userContext.getSharedPreferences(
|
||||
DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, Context.MODE_PRIVATE))
|
||||
.thenReturn(pref)
|
||||
// Just return 2 so we don't test any Dialog logic which requires a launched activity.
|
||||
`when`(pref.getInt(DeviceControlsControllerImpl.PREFS_SETTINGS_DIALOG_ATTEMPTS, 0))
|
||||
.thenReturn(2)
|
||||
|
||||
verify(secureSettings).registerContentObserver(any(Uri::class.java),
|
||||
anyBoolean(), any(ContentObserver::class.java))
|
||||
|
||||
`when`(cvh.cws.ci.controlId).thenReturn(ID)
|
||||
`when`(cvh.cws.control?.isAuthRequired()).thenReturn(true)
|
||||
action = spy(coordinator.Action(ID, {}, false))
|
||||
doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean())
|
||||
action = spy(coordinator.Action(ID, {}, false, true))
|
||||
doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean(), anyBoolean())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -119,7 +139,7 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
`when`(keyguardStateController.isShowing()).thenReturn(false)
|
||||
|
||||
coordinator.toggle(cvh, "", true)
|
||||
verify(coordinator).bouncerOrRun(action, true /*authRequired */)
|
||||
verify(coordinator).bouncerOrRun(action)
|
||||
verify(action).invoke()
|
||||
}
|
||||
|
||||
@@ -129,7 +149,7 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
|
||||
|
||||
coordinator.toggle(cvh, "", true)
|
||||
verify(coordinator).bouncerOrRun(action, true /*authRequired */)
|
||||
verify(coordinator).bouncerOrRun(action)
|
||||
verify(activityStarter).dismissKeyguardThenExecute(any(), any(), anyBoolean())
|
||||
verify(action, never()).invoke()
|
||||
|
||||
@@ -146,25 +166,41 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testToggleRunsWhenLockedAndAuthNotRequired() {
|
||||
action = spy(coordinator.Action(ID, {}, false, false))
|
||||
doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean(), anyBoolean())
|
||||
|
||||
`when`(keyguardStateController.isShowing()).thenReturn(true)
|
||||
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
|
||||
doReturn(false).`when`(coordinator).isAuthRequired(
|
||||
any(), anyBoolean())
|
||||
|
||||
coordinator.toggle(cvh, "", true)
|
||||
|
||||
verify(coordinator).bouncerOrRun(action, false /* authRequired */)
|
||||
verify(coordinator).bouncerOrRun(action)
|
||||
verify(action).invoke()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsAuthRequired() {
|
||||
`when`(cvh.cws.control?.isAuthRequired).thenReturn(true)
|
||||
assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
|
||||
fun testToggleDoesNotRunsWhenLockedAndAuthRequired() {
|
||||
action = spy(coordinator.Action(ID, {}, false, true))
|
||||
doReturn(action).`when`(coordinator).createAction(any(), any(), anyBoolean(), anyBoolean())
|
||||
|
||||
`when`(cvh.cws.control?.isAuthRequired).thenReturn(false)
|
||||
assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
|
||||
`when`(keyguardStateController.isShowing()).thenReturn(true)
|
||||
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
|
||||
|
||||
assertThat(coordinator.isAuthRequired(cvh, true)).isFalse()
|
||||
coordinator.toggle(cvh, "", true)
|
||||
|
||||
verify(coordinator).bouncerOrRun(action)
|
||||
verify(action, never()).invoke()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNullControl() {
|
||||
`when`(cvh.cws.control).thenReturn(null)
|
||||
|
||||
`when`(keyguardStateController.isShowing()).thenReturn(true)
|
||||
|
||||
coordinator.toggle(cvh, "", true)
|
||||
|
||||
verify(coordinator).bouncerOrRun(action)
|
||||
verify(action, never()).invoke()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user