diff options
| author | 2024-12-27 21:04:08 +0000 | |
|---|---|---|
| committer | 2024-12-30 16:18:03 +0000 | |
| commit | a856b5b5fd8f72e8bc13e7d6e70d6a53ffde2352 (patch) | |
| tree | a1a637d6e52a0354c74b9cb5cca8ecf0bd21d1d0 | |
| parent | 3e665607e4f58a6737f0c1686a5e9262a96628dd (diff) | |
[SB] Update ethernet icon datasource to be EthernetInteractor.
This is the last piece needed to completely remove SignalCallback usage
from StatusBarSignalPolicy.
Bug: 291321279
Flag: com.android.systemui.status_bar_signal_policy_refactor_ethernet
Test: connect and disconnect from ethernet -> verify status bar icon
appears and disappears correctly
Test: atest StatusBarSignalPolicyTest
Change-Id: I140ddc35e65fce63f6770f7c576ee7d11c7f2c51
6 files changed, 224 insertions, 7 deletions
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index a5879bfde187..2fcaaa917cb0 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -457,6 +457,13 @@ flag { } flag { + name: "status_bar_signal_policy_refactor_ethernet" + namespace: "systemui" + description: "Use recommended architecture for ethernet icon in status bar" + bug: "291321279" +} + +flag { name: "status_bar_swipe_over_chip" namespace: "systemui" description: "Allow users to swipe over the status bar chip to open the shade" diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarSignalPolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarSignalPolicyTest.kt index cbf2d7af3885..bb9141afe404 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarSignalPolicyTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarSignalPolicyTest.kt @@ -33,6 +33,10 @@ import com.android.systemui.statusbar.connectivity.NetworkController import com.android.systemui.statusbar.phone.StatusBarSignalPolicy import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor +import com.android.systemui.statusbar.pipeline.ethernet.domain.ethernetInteractor +import com.android.systemui.statusbar.pipeline.ethernet.shared.StatusBarSignalPolicyRefactorEthernet +import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository +import com.android.systemui.statusbar.pipeline.shared.data.repository.fake import com.android.systemui.statusbar.policy.SecurityController import com.android.systemui.testKosmos import com.android.systemui.tuner.tunerService @@ -65,14 +69,17 @@ class StatusBarSignalPolicyTest : SysuiTestCase() { tunerService, javaAdapter, airplaneModeInteractor, + ethernetInteractor, ) } private lateinit var slotAirplane: String + private lateinit var slotEthernet: String @Before fun setup() { slotAirplane = mContext.getString(R.string.status_bar_airplane) + slotEthernet = mContext.getString(R.string.status_bar_ethernet) } @Test @@ -152,4 +159,92 @@ class StatusBarSignalPolicyTest : SysuiTestCase() { underTest.start() verifyNoMoreInteractions(securityController, networkController, tunerService) } + + @Test + @EnableFlags(FLAG_STATUS_BAR_SIGNAL_POLICY_REFACTOR) + @DisableFlags(StatusBarSignalPolicyRefactorEthernet.FLAG_NAME) + fun ethernetIconViaSignalCallback_refactorFlagDisabled_iconUpdated() = + kosmos.runTest { + underTest.start() + clearInvocations(statusBarIconController) + + underTest.setEthernetIndicators( + IconState(/* visible= */ true, /* icon= */ 1, /* contentDescription= */ "Ethernet") + ) + verify(statusBarIconController).setIconVisibility(slotEthernet, true) + + underTest.setEthernetIndicators( + IconState( + /* visible= */ false, + /* icon= */ 0, + /* contentDescription= */ "No ethernet", + ) + ) + verify(statusBarIconController).setIconVisibility(slotEthernet, false) + } + + @Test + @EnableFlags( + FLAG_STATUS_BAR_SIGNAL_POLICY_REFACTOR, + StatusBarSignalPolicyRefactorEthernet.FLAG_NAME, + ) + fun ethernetIconViaSignalCallback_refactorFlagEnabled_iconNotUpdated() = + kosmos.runTest { + underTest.start() + clearInvocations(statusBarIconController) + + underTest.setEthernetIndicators( + IconState(/* visible= */ true, /* icon= */ 1, /* contentDescription= */ "Ethernet") + ) + verifyNoMoreInteractions(statusBarIconController) + + underTest.setEthernetIndicators( + IconState( + /* visible= */ false, + /* icon= */ 0, + /* contentDescription= */ "No ethernet", + ) + ) + verifyNoMoreInteractions(statusBarIconController) + } + + @Test + @EnableFlags(FLAG_STATUS_BAR_SIGNAL_POLICY_REFACTOR) + @DisableFlags(StatusBarSignalPolicyRefactorEthernet.FLAG_NAME) + fun ethernetIconViaInteractor_refactorFlagDisabled_iconNotUpdated() = + kosmos.runTest { + underTest.start() + clearInvocations(statusBarIconController) + + connectivityRepository.fake.setEthernetConnected(default = true, validated = true) + verifyNoMoreInteractions(statusBarIconController) + + connectivityRepository.fake.setEthernetConnected(default = false, validated = false) + verifyNoMoreInteractions(statusBarIconController) + + connectivityRepository.fake.setEthernetConnected(default = true, validated = false) + verifyNoMoreInteractions(statusBarIconController) + } + + @Test + @EnableFlags( + FLAG_STATUS_BAR_SIGNAL_POLICY_REFACTOR, + StatusBarSignalPolicyRefactorEthernet.FLAG_NAME, + ) + fun ethernetIconViaInteractor_refactorFlagEnabled_iconUpdated() = + kosmos.runTest { + underTest.start() + clearInvocations(statusBarIconController) + + connectivityRepository.fake.setEthernetConnected(default = true, validated = true) + verify(statusBarIconController).setIconVisibility(slotEthernet, true) + + connectivityRepository.fake.setEthernetConnected(default = false, validated = false) + verify(statusBarIconController).setIconVisibility(slotEthernet, false) + + clearInvocations(statusBarIconController) + + connectivityRepository.fake.setEthernetConnected(default = true, validated = false) + verify(statusBarIconController).setIconVisibility(slotEthernet, true) + } } diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt index 08e8293cbe9c..d628aca7f9e8 100644 --- a/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt +++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/ContentDescription.kt @@ -24,13 +24,9 @@ import android.content.Context * be a [reference][ContentDescription.Resource] to a resource. */ sealed class ContentDescription { - data class Loaded( - val description: String?, - ) : ContentDescription() + data class Loaded(val description: String?) : ContentDescription() - data class Resource( - @StringRes val res: Int, - ) : ContentDescription() + data class Resource(@StringRes val res: Int) : ContentDescription() companion object { /** @@ -39,6 +35,7 @@ sealed class ContentDescription { * Prefer [com.android.systemui.common.ui.binder.ContentDescriptionViewBinder.bind] over * this method. This should only be used for testing or concatenation purposes. */ + @JvmStatic fun ContentDescription?.loadContentDescription(context: Context): String? { return when (this) { null -> null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index 0513b181157b..30dc9b90d0c5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -17,7 +17,9 @@ package com.android.systemui.statusbar.phone; import static com.android.systemui.Flags.statusBarSignalPolicyRefactor; +import static com.android.systemui.common.shared.model.ContentDescription.loadContentDescription; +import android.annotation.Nullable; import android.content.Context; import android.os.Handler; import android.util.ArraySet; @@ -25,6 +27,7 @@ import android.util.Log; import com.android.settingslib.mobile.TelephonyIcons; import com.android.systemui.CoreStartable; +import com.android.systemui.common.shared.model.Icon; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.res.R; import com.android.systemui.statusbar.connectivity.IconState; @@ -32,6 +35,8 @@ import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.connectivity.SignalCallback; import com.android.systemui.statusbar.phone.ui.StatusBarIconController; import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor; +import com.android.systemui.statusbar.pipeline.ethernet.domain.EthernetInteractor; +import com.android.systemui.statusbar.pipeline.ethernet.shared.StatusBarSignalPolicyRefactorEthernet; import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; @@ -62,6 +67,7 @@ public class StatusBarSignalPolicy private final TunerService mTunerService; private final JavaAdapter mJavaAdapter; private final AirplaneModeInteractor mAirplaneModeInteractor; + private final EthernetInteractor mEthernetInteractor; private boolean mHideAirplane; private boolean mHideMobile; @@ -77,7 +83,8 @@ public class StatusBarSignalPolicy SecurityController securityController, TunerService tunerService, JavaAdapter javaAdapter, - AirplaneModeInteractor airplaneModeInteractor + AirplaneModeInteractor airplaneModeInteractor, + EthernetInteractor ethernetInteractor ) { mContext = context; @@ -87,6 +94,7 @@ public class StatusBarSignalPolicy mSecurityController = securityController; mTunerService = tunerService; mAirplaneModeInteractor = airplaneModeInteractor; + mEthernetInteractor = ethernetInteractor; mSlotAirplane = mContext.getString(com.android.internal.R.string.status_bar_airplane); mSlotMobile = mContext.getString(com.android.internal.R.string.status_bar_mobile); @@ -106,6 +114,9 @@ public class StatusBarSignalPolicy mJavaAdapter.alwaysCollectFlow( mAirplaneModeInteractor.isAirplaneMode(), this::updateAirplaneModeIcon); + if (StatusBarSignalPolicyRefactorEthernet.isEnabled()) { + mJavaAdapter.alwaysCollectFlow(mEthernetInteractor.getIcon(), this::updateEthernetIcon); + } } /** Call to initialize and register this class with the system. */ @@ -123,6 +134,9 @@ public class StatusBarSignalPolicy mAirplaneModeInteractor.isAirplaneMode(), this::updateAirplaneModeIcon); } + if (StatusBarSignalPolicyRefactorEthernet.isEnabled()) { + mJavaAdapter.alwaysCollectFlow(mEthernetInteractor.getIcon(), this::updateEthernetIcon); + } } public void destroy() { @@ -185,6 +199,10 @@ public class StatusBarSignalPolicy @Override public void setEthernetIndicators(IconState state) { + if (StatusBarSignalPolicyRefactorEthernet.isEnabled()) { + return; + } + int resId = state.icon; String description = state.contentDescription; @@ -196,6 +214,22 @@ public class StatusBarSignalPolicy } } + private void updateEthernetIcon(@Nullable Icon.Resource ethernetIcon) { + if (StatusBarSignalPolicyRefactorEthernet.isUnexpectedlyInLegacyMode()) { + return; + } + + if (ethernetIcon != null) { + mIconController.setIcon( + mSlotEthernet, + ethernetIcon.getRes(), + loadContentDescription(ethernetIcon.getContentDescription(), mContext)); + mIconController.setIconVisibility(mSlotEthernet, true); + } else { + mIconController.setIconVisibility(mSlotEthernet, false); + } + } + @Override public void setIsAirplaneMode(IconState icon) { if (statusBarSignalPolicyRefactor()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt new file mode 100644 index 000000000000..48747df23e0c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/shared/StatusBarSignalPolicyRefactorEthernet.kt @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024 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.pipeline.ethernet.shared + +import com.android.systemui.Flags +import com.android.systemui.flags.FlagToken +import com.android.systemui.flags.RefactorFlagUtils + +/** Helper for reading or using the status bar signal policy refactor ethernet flag state. */ +@Suppress("NOTHING_TO_INLINE") +object StatusBarSignalPolicyRefactorEthernet { + /** The aconfig flag name */ + const val FLAG_NAME = Flags.FLAG_STATUS_BAR_SIGNAL_POLICY_REFACTOR_ETHERNET + + /** A token used for dependency declaration */ + val token: FlagToken + get() = FlagToken(FLAG_NAME, isEnabled) + + /** Is the refactor enabled */ + @JvmStatic + inline val isEnabled + get() = Flags.statusBarSignalPolicyRefactorEthernet() + + /** + * Called to ensure code is only run when the flag is enabled. This protects users from the + * unintended behaviors caused by accidentally running new logic, while also crashing on an eng + * build to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun isUnexpectedlyInLegacyMode() = + RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is enabled. This will throw an exception if + * the flag is not enabled to ensure that the refactor author catches issues in testing. + * Caution!! Using this check incorrectly will cause crashes in nextfood builds! + */ + @JvmStatic + inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is disabled. This will throw an exception if + * the flag is enabled to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorKosmos.kt new file mode 100644 index 000000000000..3be68180abba --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorKosmos.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 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.pipeline.ethernet.domain + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository + +val Kosmos.ethernetInteractor by Fixture { EthernetInteractor(connectivityRepository) } |