add microphone availability check
This commit is contained in:
parent
ebda472c22
commit
934b98d199
|
@ -15,7 +15,10 @@ import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.media.AudioDeviceInfo;
|
import android.media.AudioDeviceInfo;
|
||||||
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.media.AudioRecord;
|
||||||
|
import android.media.MediaRecorder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -111,6 +114,40 @@ public class AppRTCAudioManager {
|
||||||
return new AppRTCAudioManager(context, speakerPhonePreference);
|
return new AppRTCAudioManager(context, speakerPhonePreference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isMicrophoneAvailable(final Context context) {
|
||||||
|
AudioRecord audioRecord = null;
|
||||||
|
boolean available = true;
|
||||||
|
try {
|
||||||
|
final int sampleRate = 44100;
|
||||||
|
final int channel = AudioFormat.CHANNEL_IN_MONO;
|
||||||
|
final int format = AudioFormat.ENCODING_PCM_16BIT;
|
||||||
|
final int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channel, format);
|
||||||
|
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channel, format, bufferSize);
|
||||||
|
audioRecord.startRecording();
|
||||||
|
final short[] buffer = new short[bufferSize];
|
||||||
|
final int audioStatus = audioRecord.read(buffer, 0, bufferSize);
|
||||||
|
if (audioStatus == AudioRecord.ERROR_INVALID_OPERATION || audioStatus == AudioRecord.STATE_UNINITIALIZED)
|
||||||
|
available = false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
available = false;
|
||||||
|
} finally {
|
||||||
|
release(audioRecord);
|
||||||
|
|
||||||
|
}
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void release(final AudioRecord audioRecord) {
|
||||||
|
if (audioRecord == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
audioRecord.release();
|
||||||
|
} catch (Exception e) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when the proximity sensor reports a state change,
|
* This method is called when the proximity sensor reports a state change,
|
||||||
* e.g. from "NEAR to FAR" or from "FAR to NEAR".
|
* e.g. from "NEAR to FAR" or from "FAR to NEAR".
|
||||||
|
|
|
@ -82,6 +82,7 @@ import eu.siacs.conversations.entities.Transferable;
|
||||||
import eu.siacs.conversations.entities.TransferablePlaceholder;
|
import eu.siacs.conversations.entities.TransferablePlaceholder;
|
||||||
import eu.siacs.conversations.http.HttpDownloadConnection;
|
import eu.siacs.conversations.http.HttpDownloadConnection;
|
||||||
import eu.siacs.conversations.persistance.FileBackend;
|
import eu.siacs.conversations.persistance.FileBackend;
|
||||||
|
import eu.siacs.conversations.services.AppRTCAudioManager;
|
||||||
import eu.siacs.conversations.services.MessageArchiveService;
|
import eu.siacs.conversations.services.MessageArchiveService;
|
||||||
import eu.siacs.conversations.services.QuickConversationsService;
|
import eu.siacs.conversations.services.QuickConversationsService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
|
@ -1272,12 +1273,16 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
|
|
||||||
|
|
||||||
private void triggerRtpSession(final String action) {
|
private void triggerRtpSession(final String action) {
|
||||||
|
if (AppRTCAudioManager.isMicrophoneAvailable(getActivity())) {
|
||||||
final Contact contact = conversation.getContact();
|
final Contact contact = conversation.getContact();
|
||||||
final Intent intent = new Intent(activity, RtpSessionActivity.class);
|
final Intent intent = new Intent(activity, RtpSessionActivity.class);
|
||||||
intent.setAction(action);
|
intent.setAction(action);
|
||||||
intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, contact.getAccount().getJid().toEscapedString());
|
intent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, contact.getAccount().getJid().toEscapedString());
|
||||||
intent.putExtra(RtpSessionActivity.EXTRA_WITH, contact.getJid().asBareJid().toEscapedString());
|
intent.putExtra(RtpSessionActivity.EXTRA_WITH, contact.getJid().asBareJid().toEscapedString());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getActivity(), R.string.microphone_unavailable, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAttachmentSelection(MenuItem item) {
|
private void handleAttachmentSelection(MenuItem item) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.databinding.DataBindingUtil;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.StringRes;
|
import android.support.annotation.StringRes;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -126,7 +127,19 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
}
|
}
|
||||||
if (PermissionUtils.hasPermission(this, permissions, REQUEST_ACCEPT_CALL)) {
|
if (PermissionUtils.hasPermission(this, permissions, REQUEST_ACCEPT_CALL)) {
|
||||||
putScreenInCallMode();
|
putScreenInCallMode();
|
||||||
|
checkRecorderAndAcceptCall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
requireRtpConnection().acceptCall();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.microphone_unavailable, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +260,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
if (PermissionUtils.allGranted(grantResults)) {
|
if (PermissionUtils.allGranted(grantResults)) {
|
||||||
if (requestCode == REQUEST_ACCEPT_CALL) {
|
if (requestCode == REQUEST_ACCEPT_CALL) {
|
||||||
requireRtpConnection().acceptCall();
|
checkRecorderAndAcceptCall();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@StringRes int res;
|
@StringRes int res;
|
||||||
|
|
|
@ -950,6 +950,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not sending session-terminate after connectivity error because session is already in state " + this.state);
|
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not sending session-terminate after connectivity error because session is already in state " + this.state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//we need to call close
|
||||||
sendSessionTerminate(Reason.CONNECTIVITY_ERROR);
|
sendSessionTerminate(Reason.CONNECTIVITY_ERROR);
|
||||||
} else {
|
} else {
|
||||||
updateEndUserState();
|
updateEndUserState();
|
||||||
|
|
|
@ -914,6 +914,7 @@
|
||||||
<string name="missed_call">Missed call</string>
|
<string name="missed_call">Missed call</string>
|
||||||
<string name="audio_call">Audio call</string>
|
<string name="audio_call">Audio call</string>
|
||||||
<string name="video_call">Video call</string>
|
<string name="video_call">Video call</string>
|
||||||
|
<string name="microphone_unavailable">Microphone unavailable</string>
|
||||||
<plurals name="view_users">
|
<plurals name="view_users">
|
||||||
<item quantity="one">View %1$d Participant</item>
|
<item quantity="one">View %1$d Participant</item>
|
||||||
<item quantity="other">View %1$d Participants</item>
|
<item quantity="other">View %1$d Participants</item>
|
||||||
|
|
Loading…
Reference in New Issue