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

Commit 9a006eea authored by Anton Potapov's avatar Anton Potapov
Browse files

Change LocalMediaRepository coroutine scope to be local to the flow

chain in MediaOutputInteractor

Now coroutine scope inside LocalMediaRepository gets properly cancelled
and collected when the package name changes. Before the fix idle
coroutines were left in the application coroutine scope.

Flag: com.android.systemui.new_volume_panel
Bug: 329561499
Test: manual on the phone with a cast device and headphones
Test: atest MediaOutputInteractorTest
Change-Id: I380a968f18cdcf27793b52f772a11bf0103068ab
parent 34649b10
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ class LocalMediaRepositoryImpl(
                    localMediaManager.unregisterCallback(callback)
                }
            }
            .shareIn(coroutineScope, SharingStarted.WhileSubscribed(), replay = 0)
            .shareIn(coroutineScope, SharingStarted.Eagerly, replay = 0)

    override val currentConnectedDevice: StateFlow<MediaDevice?> =
        merge(devicesChanges, mediaDevicesUpdates)
@@ -89,8 +89,8 @@ class LocalMediaRepositoryImpl(
            .onStart { emit(localMediaManager.currentConnectedDevice) }
            .stateIn(
                coroutineScope,
                SharingStarted.WhileSubscribed(),
                localMediaManager.currentConnectedDevice
                SharingStarted.Eagerly,
                localMediaManager.currentConnectedDevice,
            )

    private sealed interface DevicesUpdate {
+5 −4
Original line number Diff line number Diff line
@@ -19,14 +19,13 @@ import com.android.settingslib.volume.data.repository.LocalMediaRepository
import com.android.settingslib.volume.data.repository.LocalMediaRepositoryImpl
import com.android.settingslib.volume.shared.AudioManagerEventsReceiver
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.media.controls.util.LocalMediaManagerFactory
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope

interface LocalMediaRepositoryFactory {

    fun create(packageName: String?): LocalMediaRepository
    fun create(packageName: String?, coroutineScope: CoroutineScope): LocalMediaRepository
}

@SysUISingleton
@@ -35,10 +34,12 @@ class LocalMediaRepositoryFactoryImpl
constructor(
    private val eventsReceiver: AudioManagerEventsReceiver,
    private val localMediaManagerFactory: LocalMediaManagerFactory,
    @Application private val coroutineScope: CoroutineScope,
) : LocalMediaRepositoryFactory {

    override fun create(packageName: String?): LocalMediaRepository =
    override fun create(
        packageName: String?,
        coroutineScope: CoroutineScope
    ): LocalMediaRepository =
        LocalMediaRepositoryImpl(
            eventsReceiver,
            localMediaManagerFactory.create(packageName),
+5 −6
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -46,6 +47,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.transformLatest
import kotlinx.coroutines.withContext

/** Provides observable models about the current media session state. */
@@ -105,12 +107,9 @@ constructor(
            .filterData()
            .map { it?.packageName }
            .distinctUntilChanged()
            .map { localMediaRepositoryFactory.create(it) }
            .stateIn(
                coroutineScope,
                SharingStarted.Eagerly,
                localMediaRepositoryFactory.create(null)
            )
            .transformLatest {
                coroutineScope { emit(localMediaRepositoryFactory.create(it, this)) }
            }

    /** Currently connected [MediaDevice]. */
    val currentConnectedDevice: Flow<MediaDevice?> =
+5 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.volume.panel.component.mediaoutput.data.repository

import com.android.settingslib.volume.data.repository.LocalMediaRepository
import kotlinx.coroutines.CoroutineScope

class FakeLocalMediaRepositoryFactory(private val defaultProvider: () -> LocalMediaRepository) :
    LocalMediaRepositoryFactory {
@@ -27,6 +28,8 @@ class FakeLocalMediaRepositoryFactory(private val defaultProvider: () -> LocalMe
        repositories[packageName] = localMediaRepository
    }

    override fun create(packageName: String?): LocalMediaRepository =
        repositories[packageName] ?: defaultProvider()
    override fun create(
        packageName: String?,
        coroutineScope: CoroutineScope
    ): LocalMediaRepository = repositories[packageName] ?: defaultProvider()
}