Home Controls: Add Device Controls settings
Add a KEY for the settings and apply the associated business logic. Fixes: 216102581 Test: Manual Change-Id: Ic66cd0a865044c602bf7f5364abd726e445c9386
This commit is contained in:
@@ -9949,6 +9949,14 @@ public final class Settings {
|
||||
*/
|
||||
public static final String LOCKSCREEN_SHOW_CONTROLS = "lockscreen_show_controls";
|
||||
|
||||
/**
|
||||
* Whether trivial home controls can be used without authentication
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS =
|
||||
"lockscreen_allow_trivial_controls";
|
||||
|
||||
/**
|
||||
* Whether wallet should be accessible from the lockscreen
|
||||
*
|
||||
|
||||
@@ -193,6 +193,7 @@ public class SecureSettings {
|
||||
Settings.Secure.NOTIFICATION_BUBBLES,
|
||||
Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
|
||||
Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
|
||||
Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS,
|
||||
Settings.Secure.LOCKSCREEN_SHOW_WALLET,
|
||||
Settings.Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER,
|
||||
Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
|
||||
|
||||
@@ -152,6 +152,7 @@ public class SecureSettingsValidators {
|
||||
VALIDATORS.put(Secure.CONTROLS_ENABLED, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Secure.POWER_MENU_LOCKED_SHOW_CONTENT, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Secure.LOCKSCREEN_SHOW_CONTROLS, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Secure.LOCKSCREEN_SHOW_WALLET, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER, BOOLEAN_VALIDATOR);
|
||||
VALIDATORS.put(Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, BOOLEAN_VALIDATOR);
|
||||
|
||||
@@ -23,7 +23,11 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.database.ContentObserver
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.os.VibrationEffect
|
||||
import android.provider.Settings
|
||||
import android.service.controls.Control
|
||||
import android.service.controls.actions.BooleanAction
|
||||
import android.service.controls.actions.CommandAction
|
||||
@@ -38,6 +42,7 @@ import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.statusbar.VibratorHelper
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
import com.android.wm.shell.TaskViewFactory
|
||||
import java.util.Optional
|
||||
import javax.inject.Inject
|
||||
@@ -51,19 +56,41 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
private val keyguardStateController: KeyguardStateController,
|
||||
private val taskViewFactory: Optional<TaskViewFactory>,
|
||||
private val controlsMetricsLogger: ControlsMetricsLogger,
|
||||
private val vibrator: VibratorHelper
|
||||
private val vibrator: VibratorHelper,
|
||||
private val secureSettings: SecureSettings,
|
||||
@Main mainHandler: Handler
|
||||
) : ControlActionCoordinator {
|
||||
private var dialog: Dialog? = null
|
||||
private var pendingAction: Action? = null
|
||||
private var actionsInProgress = mutableSetOf<String>()
|
||||
private val isLocked: Boolean
|
||||
get() = !keyguardStateController.isUnlocked()
|
||||
private var mAllowTrivialControls: Boolean = secureSettings.getInt(
|
||||
Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
|
||||
override lateinit var activityContext: Context
|
||||
|
||||
companion object {
|
||||
private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
|
||||
}
|
||||
|
||||
init {
|
||||
val lockScreenShowControlsUri =
|
||||
secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_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
|
||||
}
|
||||
}
|
||||
}
|
||||
secureSettings.registerContentObserver(
|
||||
lockScreenShowControlsUri,
|
||||
false /* notifyForDescendants */, controlsContentObserver
|
||||
)
|
||||
}
|
||||
|
||||
override fun closeDialogs() {
|
||||
dialog?.dismiss()
|
||||
dialog = null
|
||||
@@ -80,7 +107,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
},
|
||||
true /* blockable */
|
||||
),
|
||||
isAuthRequired(cvh)
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -100,7 +127,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
},
|
||||
blockable
|
||||
),
|
||||
isAuthRequired(cvh)
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -120,7 +147,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
{ cvh.action(FloatAction(templateId, newValue)) },
|
||||
false /* blockable */
|
||||
),
|
||||
isAuthRequired(cvh)
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -139,7 +166,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
},
|
||||
false /* blockable */
|
||||
),
|
||||
isAuthRequired(cvh)
|
||||
isAuthRequired(cvh, mAllowTrivialControls)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -156,7 +183,11 @@ class ControlActionCoordinatorImpl @Inject constructor(
|
||||
actionsInProgress.remove(controlId)
|
||||
}
|
||||
|
||||
private fun isAuthRequired(cvh: ControlViewHolder) = cvh.cws.control?.isAuthRequired() ?: true
|
||||
@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)) {
|
||||
|
||||
@@ -16,15 +16,22 @@
|
||||
|
||||
package com.android.systemui.controls.ui
|
||||
|
||||
import android.database.ContentObserver
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import android.provider.Settings
|
||||
import android.test.suitebuilder.annotation.SmallTest
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.controls.ControlsMetricsLogger
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.statusbar.VibratorHelper
|
||||
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
|
||||
@@ -44,7 +51,6 @@ import java.util.Optional
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
|
||||
@Mock
|
||||
private lateinit var vibratorHelper: VibratorHelper
|
||||
@Mock
|
||||
@@ -61,6 +67,10 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
private lateinit var cvh: ControlViewHolder
|
||||
@Mock
|
||||
private lateinit var metricsLogger: ControlsMetricsLogger
|
||||
@Mock
|
||||
private lateinit var secureSettings: SecureSettings
|
||||
@Mock
|
||||
private lateinit var mainHandler: Handler
|
||||
|
||||
companion object {
|
||||
fun <T> any(): T = Mockito.any<T>()
|
||||
@@ -75,16 +85,24 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
`when`(secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
|
||||
.thenReturn(Settings.Secure
|
||||
.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
|
||||
|
||||
coordinator = spy(ControlActionCoordinatorImpl(
|
||||
mContext,
|
||||
bgExecutor,
|
||||
uiExecutor,
|
||||
activityStarter,
|
||||
keyguardStateController,
|
||||
taskViewFactory,
|
||||
metricsLogger,
|
||||
vibratorHelper
|
||||
))
|
||||
mContext,
|
||||
bgExecutor,
|
||||
uiExecutor,
|
||||
activityStarter,
|
||||
keyguardStateController,
|
||||
taskViewFactory,
|
||||
metricsLogger,
|
||||
vibratorHelper,
|
||||
secureSettings,
|
||||
mainHandler))
|
||||
|
||||
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)
|
||||
@@ -126,10 +144,23 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
|
||||
fun testToggleRunsWhenLockedAndAuthNotRequired() {
|
||||
`when`(keyguardStateController.isShowing()).thenReturn(true)
|
||||
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
|
||||
`when`(cvh.cws.control?.isAuthRequired()).thenReturn(false)
|
||||
doReturn(false).`when`(coordinator).isAuthRequired(
|
||||
any(), anyBoolean())
|
||||
|
||||
coordinator.toggle(cvh, "", true)
|
||||
|
||||
verify(coordinator).bouncerOrRun(action, false /* authRequired */)
|
||||
verify(action).invoke()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsAuthRequired() {
|
||||
`when`(cvh.cws.control?.isAuthRequired).thenReturn(true)
|
||||
assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
|
||||
|
||||
`when`(cvh.cws.control?.isAuthRequired).thenReturn(false)
|
||||
assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
|
||||
|
||||
assertThat(coordinator.isAuthRequired(cvh, true)).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user