diff --git a/changelog.d/4022.bugfix b/changelog.d/4022.bugfix new file mode 100644 index 0000000000..517926e018 --- /dev/null +++ b/changelog.d/4022.bugfix @@ -0,0 +1 @@ +Keeping device screen on whilst recording and playing back voice messages \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt index de469b9e3a..da58498238 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt @@ -19,6 +19,7 @@ package im.vector.app.core.extensions import android.app.Activity import android.content.Intent import android.os.Parcelable +import android.view.WindowManager import androidx.activity.ComponentActivity import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher @@ -112,3 +113,11 @@ fun Activity.restart() { startActivity(intent) finish() } + +fun Activity.keepScreenOn() { + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) +} + +fun Activity.endKeepScreenOn() { + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index 415ca7bc04..684c0010a5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -30,12 +30,15 @@ import com.airbnb.mvrx.viewModel import com.google.android.material.appbar.MaterialToolbar import dagger.hilt.android.AndroidEntryPoint 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.keepScreenOn import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityRoomDetailBinding 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.navigation.Navigator 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 kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import javax.inject.Inject @AndroidEntryPoint 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 + @Inject lateinit var playbackTracker: VoiceMessagePlaybackTracker private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel() @@ -114,6 +129,8 @@ class RoomDetailActivity : } } views.drawerLayout.addDrawerListener(drawerListener) + + playbackTracker.trackActivity(playbackActivityListener) } private fun handleRoomLeft(roomLeft: RequireActiveMembershipViewEvents.RoomLeft) { @@ -136,6 +153,7 @@ class RoomDetailActivity : override fun onDestroy() { supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks) views.drawerLayout.removeDrawerListener(drawerListener) + playbackTracker.unTrackActivity(playbackActivityListener) super.onDestroy() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt index 5d351e843f..592bf31739 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt @@ -74,6 +74,7 @@ class VoiceMessageHelper @Inject constructor( voiceRecorder.stopRecord() voiceRecorder.getVoiceMessageFile() } + try { voiceMessageFile?.let { val outputFileUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", it, "Voice message.${it.extension}") @@ -153,6 +154,7 @@ class VoiceMessageHelper @Inject constructor( } fun stopPlayback() { + playbackTracker.stopPlayback(VoiceMessagePlaybackTracker.RECORDING_ID) mediaPlayer?.stop() stopPlaybackTicker() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt index 86cc792e7b..c6204bff1c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt @@ -26,8 +26,17 @@ class VoiceMessagePlaybackTracker @Inject constructor() { private val mainHandler = Handler(Looper.getMainLooper()) private val listeners = mutableMapOf() + private val activityListeners = mutableListOf() private val states = mutableMapOf() + fun trackActivity(listener: ActivityListener) { + activityListeners.add(listener) + } + + fun unTrackActivity(listener: ActivityListener) { + activityListeners.remove(listener) + } + fun track(id: String, listener: Listener) { listeners[id] = listener @@ -52,8 +61,10 @@ class VoiceMessagePlaybackTracker @Inject constructor() { */ private fun setState(key: String, state: Listener.State) { states[key] = state + val isPlayingOrRecording = states.values.any { it is Listener.State.Playing || it is Listener.State.Recording } mainHandler.post { listeners[key]?.onUpdate(state) + activityListeners.forEach { it.onUpdate(isPlayingOrRecording) } } } @@ -125,4 +136,8 @@ class VoiceMessagePlaybackTracker @Inject constructor() { data class Recording(val amplitudeList: List) : State() } } + + fun interface ActivityListener { + fun onUpdate(isPlayingOrRecording: Boolean) + } }