-
Notifications
You must be signed in to change notification settings - Fork 731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Voice Broadcast] Use internal playback timer to compute the playback position #8012
Changes from all commits
af67705
a061045
bdfebac
05ffadb
003c2cd
3d87b79
ff07cad
44266bc
15c610f
7bb7a62
ecc0cb5
3ce757e
a0ab6de
f74c7fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[Voice Broadcast] Use internal playback timer to compute the current playback position |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright (c) 2023 New Vector Ltd | ||
* | ||
* 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 im.vector.lib.core.utils.timer | ||
|
||
interface Clock { | ||
fun epochMillis(): Long | ||
} | ||
|
||
class DefaultClock : Clock { | ||
|
||
/** | ||
* Provides a UTC epoch in milliseconds | ||
* | ||
* This value is not guaranteed to be correct with reality | ||
* as a User can override the system time and date to any values. | ||
*/ | ||
override fun epochMillis(): Long { | ||
return System.currentTimeMillis() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,41 +28,50 @@ import java.util.concurrent.atomic.AtomicBoolean | |
import java.util.concurrent.atomic.AtomicLong | ||
|
||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class) | ||
class CountUpTimer(private val intervalInMs: Long = 1_000) { | ||
class CountUpTimer(initialTime: Long = 0L, private val intervalInMs: Long = 1_000) { | ||
|
||
private val coroutineScope = CoroutineScope(Dispatchers.Main) | ||
private val elapsedTime: AtomicLong = AtomicLong() | ||
private val resumed: AtomicBoolean = AtomicBoolean(false) | ||
|
||
private val clock: Clock = DefaultClock() | ||
private val lastTime: AtomicLong = AtomicLong() | ||
private val elapsedTime: AtomicLong = AtomicLong(initialTime) | ||
|
||
init { | ||
startCounter() | ||
} | ||
|
||
private fun startCounter() { | ||
tickerFlow(coroutineScope, intervalInMs / 10) | ||
tickerFlow(coroutineScope, intervalInMs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Are you sure you want to revert this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bmarty The elapsed time and the current time are updated when the timer is paused & resumed (see https://github.com/vector-im/element-android/blob/941d0e5cf4c509fbc1ef6d3f29fa4242266dc74e/library/core-utils/src/main/java/im/vector/lib/core/utils/timer/CountUpTimer.kt#L58-L66), it should be more precise now and the previous trick should not be necessary anymore. Moreover, the timer does not work anymore if the interval is too low (eg. under 10 ms), the ticks are too close and it does not notify in the expected delay (it can take more than 2 seconds to notify 1 second...), so it is better to keep the real interval value and do not divide the value by ten to prevent this bad behaviour. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading the code again, I think user can observe an extra delay if we keep a tick per second. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed together IRL, @Florian14 will make a dedicated PR to improve |
||
.filter { resumed.get() } | ||
.map { elapsedTime.addAndGet(intervalInMs / 10) } | ||
.filter { it % intervalInMs == 0L } | ||
.onEach { | ||
tickListener?.onTick(it) | ||
}.launchIn(coroutineScope) | ||
.map { elapsedTime() } | ||
.onEach { tickListener?.onTick(it) } | ||
.launchIn(coroutineScope) | ||
} | ||
|
||
var tickListener: TickListener? = null | ||
|
||
fun elapsedTime(): Long { | ||
return elapsedTime.get() | ||
return if (resumed.get()) { | ||
val now = clock.epochMillis() | ||
elapsedTime.addAndGet(now - lastTime.getAndSet(now)) | ||
} else { | ||
elapsedTime.get() | ||
} | ||
} | ||
|
||
fun pause() { | ||
tickListener?.onTick(elapsedTime()) | ||
resumed.set(false) | ||
} | ||
|
||
fun resume() { | ||
lastTime.set(clock.epochMillis()) | ||
resumed.set(true) | ||
} | ||
|
||
fun stop() { | ||
tickListener?.onTick(elapsedTime()) | ||
coroutineScope.cancel() | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not find a better way instead of duplicating this file. I have issues with DI after moving the existing clock interface from the vector module into this one. Also, I cannot move the CountUpTimer to the vector module because another lib is using it.