Skip to content

Commit b5586cb

Browse files
author
Marco Romano
authored
Move MediaPlayer from messages module to new dedicated library module (#1654)
1 parent aaaad23 commit b5586cb

File tree

17 files changed

+229
-71
lines changed

17 files changed

+229
-71
lines changed

features/messages/impl/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ dependencies {
5252
implementation(projects.libraries.permissions.api)
5353
implementation(projects.libraries.preferences.api)
5454
implementation(projects.libraries.voicerecorder.api)
55+
implementation(projects.libraries.mediaplayer.api)
5556
implementation(projects.libraries.uiUtils)
5657
implementation(projects.features.networkmonitor.api)
5758
implementation(projects.services.analytics.api)
@@ -83,6 +84,7 @@ dependencies {
8384
testImplementation(projects.libraries.preferences.test)
8485
testImplementation(projects.libraries.textcomposer.test)
8586
testImplementation(projects.libraries.voicerecorder.test)
87+
testImplementation(projects.libraries.mediaplayer.test)
8688
testImplementation(libs.test.mockk)
8789

8890
ksp(libs.showkase.processor)

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import io.element.android.features.messages.impl.attachments.Attachment
3131
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
3232
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories
3333
import io.element.android.features.messages.impl.timeline.model.TimelineItem
34-
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
34+
import io.element.android.libraries.mediaplayer.api.MediaPlayer
3535
import io.element.android.libraries.di.RoomScope
3636
import io.element.android.libraries.matrix.api.core.EventId
3737
import io.element.android.libraries.matrix.api.core.RoomId

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPlayer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package io.element.android.features.messages.impl.voicemessages.composer
1818

19-
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
19+
import io.element.android.libraries.mediaplayer.api.MediaPlayer
2020
import kotlinx.coroutines.flow.Flow
2121
import kotlinx.coroutines.flow.distinctUntilChanged
2222
import kotlinx.coroutines.flow.map

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePlayer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package io.element.android.features.messages.impl.voicemessages.timeline
1818

1919
import com.squareup.anvil.annotations.ContributesBinding
20-
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
20+
import io.element.android.libraries.mediaplayer.api.MediaPlayer
2121
import io.element.android.libraries.di.RoomScope
2222
import io.element.android.libraries.matrix.api.core.EventId
2323
import io.element.android.libraries.matrix.api.media.MediaSource

features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
4343
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPlayer
4444
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPresenter
4545
import io.element.android.features.messages.media.FakeLocalMediaFactory
46-
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
46+
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
4747
import io.element.android.features.messages.textcomposer.TestRichTextEditorStateFactory
4848
import io.element.android.features.messages.timeline.components.customreaction.FakeEmojibaseProvider
4949
import io.element.android.features.messages.utils.messagesummary.FakeMessageSummaryFormatter

features/messages/impl/src/test/kotlin/io/element/android/features/messages/voicemessages/composer/VoiceMessageComposerPresenterTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import io.element.android.features.messages.impl.voicemessages.composer.VoiceMes
3030
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
3131
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
3232
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPlayer
33-
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
33+
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
3434
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
3535
import io.element.android.libraries.mediaupload.api.MediaSender
3636
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor

features/messages/impl/src/test/kotlin/io/element/android/features/messages/voicemessages/timeline/DefaultVoiceMessagePlayerTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ package io.element.android.features.messages.voicemessages.timeline
1818

1919
import app.cash.turbine.test
2020
import com.google.common.truth.Truth
21-
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
21+
import io.element.android.libraries.mediaplayer.api.MediaPlayer
2222
import io.element.android.features.messages.impl.voicemessages.timeline.DefaultVoiceMessagePlayer
2323
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageMediaRepo
24-
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
24+
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
2525
import io.element.android.libraries.matrix.api.core.EventId
2626
import io.element.android.libraries.matrix.api.media.MediaSource
2727
import io.element.android.libraries.matrix.test.AN_EVENT_ID

features/messages/impl/src/test/kotlin/io/element/android/features/messages/voicemessages/timeline/VoiceMessagePresenterTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMes
2727
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageMediaRepo
2828
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessagePresenter
2929
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageState
30-
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
30+
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
3131
import kotlinx.coroutines.test.runTest
3232
import org.junit.Test
3333

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
plugins {
17+
id("io.element.android-library")
18+
alias(libs.plugins.anvil)
19+
}
20+
21+
android {
22+
namespace = "io.element.android.libraries.mediaplayer.api"
23+
}
24+
25+
anvil {
26+
generateDaggerFactories.set(true)
27+
}
28+
29+
dependencies {
30+
implementation(projects.libraries.matrix.api)
31+
implementation(libs.coroutines.core)
32+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.element.android.libraries.mediaplayer.api
18+
19+
import io.element.android.libraries.matrix.api.core.EventId
20+
import kotlinx.coroutines.flow.StateFlow
21+
22+
/**
23+
* A media player for Element X.
24+
*/
25+
interface MediaPlayer : AutoCloseable {
26+
27+
/**
28+
* The current state of the player.
29+
*/
30+
val state: StateFlow<State>
31+
32+
/**
33+
* Acquires control of the player and starts playing the given media.
34+
*/
35+
fun acquireControlAndPlay(
36+
uri: String,
37+
mediaId: String,
38+
mimeType: String,
39+
)
40+
41+
/**
42+
* Plays the current media.
43+
*/
44+
fun play()
45+
46+
/**
47+
* Pauses the current media.
48+
*/
49+
fun pause()
50+
51+
/**
52+
* Seeks the current media to the given position.
53+
*/
54+
fun seekTo(positionMs: Long)
55+
56+
/**
57+
* Releases any resources associated with this player.
58+
*/
59+
override fun close()
60+
61+
data class State(
62+
/**
63+
* Whether the player is currently playing.
64+
*/
65+
val isPlaying: Boolean,
66+
/**
67+
* The id of the media which is currently playing.
68+
*
69+
* NB: This is usually the string representation of the [EventId] of the event
70+
* which contains the media.
71+
*/
72+
val mediaId: String?,
73+
/**
74+
* The current position of the player.
75+
*/
76+
val currentPosition: Long,
77+
)
78+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
plugins {
17+
id("io.element.android-library")
18+
alias(libs.plugins.anvil)
19+
}
20+
21+
android {
22+
namespace = "io.element.android.libraries.mediaplayer.impl"
23+
}
24+
25+
anvil {
26+
generateDaggerFactories.set(true)
27+
}
28+
29+
dependencies {
30+
api(projects.libraries.mediaplayer.api)
31+
implementation(libs.androidx.media3.exoplayer)
32+
33+
implementation(libs.dagger)
34+
implementation(projects.libraries.di)
35+
36+
implementation(libs.coroutines.core)
37+
38+
testImplementation(projects.tests.testutils)
39+
testImplementation(libs.test.junit)
40+
testImplementation(libs.test.truth)
41+
testImplementation(libs.test.mockk)
42+
testImplementation(libs.test.turbine)
43+
testImplementation(libs.coroutines.core)
44+
testImplementation(libs.coroutines.test)
45+
}
Lines changed: 2 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
* limitations under the License.
1515
*/
1616

17-
package io.element.android.features.messages.impl.mediaplayer
17+
package io.element.android.libraries.mediaplayer.impl
1818

1919
import androidx.media3.common.MediaItem
2020
import androidx.media3.common.Player
2121
import com.squareup.anvil.annotations.ContributesBinding
2222
import io.element.android.libraries.di.RoomScope
2323
import io.element.android.libraries.di.SingleIn
24-
import io.element.android.libraries.matrix.api.core.EventId
24+
import io.element.android.libraries.mediaplayer.api.MediaPlayer
2525
import kotlinx.coroutines.CoroutineScope
2626
import kotlinx.coroutines.Dispatchers
2727
import kotlinx.coroutines.Job
@@ -33,64 +33,6 @@ import kotlinx.coroutines.flow.update
3333
import kotlinx.coroutines.launch
3434
import javax.inject.Inject
3535

36-
/**
37-
* A media player for Element X.
38-
*/
39-
interface MediaPlayer : AutoCloseable {
40-
41-
/**
42-
* The current state of the player.
43-
*/
44-
val state: StateFlow<State>
45-
46-
/**
47-
* Acquires control of the player and starts playing the given media.
48-
*/
49-
fun acquireControlAndPlay(
50-
uri: String,
51-
mediaId: String,
52-
mimeType: String,
53-
)
54-
55-
/**
56-
* Plays the current media.
57-
*/
58-
fun play()
59-
60-
/**
61-
* Pauses the current media.
62-
*/
63-
fun pause()
64-
65-
/**
66-
* Seeks the current media to the given position.
67-
*/
68-
fun seekTo(positionMs: Long)
69-
70-
/**
71-
* Releases any resources associated with this player.
72-
*/
73-
override fun close()
74-
75-
data class State(
76-
/**
77-
* Whether the player is currently playing.
78-
*/
79-
val isPlaying: Boolean,
80-
/**
81-
* The id of the media which is currently playing.
82-
*
83-
* NB: This is usually the string representation of the [EventId] of the event
84-
* which contains the media.
85-
*/
86-
val mediaId: String?,
87-
/**
88-
* The current position of the player.
89-
*/
90-
val currentPosition: Long,
91-
)
92-
}
93-
9436
/**
9537
* Default implementation of [MediaPlayer] backed by a [SimplePlayer].
9638
*/
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package io.element.android.features.messages.impl.mediaplayer
17+
package io.element.android.libraries.mediaplayer.impl
1818

1919
import android.content.Context
2020
import androidx.media3.common.MediaItem
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.element.android.libraries.mediaplayer.impl
18+
19+
import kotlinx.coroutines.test.runTest
20+
import org.junit.Test
21+
22+
class MediaPlayerImplTest {
23+
@Test
24+
fun `default test`() = runTest {
25+
// TODO
26+
}
27+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
plugins {
18+
id("io.element.android-library")
19+
}
20+
21+
android {
22+
namespace = "io.element.android.libraries.mediaplayer.test"
23+
}
24+
25+
dependencies {
26+
api(projects.libraries.mediaplayer.api)
27+
implementation(projects.tests.testutils)
28+
29+
implementation(libs.coroutines.test)
30+
implementation(libs.test.truth)
31+
}

0 commit comments

Comments
 (0)