diff --git a/src/org/thoughtcrime/securesms/WebRtcCallActivity.java b/src/org/thoughtcrime/securesms/WebRtcCallActivity.java index 81e37e6c665..71d2655902d 100644 --- a/src/org/thoughtcrime/securesms/WebRtcCallActivity.java +++ b/src/org/thoughtcrime/securesms/WebRtcCallActivity.java @@ -24,11 +24,9 @@ import android.content.Intent; import android.content.res.Configuration; import android.media.AudioManager; -import android.os.Build; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; -import androidx.core.app.ActivityCompat; import org.thoughtcrime.securesms.logging.Log; import android.view.View; @@ -152,6 +150,20 @@ private void initializeResources() { callScreen.setBluetoothButtonListener(new BluetoothButtonListener()); } + private void handleSetAudioSpeaker(boolean enabled) { + Intent intent = new Intent(this, WebRtcCallService.class); + intent.setAction(WebRtcCallService.ACTION_SET_AUDIO_SPEAKER); + intent.putExtra(WebRtcCallService.EXTRA_SPEAKER, enabled); + startService(intent); + } + + private void handleSetAudioBluetooth(boolean enabled) { + Intent intent = new Intent(this, WebRtcCallService.class); + intent.setAction(WebRtcCallService.ACTION_SET_AUDIO_BLUETOOTH); + intent.putExtra(WebRtcCallService.EXTRA_BLUETOOTH, enabled); + startService(intent); + } + private void handleSetMuteAudio(boolean enabled) { Intent intent = new Intent(this, WebRtcCallService.class); intent.setAction(WebRtcCallService.ACTION_SET_MUTE_AUDIO); @@ -376,28 +388,14 @@ public void onToggle() { private class SpeakerButtonListener implements WebRtcCallControls.SpeakerButtonListener { @Override public void onSpeakerChange(boolean isSpeaker) { - AudioManager audioManager = ServiceUtil.getAudioManager(WebRtcCallActivity.this); - audioManager.setSpeakerphoneOn(isSpeaker); - - if (isSpeaker && audioManager.isBluetoothScoOn()) { - audioManager.stopBluetoothSco(); - audioManager.setBluetoothScoOn(false); - } + WebRtcCallActivity.this.handleSetAudioSpeaker(isSpeaker); } } private class BluetoothButtonListener implements WebRtcCallControls.BluetoothButtonListener { @Override public void onBluetoothChange(boolean isBluetooth) { - AudioManager audioManager = ServiceUtil.getAudioManager(WebRtcCallActivity.this); - - if (isBluetooth) { - audioManager.startBluetoothSco(); - audioManager.setBluetoothScoOn(true); - } else { - audioManager.stopBluetoothSco(); - audioManager.setBluetoothScoOn(false); - } + WebRtcCallActivity.this.handleSetAudioBluetooth(isBluetooth); } } diff --git a/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallControls.java b/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallControls.java index 524003a1d9a..4d193b203ac 100644 --- a/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallControls.java +++ b/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallControls.java @@ -100,7 +100,6 @@ public void setSpeakerButtonListener(final SpeakerButtonListener listener) { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { listener.onSpeakerChange(isChecked); - updateAudioState(bluetoothButton.getVisibility() == View.VISIBLE); } }); } @@ -110,7 +109,6 @@ public void setBluetoothButtonListener(final BluetoothButtonListener listener) { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { listener.onBluetoothChange(isChecked); - updateAudioState(true); } }); } diff --git a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java index c136fc82e99..0d8f537ce56 100644 --- a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java +++ b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java @@ -116,6 +116,8 @@ private enum CallState { public static final String EXTRA_RESULT_RECEIVER = "result_receiver"; public static final String EXTRA_CALL_ERROR = "call_error"; public static final String EXTRA_IDENTITY_KEY_BYTES = "identity_key_bytes"; + public static final String EXTRA_SPEAKER = "audio_speaker"; + public static final String EXTRA_BLUETOOTH = "audio_bluetooth"; public static final String ACTION_INCOMING_CALL = "CALL_INCOMING"; public static final String ACTION_OUTGOING_CALL = "CALL_OUTGOING"; @@ -130,6 +132,8 @@ private enum CallState { public static final String ACTION_SCREEN_OFF = "SCREEN_OFF"; public static final String ACTION_CHECK_TIMEOUT = "CHECK_TIMEOUT"; public static final String ACTION_IS_IN_CALL_QUERY = "IS_IN_CALL"; + public static final String ACTION_SET_AUDIO_SPEAKER = "SET_AUDIO_SPEAKER"; + public static final String ACTION_SET_AUDIO_BLUETOOTH = "SET_AUDIO_BLUETOOTH"; public static final String ACTION_RESPONSE_MESSAGE = "RESPONSE_MESSAGE"; public static final String ACTION_ICE_MESSAGE = "ICE_MESSAGE"; @@ -217,6 +221,8 @@ public int onStartCommand(final Intent intent, int flags, int startId) { else if (intent.getAction().equals(ACTION_CHECK_TIMEOUT)) handleCheckTimeout(intent); else if (intent.getAction().equals(ACTION_IS_IN_CALL_QUERY)) handleIsInCallQuery(intent); else if (intent.getAction().equals(ACTION_CALL_ERROR)) handleCallError(intent); + else if (intent.getAction().equals(ACTION_SET_AUDIO_SPEAKER)) handleSetSpeakerAudio(intent); + else if (intent.getAction().equals(ACTION_SET_AUDIO_BLUETOOTH)) handleSetBluetoothAudio(intent); }); return START_NOT_STICKY; @@ -406,7 +412,7 @@ private void handleOutgoingCall(Intent intent) { initializeVideo(); sendMessage(WebRtcViewModel.State.CALL_OUTGOING, recipient, localCameraState, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled); - lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL); + lockManager.updatePhoneState(getInCallPhoneState()); audioManager.initializeAudioForCall(); audioManager.startOutgoingRinger(OutgoingRinger.Type.RINGING); bluetoothStateManager.setWantsConnection(true); @@ -534,7 +540,7 @@ private void activateCallMedia() { callState = CallState.STATE_CONNECTED; if (localCameraState.isEnabled()) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO); - else lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL); + else lockManager.updatePhoneState(getInCallPhoneState()); sendMessage(WebRtcViewModel.State.CALL_CONNECTED, recipient, localCameraState, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled); @@ -746,6 +752,43 @@ private void handleRemoteHangup(Intent intent) { terminate(); } + private void handleSetSpeakerAudio(Intent intent) { + boolean isSpeaker = intent.getBooleanExtra(EXTRA_SPEAKER, false); + AudioManager audioManager = ServiceUtil.getAudioManager(this); + + audioManager.setSpeakerphoneOn(isSpeaker); + + if (isSpeaker && audioManager.isBluetoothScoOn()) { + audioManager.stopBluetoothSco(); + audioManager.setBluetoothScoOn(false); + } + + if (!localCameraState.isEnabled()) { + lockManager.updatePhoneState(getInCallPhoneState()); + } + + sendMessage(viewModelStateFor(callState), recipient, localCameraState, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled); + } + + private void handleSetBluetoothAudio(Intent intent) { + boolean isBluetooth = intent.getBooleanExtra(EXTRA_BLUETOOTH, false); + AudioManager audioManager = ServiceUtil.getAudioManager(this); + + if (isBluetooth) { + audioManager.startBluetoothSco(); + audioManager.setBluetoothScoOn(true); + } else { + audioManager.stopBluetoothSco(); + audioManager.setBluetoothScoOn(false); + } + + if (!localCameraState.isEnabled()) { + lockManager.updatePhoneState(getInCallPhoneState()); + } + + sendMessage(viewModelStateFor(callState), recipient, localCameraState, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled); + } + private void handleSetMuteAudio(Intent intent) { boolean muted = intent.getBooleanExtra(EXTRA_MUTE, false); this.microphoneEnabled = !muted; @@ -777,7 +820,7 @@ private void handleSetMuteVideo(Intent intent) { if (callState == CallState.STATE_CONNECTED) { if (localCameraState.isEnabled()) this.lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO); - else this.lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL); + else this.lockManager.updatePhoneState(getInCallPhoneState()); } if (localCameraState.isEnabled() && @@ -1346,4 +1389,13 @@ public void onAddStream(SignalMessageRecipient eventRecipient, } } + private LockManager.PhoneState getInCallPhoneState() { + AudioManager audioManager = ServiceUtil.getAudioManager(this); + if (audioManager.isSpeakerphoneOn() || audioManager.isBluetoothScoOn() || audioManager.isWiredHeadsetOn()) { + return LockManager.PhoneState.IN_HANDS_FREE_CALL; + } else { + return LockManager.PhoneState.IN_CALL; + } + } + } diff --git a/src/org/thoughtcrime/securesms/webrtc/locks/LockManager.java b/src/org/thoughtcrime/securesms/webrtc/locks/LockManager.java index 20a6edeba74..511b2c04011 100644 --- a/src/org/thoughtcrime/securesms/webrtc/locks/LockManager.java +++ b/src/org/thoughtcrime/securesms/webrtc/locks/LockManager.java @@ -32,6 +32,7 @@ public enum PhoneState { PROCESSING, //used when the phone is active but before the user should be alerted. INTERACTIVE, IN_CALL, + IN_HANDS_FREE_CALL, IN_VIDEO } @@ -100,6 +101,11 @@ public void updatePhoneState(PhoneState state) { setLockState(LockState.FULL); accelerometerListener.enable(false); break; + case IN_HANDS_FREE_CALL: + setLockState(LockState.PARTIAL); + proximityDisabled = true; + accelerometerListener.enable(false); + break; case IN_VIDEO: proximityDisabled = true; accelerometerListener.enable(false);