Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7f49465 authored by Anton Potapov's avatar Anton Potapov
Browse files

Move ScreenRecordingService binder calls to a background thread

Flag: EXEMPT BUG FIX
Bug: 368579013
Test: atest ScreenRecordingServiceInteractorTest
Change-Id: I53ee7f611c5b82f0218953d4ac0e49178586af70
parent 5ef0fe3d
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -20,7 +20,9 @@ import android.content.ComponentName
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
import android.content.ServiceConnection
import android.content.ServiceConnection
import android.graphics.drawable.Icon
import android.media.projection.StopReason
import android.media.projection.StopReason
import android.net.Uri
import android.os.IBinder
import android.os.IBinder
import androidx.annotation.WorkerThread
import androidx.annotation.WorkerThread
import com.android.app.tracing.coroutines.flow.asStateFlowTraced
import com.android.app.tracing.coroutines.flow.asStateFlowTraced
@@ -182,6 +184,8 @@ constructor(
        override fun onRecordingInterrupted(userId: Int, reason: Int) {
        override fun onRecordingInterrupted(userId: Int, reason: Int) {
            stopRecording(reason)
            stopRecording(reason)
        }
        }

        override fun onRecordingSaved(recordingUri: Uri?, thumbnail: Icon?) {}
    }
    }


    private data class RecordingContext(val status: Status, val service: IScreenRecordingService?)
    private data class RecordingContext(val status: Status, val service: IScreenRecordingService?)
+4 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.screenrecord.service;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.Intent;
import android.os.Bundle;
import android.os.Bundle;
import android.net.Uri;
import android.graphics.drawable.Icon;


oneway interface IScreenRecordingServiceCallback {
oneway interface IScreenRecordingServiceCallback {


@@ -31,4 +33,6 @@ oneway interface IScreenRecordingServiceCallback {
    * Called when the recording is interrupted for some reason.
    * Called when the recording is interrupted for some reason.
    */
    */
    void onRecordingInterrupted(int userId, int reason);
    void onRecordingInterrupted(int userId, int reason);

    void onRecordingSaved(in Uri recordingUri, in Icon thumbnail);
}
}
 No newline at end of file
+18 −8
Original line number Original line Diff line number Diff line
@@ -78,19 +78,20 @@ protected constructor(
            },
            },
        )
        )


    private val backgroundContext = Dispatchers.IO
    private val binder = BinderInterface()
    private val binder = BinderInterface()
    private val screenMediaRecorderListener: ScreenMediaRecorder.ScreenMediaRecorderListener =
    private val screenMediaRecorderListener: ScreenMediaRecorder.ScreenMediaRecorderListener =
        object : ScreenMediaRecorder.ScreenMediaRecorderListener {
        object : ScreenMediaRecorder.ScreenMediaRecorderListener {
            override fun onStarted() {
            override fun onStarted() {
                callback?.onRecordingStarted()
                launchCallbackAction { onRecordingStarted() }
            }
            }


            override fun onInfo(mr: MediaRecorder?, what: Int, extra: Int) {
            override fun onInfo(mr: MediaRecorder?, what: Int, extra: Int) {
                callback?.onRecordingInterrupted(userId, StopReason.STOP_ERROR)
                launchCallbackAction { onRecordingInterrupted(userId, StopReason.STOP_ERROR) }
            }
            }


            override fun onStopped(userId: Int, @StopReason stopReason: Int) {
            override fun onStopped(userId: Int, @StopReason stopReason: Int) {
                callback?.onRecordingInterrupted(userId, stopReason)
                launchCallbackAction { onRecordingInterrupted(userId, stopReason) }
            }
            }
        }
        }


@@ -108,11 +109,13 @@ protected constructor(
        val action = intent?.action
        val action = intent?.action
        when (action) {
        when (action) {
            ACTION_STOP ->
            ACTION_STOP ->
                callback?.onRecordingInterrupted(
                launchCallbackAction {
                    onRecordingInterrupted(
                        userId,
                        userId,
                        intent.getIntExtra(EXTRA_STOP_REASON, StopReason.STOP_UNKNOWN),
                        intent.getIntExtra(EXTRA_STOP_REASON, StopReason.STOP_UNKNOWN),
                    )
                    )
                }
                }
        }
        return START_NOT_STICKY
        return START_NOT_STICKY
    }
    }


@@ -143,7 +146,10 @@ protected constructor(
                notificationId = notificationId,
                notificationId = notificationId,
                audioSource = audioSource,
                audioSource = audioSource,
            )
            )
            val savedRecording: SavedRecording = withContext(Dispatchers.IO) { recorder.save() }
            val savedRecording: SavedRecording =
                withContext(backgroundContext) {
                    recorder.save().apply { callback?.onRecordingSaved(uri, thumbnail) }
                }
            onRecordingSaved(this, savedRecording)
            onRecordingSaved(this, savedRecording)
        } catch (e: Exception) {
        } catch (e: Exception) {
            notificationInteractor.notifyErrorSaving(notificationId)
            notificationInteractor.notifyErrorSaving(notificationId)
@@ -178,6 +184,10 @@ protected constructor(
    private fun getShouldShowTouches(): Boolean =
    private fun getShouldShowTouches(): Boolean =
        Settings.System.getInt(contentResolver, Settings.System.SHOW_TOUCHES, 0) != 0
        Settings.System.getInt(contentResolver, Settings.System.SHOW_TOUCHES, 0) != 0


    private fun launchCallbackAction(action: IScreenRecordingServiceCallback.() -> Unit) {
        callback?.let { coroutineScope.launch(backgroundContext) { it.action() } }
    }

    private inner class BinderInterface : IScreenRecordingService.Stub() {
    private inner class BinderInterface : IScreenRecordingService.Stub() {


        override fun setCallback(serviceCallback: IScreenRecordingServiceCallback?) {
        override fun setCallback(serviceCallback: IScreenRecordingServiceCallback?) {
+9 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.systemui.screenrecord.service
package com.android.systemui.screenrecord.service


import android.graphics.drawable.Icon
import android.net.Uri
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -36,12 +38,19 @@ class FakeScreenRecordingServiceCallbackWrapper(private val real: IScreenRecordi
        real.onRecordingInterrupted(userId, reason)
        real.onRecordingInterrupted(userId, reason)
    }
    }


    override fun onRecordingSaved(recordingUri: Uri, thumbnail: Icon) {
        _status.value = RecordingStatus.Saved(recordingUri = recordingUri, thumbnail = thumbnail)
        real.onRecordingSaved(recordingUri, thumbnail)
    }

    sealed interface RecordingStatus {
    sealed interface RecordingStatus {


        data object Initial : RecordingStatus
        data object Initial : RecordingStatus


        data object Started : RecordingStatus
        data object Started : RecordingStatus


        data class Saved(val recordingUri: Uri, val thumbnail: Icon) : RecordingStatus

        data class Interrupted(val userId: Int, val reason: Int) : RecordingStatus
        data class Interrupted(val userId: Int, val reason: Int) : RecordingStatus
    }
    }
}
}