Loading packages/SystemUI/aconfig/systemui.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,13 @@ flag { bug: "291321279" } flag { name: "status_bar_system_status_icons_in_compose" namespace: "systemui" description: "Use compose for displaying icons in the status bar system status area" bug: "406922954" } flag { name: "status_bar_swipe_over_chip" namespace: "systemui" Loading packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt +1 −0 Original line number Diff line number Diff line Loading @@ -667,6 +667,7 @@ private fun ContentScope.StatusIcons( val chipHighlight = viewModel.quickSettingsChipHighlight // TODO(408001821): Use composable system status icons here instead. AndroidView( factory = { context -> iconManager.setTint(primaryColor, inverseColor) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt +6 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewM import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel import com.android.systemui.statusbar.systemstatusicons.ui.viewmodel.SystemStatusIconsViewModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow Loading Loading @@ -72,6 +73,11 @@ class FakeHomeStatusBarViewModel( object : BatteryViewModel.Factory { override fun create(): BatteryViewModel = mock(BatteryViewModel::class.java) } override val systemStatusIconsViewModelFactory: SystemStatusIconsViewModel.Factory = object : SystemStatusIconsViewModel.Factory { override fun create(): SystemStatusIconsViewModel = mock(SystemStatusIconsViewModel::class.java) } override val shouldShowOperatorNameView = MutableStateFlow(false) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/systemstatusicons/airplane/ui/viewmodel/AirplaneModeIconViewModelTest.kt 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.statusbar.systemstatusicons.airplane.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.res.R import com.android.systemui.statusbar.pipeline.airplane.data.repository.airplaneModeRepository import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository import com.android.systemui.statusbar.pipeline.shared.data.repository.fake import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class AirplaneModeIconViewModelTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val underTest = kosmos.airplaneModeIconViewModelFactory.create() private val fakeConnectivityRepository = kosmos.connectivityRepository.fake private val expectedAirplaneIcon = Icon.Resource( res = com.android.internal.R.drawable.ic_qs_airplane, contentDescription = ContentDescription.Resource(R.string.accessibility_airplane_mode), ) @Before fun setUp() { underTest.activateIn(kosmos.testScope) } @Test fun icon_notAirplaneMode_outputsNull() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf()) airplaneModeRepository.setIsAirplaneMode(false) assertThat(underTest.icon).isNull() } @Test fun icon_forceHidden_outputsNull() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.AIRPLANE)) airplaneModeRepository.setIsAirplaneMode(true) assertThat(underTest.icon).isNull() } @Test fun icon_isAirplaneModeAndNotForceHidden_outputsIcon() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf()) airplaneModeRepository.setIsAirplaneMode(true) val expectedIcon = Icon.Resource( res = com.android.internal.R.drawable.ic_qs_airplane, contentDescription = ContentDescription.Resource(R.string.accessibility_airplane_mode), ) assertThat(underTest.icon).isEqualTo(expectedIcon) } @Test fun icon_updatesWhenAirplaneModeChanges() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf()) // Start not in airplane mode airplaneModeRepository.setIsAirplaneMode(false) assertThat(underTest.icon).isNull() // Turn on airplane mode airplaneModeRepository.setIsAirplaneMode(true) assertThat(underTest.icon).isEqualTo(expectedAirplaneIcon) // Turn off airplane mode airplaneModeRepository.setIsAirplaneMode(false) assertThat(underTest.icon).isNull() } @Test fun icon_updatesWhenForceHiddenChanges() = kosmos.runTest { airplaneModeRepository.setIsAirplaneMode(true) // Start not hidden fakeConnectivityRepository.setForceHiddenIcons(setOf()) assertThat(underTest.icon).isEqualTo(expectedAirplaneIcon) // Force hide fakeConnectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.AIRPLANE)) assertThat(underTest.icon).isNull() // Un-hide fakeConnectivityRepository.setForceHiddenIcons(setOf()) assertThat(underTest.icon).isEqualTo(expectedAirplaneIcon) } } packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt +4 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ interface AirplaneModeViewModel { val isAirplaneModeIconVisible: StateFlow<Boolean> } @Deprecated( message = "This view model will not be used once SystemStatusIconsInCompose is launched", replaceWith = ReplaceWith("AirplaneModeIconViewModel"), ) @SysUISingleton class AirplaneModeViewModelImpl @Inject Loading Loading
packages/SystemUI/aconfig/systemui.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,13 @@ flag { bug: "291321279" } flag { name: "status_bar_system_status_icons_in_compose" namespace: "systemui" description: "Use compose for displaying icons in the status bar system status area" bug: "406922954" } flag { name: "status_bar_swipe_over_chip" namespace: "systemui" Loading
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt +1 −0 Original line number Diff line number Diff line Loading @@ -667,6 +667,7 @@ private fun ContentScope.StatusIcons( val chipHighlight = viewModel.quickSettingsChipHighlight // TODO(408001821): Use composable system status icons here instead. AndroidView( factory = { context -> iconManager.setTint(primaryColor, inverseColor) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt +6 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewM import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel import com.android.systemui.statusbar.systemstatusicons.ui.viewmodel.SystemStatusIconsViewModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow Loading Loading @@ -72,6 +73,11 @@ class FakeHomeStatusBarViewModel( object : BatteryViewModel.Factory { override fun create(): BatteryViewModel = mock(BatteryViewModel::class.java) } override val systemStatusIconsViewModelFactory: SystemStatusIconsViewModel.Factory = object : SystemStatusIconsViewModel.Factory { override fun create(): SystemStatusIconsViewModel = mock(SystemStatusIconsViewModel::class.java) } override val shouldShowOperatorNameView = MutableStateFlow(false) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/systemstatusicons/airplane/ui/viewmodel/AirplaneModeIconViewModelTest.kt 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.statusbar.systemstatusicons.airplane.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.res.R import com.android.systemui.statusbar.pipeline.airplane.data.repository.airplaneModeRepository import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository import com.android.systemui.statusbar.pipeline.shared.data.repository.fake import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class AirplaneModeIconViewModelTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val underTest = kosmos.airplaneModeIconViewModelFactory.create() private val fakeConnectivityRepository = kosmos.connectivityRepository.fake private val expectedAirplaneIcon = Icon.Resource( res = com.android.internal.R.drawable.ic_qs_airplane, contentDescription = ContentDescription.Resource(R.string.accessibility_airplane_mode), ) @Before fun setUp() { underTest.activateIn(kosmos.testScope) } @Test fun icon_notAirplaneMode_outputsNull() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf()) airplaneModeRepository.setIsAirplaneMode(false) assertThat(underTest.icon).isNull() } @Test fun icon_forceHidden_outputsNull() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.AIRPLANE)) airplaneModeRepository.setIsAirplaneMode(true) assertThat(underTest.icon).isNull() } @Test fun icon_isAirplaneModeAndNotForceHidden_outputsIcon() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf()) airplaneModeRepository.setIsAirplaneMode(true) val expectedIcon = Icon.Resource( res = com.android.internal.R.drawable.ic_qs_airplane, contentDescription = ContentDescription.Resource(R.string.accessibility_airplane_mode), ) assertThat(underTest.icon).isEqualTo(expectedIcon) } @Test fun icon_updatesWhenAirplaneModeChanges() = kosmos.runTest { fakeConnectivityRepository.setForceHiddenIcons(setOf()) // Start not in airplane mode airplaneModeRepository.setIsAirplaneMode(false) assertThat(underTest.icon).isNull() // Turn on airplane mode airplaneModeRepository.setIsAirplaneMode(true) assertThat(underTest.icon).isEqualTo(expectedAirplaneIcon) // Turn off airplane mode airplaneModeRepository.setIsAirplaneMode(false) assertThat(underTest.icon).isNull() } @Test fun icon_updatesWhenForceHiddenChanges() = kosmos.runTest { airplaneModeRepository.setIsAirplaneMode(true) // Start not hidden fakeConnectivityRepository.setForceHiddenIcons(setOf()) assertThat(underTest.icon).isEqualTo(expectedAirplaneIcon) // Force hide fakeConnectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.AIRPLANE)) assertThat(underTest.icon).isNull() // Un-hide fakeConnectivityRepository.setForceHiddenIcons(setOf()) assertThat(underTest.icon).isEqualTo(expectedAirplaneIcon) } }
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt +4 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ interface AirplaneModeViewModel { val isAirplaneModeIconVisible: StateFlow<Boolean> } @Deprecated( message = "This view model will not be used once SystemStatusIconsInCompose is launched", replaceWith = ReplaceWith("AirplaneModeIconViewModel"), ) @SysUISingleton class AirplaneModeViewModelImpl @Inject Loading