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

Commit 5e09b18d authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Automerger Merge Worker
Browse files

Add some fakes to SystemUI-test-utils am: e496b54c

parents 13b7c33b e496b54c
Loading
Loading
Loading
Loading
+109 −45
Original line number Diff line number Diff line
@@ -68,9 +68,73 @@ import java.util.Objects
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlin.math.max
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

/** A controller for the dealing with services running in the foreground. */
interface FgsManagerController {
    /** Whether the TaskManager (and therefore this controller) is actually available. */
    val isAvailable: StateFlow<Boolean>

    /** The number of packages with a service running in the foreground. */
    val numRunningPackages: Int

    /**
     * Whether there were new changes to the foreground services since the last [shown][showDialog]
     * dialog was dismissed.
     */
    val newChangesSinceDialogWasDismissed: Boolean

    /**
     * Whether we should show a dot to indicate when [newChangesSinceDialogWasDismissed] is true.
     */
    val showFooterDot: StateFlow<Boolean>

    /**
     * Initialize this controller. This should be called once, before this controller is used for
     * the first time.
     */
    fun init()

    /**
     * Show the foreground services dialog. The dialog will be expanded from [viewLaunchedFrom] if
     * it's not `null`.
     */
    fun showDialog(viewLaunchedFrom: View?)

    /** Add a [OnNumberOfPackagesChangedListener]. */
    fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener)

    /** Remove a [OnNumberOfPackagesChangedListener]. */
    fun removeOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener)

    /** Add a [OnDialogDismissedListener]. */
    fun addOnDialogDismissedListener(listener: OnDialogDismissedListener)

    /** Remove a [OnDialogDismissedListener]. */
    fun removeOnDialogDismissedListener(listener: OnDialogDismissedListener)

    /** Whether we should update the footer visibility. */
    // TODO(b/242040009): Remove this.
    fun shouldUpdateFooterVisibility(): Boolean

    @VisibleForTesting
    fun visibleButtonsCount(): Int

    interface OnNumberOfPackagesChangedListener {
        /** Called when [numRunningPackages] changed. */
        fun onNumberOfPackagesChanged(numPackages: Int)
    }

    interface OnDialogDismissedListener {
        /** Called when a dialog shown using [showDialog] was dismissed. */
        fun onDialogDismissed()
    }
}

@SysUISingleton
class FgsManagerController @Inject constructor(
class FgsManagerControllerImpl @Inject constructor(
    private val context: Context,
    @Main private val mainExecutor: Executor,
    @Background private val backgroundExecutor: Executor,
@@ -82,25 +146,32 @@ class FgsManagerController @Inject constructor(
    private val dialogLaunchAnimator: DialogLaunchAnimator,
    private val broadcastDispatcher: BroadcastDispatcher,
    private val dumpManager: DumpManager
) : IForegroundServiceObserver.Stub(), Dumpable {
) : IForegroundServiceObserver.Stub(), Dumpable, FgsManagerController {

    companion object {
        private const val INTERACTION_JANK_TAG = "active_background_apps"
        private val LOG_TAG = FgsManagerController::class.java.simpleName
        private const val DEFAULT_TASK_MANAGER_ENABLED = true
        private const val DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT = false
        private const val DEFAULT_TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS = true
    }

    var changesSinceDialog = false
    override var newChangesSinceDialogWasDismissed = false
        private set

    var isAvailable = false
        private set
    var showFooterDot = false
        private set
    var showStopBtnForUserAllowlistedApps = false
        private set
    val _isAvailable = MutableStateFlow(false)
    override val isAvailable: StateFlow<Boolean> = _isAvailable.asStateFlow()

    val _showFooterDot = MutableStateFlow(false)
    override val showFooterDot: StateFlow<Boolean> = _showFooterDot.asStateFlow()

    private var showStopBtnForUserAllowlistedApps = false

    override val numRunningPackages: Int
        get() {
            synchronized(lock) {
                return getNumVisiblePackagesLocked()
            }
        }

    private val lock = Any()

@@ -138,15 +209,7 @@ class FgsManagerController @Inject constructor(
        }
    }

    interface OnNumberOfPackagesChangedListener {
        fun onNumberOfPackagesChanged(numPackages: Int)
    }

    interface OnDialogDismissedListener {
        fun onDialogDismissed()
    }

    fun init() {
    override fun init() {
        synchronized(lock) {
            if (initialized) {
                return
@@ -165,19 +228,19 @@ class FgsManagerController @Inject constructor(
                NAMESPACE_SYSTEMUI,
                backgroundExecutor
            ) {
                isAvailable = it.getBoolean(TASK_MANAGER_ENABLED, isAvailable)
                showFooterDot =
                    it.getBoolean(TASK_MANAGER_SHOW_FOOTER_DOT, showFooterDot)
                _isAvailable.value = it.getBoolean(TASK_MANAGER_ENABLED, _isAvailable.value)
                _showFooterDot.value =
                    it.getBoolean(TASK_MANAGER_SHOW_FOOTER_DOT, _showFooterDot.value)
                showStopBtnForUserAllowlistedApps = it.getBoolean(
                    TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS,
                    showStopBtnForUserAllowlistedApps)
            }

            isAvailable = deviceConfigProxy.getBoolean(
            _isAvailable.value = deviceConfigProxy.getBoolean(
                NAMESPACE_SYSTEMUI,
                TASK_MANAGER_ENABLED, DEFAULT_TASK_MANAGER_ENABLED
            )
            showFooterDot = deviceConfigProxy.getBoolean(
            _showFooterDot.value = deviceConfigProxy.getBoolean(
                NAMESPACE_SYSTEMUI,
                TASK_MANAGER_SHOW_FOOTER_DOT, DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT
            )
@@ -232,42 +295,45 @@ class FgsManagerController @Inject constructor(
    }

    @GuardedBy("lock")
    val onNumberOfPackagesChangedListeners: MutableSet<OnNumberOfPackagesChangedListener> =
        mutableSetOf()
    private val onNumberOfPackagesChangedListeners =
        mutableSetOf<FgsManagerController.OnNumberOfPackagesChangedListener>()

    @GuardedBy("lock")
    val onDialogDismissedListeners: MutableSet<OnDialogDismissedListener> = mutableSetOf()
    private val onDialogDismissedListeners =
        mutableSetOf<FgsManagerController.OnDialogDismissedListener>()

    fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener) {
    override fun addOnNumberOfPackagesChangedListener(
        listener: FgsManagerController.OnNumberOfPackagesChangedListener
    ) {
        synchronized(lock) {
            onNumberOfPackagesChangedListeners.add(listener)
        }
    }

    fun removeOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener) {
    override fun removeOnNumberOfPackagesChangedListener(
        listener: FgsManagerController.OnNumberOfPackagesChangedListener
    ) {
        synchronized(lock) {
            onNumberOfPackagesChangedListeners.remove(listener)
        }
    }

    fun addOnDialogDismissedListener(listener: OnDialogDismissedListener) {
    override fun addOnDialogDismissedListener(
        listener: FgsManagerController.OnDialogDismissedListener
    ) {
        synchronized(lock) {
            onDialogDismissedListeners.add(listener)
        }
    }

    fun removeOnDialogDismissedListener(listener: OnDialogDismissedListener) {
    override fun removeOnDialogDismissedListener(
        listener: FgsManagerController.OnDialogDismissedListener
    ) {
        synchronized(lock) {
            onDialogDismissedListeners.remove(listener)
        }
    }

    fun getNumRunningPackages(): Int {
        synchronized(lock) {
            return getNumVisiblePackagesLocked()
        }
    }

    private fun getNumVisiblePackagesLocked(): Int {
        return runningServiceTokens.keys.count {
            it.uiControl != UIControl.HIDE_ENTRY && currentProfileIds.contains(it.userId)
@@ -278,7 +344,7 @@ class FgsManagerController @Inject constructor(
        val num = getNumVisiblePackagesLocked()
        if (num != lastNumberOfVisiblePackages) {
            lastNumberOfVisiblePackages = num
            changesSinceDialog = true
            newChangesSinceDialogWasDismissed = true
            onNumberOfPackagesChangedListeners.forEach {
                backgroundExecutor.execute {
                    it.onNumberOfPackagesChanged(num)
@@ -287,9 +353,7 @@ class FgsManagerController @Inject constructor(
        }
    }

    @VisibleForTesting
    @JvmName("getNumVisibleButtons")
    internal fun getNumVisibleButtons(): Int {
    override fun visibleButtonsCount(): Int {
        synchronized(lock) {
            return getNumVisibleButtonsLocked()
        }
@@ -301,9 +365,9 @@ class FgsManagerController @Inject constructor(
        }
    }

    fun shouldUpdateFooterVisibility() = dialog == null
    override fun shouldUpdateFooterVisibility() = dialog == null

    fun showDialog(viewLaunchedFrom: View?) {
    override fun showDialog(viewLaunchedFrom: View?) {
        synchronized(lock) {
            if (dialog == null) {

@@ -328,7 +392,7 @@ class FgsManagerController @Inject constructor(
                this.dialog = dialog

                dialog.setOnDismissListener {
                    changesSinceDialog = false
                    newChangesSinceDialogWasDismissed = false
                    synchronized(lock) {
                        this.dialog = null
                        updateAppItemsLocked()
@@ -656,7 +720,7 @@ class FgsManagerController @Inject constructor(
        val pw = IndentingPrintWriter(printwriter)
        synchronized(lock) {
            pw.println("current user profiles = $currentProfileIds")
            pw.println("changesSinceDialog=$changesSinceDialog")
            pw.println("newChangesSinceDialogWasShown=$newChangesSinceDialogWasDismissed")
            pw.println("Running service tokens: [")
            pw.indentIfPossible {
                runningServiceTokens.forEach { (userPackage, startTimeAndTokens) ->
+5 −3
Original line number Diff line number Diff line
@@ -149,9 +149,11 @@ public class QSFgsManagerFooter implements View.OnClickListener,
            mNumberView.setContentDescription(text);
            if (mFgsManagerController.shouldUpdateFooterVisibility()) {
                mRootView.setVisibility(mNumPackages > 0
                        && mFgsManagerController.isAvailable() ? View.VISIBLE : View.GONE);
                int dotVis = mFgsManagerController.getShowFooterDot()
                        && mFgsManagerController.getChangesSinceDialog() ? View.VISIBLE : View.GONE;
                        && mFgsManagerController.isAvailable().getValue() ? View.VISIBLE
                        : View.GONE);
                int dotVis = mFgsManagerController.getShowFooterDot().getValue()
                        && mFgsManagerController.getNewChangesSinceDialogWasDismissed()
                        ? View.VISIBLE : View.GONE;
                mDotView.setVisibility(dotVis);
                mCollapsedDotView.setVisibility(dotVis);
                if (mVisibilityChangedListener != null) {
+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.privacy.OngoingPrivacyChip;
import com.android.systemui.qs.FgsManagerController;
import com.android.systemui.qs.FgsManagerControllerImpl;
import com.android.systemui.qs.FooterActionsView;
import com.android.systemui.qs.QSContainerImpl;
import com.android.systemui.qs.QSFooter;
@@ -194,4 +196,8 @@ public interface QSFragmentModule {
    ) {
        return layoutInflater.inflate(R.layout.fgs_footer, footerActionsView, false);
    }

    /** */
    @Binds
    FgsManagerController bindFgsManagerController(FgsManagerControllerImpl impl);
}
 No newline at end of file
+6 −6
Original line number Diff line number Diff line
@@ -188,9 +188,9 @@ public class FgsManagerControllerTest extends SysuiTestCase {
    public void testChangesSinceLastDialog() throws RemoteException {
        setUserProfiles(0);

        Assert.assertFalse(mFmc.getChangesSinceDialog());
        Assert.assertFalse(mFmc.getNewChangesSinceDialogWasDismissed());
        mIForegroundServiceObserver.onForegroundStateChanged(new Binder(), "pkg", 0, true);
        Assert.assertTrue(mFmc.getChangesSinceDialog());
        Assert.assertTrue(mFmc.getNewChangesSinceDialogWasDismissed());
    }

    @Test
@@ -233,14 +233,14 @@ public class FgsManagerControllerTest extends SysuiTestCase {
        final Binder binder = new Binder();
        setShowStopButtonForUserAllowlistedApps(true);
        mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, true);
        Assert.assertEquals(1, mFmc.getNumVisibleButtons());
        Assert.assertEquals(1, mFmc.visibleButtonsCount());

        mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, false);
        Assert.assertEquals(0, mFmc.getNumVisibleButtons());
        Assert.assertEquals(0, mFmc.visibleButtonsCount());

        setShowStopButtonForUserAllowlistedApps(false);
        mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, true);
        Assert.assertEquals(0, mFmc.getNumVisibleButtons());
        Assert.assertEquals(0, mFmc.visibleButtonsCount());
    }

    private void setShowStopButtonForUserAllowlistedApps(boolean enable) {
@@ -269,7 +269,7 @@ public class FgsManagerControllerTest extends SysuiTestCase {
        ArgumentCaptor<BroadcastReceiver> showFgsManagerReceiverArgumentCaptor =
                ArgumentCaptor.forClass(BroadcastReceiver.class);

        FgsManagerController result = new FgsManagerController(
        FgsManagerController result = new FgsManagerControllerImpl(
                mContext,
                mMainExecutor,
                mBackgroundExecutor,
+0 −1
Original line number Diff line number Diff line
@@ -56,7 +56,6 @@ class FakeFeatureFlags : FeatureFlags {
        stringFlags.put(flag.id, value)
    }


    override fun isEnabled(flag: UnreleasedFlag): Boolean = requireBooleanValue(flag.id)

    override fun isEnabled(flag: ReleasedFlag): Boolean = requireBooleanValue(flag.id)
Loading