Merge pull request #4557 from vector-im/feature/adm/voice-keep-screen-on
Keep device screen on during voice message playback and recording
This commit is contained in:
commit
7beec1c726
|
@ -0,0 +1 @@
|
||||||
|
Keeping device screen on whilst recording and playing back voice messages
|
|
@ -19,6 +19,7 @@ package im.vector.app.core.extensions
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import android.view.WindowManager
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.result.ActivityResult
|
import androidx.activity.result.ActivityResult
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
@ -112,3 +113,11 @@ fun Activity.restart() {
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Activity.keepScreenOn() {
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Activity.endKeepScreenOn() {
|
||||||
|
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
}
|
||||||
|
|
|
@ -30,12 +30,15 @@ import com.airbnb.mvrx.viewModel
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.extensions.endKeepScreenOn
|
||||||
import im.vector.app.core.extensions.hideKeyboard
|
import im.vector.app.core.extensions.hideKeyboard
|
||||||
|
import im.vector.app.core.extensions.keepScreenOn
|
||||||
import im.vector.app.core.extensions.replaceFragment
|
import im.vector.app.core.extensions.replaceFragment
|
||||||
import im.vector.app.core.platform.ToolbarConfigurable
|
import im.vector.app.core.platform.ToolbarConfigurable
|
||||||
import im.vector.app.core.platform.VectorBaseActivity
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
import im.vector.app.databinding.ActivityRoomDetailBinding
|
import im.vector.app.databinding.ActivityRoomDetailBinding
|
||||||
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment
|
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment
|
||||||
|
import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker
|
||||||
import im.vector.app.features.matrixto.MatrixToBottomSheet
|
import im.vector.app.features.matrixto.MatrixToBottomSheet
|
||||||
import im.vector.app.features.navigation.Navigator
|
import im.vector.app.features.navigation.Navigator
|
||||||
import im.vector.app.features.room.RequireActiveMembershipAction
|
import im.vector.app.features.room.RequireActiveMembershipAction
|
||||||
|
@ -43,6 +46,7 @@ import im.vector.app.features.room.RequireActiveMembershipViewEvents
|
||||||
import im.vector.app.features.room.RequireActiveMembershipViewModel
|
import im.vector.app.features.room.RequireActiveMembershipViewModel
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class RoomDetailActivity :
|
class RoomDetailActivity :
|
||||||
|
@ -71,8 +75,19 @@ class RoomDetailActivity :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var lastKnownPlayingOrRecordingState: Boolean? = null
|
||||||
|
private val playbackActivityListener = VoiceMessagePlaybackTracker.ActivityListener { isPlayingOrRecording ->
|
||||||
|
if (lastKnownPlayingOrRecordingState == isPlayingOrRecording) return@ActivityListener
|
||||||
|
when (isPlayingOrRecording) {
|
||||||
|
true -> keepScreenOn()
|
||||||
|
false -> endKeepScreenOn()
|
||||||
|
}
|
||||||
|
lastKnownPlayingOrRecordingState = isPlayingOrRecording
|
||||||
|
}
|
||||||
|
|
||||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||||
|
|
||||||
|
@Inject lateinit var playbackTracker: VoiceMessagePlaybackTracker
|
||||||
private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel
|
private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel
|
||||||
private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel()
|
private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel()
|
||||||
|
|
||||||
|
@ -114,6 +129,8 @@ class RoomDetailActivity :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
views.drawerLayout.addDrawerListener(drawerListener)
|
views.drawerLayout.addDrawerListener(drawerListener)
|
||||||
|
|
||||||
|
playbackTracker.trackActivity(playbackActivityListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRoomLeft(roomLeft: RequireActiveMembershipViewEvents.RoomLeft) {
|
private fun handleRoomLeft(roomLeft: RequireActiveMembershipViewEvents.RoomLeft) {
|
||||||
|
@ -136,6 +153,7 @@ class RoomDetailActivity :
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks)
|
supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks)
|
||||||
views.drawerLayout.removeDrawerListener(drawerListener)
|
views.drawerLayout.removeDrawerListener(drawerListener)
|
||||||
|
playbackTracker.unTrackActivity(playbackActivityListener)
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ class VoiceMessageHelper @Inject constructor(
|
||||||
voiceRecorder.stopRecord()
|
voiceRecorder.stopRecord()
|
||||||
voiceRecorder.getVoiceMessageFile()
|
voiceRecorder.getVoiceMessageFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
voiceMessageFile?.let {
|
voiceMessageFile?.let {
|
||||||
val outputFileUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", it, "Voice message.${it.extension}")
|
val outputFileUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", it, "Voice message.${it.extension}")
|
||||||
|
@ -153,6 +154,7 @@ class VoiceMessageHelper @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopPlayback() {
|
fun stopPlayback() {
|
||||||
|
playbackTracker.stopPlayback(VoiceMessagePlaybackTracker.RECORDING_ID)
|
||||||
mediaPlayer?.stop()
|
mediaPlayer?.stop()
|
||||||
stopPlaybackTicker()
|
stopPlaybackTicker()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,17 @@ class VoiceMessagePlaybackTracker @Inject constructor() {
|
||||||
|
|
||||||
private val mainHandler = Handler(Looper.getMainLooper())
|
private val mainHandler = Handler(Looper.getMainLooper())
|
||||||
private val listeners = mutableMapOf<String, Listener>()
|
private val listeners = mutableMapOf<String, Listener>()
|
||||||
|
private val activityListeners = mutableListOf<ActivityListener>()
|
||||||
private val states = mutableMapOf<String, Listener.State>()
|
private val states = mutableMapOf<String, Listener.State>()
|
||||||
|
|
||||||
|
fun trackActivity(listener: ActivityListener) {
|
||||||
|
activityListeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unTrackActivity(listener: ActivityListener) {
|
||||||
|
activityListeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
fun track(id: String, listener: Listener) {
|
fun track(id: String, listener: Listener) {
|
||||||
listeners[id] = listener
|
listeners[id] = listener
|
||||||
|
|
||||||
|
@ -52,8 +61,10 @@ class VoiceMessagePlaybackTracker @Inject constructor() {
|
||||||
*/
|
*/
|
||||||
private fun setState(key: String, state: Listener.State) {
|
private fun setState(key: String, state: Listener.State) {
|
||||||
states[key] = state
|
states[key] = state
|
||||||
|
val isPlayingOrRecording = states.values.any { it is Listener.State.Playing || it is Listener.State.Recording }
|
||||||
mainHandler.post {
|
mainHandler.post {
|
||||||
listeners[key]?.onUpdate(state)
|
listeners[key]?.onUpdate(state)
|
||||||
|
activityListeners.forEach { it.onUpdate(isPlayingOrRecording) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,4 +136,8 @@ class VoiceMessagePlaybackTracker @Inject constructor() {
|
||||||
data class Recording(val amplitudeList: List<Int>) : State()
|
data class Recording(val amplitudeList: List<Int>) : State()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun interface ActivityListener {
|
||||||
|
fun onUpdate(isPlayingOrRecording: Boolean)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue