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

Commit 53643fcf authored by Matías Hernández's avatar Matías Hernández
Browse files

Remove obsolete "Gaming" zen rule

SystemUI used to create this AutomaticZenRule, but stopped doing so around Android S or thereabouts, and was left over in some devices (or any newer devices that restore from such backups).

Fixes: 372705480
Test: ZenModesCleanupTest
Flag: android.app.modes_ui
Change-Id: Idf49dd8d67d00d3d7ce904f552e4a1092478c775
parent f8afa218
Loading
Loading
Loading
Loading
+117 −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.policy

import android.app.AutomaticZenRule
import android.app.NotificationManager
import android.net.Uri
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.backgroundCoroutineContext
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
@SmallTest
class ZenModesCleanupStartableTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope

    @Mock private lateinit var notificationManager: NotificationManager

    private lateinit var underTest: ZenModesCleanupStartable

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        underTest =
            ZenModesCleanupStartable(
                testScope.backgroundScope,
                kosmos.backgroundCoroutineContext,
                notificationManager,
            )
    }

    @Test
    fun start_withGamingModeZenRule_deletesIt() =
        testScope.runTest {
            whenever(notificationManager.automaticZenRules)
                .thenReturn(
                    mutableMapOf(
                        Pair(
                            "gaming",
                            AutomaticZenRule.Builder(
                                    "Gaming Mode",
                                    Uri.parse(
                                        "android-app://com.android.systemui/game-mode-dnd-controller"
                                    ),
                                )
                                .setPackage("com.android.systemui")
                                .build(),
                        ),
                        Pair(
                            "other",
                            AutomaticZenRule.Builder("Other Mode", Uri.parse("something-else"))
                                .setPackage("com.other.package")
                                .build(),
                        ),
                    )
                )

            underTest.start()
            runCurrent()

            verify(notificationManager).removeAutomaticZenRule(eq("gaming"))
        }

    @Test
    fun start_withoutGamingModeZenRule_doesNothing() =
        testScope.runTest {
            whenever(notificationManager.automaticZenRules)
                .thenReturn(
                    mutableMapOf(
                        Pair(
                            "other",
                            AutomaticZenRule.Builder("Other Mode", Uri.parse("something-else"))
                                .setPackage("com.android.systemui")
                                .build(),
                        )
                    )
                )

            underTest.start()
            runCurrent()

            verify(notificationManager, never()).removeAutomaticZenRule(any())
        }
}
+7 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.ZenModesCleanupStartable;

import dagger.Binds;
import dagger.Module;
@@ -299,4 +300,10 @@ public interface NotificationsModule {
            ZenModeRepository repository) {
        return new NotificationsSoundPolicyInteractor(repository);
    }

    /** Binds {@link ZenModesCleanupStartable} as a {@link CoreStartable}. */
    @Binds
    @IntoMap
    @ClassKey(ZenModesCleanupStartable.class)
    CoreStartable bindsZenModesCleanup(ZenModesCleanupStartable zenModesCleanup);
}
+64 −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.policy

import android.app.NotificationManager
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.modes.shared.ModesUi
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * Cleanup task that deletes the obsolete "Gaming" AutomaticZenRule that was created by SystemUI in
 * the faraway past, and still exists on some devices through upgrades or B&R.
 */
// TODO: b/372874878 - Remove this thing once it has run long enough
class ZenModesCleanupStartable
@Inject
constructor(
    @Application private val applicationCoroutineScope: CoroutineScope,
    @Background private val bgContext: CoroutineContext,
    val notificationManager: NotificationManager,
) : CoreStartable {

    override fun start() {
        if (!ModesUi.isEnabled) {
            return
        }
        applicationCoroutineScope.launch { deleteObsoleteGamingMode() }
    }

    private suspend fun deleteObsoleteGamingMode() {
        withContext(bgContext) {
            val allRules = notificationManager.automaticZenRules
            val gamingModeEntry =
                allRules.entries.firstOrNull { entry ->
                    entry.value.packageName == "com.android.systemui" &&
                        entry.value.conditionId?.toString() ==
                            "android-app://com.android.systemui/game-mode-dnd-controller"
                }
            if (gamingModeEntry != null) {
                notificationManager.removeAutomaticZenRule(gamingModeEntry.key)
            }
        }
    }
}