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

Commit 4715e2b5 authored by Ioana Alexandru's avatar Ioana Alexandru Committed by Android (Google) Code Review
Browse files

Merge changes Ibab0f9de,I4ab669ac into main

* changes:
  Toggle modes when pressing tile
  Add modes tiles to dialog
parents eee4f0b3 d7b76a6a
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.NotificationManager
import android.provider.Settings
import com.android.settingslib.notification.modes.TestModeBuilder
import com.android.settingslib.notification.modes.ZenMode
import java.time.Duration
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -35,8 +36,7 @@ class FakeZenModeRepository : ZenModeRepository {
    override val globalZenMode: StateFlow<Int>
        get() = mutableZenMode.asStateFlow()

    private val mutableModesFlow: MutableStateFlow<List<ZenMode>> =
        MutableStateFlow(listOf(TestModeBuilder.EXAMPLE))
    private val mutableModesFlow: MutableStateFlow<List<ZenMode>> = MutableStateFlow(listOf())
    override val modes: Flow<List<ZenMode>>
        get() = mutableModesFlow.asStateFlow()

@@ -52,6 +52,10 @@ class FakeZenModeRepository : ZenModeRepository {
        mutableZenMode.value = zenMode
    }

    fun addModes(zenModes: List<ZenMode>) {
        mutableModesFlow.value += zenModes
    }

    fun addMode(id: String, active: Boolean = false) {
        mutableModesFlow.value += newMode(id, active)
    }
@@ -60,6 +64,20 @@ class FakeZenModeRepository : ZenModeRepository {
        mutableModesFlow.value = mutableModesFlow.value.filter { it.id != id }
    }

    override fun activateMode(zenMode: ZenMode, duration: Duration?) {
        activateMode(zenMode.id)
    }

    override fun deactivateMode(zenMode: ZenMode) {
        deactivateMode(zenMode.id)
    }

    fun activateMode(id: String) {
        val oldMode = mutableModesFlow.value.find { it.id == id } ?: return
        removeMode(id)
        mutableModesFlow.value += TestModeBuilder(oldMode).setActive(true).build()
    }

    fun deactivateMode(id: String) {
        val oldMode = mutableModesFlow.value.find { it.id == id } ?: return
        removeMode(id)
+13 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.provider.Settings
import com.android.settingslib.flags.Flags
import com.android.settingslib.notification.modes.ZenMode
import com.android.settingslib.notification.modes.ZenModesBackend
import java.time.Duration
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
@@ -57,6 +58,10 @@ interface ZenModeRepository {

    /** A list of all existing priority modes. */
    val modes: Flow<List<ZenMode>>

    fun activateMode(zenMode: ZenMode, duration: Duration? = null)

    fun deactivateMode(zenMode: ZenMode)
}

@SuppressLint("SharedFlowCreation")
@@ -178,4 +183,12 @@ class ZenModeRepositoryImpl(
            flowOf(emptyList())
        }
    }

    override fun activateMode(zenMode: ZenMode, duration: Duration?) {
        backend.activateMode(zenMode, duration)
    }

    override fun deactivateMode(zenMode: ZenMode) {
        backend.deactivateMode(zenMode)
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -37,6 +37,13 @@ public class TestModeBuilder {
    private ZenModeConfig.ZenRule mConfigZenRule;

    public static final ZenMode EXAMPLE = new TestModeBuilder().build();
    public static final ZenMode MANUAL_DND = ZenMode.manualDndMode(
            new AutomaticZenRule.Builder("Manual DND", Uri.parse("rule://dnd"))
                    .setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY)
                    .setZenPolicy(new ZenPolicy.Builder().disallowAllSounds().build())
                    .build(),
            true /* isActive */
    );

    public TestModeBuilder() {
        // Reasonable defaults
+1 −0
Original line number Diff line number Diff line
@@ -539,6 +539,7 @@ android_library {
        "androidx.preference_preference",
        "androidx.appcompat_appcompat",
        "androidx.concurrent_concurrent-futures",
        "androidx.concurrent_concurrent-futures-ktx",
        "androidx.mediarouter_mediarouter",
        "androidx.palette_palette",
        "androidx.legacy_legacy-preference-v14",
+164 −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.
 */

@file:OptIn(ExperimentalCoroutinesApi::class)

package com.android.systemui.statusbar.policy.ui.dialog.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.notification.modes.TestModeBuilder
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository
import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class ModesDialogViewModelTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    val repository = kosmos.fakeZenModeRepository
    val interactor = kosmos.zenModeInteractor

    val underTest = ModesDialogViewModel(context, interactor, kosmos.testDispatcher)

    @Test
    fun tiles_filtersOutDisabledModes() =
        testScope.runTest {
            val tiles by collectLastValue(underTest.tiles)

            repository.addModes(
                listOf(
                    TestModeBuilder().setName("Disabled").setEnabled(false).build(),
                    TestModeBuilder.MANUAL_DND,
                    TestModeBuilder()
                        .setName("Enabled")
                        .setEnabled(true)
                        .setManualInvocationAllowed(true)
                        .build(),
                    TestModeBuilder()
                        .setName("Disabled with manual")
                        .setEnabled(false)
                        .setManualInvocationAllowed(true)
                        .build(),
                ))
            runCurrent()

            assertThat(tiles?.size).isEqualTo(2)
            with(tiles?.elementAt(0)!!) {
                assertThat(this.text).isEqualTo("Manual DND")
                assertThat(this.subtext).isEqualTo("On")
                assertThat(this.enabled).isEqualTo(true)
            }
            with(tiles?.elementAt(1)!!) {
                assertThat(this.text).isEqualTo("Enabled")
                assertThat(this.subtext).isEqualTo("Off")
                assertThat(this.enabled).isEqualTo(false)
            }
        }

    @Test
    fun tiles_filtersOutInactiveModesWithoutManualInvocation() =
        testScope.runTest {
            val tiles by collectLastValue(underTest.tiles)

            repository.addModes(
                listOf(
                    TestModeBuilder()
                        .setName("Active without manual")
                        .setActive(true)
                        .setManualInvocationAllowed(false)
                        .build(),
                    TestModeBuilder()
                        .setName("Active with manual")
                        .setTriggerDescription("trigger description")
                        .setActive(true)
                        .setManualInvocationAllowed(true)
                        .build(),
                    TestModeBuilder()
                        .setName("Inactive with manual")
                        .setActive(false)
                        .setManualInvocationAllowed(true)
                        .build(),
                    TestModeBuilder()
                        .setName("Inactive without manual")
                        .setActive(false)
                        .setManualInvocationAllowed(false)
                        .build(),
                ))
            runCurrent()

            assertThat(tiles?.size).isEqualTo(3)
            with(tiles?.elementAt(0)!!) {
                assertThat(this.text).isEqualTo("Active without manual")
                assertThat(this.subtext).isEqualTo("On")
                assertThat(this.enabled).isEqualTo(true)
            }
            with(tiles?.elementAt(1)!!) {
                assertThat(this.text).isEqualTo("Active with manual")
                assertThat(this.subtext).isEqualTo("trigger description")
                assertThat(this.enabled).isEqualTo(true)
            }
            with(tiles?.elementAt(2)!!) {
                assertThat(this.text).isEqualTo("Inactive with manual")
                assertThat(this.subtext).isEqualTo("Off")
                assertThat(this.enabled).isEqualTo(false)
            }
        }

    @Test
    fun onClick_togglesTileState() =
        testScope.runTest {
            val tiles by collectLastValue(underTest.tiles)

            val modeId = "id"
            repository.addModes(
                listOf(
                    TestModeBuilder()
                        .setId(modeId)
                        .setName("Test")
                        .setManualInvocationAllowed(true)
                        .build()
                )
            )
            runCurrent()

            assertThat(tiles?.size).isEqualTo(1)
            assertThat(tiles?.elementAt(0)?.enabled).isFalse()

            // Trigger onClick
            tiles?.first()?.onClick?.let { it() }
            runCurrent()

            assertThat(tiles?.first()?.enabled).isTrue()

            // Trigger onClick
            tiles?.first()?.onClick?.let { it() }
            runCurrent()

            assertThat(tiles?.first()?.enabled).isFalse()
        }
}
Loading