Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a856b5b5 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[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
parent 3e665607
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -456,6 +456,13 @@ flag {
   bug: "264539100"
}

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"
+95 −0
Original line number Diff line number Diff line
@@ -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)
        }
}
+3 −6
Original line number Diff line number Diff line
@@ -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
+35 −1
Original line number Diff line number Diff line
@@ -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()) {
+61 −0
Original line number Diff line number Diff line
/*
 * 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)
}
Loading