Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt +93 −112 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import androidx.lifecycle.LifecycleOwner import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityTransitionAnimator import com.android.systemui.classifier.FalsingManagerFake Loading @@ -45,13 +44,14 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.res.R import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.settings.SecureSettings import com.google.common.truth.Truth.assertThat import java.util.Optional import org.junit.After import org.junit.Before import org.junit.Test Loading @@ -67,40 +67,27 @@ import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations import java.util.Optional @SmallTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) class DeviceControlsTileTest : SysuiTestCase() { @Mock private lateinit var qsHost: QSHost @Mock private lateinit var metricsLogger: MetricsLogger @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var qsLogger: QSLogger @Mock private lateinit var controlsComponent: ControlsComponent @Mock private lateinit var controlsUiController: ControlsUiController @Mock private lateinit var controlsListingController: ControlsListingController @Mock private lateinit var controlsController: ControlsController @Mock private lateinit var serviceInfo: ControlsServiceInfo @Mock private lateinit var uiEventLogger: QsEventLogger @Mock private lateinit var qsHost: QSHost @Mock private lateinit var metricsLogger: MetricsLogger @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var qsLogger: QSLogger @Mock private lateinit var controlsComponent: ControlsComponent @Mock private lateinit var controlsUiController: ControlsUiController @Mock private lateinit var controlsListingController: ControlsListingController @Mock private lateinit var controlsController: ControlsController @Mock private lateinit var serviceInfo: ControlsServiceInfo @Mock private lateinit var uiEventLogger: QsEventLogger @Captor private lateinit var listingCallbackCaptor: ArgumentCaptor<ControlsListingController.ControlsListingCallback> @Captor private lateinit var intentCaptor: ArgumentCaptor<Intent> @Captor private lateinit var intentCaptor: ArgumentCaptor<Intent> private lateinit var testableLooper: TestableLooper private lateinit var tile: DeviceControlsTile Loading @@ -120,8 +107,11 @@ class DeviceControlsTileTest : SysuiTestCase() { `when`(qsHost.context).thenReturn(spiedContext) `when`(controlsComponent.isEnabled()).thenReturn(true) `when`(controlsController.getPreferredSelection()) .thenReturn(SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))) .thenReturn( SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()) ) ) secureSettings.putInt(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS, 1) setupControlsComponent() Loading Loading @@ -182,9 +172,10 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testObservingCallback() { verify(controlsListingController).observe( verify(controlsListingController) .observe( any(LifecycleOwner::class.java), any(ControlsListingController.ControlsListingCallback::class.java) any(ControlsListingController.ControlsListingCallback::class.java), ) } Loading @@ -205,10 +196,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateUnavailableIfNoListings() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) listingCallbackCaptor.value.onServicesUpdated(emptyList()) testableLooper.processAllMessages() Loading @@ -218,10 +207,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateUnavailableIfNotEnabled() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.isEnabled()).thenReturn(false) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -232,17 +219,18 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateActiveIfListingsHasControlsFavorited() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsController.getPreferredSelection()).thenReturn( SelectedItem.StructureItem(StructureInfo( `when`(controlsController.getPreferredSelection()) .thenReturn( SelectedItem.StructureItem( StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) )) listOf(ControlInfo("id", "title", "subtitle", 1)), ) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -253,14 +241,15 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateInactiveIfListingsHasNoControlsFavorited() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsController.getPreferredSelection()) .thenReturn(SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))) .thenReturn( SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) testableLooper.processAllMessages() Loading @@ -270,10 +259,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateActiveIfPreferredIsPanel() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsController.getPreferredSelection()) .thenReturn(SelectedItem.PanelItem("appName", ComponentName("pkg", "cls"))) Loading @@ -286,10 +273,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateInactiveIfLocked() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()) .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK) Loading @@ -301,10 +286,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testMoveBetweenStates() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) testableLooper.processAllMessages() Loading @@ -325,18 +308,19 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun handleClick_available_shownOverLockscreenWhenLocked() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java) `when`(controlsController.getPreferredSelection()).thenReturn( SelectedItem.StructureItem(StructureInfo( `when`(controlsController.getPreferredSelection()) .thenReturn( SelectedItem.StructureItem( StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) )) listOf(ControlInfo("id", "title", "subtitle", 1)), ) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -345,29 +329,32 @@ class DeviceControlsTileTest : SysuiTestCase() { tile.click(null /* view */) testableLooper.processAllMessages() verify(activityStarter).startActivity( verify(activityStarter) .startActivity( intentCaptor.capture(), eq(true) /* dismissShade */, nullable(ActivityTransitionAnimator.Controller::class.java), eq(true) /* showOverLockscreenWhenLocked */) eq(true), /* showOverLockscreenWhenLocked */ ) assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) } @Test fun handleClick_availableAfterUnlock_notShownOverLockscreenWhenLocked() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()) .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK) `when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java) `when`(controlsController.getPreferredSelection()).thenReturn( SelectedItem.StructureItem(StructureInfo( `when`(controlsController.getPreferredSelection()) .thenReturn( SelectedItem.StructureItem( StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) )) listOf(ControlInfo("id", "title", "subtitle", 1)), ) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -376,26 +363,19 @@ class DeviceControlsTileTest : SysuiTestCase() { tile.click(null /* view */) testableLooper.processAllMessages() verify(activityStarter).startActivity( verify(activityStarter) .startActivity( intentCaptor.capture(), anyBoolean() /* dismissShade */, nullable(ActivityTransitionAnimator.Controller::class.java), eq(false) /* showOverLockscreenWhenLocked */) eq(false), /* showOverLockscreenWhenLocked */ ) assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) } @Test fun verifyTileEqualsResourceFromComponent() { assertThat(tile.tileLabel) .isEqualTo( context.getText( controlsComponent.getTileTitleId())) } @Test fun verifyTileImageEqualsResourceFromComponent() { assertThat(tile.icon) .isEqualTo(QSTileImpl.ResourceIcon.get(controlsComponent.getTileImageId())) assertThat(tile.tileLabel).isEqualTo(context.getText(controlsComponent.getTileTitleId())) } private fun createTile(): DeviceControlsTile { Loading @@ -409,8 +389,9 @@ class DeviceControlsTileTest : SysuiTestCase() { statusBarStateController, activityStarter, qsLogger, controlsComponent ).also { controlsComponent, ) .also { it.initialize() testableLooper.processAllMessages() } Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt +1 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.Drawable import android.text.TextUtils import androidx.compose.animation.animateColorAsState import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi import androidx.compose.animation.graphics.res.animatedVectorResource import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter import androidx.compose.animation.graphics.vector.AnimatedImageVector Loading Loading @@ -192,7 +191,6 @@ fun LargeTileLabels( } } @OptIn(ExperimentalAnimationGraphicsApi::class) @Composable fun SmallTileContent( modifier: Modifier = Modifier, Loading Loading @@ -229,6 +227,7 @@ fun SmallTileContent( } } } is Icon.Loaded -> { LaunchedEffect(loadedDrawable) { if (loadedDrawable is AnimatedVectorDrawable) { Loading packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +19 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; Loading Loading @@ -68,6 +69,7 @@ import com.android.systemui.qs.QSEvent; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QsEventLogger; import com.android.systemui.qs.SideLabelTileLayout; import com.android.systemui.qs.flags.QsInCompose; import com.android.systemui.qs.logging.QSLogger; import java.io.PrintWriter; Loading Loading @@ -535,6 +537,23 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy } } protected Icon maybeLoadResourceIcon(int id) { return maybeLoadResourceIcon(id, mContext); } /** * Returns the {@link QSTile.Icon} for the resource ID, optionally loading the drawable if * {@link QsInCompose#isEnabled()} is true. */ @SuppressLint("UseCompatLoadingForDrawables") public static Icon maybeLoadResourceIcon(int id, Context context) { if (QsInCompose.isEnabled()) { return new DrawableIconWithRes(context.getDrawable(id), id); } else { return ResourceIcon.get(id); } } @Override public String getMetricsSpec() { return mTileSpec; Loading packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +1 −1 Original line number Diff line number Diff line Loading @@ -160,7 +160,7 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> { final boolean airplaneMode = value != 0; state.value = airplaneMode; state.label = mContext.getString(R.string.airplane_mode); state.icon = ResourceIcon.get(state.value state.icon = maybeLoadResourceIcon(state.value ? R.drawable.qs_airplane_icon_on : R.drawable.qs_airplane_icon_off); state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; state.contentDescription = state.label; Loading packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt +32 −25 Original line number Diff line number Diff line Loading @@ -42,8 +42,9 @@ constructor( activityStarter: ActivityStarter, qsLogger: QSLogger, private val userTracker: UserTracker, nextAlarmController: NextAlarmController ) : QSTileImpl<QSTile.State>( nextAlarmController: NextAlarmController, ) : QSTileImpl<QSTile.State>( host, uiEventLogger, backgroundLooper, Loading @@ -52,13 +53,14 @@ constructor( metricsLogger, statusBarStateController, activityStarter, qsLogger qsLogger, ) { private var lastAlarmInfo: AlarmManager.AlarmClockInfo? = null private val icon = ResourceIcon.get(R.drawable.ic_alarm) private var icon: QSTile.Icon? = null @VisibleForTesting internal val defaultIntent = Intent(AlarmClock.ACTION_SHOW_ALARMS) private val callback = NextAlarmController.NextAlarmChangeCallback { nextAlarm -> private val callback = NextAlarmController.NextAlarmChangeCallback { nextAlarm -> lastAlarmInfo = nextAlarm refreshState() } Loading @@ -68,9 +70,7 @@ constructor( } override fun newTileState(): QSTile.State { return QSTile.State().apply { handlesLongClick = false } return QSTile.State().apply { handlesLongClick = false } } override fun handleClick(expandable: Expandable?) { Loading @@ -82,18 +82,25 @@ constructor( if (pendingIntent != null) { mActivityStarter.postStartActivityDismissingKeyguard(pendingIntent, animationController) } else { mActivityStarter.postStartActivityDismissingKeyguard(defaultIntent, 0, animationController) mActivityStarter.postStartActivityDismissingKeyguard( defaultIntent, 0, animationController, ) } } override fun handleUpdateState(state: QSTile.State, arg: Any?) { if (icon == null) { icon = maybeLoadResourceIcon(R.drawable.ic_alarm) } state.icon = icon state.label = tileLabel lastAlarmInfo?.let { state.secondaryLabel = formatNextAlarm(it) state.state = Tile.STATE_ACTIVE } ?: run { } ?: run { state.secondaryLabel = mContext.getString(R.string.qs_alarm_tile_no_alarm) state.state = Tile.STATE_INACTIVE } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt +93 −112 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import androidx.lifecycle.LifecycleOwner import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityTransitionAnimator import com.android.systemui.classifier.FalsingManagerFake Loading @@ -45,13 +44,14 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSHost import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.res.R import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.settings.SecureSettings import com.google.common.truth.Truth.assertThat import java.util.Optional import org.junit.After import org.junit.Before import org.junit.Test Loading @@ -67,40 +67,27 @@ import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations import java.util.Optional @SmallTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) class DeviceControlsTileTest : SysuiTestCase() { @Mock private lateinit var qsHost: QSHost @Mock private lateinit var metricsLogger: MetricsLogger @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var qsLogger: QSLogger @Mock private lateinit var controlsComponent: ControlsComponent @Mock private lateinit var controlsUiController: ControlsUiController @Mock private lateinit var controlsListingController: ControlsListingController @Mock private lateinit var controlsController: ControlsController @Mock private lateinit var serviceInfo: ControlsServiceInfo @Mock private lateinit var uiEventLogger: QsEventLogger @Mock private lateinit var qsHost: QSHost @Mock private lateinit var metricsLogger: MetricsLogger @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var qsLogger: QSLogger @Mock private lateinit var controlsComponent: ControlsComponent @Mock private lateinit var controlsUiController: ControlsUiController @Mock private lateinit var controlsListingController: ControlsListingController @Mock private lateinit var controlsController: ControlsController @Mock private lateinit var serviceInfo: ControlsServiceInfo @Mock private lateinit var uiEventLogger: QsEventLogger @Captor private lateinit var listingCallbackCaptor: ArgumentCaptor<ControlsListingController.ControlsListingCallback> @Captor private lateinit var intentCaptor: ArgumentCaptor<Intent> @Captor private lateinit var intentCaptor: ArgumentCaptor<Intent> private lateinit var testableLooper: TestableLooper private lateinit var tile: DeviceControlsTile Loading @@ -120,8 +107,11 @@ class DeviceControlsTileTest : SysuiTestCase() { `when`(qsHost.context).thenReturn(spiedContext) `when`(controlsComponent.isEnabled()).thenReturn(true) `when`(controlsController.getPreferredSelection()) .thenReturn(SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))) .thenReturn( SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()) ) ) secureSettings.putInt(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS, 1) setupControlsComponent() Loading Loading @@ -182,9 +172,10 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testObservingCallback() { verify(controlsListingController).observe( verify(controlsListingController) .observe( any(LifecycleOwner::class.java), any(ControlsListingController.ControlsListingCallback::class.java) any(ControlsListingController.ControlsListingCallback::class.java), ) } Loading @@ -205,10 +196,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateUnavailableIfNoListings() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) listingCallbackCaptor.value.onServicesUpdated(emptyList()) testableLooper.processAllMessages() Loading @@ -218,10 +207,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateUnavailableIfNotEnabled() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.isEnabled()).thenReturn(false) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -232,17 +219,18 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateActiveIfListingsHasControlsFavorited() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsController.getPreferredSelection()).thenReturn( SelectedItem.StructureItem(StructureInfo( `when`(controlsController.getPreferredSelection()) .thenReturn( SelectedItem.StructureItem( StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) )) listOf(ControlInfo("id", "title", "subtitle", 1)), ) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -253,14 +241,15 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateInactiveIfListingsHasNoControlsFavorited() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsController.getPreferredSelection()) .thenReturn(SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()))) .thenReturn( SelectedItem.StructureItem( StructureInfo(ComponentName("pkg", "cls"), "structure", listOf()) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) testableLooper.processAllMessages() Loading @@ -270,10 +259,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateActiveIfPreferredIsPanel() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsController.getPreferredSelection()) .thenReturn(SelectedItem.PanelItem("appName", ComponentName("pkg", "cls"))) Loading @@ -286,10 +273,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testStateInactiveIfLocked() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()) .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK) Loading @@ -301,10 +286,8 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun testMoveBetweenStates() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) testableLooper.processAllMessages() Loading @@ -325,18 +308,19 @@ class DeviceControlsTileTest : SysuiTestCase() { @Test fun handleClick_available_shownOverLockscreenWhenLocked() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()).thenReturn(ControlsComponent.Visibility.AVAILABLE) `when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java) `when`(controlsController.getPreferredSelection()).thenReturn( SelectedItem.StructureItem(StructureInfo( `when`(controlsController.getPreferredSelection()) .thenReturn( SelectedItem.StructureItem( StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) )) listOf(ControlInfo("id", "title", "subtitle", 1)), ) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -345,29 +329,32 @@ class DeviceControlsTileTest : SysuiTestCase() { tile.click(null /* view */) testableLooper.processAllMessages() verify(activityStarter).startActivity( verify(activityStarter) .startActivity( intentCaptor.capture(), eq(true) /* dismissShade */, nullable(ActivityTransitionAnimator.Controller::class.java), eq(true) /* showOverLockscreenWhenLocked */) eq(true), /* showOverLockscreenWhenLocked */ ) assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) } @Test fun handleClick_availableAfterUnlock_notShownOverLockscreenWhenLocked() { verify(controlsListingController).observe( any(LifecycleOwner::class.java), capture(listingCallbackCaptor) ) verify(controlsListingController) .observe(any(LifecycleOwner::class.java), capture(listingCallbackCaptor)) `when`(controlsComponent.getVisibility()) .thenReturn(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK) `when`(controlsUiController.resolveActivity()).thenReturn(ControlsActivity::class.java) `when`(controlsController.getPreferredSelection()).thenReturn( SelectedItem.StructureItem(StructureInfo( `when`(controlsController.getPreferredSelection()) .thenReturn( SelectedItem.StructureItem( StructureInfo( ComponentName("pkg", "cls"), "structure", listOf(ControlInfo("id", "title", "subtitle", 1)) )) listOf(ControlInfo("id", "title", "subtitle", 1)), ) ) ) listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo)) Loading @@ -376,26 +363,19 @@ class DeviceControlsTileTest : SysuiTestCase() { tile.click(null /* view */) testableLooper.processAllMessages() verify(activityStarter).startActivity( verify(activityStarter) .startActivity( intentCaptor.capture(), anyBoolean() /* dismissShade */, nullable(ActivityTransitionAnimator.Controller::class.java), eq(false) /* showOverLockscreenWhenLocked */) eq(false), /* showOverLockscreenWhenLocked */ ) assertThat(intentCaptor.value.component?.className).isEqualTo(CONTROLS_ACTIVITY_CLASS_NAME) } @Test fun verifyTileEqualsResourceFromComponent() { assertThat(tile.tileLabel) .isEqualTo( context.getText( controlsComponent.getTileTitleId())) } @Test fun verifyTileImageEqualsResourceFromComponent() { assertThat(tile.icon) .isEqualTo(QSTileImpl.ResourceIcon.get(controlsComponent.getTileImageId())) assertThat(tile.tileLabel).isEqualTo(context.getText(controlsComponent.getTileTitleId())) } private fun createTile(): DeviceControlsTile { Loading @@ -409,8 +389,9 @@ class DeviceControlsTileTest : SysuiTestCase() { statusBarStateController, activityStarter, qsLogger, controlsComponent ).also { controlsComponent, ) .also { it.initialize() testableLooper.processAllMessages() } Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt +1 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.Drawable import android.text.TextUtils import androidx.compose.animation.animateColorAsState import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi import androidx.compose.animation.graphics.res.animatedVectorResource import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter import androidx.compose.animation.graphics.vector.AnimatedImageVector Loading Loading @@ -192,7 +191,6 @@ fun LargeTileLabels( } } @OptIn(ExperimentalAnimationGraphicsApi::class) @Composable fun SmallTileContent( modifier: Modifier = Modifier, Loading Loading @@ -229,6 +227,7 @@ fun SmallTileContent( } } } is Icon.Loaded -> { LaunchedEffect(loadedDrawable) { if (loadedDrawable is AnimatedVectorDrawable) { Loading
packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +19 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; Loading Loading @@ -68,6 +69,7 @@ import com.android.systemui.qs.QSEvent; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QsEventLogger; import com.android.systemui.qs.SideLabelTileLayout; import com.android.systemui.qs.flags.QsInCompose; import com.android.systemui.qs.logging.QSLogger; import java.io.PrintWriter; Loading Loading @@ -535,6 +537,23 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy } } protected Icon maybeLoadResourceIcon(int id) { return maybeLoadResourceIcon(id, mContext); } /** * Returns the {@link QSTile.Icon} for the resource ID, optionally loading the drawable if * {@link QsInCompose#isEnabled()} is true. */ @SuppressLint("UseCompatLoadingForDrawables") public static Icon maybeLoadResourceIcon(int id, Context context) { if (QsInCompose.isEnabled()) { return new DrawableIconWithRes(context.getDrawable(id), id); } else { return ResourceIcon.get(id); } } @Override public String getMetricsSpec() { return mTileSpec; Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +1 −1 Original line number Diff line number Diff line Loading @@ -160,7 +160,7 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> { final boolean airplaneMode = value != 0; state.value = airplaneMode; state.label = mContext.getString(R.string.airplane_mode); state.icon = ResourceIcon.get(state.value state.icon = maybeLoadResourceIcon(state.value ? R.drawable.qs_airplane_icon_on : R.drawable.qs_airplane_icon_off); state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; state.contentDescription = state.label; Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt +32 −25 Original line number Diff line number Diff line Loading @@ -42,8 +42,9 @@ constructor( activityStarter: ActivityStarter, qsLogger: QSLogger, private val userTracker: UserTracker, nextAlarmController: NextAlarmController ) : QSTileImpl<QSTile.State>( nextAlarmController: NextAlarmController, ) : QSTileImpl<QSTile.State>( host, uiEventLogger, backgroundLooper, Loading @@ -52,13 +53,14 @@ constructor( metricsLogger, statusBarStateController, activityStarter, qsLogger qsLogger, ) { private var lastAlarmInfo: AlarmManager.AlarmClockInfo? = null private val icon = ResourceIcon.get(R.drawable.ic_alarm) private var icon: QSTile.Icon? = null @VisibleForTesting internal val defaultIntent = Intent(AlarmClock.ACTION_SHOW_ALARMS) private val callback = NextAlarmController.NextAlarmChangeCallback { nextAlarm -> private val callback = NextAlarmController.NextAlarmChangeCallback { nextAlarm -> lastAlarmInfo = nextAlarm refreshState() } Loading @@ -68,9 +70,7 @@ constructor( } override fun newTileState(): QSTile.State { return QSTile.State().apply { handlesLongClick = false } return QSTile.State().apply { handlesLongClick = false } } override fun handleClick(expandable: Expandable?) { Loading @@ -82,18 +82,25 @@ constructor( if (pendingIntent != null) { mActivityStarter.postStartActivityDismissingKeyguard(pendingIntent, animationController) } else { mActivityStarter.postStartActivityDismissingKeyguard(defaultIntent, 0, animationController) mActivityStarter.postStartActivityDismissingKeyguard( defaultIntent, 0, animationController, ) } } override fun handleUpdateState(state: QSTile.State, arg: Any?) { if (icon == null) { icon = maybeLoadResourceIcon(R.drawable.ic_alarm) } state.icon = icon state.label = tileLabel lastAlarmInfo?.let { state.secondaryLabel = formatNextAlarm(it) state.state = Tile.STATE_ACTIVE } ?: run { } ?: run { state.secondaryLabel = mContext.getString(R.string.qs_alarm_tile_no_alarm) state.state = Tile.STATE_INACTIVE } Loading