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

Commit 779598b8 authored by Beth Thibodeau's avatar Beth Thibodeau Committed by Android (Google) Code Review
Browse files

Merge "Remove recommendation logic in pipeline" into main

parents 7b16fe58 b2a5a493
Loading
Loading
Loading
Loading
+0 −33
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.media.controls

import android.app.smartspace.SmartspaceAction
import android.graphics.drawable.Icon
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever

class MediaTestHelper {
    companion object {
        /** Returns a list of three mocked recommendations */
        fun getValidRecommendationList(mediaIcon: Icon): List<SmartspaceAction> {
            val mediaRecommendationItem =
                mock<SmartspaceAction> { whenever(icon).thenReturn(mediaIcon) }
            return listOf(mediaRecommendationItem, mediaRecommendationItem, mediaRecommendationItem)
        }
    }
}
+0 −40
Original line number Diff line number Diff line
@@ -16,16 +16,12 @@

package com.android.systemui.media.controls.data.repository

import android.R
import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -41,17 +37,6 @@ class MediaDataRepositoryTest : SysuiTestCase() {

    private val underTest: MediaDataRepository = kosmos.mediaDataRepository

    @Test
    fun setRecommendation() =
        testScope.runTest {
            val smartspaceData by collectLastValue(underTest.smartspaceMediaData)
            val recommendation = SmartspaceMediaData(isActive = true)

            underTest.setRecommendation(recommendation)

            assertThat(smartspaceData).isEqualTo(recommendation)
        }

    @Test
    fun addAndRemoveMediaData() =
        testScope.runTest {
@@ -75,29 +60,4 @@ class MediaDataRepositoryTest : SysuiTestCase() {
            assertThat(entries!!.size).isEqualTo(1)
            assertThat(entries!![secondKey]).isEqualTo(secondData)
        }

    @Test
    fun dismissRecommendation() =
        testScope.runTest {
            val smartspaceData by collectLastValue(underTest.smartspaceMediaData)
            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
            val recommendation =
                SmartspaceMediaData(
                    targetId = KEY_MEDIA_SMARTSPACE,
                    isActive = true,
                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                )

            underTest.setRecommendation(recommendation)

            assertThat(smartspaceData).isEqualTo(recommendation)

            underTest.dismissSmartspaceRecommendation(KEY_MEDIA_SMARTSPACE)

            assertThat(smartspaceData!!.isActive).isFalse()
        }

    companion object {
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
    }
}
+15 −117
Original line number Diff line number Diff line
@@ -16,20 +16,15 @@

package com.android.systemui.media.controls.data.repository

import android.R
import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -42,13 +37,6 @@ class MediaFilterRepositoryTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
    private val mediaRecommendation =
        SmartspaceMediaData(
            targetId = KEY_MEDIA_SMARTSPACE,
            isActive = true,
            recommendations = MediaTestHelper.getValidRecommendationList(icon),
        )

    private val underTest: MediaFilterRepository = with(kosmos) { mediaFilterRepository }

@@ -139,21 +127,6 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(underTest.removeMediaEntry(KEY)).isEqualTo(userMedia)
        }

    @Test
    fun addActiveRecommendation_thenInactive() =
        testScope.runTest {
            val smartspaceMediaData by collectLastValue(underTest.smartspaceMediaData)

            underTest.setRecommendation(mediaRecommendation)

            assertThat(smartspaceMediaData).isEqualTo(mediaRecommendation)

            underTest.setRecommendation(mediaRecommendation.copy(isActive = false))

            assertThat(smartspaceMediaData).isNotEqualTo(mediaRecommendation)
            assertThat(underTest.isRecommendationActive()).isFalse()
        }

    @Test
    fun addMediaControlPlayingThenRemote() =
        testScope.runTest {
@@ -163,10 +136,6 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            val playingData = createMediaData("app1", true, LOCAL, false, playingInstanceId)
            val remoteData = createMediaData("app2", true, REMOTE, false, remoteInstanceId)

            underTest.setRecommendation(mediaRecommendation)
            underTest.setRecommendationsLoadingState(
                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
            )
            underTest.addSelectedUserMediaEntry(playingData)
            underTest.addMediaDataLoadingState(
                MediaDataLoadingModel.Loaded(playingInstanceId),
@@ -179,14 +148,11 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
                false,
            )

            assertThat(currentMedia?.size).isEqualTo(3)
            assertThat(currentMedia?.size).isEqualTo(2)
            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(remoteInstanceId)),
                    MediaCommonModel.MediaRecommendations(
                        SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
                    ),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(playingInstanceId)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(remoteInstanceId)),
                )
                .inOrder()
        }
@@ -208,8 +174,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(currentMedia?.size).isEqualTo(2)
            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId2)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(playingInstanceId1)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(playingInstanceId2)),
                )
                .inOrder()

@@ -224,8 +190,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(currentMedia?.size).isEqualTo(2)
            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId2)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(playingInstanceId1)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(playingInstanceId2)),
                )
                .inOrder()

@@ -234,8 +200,8 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            assertThat(currentMedia?.size).isEqualTo(2)
            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId2)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId1)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(playingInstanceId2)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(playingInstanceId1)),
                )
                .inOrder()
        }
@@ -270,81 +236,16 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
            underTest.addSelectedUserMediaEntry(playingAndRemoteData)
            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId2))

            underTest.setRecommendation(mediaRecommendation)
            underTest.setRecommendationsLoadingState(
                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
            )
            underTest.setOrderedMedia()

            assertThat(currentMedia?.size).isEqualTo(6)
            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId1)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId2)),
                    MediaCommonModel.MediaRecommendations(
                        SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
                    ),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId4)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId3)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId5)),
                )
                .inOrder()
        }

    @Test
    fun loadMediaFromRec() =
        testScope.runTest {
            val currentMedia by collectLastValue(underTest.currentMedia)
            val instanceId1 = InstanceId.fakeInstanceId(123)
            val instanceId2 = InstanceId.fakeInstanceId(456)
            val data =
                MediaData(
                    active = true,
                    instanceId = instanceId1,
                    packageName = PACKAGE_NAME,
                    isPlaying = true,
                    notificationKey = KEY,
                )
            val newData =
                MediaData(
                    active = true,
                    instanceId = instanceId2,
                    isPlaying = true,
                    notificationKey = KEY_2,
                )

            underTest.setMediaFromRecPackageName(PACKAGE_NAME)
            underTest.addSelectedUserMediaEntry(data)
            underTest.setRecommendation(mediaRecommendation)
            underTest.setRecommendationsLoadingState(
                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
            )
            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId1))

            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(
                        MediaDataLoadingModel.Loaded(instanceId1),
                        isMediaFromRec = true,
                    ),
                    MediaCommonModel.MediaRecommendations(
                        SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
                    ),
                )
                .inOrder()

            underTest.addSelectedUserMediaEntry(newData)
            underTest.addSelectedUserMediaEntry(data.copy(isPlaying = false))
            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId2))
            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId1))

            assertThat(currentMedia?.size).isEqualTo(5)
            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId2)),
                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(instanceId1)),
                    MediaCommonModel.MediaRecommendations(
                        SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
                    ),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(instanceId1)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(instanceId2)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(instanceId4)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(instanceId3)),
                    MediaCommonModel(MediaDataLoadingModel.Loaded(instanceId5)),
                )
                .inOrder()
        }
@@ -377,8 +278,5 @@ class MediaFilterRepositoryTest : SysuiTestCase() {
        private const val LOCAL = MediaData.PLAYBACK_LOCAL
        private const val REMOTE = MediaData.PLAYBACK_CAST_LOCAL
        private const val KEY = "KEY"
        private const val KEY_2 = "KEY_2"
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
        private const val PACKAGE_NAME = "com.android.example"
    }
}
+1 −33
Original line number Diff line number Diff line
@@ -16,9 +16,7 @@

package com.android.systemui.media.controls.domain.interactor

import android.R
import android.app.PendingIntent
import android.graphics.drawable.Icon
import android.os.Bundle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -32,7 +30,6 @@ import com.android.systemui.bluetooth.mockBroadcastDialogController
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.data.repository.mediaDataRepository
import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
import com.android.systemui.media.controls.domain.pipeline.MediaDataProcessor
@@ -41,7 +38,6 @@ import com.android.systemui.media.controls.domain.pipeline.interactor.mediaContr
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
import com.android.systemui.media.controls.domain.pipeline.mediaDataProcessor
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.util.mediaInstanceId
import com.android.systemui.media.mediaOutputDialogManager
import com.android.systemui.mockActivityIntentHelper
@@ -72,13 +68,6 @@ class MediaControlInteractorTest : SysuiTestCase() {
    private val keyguardStateController = kosmos.keyguardStateController
    private val instanceId: InstanceId = kosmos.mediaInstanceId
    private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager
    private val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
    private val mediaRecommendation =
        SmartspaceMediaData(
            targetId = KEY_MEDIA_SMARTSPACE,
            isActive = true,
            recommendations = MediaTestHelper.getValidRecommendationList(icon),
        )

    private val underTest: MediaControlInteractor =
        with(kosmos) {
@@ -159,7 +148,6 @@ class MediaControlInteractorTest : SysuiTestCase() {
        whenever(expandable.activityTransitionController(any())).thenReturn(activityController)

        val mediaData = MediaData(userId = USER_ID, instanceId = instanceId, artist = ARTIST)
        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, mediaRecommendation, true)
        mediaDataFilter.onMediaDataLoaded(KEY, null, mediaData)
        underTest.startClickIntent(expandable, clickIntent)

@@ -240,7 +228,7 @@ class MediaControlInteractorTest : SysuiTestCase() {
    }

    @Test
    fun removeMediaControl_noRecommendation() {
    fun removeMediaControl() {
        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
        val listener = mock<MediaDataProcessor.Listener>()
@@ -257,25 +245,6 @@ class MediaControlInteractorTest : SysuiTestCase() {
        verify(listener).onMediaDataRemoved(eq(KEY), eq(true))
    }

    @Test
    fun removeMediaControl_recommendationsExist() {
        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
        val listener = mock<MediaDataProcessor.Listener>()
        kosmos.mediaDataProcessor.addInternalListener(listener)

        val mediaData = MediaData(userId = USER_ID, instanceId = instanceId, artist = ARTIST)
        kosmos.mediaDataRepository.addMediaEntry(KEY, mediaData)
        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, mediaRecommendation, true)
        mediaDataFilter.onMediaDataLoaded(KEY, null, mediaData)

        underTest.removeMediaControl(null, instanceId, 0L)
        kosmos.fakeExecutor.advanceClockToNext()
        kosmos.fakeExecutor.runAllReady()

        verify(listener).onMediaDataRemoved(eq(KEY), eq(true))
    }

    companion object {
        private const val USER_ID = 0
        private const val KEY = "key"
@@ -283,6 +252,5 @@ class MediaControlInteractorTest : SysuiTestCase() {
        private const val APP_NAME = "app"
        private const val ARTIST = "artist"
        private const val ARTIST_2 = "artist2"
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
    }
}
+0 −6
Original line number Diff line number Diff line
@@ -25,9 +25,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.media.controls.MediaTestUtils
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.util.MediaControllerFactory
import com.android.systemui.media.controls.util.MediaFlags
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.util.concurrency.FakeExecutor
@@ -58,7 +56,6 @@ private const val PACKAGE = "PKG"
private const val SESSION_KEY = "SESSION_KEY"
private const val SESSION_ARTIST = "SESSION_ARTIST"
private const val SESSION_TITLE = "SESSION_TITLE"
private const val SMARTSPACE_KEY = "SMARTSPACE_KEY"

private fun <T> anyObject(): T {
    return ArgumentMatchers.any<T>()
@@ -90,8 +87,6 @@ class MediaTimeoutListenerTest : SysuiTestCase() {
    private lateinit var mainExecutor: FakeExecutor
    private lateinit var bgExecutor: FakeExecutor
    private lateinit var uiExecutor: FakeExecutor
    @Mock private lateinit var mediaFlags: MediaFlags
    @Mock private lateinit var smartspaceData: SmartspaceMediaData

    @Before
    fun setup() {
@@ -108,7 +103,6 @@ class MediaTimeoutListenerTest : SysuiTestCase() {
                logger,
                statusBarStateController,
                clock,
                mediaFlags,
            )
        mediaTimeoutListener.timeoutCallback = timeoutCallback
        mediaTimeoutListener.stateCallback = stateCallback
Loading