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

Commit e0725906 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add logs when media is visually added or removed" into main

parents c804cc50 e0e4711b
Loading
Loading
Loading
Loading
+65 −2
Original line number Diff line number Diff line
@@ -33,13 +33,14 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
import com.android.systemui.media.controls.shared.mediaLogger
import com.android.systemui.media.controls.shared.mockMediaLogger
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -48,12 +49,16 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
import org.mockito.Mockito
import org.mockito.kotlin.eq
import org.mockito.kotlin.never
import org.mockito.kotlin.reset
import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
class MediaCarouselViewModelTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val kosmos = testKosmos().apply { mediaLogger = mockMediaLogger }
    private val testScope = kosmos.testScope

    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
@@ -166,6 +171,64 @@ class MediaCarouselViewModelTest : SysuiTestCase() {
            assertThat(mediaControl.isMediaFromRec).isTrue()
        }

    @Test
    fun addMediaControlThenRemove_mediaEventsAreLogged() =
        testScope.runTest {
            val sortedMedia by collectLastValue(underTest.mediaItems)
            val instanceId = InstanceId.fakeInstanceId(123)

            loadMediaControl(KEY, instanceId)

            val mediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
            assertThat(mediaControl.instanceId).isEqualTo(instanceId)

            // when media control is added to carousel
            mediaControl.onAdded(mediaControl)

            verify(kosmos.mediaLogger).logMediaCardAdded(eq(instanceId))

            reset(kosmos.mediaLogger)

            // when media control is updated.
            mediaControl.onUpdated(mediaControl)

            verify(kosmos.mediaLogger, never()).logMediaCardAdded(eq(instanceId))

            mediaDataFilter.onMediaDataRemoved(KEY, true)
            assertThat(sortedMedia).isEmpty()

            // when media control is removed from carousel
            mediaControl.onRemoved(true)

            verify(kosmos.mediaLogger).logMediaCardRemoved(eq(instanceId))
        }

    @Test
    fun addMediaRecommendationThenRemove_mediaEventsAreLogged() =
        testScope.runTest {
            val sortedMedia by collectLastValue(underTest.mediaItems)
            kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)

            loadMediaRecommendations()

            val mediaRecommendations =
                sortedMedia?.get(0) as MediaCommonViewModel.MediaRecommendations
            assertThat(mediaRecommendations.key).isEqualTo(KEY_MEDIA_SMARTSPACE)

            // when media recommendation is added to carousel
            mediaRecommendations.onAdded(mediaRecommendations)

            verify(kosmos.mediaLogger).logMediaRecommendationCardAdded(eq(KEY_MEDIA_SMARTSPACE))

            mediaDataFilter.onSmartspaceMediaDataRemoved(KEY, true)
            assertThat(sortedMedia).isEmpty()

            // when media recommendation is removed from carousel
            mediaRecommendations.onRemoved(true)

            verify(kosmos.mediaLogger).logMediaRecommendationCardRemoved(eq(KEY_MEDIA_SMARTSPACE))
        }

    private fun loadMediaControl(key: String, instanceId: InstanceId, isPlaying: Boolean = true) {
        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
+3 −3
Original line number Diff line number Diff line
@@ -369,9 +369,9 @@ public class LogModule {
     */
    @Provides
    @SysUISingleton
    @MediaLoadingLog
    public static LogBuffer providesMediaLoadingLogBuffer(LogBufferFactory factory) {
        return factory.create("MediaLoadingLog", 20);
    @MediaLog
    public static LogBuffer providesMediaLogBuffer(LogBufferFactory factory) {
        return factory.create("MediaLog", 20);
    }

    /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
+2 −5
Original line number Diff line number Diff line
@@ -19,8 +19,5 @@ package com.android.systemui.log.dagger
import com.android.systemui.log.LogBuffer
import javax.inject.Qualifier

/** A [LogBuffer] for [com.android.systemui.media.controls.domain.pipeline.MediaLoadingLogger] */
@Qualifier
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class MediaLoadingLog
/** A [LogBuffer] for [com.android.systemui.media.controls.shared.MediaLogger] */
@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class MediaLog
+11 −21
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
import com.android.systemui.media.controls.shared.MediaLogger
import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
@@ -70,7 +71,7 @@ constructor(
    private val logger: MediaUiEventLogger,
    private val mediaFlags: MediaFlags,
    private val mediaFilterRepository: MediaFilterRepository,
    private val mediaLoadingLogger: MediaLoadingLogger,
    private val mediaLogger: MediaLogger,
) : MediaDataManager.Listener {
    /** Non-UI listeners to media changes. */
    private val _listeners: MutableSet<MediaDataProcessor.Listener> = mutableSetOf()
@@ -118,7 +119,7 @@ constructor(

        val isUpdate = mediaFilterRepository.addSelectedUserMediaEntry(data)

        mediaLoadingLogger.logMediaLoaded(data.instanceId, data.active, "loading media")
        mediaLogger.logMediaLoaded(data.instanceId, data.active, "loading media")
        mediaFilterRepository.addMediaDataLoadingState(
            MediaDataLoadingModel.Loaded(data.instanceId),
            isUpdate
@@ -189,7 +190,7 @@ constructor(
                        isSsReactivated = true
                    )
                )
                mediaLoadingLogger.logMediaLoaded(
                mediaLogger.logMediaLoaded(
                    mediaData.instanceId,
                    mediaData.active,
                    "reactivating media instead of smartspace"
@@ -226,7 +227,7 @@ constructor(
        mediaFilterRepository.setRecommendationsLoadingState(
            SmartspaceMediaLoadingModel.Loaded(key, shouldPrioritizeMutable)
        )
        mediaLoadingLogger.logRecommendationLoaded(key, data.isActive, "loading recommendations")
        mediaLogger.logRecommendationLoaded(key, data.isActive, "loading recommendations")
        listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable) }
    }

@@ -237,7 +238,7 @@ constructor(
                mediaFilterRepository.addMediaDataLoadingState(
                    MediaDataLoadingModel.Removed(instanceId)
                )
                mediaLoadingLogger.logMediaRemoved(instanceId, "removing media card")
                mediaLogger.logMediaRemoved(instanceId, "removing media card")
                // Only notify listeners if something actually changed
                listeners.forEach { it.onMediaDataRemoved(key, userInitiated) }
            }
@@ -253,11 +254,7 @@ constructor(
                mediaFilterRepository.addMediaDataLoadingState(
                    MediaDataLoadingModel.Loaded(lastActiveId, immediately)
                )
                mediaLoadingLogger.logMediaLoaded(
                    lastActiveId,
                    it.active,
                    "expiring reactivated id"
                )
                mediaLogger.logMediaLoaded(lastActiveId, it.active, "expiring reactivated id")
                listeners.forEach { listener ->
                    getKey(lastActiveId)?.let { lastActiveKey ->
                        listener.onMediaDataLoaded(lastActiveKey, lastActiveKey, it, immediately)
@@ -278,11 +275,7 @@ constructor(
        mediaFilterRepository.setRecommendationsLoadingState(
            SmartspaceMediaLoadingModel.Removed(key, immediately)
        )
        mediaLoadingLogger.logRecommendationRemoved(
            key,
            immediately,
            "removing recommendations card"
        )
        mediaLogger.logRecommendationRemoved(key, immediately, "removing recommendations card")
        listeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) }
    }

@@ -296,10 +289,7 @@ constructor(
                mediaFilterRepository.addMediaDataLoadingState(
                    MediaDataLoadingModel.Removed(data.instanceId)
                )
                mediaLoadingLogger.logMediaRemoved(
                    data.instanceId,
                    "Removing $key after profile change"
                )
                mediaLogger.logMediaRemoved(data.instanceId, "Removing $key after profile change")
                listeners.forEach { listener -> listener.onMediaDataRemoved(key, false) }
            }
        }
@@ -316,7 +306,7 @@ constructor(
            mediaFilterRepository.addMediaDataLoadingState(
                MediaDataLoadingModel.Removed(instanceId)
            )
            mediaLoadingLogger.logMediaRemoved(instanceId, "Removing media after user change")
            mediaLogger.logMediaRemoved(instanceId, "Removing media after user change")
            getKey(instanceId)?.let {
                listenersCopy.forEach { listener -> listener.onMediaDataRemoved(it, false) }
            }
@@ -329,7 +319,7 @@ constructor(
                    MediaDataLoadingModel.Loaded(data.instanceId),
                    isUpdate
                )
                mediaLoadingLogger.logMediaLoaded(
                mediaLogger.logMediaLoaded(
                    data.instanceId,
                    data.active,
                    "Re-adding $key after user change"
+40 −4
Original line number Diff line number Diff line
@@ -14,18 +14,18 @@
 * limitations under the License.
 */

package com.android.systemui.media.controls.domain.pipeline
package com.android.systemui.media.controls.shared

import com.android.internal.logging.InstanceId
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
import com.android.systemui.log.dagger.MediaLoadingLog
import com.android.systemui.log.dagger.MediaLog
import javax.inject.Inject

/** A buffered log for media loading events. */
@SysUISingleton
class MediaLoadingLogger @Inject constructor(@MediaLoadingLog private val buffer: LogBuffer) {
class MediaLogger @Inject constructor(@MediaLog private val buffer: LogBuffer) {

    fun logMediaLoaded(instanceId: InstanceId, active: Boolean, reason: String) {
        buffer.log(
@@ -78,7 +78,43 @@ class MediaLoadingLogger @Inject constructor(@MediaLoadingLog private val buffer
        )
    }

    fun logMediaCardAdded(instanceId: InstanceId) {
        buffer.log(
            TAG,
            LogLevel.DEBUG,
            { str1 = instanceId.toString() },
            { "adding media card $str1 to carousel" }
        )
    }

    fun logMediaCardRemoved(instanceId: InstanceId) {
        buffer.log(
            TAG,
            LogLevel.DEBUG,
            { str1 = instanceId.toString() },
            { "removing media card $str1 from carousel" }
        )
    }

    fun logMediaRecommendationCardAdded(key: String) {
        buffer.log(
            TAG,
            LogLevel.DEBUG,
            { str1 = key },
            { "adding recommendation card $str1 to carousel" }
        )
    }

    fun logMediaRecommendationCardRemoved(key: String) {
        buffer.log(
            TAG,
            LogLevel.DEBUG,
            { str1 = key },
            { "removing recommendation card $str1 from carousel" }
        )
    }

    companion object {
        private const val TAG = "MediaLoadingLog"
        private const val TAG = "MediaLog"
    }
}
Loading