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

Commit bffd0c88 authored by Evan Laird's avatar Evan Laird
Browse files

[sb] icon allow/block lists for HomeStatusBarInteractor

Adds a HomeStatusBarIconBlockListInteractor specifically to encode
status bar's logic about which icons to block.

Flag: com.android.systemui.status_bar_root_modernization
Bug: 364360986
Test: HomeStatusBarIconBlockListInteractorTest
Test: HomeStatusBarViewModelImplTest

Change-Id: I01bf143bee2432946ba3afe4206b994f8ff58299
parent 0b147716
Loading
Loading
Loading
Loading
+103 −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.shared.domain.interactor

import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.res.R
import com.android.systemui.shared.settings.data.repository.fakeSecureSettingsRepository
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class HomeStatusBarIconBlockListInteractorTest : SysuiTestCase() {
    val kosmos = testKosmos()
    private val Kosmos.underTest by Kosmos.Fixture { kosmos.homeStatusBarIconBlockListInteractor }

    @Test
    fun iconBlockList_containsResources() =
        kosmos.runTest {
            // GIVEN a list of blocked icons
            overrideResource(
                R.array.config_collapsed_statusbar_icon_blocklist,
                arrayOf("test1", "test2"),
            )

            // GIVEN the vibrate is set to show (not blocked)
            fakeSecureSettingsRepository.setInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 1)

            val latest by collectLastValue(underTest.iconBlockList)

            // THEN the volume is not the blocklist
            assertThat(latest).containsExactly("test1", "test2")
        }

    @Test
    fun iconBlockList_checksVolumeSetting() =
        kosmos.runTest {
            // GIVEN a list of blocked icons
            overrideResource(
                R.array.config_collapsed_statusbar_icon_blocklist,
                arrayOf("test1", "test2"),
            )

            // GIVEN the vibrate icon is set to be hidden
            fakeSecureSettingsRepository.setInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0)

            val latest by collectLastValue(underTest.iconBlockList)

            // THEN the volume is in the blocklist
            assertThat(latest).containsExactly("test1", "test2", "volume")
        }

    @Test
    fun iconBlockList_updatesWithVolumeSetting() =
        kosmos.runTest {
            // GIVEN a list of blocked icons
            overrideResource(
                R.array.config_collapsed_statusbar_icon_blocklist,
                arrayOf("test1", "test2"),
            )

            fakeSecureSettingsRepository.setInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0)

            val latest by collectLastValue(underTest.iconBlockList)

            // Initially blocked
            assertThat(latest).containsExactly("test1", "test2", "volume")

            // Setting updates
            fakeSecureSettingsRepository.setInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 1)

            // Not blocked
            assertThat(latest).containsExactly("test1", "test2")

            // Setting updates again
            fakeSecureSettingsRepository.setInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0)

            // ... blocked
            assertThat(latest).containsExactly("test1", "test2", "volume")
        }
}
+2 −0
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@ class FakeHomeStatusBarViewModel(
            )
        )

    override val iconBlockList: MutableStateFlow<List<String>> = MutableStateFlow(listOf())

    override fun areNotificationsLightsOut(displayId: Int): Flow<Boolean> = areNotificationLightsOut

    val darkRegions = mutableListOf<Rect>()
+11 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataS
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
import com.android.systemui.statusbar.phone.data.repository.fakeDarkIconRepository
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarIconBlockList
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarInteractorShowOperatorName
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel
import com.android.systemui.testKosmos
@@ -1051,6 +1052,16 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
            assertThat(tint).isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
        }

    @Test
    fun iconBlockList_followsInteractor() =
        kosmos.runTest {
            setHomeStatusBarIconBlockList(listOf("icon1", "icon2"))

            val latest by collectLastValue(underTest.iconBlockList)

            assertThat(latest).containsExactly("icon1", "icon2")
        }

    private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) =
        ActiveNotificationsStore.Builder()
            .apply { notifications.forEach(::addIndividualNotif) }
+56 −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.shared.domain.interactor

import android.content.res.Resources
import android.provider.Settings
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.res.R
import com.android.systemui.shared.settings.data.repository.SecureSettingsRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

/** A place to define the blocklist/allowlist for home status bar icons */
@SysUISingleton
class HomeStatusBarIconBlockListInteractor
@Inject
constructor(@Main res: Resources, secureSettingsRepository: SecureSettingsRepository) {
    private val defaultBlockedIcons =
        res.getStringArray(R.array.config_collapsed_statusbar_icon_blocklist)

    private val vibrateIconSlot = res.getString(com.android.internal.R.string.status_bar_volume)

    /** Tracks the user setting [Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON] */
    private val shouldShowVibrateIcon: Flow<Boolean> =
        secureSettingsRepository.boolSetting(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, false)

    val iconBlockList: Flow<List<String>> =
        shouldShowVibrateIcon.map {
            val defaultSet = defaultBlockedIcons.toMutableSet()
            // It's possible that the vibrate icon was in the default blocklist, so we manually
            // merge the setting and list
            if (it) {
                defaultSet.remove(vibrateIconSlot)
            } else {
                defaultSet.add(vibrateIconSlot)
            }

            defaultSet.toList()
        }
}
+34 −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.shared.ui.binder

import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.phone.ui.IconManager
import kotlinx.coroutines.flow.Flow

object HomeStatusBarIconBlockListBinder {
    fun bind(view: View, iconManager: IconManager, iconList: Flow<List<String>>) {
        view.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                iconList.collect { newBlockList -> iconManager.setBlockList(newBlockList) }
            }
        }
    }
}
Loading