From 2c8808d0472fd9d2806946de37bb47546114ab5d Mon Sep 17 00:00:00 2001 From: Abhay Singh Gill Date: Sat, 14 Dec 2024 22:49:56 +0530 Subject: [PATCH 1/2] SystemUI: Use Material3 switches for screenrecord options Signed-off-by: Abhay Singh Gill Signed-off-by: Dmitrii Signed-off-by: Ghosuto --- .../res/layout/screen_record_options.xml | 26 +++++++++---------- .../ScreenRecordPermissionContentManager.kt | 14 +++++----- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/SystemUI/res/layout/screen_record_options.xml b/packages/SystemUI/res/layout/screen_record_options.xml index cb9f904072eab..53474b9b365c4 100644 --- a/packages/SystemUI/res/layout/screen_record_options.xml +++ b/packages/SystemUI/res/layout/screen_record_options.xml @@ -41,14 +41,14 @@ android:dropDownWidth="274dp" android:importantForAccessibility="yes"/> - - - - - - - \ No newline at end of file + diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt index 71f8ce079b1f7..6e98c37dccf47 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt @@ -38,8 +38,8 @@ import android.view.View.VISIBLE import android.view.accessibility.AccessibilityNodeInfo import android.widget.AdapterView import android.widget.ArrayAdapter +import android.widget.CompoundButton import android.widget.Spinner -import android.widget.Switch import androidx.annotation.LayoutRes import com.android.systemui.Prefs import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget @@ -109,12 +109,12 @@ class ScreenRecordPermissionContentManager( ): ScreenRecordPermissionContentManager } - private lateinit var tapsSwitch: Switch - private lateinit var audioSwitch: Switch - private lateinit var lowQualitySwitch: Switch - private lateinit var longerDurationSwitch: Switch - private lateinit var skipTimeSwitch: Switch - private lateinit var hevcSwitch: Switch + private lateinit var tapsSwitch: CompoundButton + private lateinit var audioSwitch: CompoundButton + private lateinit var lowQualitySwitch: CompoundButton + private lateinit var longerDurationSwitch: CompoundButton + private lateinit var skipTimeSwitch: CompoundButton + private lateinit var hevcSwitch: CompoundButton private lateinit var tapsView: View private lateinit var options: Spinner From 8b16fc13f93a2b8cc38d7c3c2c9938dc6ad76d66 Mon Sep 17 00:00:00 2001 From: rmp22 <195054967+rmp22@users.noreply.github.com> Date: Tue, 7 Apr 2026 11:52:46 +0800 Subject: [PATCH 2/2] SystemUI: Extending screen recorder options feature specs taken from motorola Change-Id: I04b794f1114cab0b50e49708827e91fd56de773e Signed-off-by: rmp22 <195054967+rmp22@users.noreply.github.com> Signed-off-by: Ghosuto Signed-off-by: zerotwo-alt --- .../res/layout/screen_record_options.xml | 169 +++++++++++++++++- .../res/layout/screenrecord_spinner_item.xml | 24 +++ packages/SystemUI/res/values/cm_strings.xml | 23 +++ packages/SystemUI/res/values/cr_arrays.xml | 46 ++++- .../screenrecord/RecordingService.java | 86 +++++++++ .../screenrecord/ScreenMediaRecorder.java | 55 +++++- .../ScreenRecordPermissionContentManager.kt | 100 +++++++++++ .../domain/ScreenRecordingParameters.kt | 5 + ...egacyScreenRecordingStartStopInteractor.kt | 5 + 9 files changed, 492 insertions(+), 21 deletions(-) create mode 100644 packages/SystemUI/res/layout/screenrecord_spinner_item.xml diff --git a/packages/SystemUI/res/layout/screen_record_options.xml b/packages/SystemUI/res/layout/screen_record_options.xml index 53474b9b365c4..be47cb6d41676 100644 --- a/packages/SystemUI/res/layout/screen_record_options.xml +++ b/packages/SystemUI/res/layout/screen_record_options.xml @@ -91,7 +91,8 @@ android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" - android:layout_marginTop="@dimen/screenrecord_option_padding"> + android:layout_marginTop="@dimen/screenrecord_option_padding" + android:visibility="gone"> + android:layout_marginTop="@dimen/screenrecord_option_padding" + android:visibility="gone"> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/values/cm_strings.xml b/packages/SystemUI/res/values/cm_strings.xml index 381dc02c91103..4fbd6818b1a13 100644 --- a/packages/SystemUI/res/values/cm_strings.xml +++ b/packages/SystemUI/res/values/cm_strings.xml @@ -129,6 +129,29 @@ Remove the 3 second wait HEVC encoding Use the more efficient HEVC encoder + Resolution + Frame rate + Time limit + File size limit + Video quality + High + Medium + Low + Auto + Auto + 30 FPS + 60 FPS + Unlimited + 5 minutes + 10 minutes + 30 minutes + 60 minutes + Unlimited + 10 MB + 100 MB + 500 MB + 1 GB + 15 GB This keeps it in view until you unpin. Touch & hold Back to unpin. diff --git a/packages/SystemUI/res/values/cr_arrays.xml b/packages/SystemUI/res/values/cr_arrays.xml index 79515214b333c..0640396f0d1b8 100644 --- a/packages/SystemUI/res/values/cr_arrays.xml +++ b/packages/SystemUI/res/values/cr_arrays.xml @@ -7,17 +7,47 @@ - @string/quick_settings_compass_N - @string/quick_settings_compass_NE - @string/quick_settings_compass_E - @string/quick_settings_compass_SE - @string/quick_settings_compass_S - @string/quick_settings_compass_SW - @string/quick_settings_compass_W - @string/quick_settings_compass_NW + @string/quick_settings_compass_N + @string/quick_settings_compass_NE + @string/quick_settings_compass_E + @string/quick_settings_compass_SE + @string/quick_settings_compass_S + @string/quick_settings_compass_SW + @string/quick_settings_compass_W + @string/quick_settings_compass_NW + + + @string/screenrecord_bitrate_high + @string/screenrecord_bitrate_medium + @string/screenrecord_bitrate_low + + + + @string/screenrecord_fps_auto + @string/screenrecord_fps_30 + @string/screenrecord_fps_60 + + + + @string/screenrecord_time_unlimited + @string/screenrecord_time_5min + @string/screenrecord_time_10min + @string/screenrecord_time_30min + @string/screenrecord_time_60min + + + + @string/screenrecord_size_unlimited + @string/screenrecord_size_10mb + @string/screenrecord_size_100mb + @string/screenrecord_size_500mb + @string/screenrecord_size_1gb + @string/screenrecord_size_15gb + + diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index 14ffbd6c54786..f139ecd537627 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -94,6 +94,11 @@ public class RecordingService extends Service implements ScreenMediaRecorderList private static final String EXTRA_LOW_QUALITY = "extra_lowQuality"; private static final String EXTRA_LONGER_DURATION = "extra_longerDuration"; private final static String EXTRA_HEVC = "extra_HEVC"; + private static final String EXTRA_RESOLUTION_MODE = "extra_resolutionMode"; + private static final String EXTRA_FPS_MODE = "extra_fpsMode"; + private static final String EXTRA_TIME_LIMIT_MS = "extra_timeLimitMs"; + private static final String EXTRA_FILE_SIZE_BYTES = "extra_fileSizeBytes"; + private static final String EXTRA_BITRATE_MULTIPLIER = "extra_bitrateMultiplier"; protected static final String ACTION_START = "com.android.systemui.screenrecord.START"; protected static final String ACTION_SHOW_START_NOTIF = @@ -129,6 +134,11 @@ public class RecordingService extends Service implements ScreenMediaRecorderList private boolean mLowQuality; private boolean mLongerDuration; private boolean mHEVC; + private int mResolutionMode; + private int mFpsMode; + private int mTimeLimitMs; + private long mFileSizeBytes; + private float mBitrateMultiplier = 1.0f; @Inject public RecordingService(ScreenRecordUxController controller, @LongRunning Executor executor, @@ -174,6 +184,21 @@ public static Intent getStartIntent(Context context, int resultCode, .putExtra(EXTRA_HEVC, hevc); } + public static Intent getStartIntent(Context context, int resultCode, + int audioSource, boolean showTaps, + @Nullable MediaProjectionCaptureTarget captureTarget, + boolean lowQuality, boolean longerDuration, boolean hevc, + int resolutionMode, int fpsMode, int timeLimitMs, long fileSizeBytes, + float bitrateMultiplier) { + return getStartIntent(context, resultCode, audioSource, showTaps, captureTarget, + lowQuality, longerDuration, hevc) + .putExtra(EXTRA_RESOLUTION_MODE, resolutionMode) + .putExtra(EXTRA_FPS_MODE, fpsMode) + .putExtra(EXTRA_TIME_LIMIT_MS, timeLimitMs) + .putExtra(EXTRA_FILE_SIZE_BYTES, fileSizeBytes) + .putExtra(EXTRA_BITRATE_MULTIPLIER, bitrateMultiplier); + } + /** * Get an intent to start the recording service. * @@ -202,6 +227,27 @@ public static Intent getStartIntent( .putExtra(EXTRA_DISPLAY_ID, displayId); } + public static Intent getStartIntent( + Context context, + int resultCode, + int audioSource, + boolean showTaps, + int displayId, + @Nullable MediaProjectionCaptureTarget captureTarget, + boolean lowQuality, + boolean longerDuration, + boolean hevc, + int resolutionMode, + int fpsMode, + int timeLimitMs, + long fileSizeBytes, + float bitrateMultiplier) { + return getStartIntent(context, resultCode, audioSource, showTaps, captureTarget, lowQuality, + longerDuration, hevc, resolutionMode, fpsMode, timeLimitMs, fileSizeBytes, + bitrateMultiplier) + .putExtra(EXTRA_DISPLAY_ID, displayId); + } + @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent == null) { @@ -231,6 +277,11 @@ public int onStartCommand(Intent intent, int flags, int startId) { mLowQuality = intent.getBooleanExtra(EXTRA_LOW_QUALITY, false); mLongerDuration = intent.getBooleanExtra(EXTRA_LONGER_DURATION, false); mHEVC = intent.getBooleanExtra(EXTRA_HEVC, true); + mResolutionMode = intent.getIntExtra(EXTRA_RESOLUTION_MODE, 0); + mFpsMode = intent.getIntExtra(EXTRA_FPS_MODE, 0); + mTimeLimitMs = intent.getIntExtra(EXTRA_TIME_LIMIT_MS, 0); + mFileSizeBytes = intent.getLongExtra(EXTRA_FILE_SIZE_BYTES, 0L); + mBitrateMultiplier = intent.getFloatExtra(EXTRA_BITRATE_MULTIPLIER, 1.0f); MediaProjectionCaptureTarget captureTarget = intent.getParcelableExtra(EXTRA_CAPTURE_TARGET, @@ -259,6 +310,11 @@ public int onStartCommand(Intent intent, int flags, int startId) { setLowQuality(mLowQuality); setLongerDuration(mLongerDuration); setHEVC(mHEVC); + setResolutionMode(mResolutionMode); + setRequestedFps(mFpsMode); + setTimeLimitMs(mTimeLimitMs); + setFileSizeBytes(mFileSizeBytes); + setBitrateMultiplier(mBitrateMultiplier); if (startRecording()) { updateState(true); @@ -701,6 +757,36 @@ private void setHEVC(boolean hevc) { } } + private void setResolutionMode(int resolutionMode) { + if (getRecorder() != null) { + getRecorder().setResolutionMode(resolutionMode); + } + } + + private void setRequestedFps(int fps) { + if (getRecorder() != null) { + getRecorder().setRequestedFps(fps); + } + } + + private void setTimeLimitMs(int timeLimitMs) { + if (getRecorder() != null) { + getRecorder().setTimeLimitMs(timeLimitMs); + } + } + + private void setFileSizeBytes(long fileSizeBytes) { + if (getRecorder() != null) { + getRecorder().setFileSizeBytes(fileSizeBytes); + } + } + + private void setBitrateMultiplier(float multiplier) { + if (getRecorder() != null) { + getRecorder().setBitrateMultiplier(multiplier); + } + } + private PendingIntent getStopPendingIntent() { return PendingIntent.getService(this, REQUEST_CODE, getStopIntent(this), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java index 8274713d3cb7e..996a521e25f75 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java @@ -102,6 +102,11 @@ public class ScreenMediaRecorder extends MediaProjection.Callback { private boolean mLowQuality; private boolean mLongerDuration; private boolean mHEVC; + private int mResolutionMode; + private int mRequestedFps; + private int mTimeLimitMs; + private long mFileSizeBytes; + private float mBitrateMultiplier = 1.0f; private Context mContext; ScreenMediaRecorderListener mListener; @@ -157,6 +162,26 @@ public void setHEVC(boolean hevc) { mHEVC = hevc; } + public void setResolutionMode(int resolutionMode) { + mResolutionMode = resolutionMode; + } + + public void setRequestedFps(int fps) { + mRequestedFps = fps; + } + + public void setTimeLimitMs(int timeLimitMs) { + mTimeLimitMs = timeLimitMs; + } + + public void setFileSizeBytes(long fileSizeBytes) { + mFileSizeBytes = fileSizeBytes; + } + + public void setBitrateMultiplier(float multiplier) { + mBitrateMultiplier = multiplier; + } + private void prepare() throws IOException, RemoteException, RuntimeException { //Setup media projection IBinder b = ServiceManager.getService(MEDIA_PROJECTION_SERVICE); @@ -198,16 +223,35 @@ private void prepare() throws IOException, RemoteException, RuntimeException { DisplayManager dm = mContext.getSystemService(DisplayManager.class); Display display = dm.getDisplay(mDisplayId); display.getRealMetrics(metrics); - int refreshRate = mLowQuality ? LOW_VIDEO_FRAME_RATE : (int) display.getRefreshRate(); + int refreshRate; + if (mRequestedFps > 0) { + refreshRate = mRequestedFps; + } else { + refreshRate = mLowQuality ? LOW_VIDEO_FRAME_RATE : (int) display.getRefreshRate(); + } if (mMaxRefreshRate != 0 && refreshRate > mMaxRefreshRate) refreshRate = mMaxRefreshRate; - int[] dimens = getSupportedSize(metrics.widthPixels, metrics.heightPixels, refreshRate); + int targetWidth = metrics.widthPixels; + int targetHeight = metrics.heightPixels; + if (mResolutionMode > 0) { + int longEdge = Math.max(targetWidth, targetHeight); + if (longEdge > mResolutionMode) { + double scale = (double) mResolutionMode / longEdge; + targetWidth = (int) (targetWidth * scale); + targetHeight = (int) (targetHeight * scale); + } + } else if (mResolutionMode == -1) { + targetWidth = targetWidth * 3 / 4; + targetHeight = targetHeight * 3 / 4; + } + int[] dimens = getSupportedSize(targetWidth, targetHeight, refreshRate); int width = dimens[0]; int height = dimens[1]; refreshRate = dimens[2]; int resRatio = mLowQuality ? LOW_VIDEO_FRAME_RATE_TO_RESOLUTION_RATIO : VIDEO_FRAME_RATE_TO_RESOLUTION_RATIO; - int vidBitRate = width * height * refreshRate / VIDEO_FRAME_RATE * resRatio; - long maxFilesize = mLongerDuration ? MAX_FILESIZE_BYTES_LONGER : MAX_FILESIZE_BYTES; + int vidBitRate = (int) (width * height * refreshRate / VIDEO_FRAME_RATE * resRatio * mBitrateMultiplier); + long maxFilesize = mFileSizeBytes > 0 ? mFileSizeBytes + : (mLongerDuration ? MAX_FILESIZE_BYTES_LONGER : MAX_FILESIZE_BYTES); if (!mHEVC) { mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setVideoEncodingProfileLevel( @@ -224,7 +268,8 @@ private void prepare() throws IOException, RemoteException, RuntimeException { mMediaRecorder.setVideoSize(width, height); mMediaRecorder.setVideoFrameRate(refreshRate); mMediaRecorder.setVideoEncodingBitRate(vidBitRate); - mMediaRecorder.setMaxDuration(mLongerDuration ? 0 : MAX_DURATION_MS); + int maxDurationMs = mTimeLimitMs > 0 ? mTimeLimitMs : (mLongerDuration ? 0 : MAX_DURATION_MS); + mMediaRecorder.setMaxDuration(maxDurationMs); mMediaRecorder.setMaxFileSize(maxFilesize); // Set up audio diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt index 6e98c37dccf47..4abe7d02837f9 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionContentManager.kt @@ -21,6 +21,7 @@ import android.app.Activity import android.content.Intent import android.hardware.display.DisplayManager import android.media.MediaCodecInfo +import android.util.DisplayMetrics import android.media.MediaCodecList import android.media.MediaFormat import android.media.projection.StopReason @@ -117,6 +118,12 @@ class ScreenRecordPermissionContentManager( private lateinit var hevcSwitch: CompoundButton private lateinit var tapsView: View private lateinit var options: Spinner + private lateinit var bitrateSpinner: Spinner + private lateinit var resolutionSpinner: Spinner + private lateinit var fpsSpinner: Spinner + private lateinit var timeLimitSpinner: Spinner + private lateinit var fileSizeSpinner: Spinner + private val resolutionModeValues = mutableListOf() override fun bind(view: View) { super.bind(view) @@ -191,6 +198,17 @@ class ScreenRecordPermissionContentManager( audioSwitch.isChecked = true } + resolutionSpinner = containerView.requireViewById(R.id.screenrecord_resolution_spinner) + fpsSpinner = containerView.requireViewById(R.id.screenrecord_fps_spinner) + timeLimitSpinner = containerView.requireViewById(R.id.screenrecord_time_limit_spinner) + fileSizeSpinner = containerView.requireViewById(R.id.screenrecord_file_size_spinner) + bitrateSpinner = containerView.requireViewById(R.id.screenrecord_bitrate_spinner) + setupSpinner(bitrateSpinner, R.array.screenrecord_bitrate_entries) + setupResolutionSpinner() + setupSpinner(fpsSpinner, R.array.screenrecord_fps_entries) + setupSpinner(timeLimitSpinner, R.array.screenrecord_time_limit_entries) + setupSpinner(fileSizeSpinner, R.array.screenrecord_file_size_entries) + // Disable HEVC when hardware accelerated codec is not available if (!hasHevcHwEncoder()) { Prefs.putInt(containerView.context, PREF_HEVC, 0) @@ -242,6 +260,11 @@ class ScreenRecordPermissionContentManager( val longerDuration = longerDurationSwitch.isChecked val skipTime = skipTimeSwitch.isChecked val hevc = hevcSwitch.isChecked + val bitrateMultiplier = BITRATE_MULTIPLIER_VALUES[bitrateSpinner.selectedItemPosition] + val resolutionMode = resolutionModeValues[resolutionSpinner.selectedItemPosition] + val fpsMode = FPS_MODE_VALUES[fpsSpinner.selectedItemPosition] + val timeLimitMs = TIME_LIMIT_VALUES_MS[timeLimitSpinner.selectedItemPosition] + val fileSizeBytes = FILE_SIZE_VALUES_BYTES[fileSizeSpinner.selectedItemPosition] savePrefs(); @@ -258,6 +281,11 @@ class ScreenRecordPermissionContentManager( lowQuality = lowQuality, longerDuration = longerDuration, hevc = hevc, + bitrateMultiplier = bitrateMultiplier, + resolutionMode = resolutionMode, + fpsMode = fpsMode, + timeLimitMs = timeLimitMs, + fileSizeBytes = fileSizeBytes, ) ) }, @@ -265,6 +293,57 @@ class ScreenRecordPermissionContentManager( ) } + private fun setupResolutionSpinner() { + val ctx = containerView.context + val dm = ctx.getSystemService(DisplayManager::class.java) + val metrics = DisplayMetrics() + dm.getDisplay(Display.DEFAULT_DISPLAY).getRealMetrics(metrics) + val screenW = metrics.widthPixels + val screenH = metrics.heightPixels + val longEdge = maxOf(screenW, screenH) + + val entries = mutableListOf(ctx.getString(R.string.screenrecord_resolution_auto)) + resolutionModeValues.clear() + resolutionModeValues.add(0) + + if (longEdge > 2560) { + entries.add(resolutionLabel(screenW, screenH, 2560)) + resolutionModeValues.add(2560) + } + if (longEdge > 1920) { + entries.add(resolutionLabel(screenW, screenH, 1920)) + resolutionModeValues.add(1920) + } + if (longEdge > 1280) { + entries.add(resolutionLabel(screenW, screenH, 1280)) + resolutionModeValues.add(1280) + } + + val adapter = ArrayAdapter(ctx, R.layout.screenrecord_spinner_item, entries) + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + resolutionSpinner.adapter = adapter + } + + private fun resolutionLabel(screenW: Int, screenH: Int, longEdgeCap: Int): String { + val scale = longEdgeCap.toDouble() / maxOf(screenW, screenH) + val w = (screenW * scale).toInt() + val h = (screenH * scale).toInt() + val className = when (longEdgeCap) { + 2560 -> "1440p" + 1920 -> "1080p" + else -> "720p" + } + return "$className ($w × $h)" + } + + private fun setupSpinner(spinner: Spinner, entriesRes: Int) { + val ctx = containerView.context + val entries = ctx.resources.getTextArray(entriesRes) + val adapter = ArrayAdapter(ctx, R.layout.screenrecord_spinner_item, entries) + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + spinner.adapter = adapter + } + private fun hasHevcHwEncoder(): Boolean { val mediaCodecList = MediaCodecList(MediaCodecList.REGULAR_CODECS) @@ -292,6 +371,11 @@ class ScreenRecordPermissionContentManager( Prefs.putInt(userContext, PREF_AUDIO_SOURCE, options.selectedItemPosition) Prefs.putInt(userContext, PREF_SKIP, if (skipTimeSwitch.isChecked) 1 else 0) Prefs.putInt(userContext, PREF_HEVC, if (hevcSwitch.isChecked) 1 else 0) + Prefs.putInt(userContext, PREF_BITRATE, bitrateSpinner.selectedItemPosition) + Prefs.putInt(userContext, PREF_RESOLUTION, resolutionModeValues[resolutionSpinner.selectedItemPosition]) + Prefs.putInt(userContext, PREF_FPS, fpsSpinner.selectedItemPosition) + Prefs.putInt(userContext, PREF_TIME_LIMIT, timeLimitSpinner.selectedItemPosition) + Prefs.putInt(userContext, PREF_FILE_SIZE, fileSizeSpinner.selectedItemPosition) } private fun loadPrefs() { @@ -303,6 +387,12 @@ class ScreenRecordPermissionContentManager( options.setSelection(Prefs.getInt(userContext, PREF_AUDIO_SOURCE, 0)) skipTimeSwitch.isChecked = Prefs.getInt(userContext, PREF_SKIP, 0) == 1 hevcSwitch.isChecked = Prefs.getInt(userContext, PREF_HEVC, 1) == 1 + bitrateSpinner.setSelection(Prefs.getInt(userContext, PREF_BITRATE, 0)) + val savedResMode = Prefs.getInt(userContext, PREF_RESOLUTION, 0) + resolutionSpinner.setSelection(resolutionModeValues.indexOf(savedResMode).coerceAtLeast(0)) + fpsSpinner.setSelection(Prefs.getInt(userContext, PREF_FPS, 0)) + timeLimitSpinner.setSelection(Prefs.getInt(userContext, PREF_TIME_LIMIT, 0)) + fileSizeSpinner.setSelection(Prefs.getInt(userContext, PREF_FILE_SIZE, 0)) } private inner class CaptureTargetResultReceiver : @@ -340,6 +430,16 @@ class ScreenRecordPermissionContentManager( private const val PREF_AUDIO_SOURCE = "screenrecord_audio_source" private const val PREF_SKIP = "screenrecord_skip_timer" private const val PREF_HEVC = "screenrecord_use_hevc" + private const val PREF_BITRATE = "screenrecord_bitrate" + private const val PREF_RESOLUTION = "screenrecord_resolution_mode" + private const val PREF_FPS = "screenrecord_fps_mode" + private const val PREF_TIME_LIMIT = "screenrecord_time_limit" + private const val PREF_FILE_SIZE = "screenrecord_file_size" + + private val BITRATE_MULTIPLIER_VALUES = floatArrayOf(1.0f, 0.5f, 0.25f) + private val FPS_MODE_VALUES = intArrayOf(0, 30, 60) + private val TIME_LIMIT_VALUES_MS = intArrayOf(0, 5 * 60 * 1000, 10 * 60 * 1000, 30 * 60 * 1000, 60 * 60 * 1000) + private val FILE_SIZE_VALUES_BYTES = longArrayOf(0L, 10L shl 20, 100L shl 20, 500L shl 20, 1L shl 30, 15L shl 30) fun createOptionList(displayManager: DisplayManager): List { val connectedDisplays = getConnectedDisplays(displayManager) diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/domain/ScreenRecordingParameters.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/domain/ScreenRecordingParameters.kt index b79d115adc3f5..cbbd0e567ea5b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/domain/ScreenRecordingParameters.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/domain/ScreenRecordingParameters.kt @@ -27,4 +27,9 @@ data class ScreenRecordingParameters( val lowQuality: Boolean, val longerDuration: Boolean, val hevc: Boolean, + val resolutionMode: Int = 0, + val fpsMode: Int = 0, + val timeLimitMs: Int = 0, + val fileSizeBytes: Long = 0L, + val bitrateMultiplier: Float = 1.0f, ) diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/domain/interactor/LegacyScreenRecordingStartStopInteractor.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/domain/interactor/LegacyScreenRecordingStartStopInteractor.kt index 4ff01b6600ba6..5f507a7af6852 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/domain/interactor/LegacyScreenRecordingStartStopInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/domain/interactor/LegacyScreenRecordingStartStopInteractor.kt @@ -50,6 +50,11 @@ constructor(private val userContextProvider: UserContextProvider) : lowQuality, longerDuration, hevc, + resolutionMode, + fpsMode, + timeLimitMs, + fileSizeBytes, + bitrateMultiplier, ) }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,