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 <https://github.com/Genymobile/scrcpy/issues/3796>
This commit is contained in:
Romain Vimont 2023-03-16 21:54:06 +01:00
parent a3871130cc
commit 02f4ff7534

View file

@ -72,8 +72,6 @@ public final class AudioCapture {
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 @@ public final class AudioCapture {
}
}
public void start() throws AudioCaptureForegroundException {
startWorkaroundAndroid11();
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, it is only possible to capture in foreground, make sure that the device is unlocked when starting scrcpy.");
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 {
tryStartRecording(3, 100);
} finally {
stopWorkaroundAndroid11();
}