diff --git a/Android.bp b/Android.bp
index 0652f15..6e26d9f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -11,7 +11,8 @@ android_app {
srcs: [
"src/**/*.kt",
- "src/**/*.java"
+ "src/**/*.java",
+ "src/**/*.aidl"
],
certificate: "platform",
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 400773b..81f64e3 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -85,6 +85,7 @@
- Start/Stop Log Capture
- Open GameBar Settings
- Take Screenshot
+ - Start/Stop Screen Record
- no_action
@@ -92,6 +93,7 @@
- capture_logs
- open_settings
- take_screenshot
+ - screen_record
diff --git a/src/com/android/gamebar/GameBar.kt b/src/com/android/gamebar/GameBar.kt
index d1a4680..8ec05b8 100644
--- a/src/com/android/gamebar/GameBar.kt
+++ b/src/com/android/gamebar/GameBar.kt
@@ -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 {
diff --git a/src/com/android/systemui/screenrecord/IRecordingCallback.aidl b/src/com/android/systemui/screenrecord/IRecordingCallback.aidl
new file mode 100644
index 0000000..ee4a463
--- /dev/null
+++ b/src/com/android/systemui/screenrecord/IRecordingCallback.aidl
@@ -0,0 +1,6 @@
+package com.android.systemui.screenrecord;
+
+interface IRecordingCallback {
+ void onRecordingStart();
+ void onRecordingEnd();
+}
diff --git a/src/com/android/systemui/screenrecord/IRemoteRecording.aidl b/src/com/android/systemui/screenrecord/IRemoteRecording.aidl
new file mode 100644
index 0000000..13cbf8d
--- /dev/null
+++ b/src/com/android/systemui/screenrecord/IRemoteRecording.aidl
@@ -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);
+}