summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt131
4 files changed, 110 insertions, 46 deletions
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3b42600076ac..70e8b8946ae6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2717,6 +2717,9 @@
<!-- Controls dialog confirmation [CHAR LIMIT=30] -->
<string name="controls_dialog_confirmation">Controls updated</string>
+ <!-- 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>
+
<!-- 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] -->
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
index 36937d622b5b..6b7a1ac8cb7e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
@@ -91,7 +91,7 @@ class ControlsComponent @Inject constructor(
}
/**
- * @return true if controls are feature-enabled and have available services to serve controls
+ * @return true if controls are feature-enabled and the user has the setting enabled
*/
fun isEnabled() = featureEnabled && lazyControlsController.get().available
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index 41445917a011..3b9f5dc8ea03 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -25,7 +25,7 @@ import com.android.internal.logging.MetricsLogger
import com.android.systemui.R
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.dagger.ControlsComponent
-import com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE
+import com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE
import com.android.systemui.controls.management.ControlsListingController
import com.android.systemui.controls.ui.ControlsDialog
import com.android.systemui.dagger.qualifiers.Background
@@ -92,7 +92,7 @@ class DeviceControlsTile @Inject constructor(
override fun isAvailable(): Boolean {
return featureFlags.isKeyguardLayoutEnabled &&
controlsLockscreen &&
- controlsComponent.getVisibility() != UNAVAILABLE
+ controlsComponent.getControlsController().isPresent
}
override fun newTileState(): QSTile.State {
@@ -119,7 +119,7 @@ class DeviceControlsTile @Inject constructor(
}
override fun handleClick() {
- if (state.state != Tile.STATE_UNAVAILABLE) {
+ if (state.state == Tile.STATE_ACTIVE) {
mUiHandler.post {
createDialog()
controlsDialog?.show(controlsComponent.getControlsUiController().get())
@@ -129,15 +129,21 @@ class DeviceControlsTile @Inject constructor(
override fun handleUpdateState(state: QSTile.State, arg: Any?) {
state.label = tileLabel
- state.secondaryLabel = ""
- state.stateDescription = ""
+
state.contentDescription = state.label
state.icon = icon
- if (hasControlsApps.get()) {
- state.state = Tile.STATE_ACTIVE
+ if (controlsComponent.isEnabled() && hasControlsApps.get()) {
if (controlsDialog == null) {
mUiHandler.post(this::createDialog)
}
+ if (controlsComponent.getVisibility() == AVAILABLE) {
+ state.state = Tile.STATE_ACTIVE
+ state.secondaryLabel = ""
+ } else {
+ state.state = Tile.STATE_INACTIVE
+ state.secondaryLabel = mContext.getText(R.string.controls_tile_locked)
+ }
+ state.stateDescription = state.secondaryLabel
} else {
state.state = Tile.STATE_UNAVAILABLE
dismissDialog()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index d3dbe2bf7d2b..ccd9548b269f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -25,7 +25,6 @@ import androidx.lifecycle.LifecycleOwner
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
-import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.controller.ControlsController
@@ -37,9 +36,7 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
-import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.FeatureFlags
-import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.settings.FakeSettings
@@ -49,7 +46,6 @@ import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Answers
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
@@ -57,6 +53,7 @@ import org.mockito.Mockito.`when`
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import java.util.Optional
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -73,6 +70,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
private lateinit var activityStarter: ActivityStarter
@Mock
private lateinit var qsLogger: QSLogger
+ @Mock
private lateinit var controlsComponent: ControlsComponent
@Mock
private lateinit var controlsUiController: ControlsUiController
@@ -96,54 +94,64 @@ class DeviceControlsTileTest : SysuiTestCase() {
private lateinit var testableLooper: TestableLooper
private lateinit var tile: DeviceControlsTile
- @Mock
- private lateinit var keyguardStateController: KeyguardStateController
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private lateinit var userTracker: UserTracker
- @Mock
- private lateinit var lockPatternUtils: LockPatternUtils
- @Mock
private lateinit var secureSettings: SecureSettings
+ private var featureEnabled = true
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
+ secureSettings = FakeSettings()
`when`(qsHost.context).thenReturn(mContext)
`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+ `when`(controlsController.available).thenReturn(true)
+ `when`(controlsComponent.isEnabled()).thenReturn(true)
+ secureSettings.putInt(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT, 1)
- controlsComponent = ControlsComponent(
- true,
- mContext,
- { controlsController },
- { controlsUiController },
- { controlsListingController },
- lockPatternUtils,
- keyguardStateController,
- userTracker,
- secureSettings
- )
+ setupControlsComponent()
globalSettings = FakeSettings()
globalSettings.putInt(DeviceControlsTile.SETTINGS_FLAG, 1)
`when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(true)
- `when`(userTracker.userHandle.identifier).thenReturn(0)
-
tile = createTile()
}
+ private fun setupControlsComponent() {
+ `when`(controlsComponent.getControlsController()).thenAnswer {
+ if (featureEnabled) {
+ Optional.of(controlsController)
+ } else {
+ Optional.empty()
+ }
+ }
+
+ `when`(controlsComponent.getControlsListingController()).thenAnswer {
+ if (featureEnabled) {
+ Optional.of(controlsListingController)
+ } else {
+ Optional.empty()
+ }
+ }
+
+ `when`(controlsComponent.getControlsUiController()).thenAnswer {
+ if (featureEnabled) {
+ Optional.of(controlsUiController)
+ } else {
+ Optional.empty()
+ }
+ }
+ }
+
@Test
fun testAvailable() {
- `when`(controlsController.available).thenReturn(true)
assertThat(tile.isAvailable).isTrue()
}
@Test
fun testNotAvailableFeature() {
- `when`(controlsController.available).thenReturn(true)
`when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(false)
assertThat(tile.isAvailable).isFalse()
@@ -151,24 +159,22 @@ class DeviceControlsTileTest : SysuiTestCase() {
@Test
fun testNotAvailableControls() {
- controlsComponent = ControlsComponent(
- false,
- mContext,
- { controlsController },
- { controlsUiController },
- { controlsListingController },
- lockPatternUtils,
- keyguardStateController,
- userTracker,
- secureSettings
- )
+ featureEnabled = false
tile = createTile()
assertThat(tile.isAvailable).isFalse()
}
@Test
- fun testNotAvailableFlag() {
+ fun testAvailableControlsSettingOff() {
+ `when`(controlsController.available).thenReturn(false)
+
+ tile = createTile()
+ assertThat(tile.isAvailable).isTrue()
+ }
+
+ @Test
+ fun testNotAvailableControlsLockscreenFlag() {
globalSettings.putInt(DeviceControlsTile.SETTINGS_FLAG, 0)
tile = createTile()
@@ -207,11 +213,26 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
+ fun testStateUnavailableIfNotEnabled() {
+ verify(controlsListingController).observe(
+ any(LifecycleOwner::class.java),
+ capture(listingCallbackCaptor)
+ )
+ `when`(controlsComponent.isEnabled()).thenReturn(false)
+
+ listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
+ testableLooper.processAllMessages()
+
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_UNAVAILABLE)
+ }
+
+ @Test
fun testStateAvailableIfListings() {
verify(controlsListingController).observe(
any(LifecycleOwner::class.java),
capture(listingCallbackCaptor)
)
+ `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
testableLooper.processAllMessages()
@@ -220,6 +241,21 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
+ fun testStateInactiveIfLocked() {
+ verify(controlsListingController).observe(
+ any(LifecycleOwner::class.java),
+ capture(listingCallbackCaptor)
+ )
+ `when`(controlsComponent.getVisibility())
+ .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)
+
+ listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
+ testableLooper.processAllMessages()
+
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
+ }
+
+ @Test
fun testMoveBetweenStates() {
verify(controlsListingController).observe(
any(LifecycleOwner::class.java),
@@ -249,6 +285,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
any(LifecycleOwner::class.java),
capture(listingCallbackCaptor)
)
+ `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE)
listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
testableLooper.processAllMessages()
@@ -260,6 +297,24 @@ class DeviceControlsTileTest : SysuiTestCase() {
}
@Test
+ fun testNoDialogWhenInactive() {
+ verify(controlsListingController).observe(
+ any(LifecycleOwner::class.java),
+ capture(listingCallbackCaptor)
+ )
+ `when`(controlsComponent.getVisibility())
+ .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK)
+
+ listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
+ testableLooper.processAllMessages()
+
+ tile.click()
+ testableLooper.processAllMessages()
+
+ verify(controlsDialog, never()).show(any(ControlsUiController::class.java))
+ }
+
+ @Test
fun testDialogDismissedOnDestroy() {
verify(controlsListingController).observe(
any(LifecycleOwner::class.java),