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:
@@ -11,7 +11,8 @@ android_app {
|
|||||||
|
|
||||||
srcs: [
|
srcs: [
|
||||||
"src/**/*.kt",
|
"src/**/*.kt",
|
||||||
"src/**/*.java"
|
"src/**/*.java",
|
||||||
|
"src/**/*.aidl"
|
||||||
],
|
],
|
||||||
|
|
||||||
certificate: "platform",
|
certificate: "platform",
|
||||||
|
|||||||
@@ -85,6 +85,7 @@
|
|||||||
<item>Start/Stop Log Capture</item>
|
<item>Start/Stop Log Capture</item>
|
||||||
<item>Open GameBar Settings</item>
|
<item>Open GameBar Settings</item>
|
||||||
<item>Take Screenshot</item>
|
<item>Take Screenshot</item>
|
||||||
|
<item>Start/Stop Screen Record</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="gesture_function_values">
|
<string-array name="gesture_function_values">
|
||||||
<item>no_action</item>
|
<item>no_action</item>
|
||||||
@@ -92,6 +93,7 @@
|
|||||||
<item>capture_logs</item>
|
<item>capture_logs</item>
|
||||||
<item>open_settings</item>
|
<item>open_settings</item>
|
||||||
<item>take_screenshot</item>
|
<item>take_screenshot</item>
|
||||||
|
<item>screen_record</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<!-- Long press timeouts -->
|
<!-- Long press timeouts -->
|
||||||
|
|||||||
@@ -35,6 +35,13 @@ import java.io.IOException
|
|||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
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) {
|
class GameBar private constructor(context: Context) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -131,6 +138,17 @@ class GameBar private constructor(context: Context) {
|
|||||||
private var longPressFunction = "open_settings"
|
private var longPressFunction = "open_settings"
|
||||||
private var bgDrawable: GradientDrawable? = null
|
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 itemSpacingDp = 8
|
||||||
private var layoutChanged = false
|
private var layoutChanged = false
|
||||||
|
|
||||||
@@ -208,6 +226,9 @@ class GameBar private constructor(context: Context) {
|
|||||||
"take_screenshot" -> {
|
"take_screenshot" -> {
|
||||||
takeScreenshot()
|
takeScreenshot()
|
||||||
}
|
}
|
||||||
|
"screen_record" -> {
|
||||||
|
toggleScreenRecording()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +323,9 @@ class GameBar private constructor(context: Context) {
|
|||||||
}
|
}
|
||||||
overlayView = null
|
overlayView = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bindScreenRecorder()
|
||||||
|
|
||||||
applyPreferences()
|
applyPreferences()
|
||||||
|
|
||||||
layoutParams = WindowManager.LayoutParams(
|
layoutParams = WindowManager.LayoutParams(
|
||||||
@@ -433,6 +456,8 @@ class GameBar private constructor(context: Context) {
|
|||||||
rootLayout = null
|
rootLayout = null
|
||||||
layoutParams = null
|
layoutParams = null
|
||||||
layoutChanged = true // Mark layout as changed
|
layoutChanged = true // Mark layout as changed
|
||||||
|
|
||||||
|
unbindScreenRecorder()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cleanup() {
|
fun cleanup() {
|
||||||
@@ -1167,6 +1192,59 @@ class GameBar private constructor(context: Context) {
|
|||||||
Toast.makeText(context, "Failed to take screenshot", Toast.LENGTH_SHORT).show()
|
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() {
|
private fun openOverlaySettings() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.android.systemui.screenrecord;
|
||||||
|
|
||||||
|
interface IRecordingCallback {
|
||||||
|
void onRecordingStart();
|
||||||
|
void onRecordingEnd();
|
||||||
|
}
|
||||||
12
src/com/android/systemui/screenrecord/IRemoteRecording.aidl
Normal file
12
src/com/android/systemui/screenrecord/IRemoteRecording.aidl
Normal 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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user