Loading components/feature/media/src/main/java/mozilla/components/feature/media/MediaFeature.kt +3 −6 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ package mozilla.components.feature.media import android.content.Context import mozilla.components.feature.media.ext.hasMediaWithSufficientLongDuration import mozilla.components.feature.media.facts.emitStatePauseFact import mozilla.components.feature.media.facts.emitStatePlayFact import mozilla.components.feature.media.facts.emitStateStopFact Loading Loading @@ -48,12 +47,10 @@ class MediaFeature( private fun notifyService(state: MediaState) { when (state) { is MediaState.Playing -> { if (state.hasMediaWithSufficientLongDuration()) { MediaService.updateState(context) serviceStarted = true emitStatePlayFact() } } is MediaState.Paused -> { if (serviceStarted) { Loading components/feature/media/src/main/java/mozilla/components/feature/media/ext/Media.kt +22 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,11 @@ package mozilla.components.feature.media.ext import mozilla.components.concept.engine.media.Media /** * The minimum duration (in seconds) for media so that we bother with showing a media notification. */ private const val MINIMUM_DURATION_SECONDS = 5 /** * Pauses all [Media] in this list. */ Loading @@ -19,3 +24,20 @@ internal fun List<Media>.pause() { internal fun List<Media>.play() { forEach { it.controller.play() } } /** * Does this list contain [Media] that is sufficient long to justify showing media controls for it? */ internal fun List<Media>.hasMediaWithSufficientLongDuration(): Boolean { forEach { media -> if (media.metadata.duration < 0) { return true } if (media.metadata.duration > MINIMUM_DURATION_SECONDS) { return true } } return false } components/feature/media/src/main/java/mozilla/components/feature/media/ext/MediaState.kt +0 −19 Original line number Diff line number Diff line Loading @@ -9,11 +9,6 @@ import mozilla.components.browser.session.Session import mozilla.components.concept.engine.media.Media import mozilla.components.feature.media.state.MediaState /** * The minimum duration (in seconds) for media so that we bother with showing a media notification. */ private const val MINIMUM_DURATION_SECONDS = 5 /** * Gets the list of [Media] associated with this [MediaState]. */ Loading Loading @@ -84,17 +79,3 @@ fun MediaState.playIfPaused() { media.play() } } internal fun MediaState.hasMediaWithSufficientLongDuration(): Boolean { getMedia().forEach { media -> if (media.metadata.duration < 0) { return true } if (media.metadata.duration > MINIMUM_DURATION_SECONDS) { return true } } return false } components/feature/media/src/main/java/mozilla/components/feature/media/state/MediaStateMachine.kt +11 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.utils.AllSessionsObserver import mozilla.components.concept.engine.media.Media import mozilla.components.feature.media.ext.hasMediaWithSufficientLongDuration import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.base.observer.Observable import mozilla.components.support.base.observer.ObserverRegistry Loading Loading @@ -162,7 +163,7 @@ private class MediaSessionObserver( } } @Suppress("ReturnCount") @Suppress("ReturnCount", "ComplexMethod") private fun determineNewState(): MediaState { val currentState = stateMachine.state Loading @@ -178,10 +179,15 @@ private class MediaSessionObserver( // Check if there's a session that has playing media and emit a "playing" state for it. val playingSession = mediaMap.findPlayingSession() if (playingSession != null) { return MediaState.Playing( playingSession.first, playingSession.second ) val (session, media) = playingSession // We only switch to playing state if there's media playing that has a sufficient long // duration. Otherwise we let just Gecko play it and do not request audio focus or show // a media notification. This will let us ignore short audio effects (Beeep!). return if (media.hasMediaWithSufficientLongDuration()) { return MediaState.Playing(session, media) } else { MediaState.None } } // If we were in "playing" state and the media for this session is now paused then emit a "paused" state. Loading components/feature/media/src/test/java/mozilla/components/feature/media/MockMedia.kt +8 −5 Original line number Diff line number Diff line Loading @@ -6,16 +6,19 @@ package mozilla.components.feature.media import mozilla.components.concept.engine.media.Media import mozilla.components.support.test.mock import org.mockito.Mockito.doReturn internal class MockMedia( initialState: PlaybackState initialState: PlaybackState, duration: Double = 10.0 ) : Media() { init { playbackState = initialState } override val controller: Controller = mock() override val metadata: Metadata = mock() init { playbackState = initialState doReturn(duration).`when`(metadata).duration } } Loading
components/feature/media/src/main/java/mozilla/components/feature/media/MediaFeature.kt +3 −6 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ package mozilla.components.feature.media import android.content.Context import mozilla.components.feature.media.ext.hasMediaWithSufficientLongDuration import mozilla.components.feature.media.facts.emitStatePauseFact import mozilla.components.feature.media.facts.emitStatePlayFact import mozilla.components.feature.media.facts.emitStateStopFact Loading Loading @@ -48,12 +47,10 @@ class MediaFeature( private fun notifyService(state: MediaState) { when (state) { is MediaState.Playing -> { if (state.hasMediaWithSufficientLongDuration()) { MediaService.updateState(context) serviceStarted = true emitStatePlayFact() } } is MediaState.Paused -> { if (serviceStarted) { Loading
components/feature/media/src/main/java/mozilla/components/feature/media/ext/Media.kt +22 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,11 @@ package mozilla.components.feature.media.ext import mozilla.components.concept.engine.media.Media /** * The minimum duration (in seconds) for media so that we bother with showing a media notification. */ private const val MINIMUM_DURATION_SECONDS = 5 /** * Pauses all [Media] in this list. */ Loading @@ -19,3 +24,20 @@ internal fun List<Media>.pause() { internal fun List<Media>.play() { forEach { it.controller.play() } } /** * Does this list contain [Media] that is sufficient long to justify showing media controls for it? */ internal fun List<Media>.hasMediaWithSufficientLongDuration(): Boolean { forEach { media -> if (media.metadata.duration < 0) { return true } if (media.metadata.duration > MINIMUM_DURATION_SECONDS) { return true } } return false }
components/feature/media/src/main/java/mozilla/components/feature/media/ext/MediaState.kt +0 −19 Original line number Diff line number Diff line Loading @@ -9,11 +9,6 @@ import mozilla.components.browser.session.Session import mozilla.components.concept.engine.media.Media import mozilla.components.feature.media.state.MediaState /** * The minimum duration (in seconds) for media so that we bother with showing a media notification. */ private const val MINIMUM_DURATION_SECONDS = 5 /** * Gets the list of [Media] associated with this [MediaState]. */ Loading Loading @@ -84,17 +79,3 @@ fun MediaState.playIfPaused() { media.play() } } internal fun MediaState.hasMediaWithSufficientLongDuration(): Boolean { getMedia().forEach { media -> if (media.metadata.duration < 0) { return true } if (media.metadata.duration > MINIMUM_DURATION_SECONDS) { return true } } return false }
components/feature/media/src/main/java/mozilla/components/feature/media/state/MediaStateMachine.kt +11 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.utils.AllSessionsObserver import mozilla.components.concept.engine.media.Media import mozilla.components.feature.media.ext.hasMediaWithSufficientLongDuration import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.base.observer.Observable import mozilla.components.support.base.observer.ObserverRegistry Loading Loading @@ -162,7 +163,7 @@ private class MediaSessionObserver( } } @Suppress("ReturnCount") @Suppress("ReturnCount", "ComplexMethod") private fun determineNewState(): MediaState { val currentState = stateMachine.state Loading @@ -178,10 +179,15 @@ private class MediaSessionObserver( // Check if there's a session that has playing media and emit a "playing" state for it. val playingSession = mediaMap.findPlayingSession() if (playingSession != null) { return MediaState.Playing( playingSession.first, playingSession.second ) val (session, media) = playingSession // We only switch to playing state if there's media playing that has a sufficient long // duration. Otherwise we let just Gecko play it and do not request audio focus or show // a media notification. This will let us ignore short audio effects (Beeep!). return if (media.hasMediaWithSufficientLongDuration()) { return MediaState.Playing(session, media) } else { MediaState.None } } // If we were in "playing" state and the media for this session is now paused then emit a "paused" state. Loading
components/feature/media/src/test/java/mozilla/components/feature/media/MockMedia.kt +8 −5 Original line number Diff line number Diff line Loading @@ -6,16 +6,19 @@ package mozilla.components.feature.media import mozilla.components.concept.engine.media.Media import mozilla.components.support.test.mock import org.mockito.Mockito.doReturn internal class MockMedia( initialState: PlaybackState initialState: PlaybackState, duration: Double = 10.0 ) : Media() { init { playbackState = initialState } override val controller: Controller = mock() override val metadata: Metadata = mock() init { playbackState = initialState doReturn(duration).`when`(metadata).duration } }