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

Commit 153d1d98 authored by Ebru Kurnaz's avatar Ebru Kurnaz Committed by Android (Google) Code Review
Browse files

Merge "Add basic notes tile implementation behind aconfig flag." into main

parents 97216c70 31518075
Loading
Loading
Loading
Loading
+73 −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.qs.tiles.impl.notes.domain

import android.graphics.drawable.TestStubDrawable
import android.widget.Button
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
import com.android.systemui.qs.tiles.impl.notes.qsNotesTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.res.R
import kotlin.test.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class NotesTileMapperTest : SysuiTestCase() {
    private val kosmos = Kosmos()
    private val qsTileConfig = kosmos.qsNotesTileConfig

    private val mapper by lazy {
        NotesTileMapper(
            context.orCreateTestableResources
                .apply { addOverride(R.drawable.ic_qs_notes, TestStubDrawable()) }
                .resources,
            context.theme,
        )
    }

    @Test
    fun mappedStateMatchesModel() {
        val inputModel = NotesTileModel

        val outputState = mapper.map(qsTileConfig, inputModel)

        val expectedState = createNotesTileState()
        QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
    }

    private fun createNotesTileState(): QSTileState =
        QSTileState(
            Icon.Loaded(context.getDrawable(R.drawable.ic_qs_notes)!!, null),
            R.drawable.ic_qs_notes,
            context.getString(R.string.quick_settings_notes_label),
            QSTileState.ActivationState.INACTIVE,
            /* secondaryLabel= */ null,
            setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK),
            context.getString(R.string.quick_settings_notes_label),
            /* stateDescription= */ null,
            QSTileState.SideViewIcon.Chevron,
            QSTileState.EnabledState.ENABLED,
            Button::class.qualifiedName,
        )
}
+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.qs.tiles.impl.notes.domain.interactor

import android.os.UserHandle
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toCollection
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class NotesTileDataInteractorTest : SysuiTestCase() {
    private val kosmos = Kosmos()
    private val testScope = kosmos.testScope
    private val testUser = UserHandle.of(1)
    private lateinit var underTest: NotesTileDataInteractor


    @EnableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
    @Test
    fun availability_qsFlagEnabled_notesRoleEnabled_returnTrue() =
        testScope.runTest {
            underTest = NotesTileDataInteractor(isNoteTaskEnabled = true)

            val availability = underTest.availability(testUser).toCollection(mutableListOf())

            assertThat(availability).containsExactly(true)
        }

    @DisableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
    @Test
    fun availability_qsFlagDisabled_notesRoleEnabled_returnFalse() =
        testScope.runTest {
            underTest = NotesTileDataInteractor(isNoteTaskEnabled = true)

            val availability = underTest.availability(testUser).toCollection(mutableListOf())

            assertThat(availability).containsExactly(false)
        }

    @EnableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
    @Test
    fun availability_qsFlagEnabled_notesRoleDisabled_returnFalse() =
        testScope.runTest {
            underTest = NotesTileDataInteractor(isNoteTaskEnabled = false)

            val availability = underTest.availability(testUser).toCollection(mutableListOf())

            assertThat(availability).containsExactly(false)
        }

    @DisableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
    @Test
    fun availability_qsFlagDisabled_notesRoleDisabled_returnFalse() =
        testScope.runTest {
            underTest = NotesTileDataInteractor(isNoteTaskEnabled = false)

            val availability = underTest.availability(testUser).toCollection(mutableListOf())

            assertThat(availability).containsExactly(false)
        }

    @Test
    fun tileData_notEmpty() = runTest {
        underTest = NotesTileDataInteractor(isNoteTaskEnabled = true)
        val flowValue by
        collectLastValue(underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest)))

        runCurrent()

        assertThat(flowValue).isNotNull()
    }
}
+73 −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.qs.tiles.impl.notes.domain.interactor

import android.content.Intent
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.testScope
import com.android.systemui.notetask.NoteTaskController
import com.android.systemui.notetask.NoteTaskEntryPoint
import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.Mockito.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
class NotesTileUserActionInteractorTest : SysuiTestCase() {
    private val kosmos = Kosmos()
    private val testScope = kosmos.testScope
    private val inputHandler = FakeQSTileIntentUserInputHandler()
    private val panelInteractor = mock<PanelInteractor>()
    private val noteTaskController = mock<NoteTaskController>()

    private lateinit var underTest: NotesTileUserActionInteractor

    @Before
    fun setUp() {
        underTest = NotesTileUserActionInteractor(inputHandler, panelInteractor, noteTaskController)
    }

    @Test
    fun handleClick_launchDefaultNotesApp() =
        testScope.runTest {
            underTest.handleInput(QSTileInputTestKtx.click(NotesTileModel))

            verify(noteTaskController).showNoteTask(NoteTaskEntryPoint.QS_NOTES_TILE)
        }

    @Test
    fun handleLongClick_launchSettings() =
        testScope.runTest {
            underTest.handleInput(QSTileInputTestKtx.longClick(NotesTileModel))

            QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
                assertThat(it.intent.action).isEqualTo(Intent.ACTION_MANAGE_DEFAULT_APP)
            }
        }
}
+23 −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 Lice/packages/SystemUI/res/drawable/ic_qs_notes.xmlnse.
  -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="960"
    android:viewportHeight="960"
    android:tint="?attr/colorControlNormal">
    <path android:fillColor="@android:color/white" android:pathData="M499,673L834,338Q834,338 834,338Q834,338 834,338L782,286Q782,286 782,286Q782,286 782,286L447,621L499,673ZM238,760Q138,755 89,718Q40,681 40,611Q40,546 93.5,505.5Q147,465 242,457Q281,454 300.5,444.5Q320,435 320,418Q320,392 290.5,379Q261,366 193,360L200,280Q303,288 351.5,321.5Q400,355 400,418Q400,471 361.5,501Q323,531 248,537Q184,542 152,560.5Q120,579 120,611Q120,646 148,661.5Q176,677 242,680L238,760ZM518,767L353,602L735,220Q755,200 782.5,200Q810,200 830,220L900,290Q920,310 920,337.5Q920,365 900,385L518,767ZM359,800Q342,804 329,791Q316,778 320,761L353,602L518,767L359,800Z"/>
</vector>
+1 −1
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@

    <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
    <string name="quick_settings_tiles_stock" translatable="false">
        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices
        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue,hearing_devices,notes
    </string>

    <!-- The tiles to display in QuickSettings -->
Loading