diff --git a/src/main/java/eu/siacs/conversations/services/AppRTCAudioManager.java b/src/main/java/eu/siacs/conversations/services/AppRTCAudioManager.java index 07d52891b..cd8a19820 100644 --- a/src/main/java/eu/siacs/conversations/services/AppRTCAudioManager.java +++ b/src/main/java/eu/siacs/conversations/services/AppRTCAudioManager.java @@ -28,6 +28,7 @@ import org.webrtc.ThreadUtils; import java.util.Collections; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.CountDownLatch; import eu.siacs.conversations.Config; import eu.siacs.conversations.utils.AppRTCUtils; @@ -36,6 +37,9 @@ import eu.siacs.conversations.utils.AppRTCUtils; * AppRTCAudioManager manages all audio related parts of the AppRTC demo. */ public class AppRTCAudioManager { + + private static CountDownLatch microphoneLatch; + private final Context apprtcContext; // Contains speakerphone setting: auto, true or false @Nullable @@ -114,7 +118,8 @@ public class AppRTCAudioManager { return new AppRTCAudioManager(context, speakerPhonePreference); } - public static boolean isMicrophoneAvailable(final Context context) { + public static boolean isMicrophoneAvailable() { + microphoneLatch = new CountDownLatch(1); AudioRecord audioRecord = null; boolean available = true; try { @@ -134,6 +139,7 @@ public class AppRTCAudioManager { release(audioRecord); } + microphoneLatch.countDown(); return available; } @@ -181,6 +187,7 @@ public class AppRTCAudioManager { Log.e(Config.LOGTAG, "AudioManager is already active"); return; } + awaitMicrophoneLatch(); // TODO(henrika): perhaps call new method called preInitAudio() here if UNINITIALIZED. Log.d(Config.LOGTAG, "AudioManager starts..."); this.audioManagerEvents = audioManagerEvents; @@ -261,6 +268,18 @@ public class AppRTCAudioManager { Log.d(Config.LOGTAG, "AudioManager started"); } + private void awaitMicrophoneLatch() { + final CountDownLatch latch = microphoneLatch; + if (latch == null) { + return; + } + try { + latch.await(); + } catch (InterruptedException e) { + //ignore + } + } + @SuppressWarnings("deprecation") // TODO(henrika): audioManager.abandonAudioFocus() is deprecated. public void stop() { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index e5c1925f7..2c6e2c863 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1273,16 +1273,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke private void triggerRtpSession(final String action) { - if (AppRTCAudioManager.isMicrophoneAvailable(getActivity())) { - final Contact contact = conversation.getContact(); - final Intent intent = new Intent(activity, RtpSessionActivity.class); - intent.setAction(action); - intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, contact.getAccount().getJid().toEscapedString()); - intent.putExtra(RtpSessionActivity.EXTRA_WITH, contact.getJid().asBareJid().toEscapedString()); - startActivity(intent); - } else { - Toast.makeText(getActivity(), R.string.microphone_unavailable, Toast.LENGTH_SHORT).show(); - } + final Contact contact = conversation.getContact(); + final Intent intent = new Intent(activity, RtpSessionActivity.class); + intent.setAction(action); + intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, contact.getAccount().getJid().toEscapedString()); + intent.putExtra(RtpSessionActivity.EXTRA_WITH, contact.getJid().asBareJid().toEscapedString()); + startActivity(intent); } private void handleAttachmentSelection(MenuItem item) { diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 7b6c1fefe..c3ef71c80 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -132,15 +132,22 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } private void checkRecorderAndAcceptCall() { - final long start = SystemClock.elapsedRealtime(); - final boolean isMicrophoneAvailable = AppRTCAudioManager.isMicrophoneAvailable(this); - final long stop = SystemClock.elapsedRealtime(); - Log.d(Config.LOGTAG, "checking microphone availability took " + (stop - start) + "ms"); - if (isMicrophoneAvailable) { - requireRtpConnection().acceptCall(); - } else { - Toast.makeText(this, R.string.microphone_unavailable, Toast.LENGTH_SHORT).show(); + checkMicrophoneAvailability(); + requireRtpConnection().acceptCall(); + } + + private void checkMicrophoneAvailability() { + new Thread(() -> { + final long start = SystemClock.elapsedRealtime(); + final boolean isMicrophoneAvailable = AppRTCAudioManager.isMicrophoneAvailable(); + final long stop = SystemClock.elapsedRealtime(); + Log.d(Config.LOGTAG, "checking microphone availability took " + (stop - start) + "ms"); + if (isMicrophoneAvailable) { + return; + } + runOnUiThread(() -> Toast.makeText(this, R.string.microphone_unavailable, Toast.LENGTH_SHORT).show()); } + ).start(); } private void putScreenInCallMode() { @@ -251,6 +258,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } private void proposeJingleRtpSession(final Account account, final Jid with, final Set media) { + checkMicrophoneAvailability(); xmppConnectionService.getJingleConnectionManager().proposeJingleRtpSession(account, with, media); putScreenInCallMode(media); } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 9b05af9e3..63a991e76 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -914,7 +914,7 @@ Missed call Audio call Video call - Microphone unavailable + Your microphone is unavailable View %1$d Participant View %1$d Participants