GameBar: Add screen recording support and add "take screen record" in gesture quick actions menu

Signed-off-by: kenway214 <kenway214@outlook.com>
This commit is contained in:
kenway214
2025-11-03 00:30:44 +05:30
parent 71cdb5b6a2
commit 55fcc0a04c
5 changed files with 101 additions and 2 deletions

View File

@@ -11,7 +11,8 @@ android_app {
srcs: [
"src/**/*.kt",
"src/**/*.java"
"src/**/*.java",
"src/**/*.aidl"
],
certificate: "platform",

View File

@@ -85,6 +85,7 @@
<item>Start/Stop Log Capture</item>
<item>Open GameBar Settings</item>
<item>Take Screenshot</item>
<item>Start/Stop Screen Record</item>
</string-array>
<string-array name="gesture_function_values">
<item>no_action</item>
@@ -92,6 +93,7 @@
<item>capture_logs</item>
<item>open_settings</item>
<item>take_screenshot</item>
<item>screen_record</item>
</string-array>
<!-- Long press timeouts -->

View File

@@ -35,6 +35,13 @@ import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import android.content.ComponentName
import android.content.ServiceConnection
import android.os.IBinder
import android.os.UserHandle
import com.android.systemui.screenrecord.IRemoteRecording
import com.android.systemui.screenrecord.IRecordingCallback
class GameBar private constructor(context: Context) {
companion object {
@@ -131,6 +138,17 @@ class GameBar private constructor(context: Context) {
private var longPressFunction = "open_settings"
private var bgDrawable: GradientDrawable? = null
private var isRecorderBound = false
private var remoteRecording: IRemoteRecording? = null
private val recorderConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
remoteRecording = IRemoteRecording.Stub.asInterface(service)
}
override fun onServiceDisconnected(name: ComponentName?) {
remoteRecording = null
}
}
private var itemSpacingDp = 8
private var layoutChanged = false
@@ -208,6 +226,9 @@ class GameBar private constructor(context: Context) {
"take_screenshot" -> {
takeScreenshot()
}
"screen_record" -> {
toggleScreenRecording()
}
}
}
@@ -302,7 +323,9 @@ class GameBar private constructor(context: Context) {
}
overlayView = null
}
bindScreenRecorder()
applyPreferences()
layoutParams = WindowManager.LayoutParams(
@@ -433,6 +456,8 @@ class GameBar private constructor(context: Context) {
rootLayout = null
layoutParams = null
layoutChanged = true // Mark layout as changed
unbindScreenRecorder()
}
fun cleanup() {
@@ -1167,6 +1192,59 @@ class GameBar private constructor(context: Context) {
Toast.makeText(context, "Failed to take screenshot", Toast.LENGTH_SHORT).show()
}
}
private fun bindScreenRecorder() {
try {
isRecorderBound = context.bindServiceAsUser(Intent().apply {
component = ComponentName(
"com.android.systemui",
"com.android.systemui.screenrecord.RecordingService"
)
}, recorderConnection, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)
} catch (e: Exception) {
android.util.Log.e("GameBar", "Failed to bind screen recorder: ${e.message}")
isRecorderBound = false
}
}
private fun unbindScreenRecorder() {
if (isRecorderBound) {
try {
context.unbindService(recorderConnection)
} catch (e: Exception) {
android.util.Log.w("GameBar", "Failed to unbind screen recorder: ${e.message}")
} finally {
isRecorderBound = false
remoteRecording = null
}
}
}
private fun toggleScreenRecording() {
val recorder = remoteRecording
if (recorder == null) {
Toast.makeText(context, "Screen recorder not available", Toast.LENGTH_SHORT).show()
return
}
try {
val isStarting = try { recorder.isStarting } catch (e: Exception) { false }
val isRecording = try { recorder.isRecording } catch (e: Exception) { false }
if (!isStarting) {
if (!isRecording) {
recorder.startRecording()
Toast.makeText(context, "Screen recording started", Toast.LENGTH_SHORT).show()
} else {
recorder.stopRecording()
Toast.makeText(context, "Screen recording stopped", Toast.LENGTH_SHORT).show()
}
}
} catch (e: Exception) {
Toast.makeText(context, "Failed to toggle screen recording", Toast.LENGTH_SHORT).show()
android.util.Log.e("GameBar", "Screen recording error: ${e.message}")
}
}
private fun openOverlaySettings() {
try {

View File

@@ -0,0 +1,6 @@
package com.android.systemui.screenrecord;
interface IRecordingCallback {
void onRecordingStart();
void onRecordingEnd();
}

View File

@@ -0,0 +1,12 @@
package com.android.systemui.screenrecord;
import com.android.systemui.screenrecord.IRecordingCallback;
interface IRemoteRecording {
void startRecording();
void stopRecording();
boolean isRecording();
boolean isStarting();
void addRecordingCallback(in IRecordingCallback callback);
void removeRecordingCallback(in IRecordingCallback callback);
}