From 1871a919447dd7be5d8d225d218ab09af49d49d2 Mon Sep 17 00:00:00 2001 From: Noah Richards Date: Mon, 14 Aug 2017 10:08:33 -0700 Subject: [PATCH] Check keepAlive before calling nativeDataIsRecording. We're encountering a bug where audioRecord.read() can hang for long enough that stopRecording() fails to join the recording thread (in two seconds) and returns. In that case, JNI methods get unregistered and when the recording thread calls nativeDataIsRecorded, it crashes when it can't find the native method to call. This version still isn't 100% safe, as the threading sequence still technically allows for an ordering where (for some reason) the thread fails to join after the final keepAlive check and long enough for all the JNI methods to get unregistered, but that seems very unlikely. BUG=b/64174142 Change-Id: Ie7432a70d0e53bace0885edf35e24bd3f6585399 Reviewed-on: https://chromium-review.googlesource.com/613501 Reviewed-by: Henrik Andreasson Commit-Queue: Noah Richards Cr-Commit-Position: refs/heads/master@{#19358} --- .../java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java index 16abd08b21..66c1483851 100644 --- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java +++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java @@ -106,7 +106,12 @@ public class WebRtcAudioRecord { byteBuffer.clear(); byteBuffer.put(emptyBytes); } - nativeDataIsRecorded(bytesRead, nativeAudioRecord); + // It's possible we've been shut down during the read, and stopRecording() tried and + // failed to join this thread. To be a bit safer, try to avoid calling any native methods + // in case they've been unregistered after stopRecording() returned. + if (keepAlive) { + nativeDataIsRecorded(bytesRead, nativeAudioRecord); + } } else { String errorMessage = "AudioRecord.read failed: " + bytesRead; Logging.e(TAG, errorMessage);