From 02f4ff7534649153d6f87b05a0757431a2d0ee5f Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Thu, 16 Mar 2023 21:54:06 +0100 Subject: [PATCH] Make 3 attempts to start AudioRecord On Android 11, a fake popup must be briefly opened to make the system think that the shell app is in the foreground so that audio may be recorded. Making the shell app foreground may take some time depending on the device, so make 3 attempts, waiting 100ms before each. Fixes #3796 --- .../com/genymobile/scrcpy/AudioCapture.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java b/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java index 6bb3ce23e1..e15c8285cf 100644 --- a/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/AudioCapture.java @@ -72,8 +72,6 @@ private static void startWorkaroundAndroid11() { intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setComponent(new ComponentName(FakeContext.PACKAGE_NAME, "com.android.shell.HeapDumpActivity")); ServiceManager.getActivityManager().startActivityAsUserWithFeature(intent); - // Wait for activity to start - SystemClock.sleep(150); } } } @@ -84,18 +82,35 @@ private static void stopWorkaroundAndroid11() { } } + private void tryStartRecording(int attempts, int delayMs) throws AudioCaptureForegroundException { + while (attempts-- > 0) { + // Wait for activity to start + SystemClock.sleep(delayMs); + try { + recorder = createAudioRecord(); + recorder.startRecording(); + return; // it worked + } catch (UnsupportedOperationException e) { + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) { + if (attempts == 0) { + Ln.e("Failed to start audio capture"); + Ln.e("On Android 11, audio capture must be started in the foreground, make sure that the device is unlocked when starting " + + "scrcpy."); + throw new AudioCaptureForegroundException(); + } else { + Ln.d("Failed to start audio capture, retrying..."); + } + } else { + throw e; + } + } + } + } + public void start() throws AudioCaptureForegroundException { startWorkaroundAndroid11(); try { - recorder = createAudioRecord(); - recorder.startRecording(); - } catch (UnsupportedOperationException e) { - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) { - Ln.e("Failed to start audio capture"); - Ln.e("On Android 11, it is only possible to capture in foreground, make sure that the device is unlocked when starting scrcpy."); - throw new AudioCaptureForegroundException(); - } - throw e; + tryStartRecording(3, 100); } finally { stopWorkaroundAndroid11(); }