diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java
index ea248a0f0..07866e142 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java
@@ -72,6 +72,7 @@ import com.nextcloud.talk.models.json.signaling.SignalingOverall;
import com.nextcloud.talk.models.json.signaling.settings.IceServer;
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
import com.nextcloud.talk.utils.ApiUtils;
+import com.nextcloud.talk.utils.MagicFlipView;
import com.nextcloud.talk.utils.animations.PulseAnimation;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
@@ -152,6 +153,9 @@ public class CallController extends BaseController {
Manifest.permission.RECORD_AUDIO
};
+ @BindView(R.id.callControlEnableSpeaker)
+ MagicFlipView callControlEnableSpeaker;
+
@BindView(R.id.pip_video_view)
SurfaceViewRenderer pipVideoView;
@BindView(R.id.relative_layout)
@@ -300,6 +304,10 @@ public class CallController extends BaseController {
Log.e(TAG, "Failed to evict cache");
}
+ if (isVoiceOnlyCall) {
+ callControlEnableSpeaker.setVisibility(View.VISIBLE);
+ }
+
callControls.setZ(100.0f);
basicInitialization();
@@ -330,7 +338,7 @@ public class CallController extends BaseController {
// Create and audio manager that will take care of audio routing,
// audio modes, audio device enumeration etc.
- audioManager = MagicAudioManager.create(getApplicationContext());
+ audioManager = MagicAudioManager.create(getApplicationContext(), !isVoiceOnlyCall);
// Store existing audio settings and change audio mode to
// MODE_IN_COMMUNICATION for best possible VoIP performance.
Log.d(TAG, "Starting the audio manager...");
@@ -422,7 +430,7 @@ public class CallController extends BaseController {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(PERMISSIONS_CALL, 100);
} else {
- onRequestPermissionsResult(100, PERMISSIONS_CALL, new int[]{1});
+ onRequestPermissionsResult(100, PERMISSIONS_CALL, new int[]{1, 1});
}
}
@@ -586,6 +594,20 @@ public class CallController extends BaseController {
return true;
}
+ @OnClick(R.id.callControlEnableSpeaker)
+ public void onEnableSpeakerphoneClick() {
+ if (audioManager != null) {
+ audioManager.toggleUseSpeakerphone();
+ if (audioManager.isSpeakerphoneAutoOn()) {
+ callControlEnableSpeaker.getFrontImageView().setImageDrawable(getResources().getDrawable(R.drawable
+ .ic_speaker_white_24dp));
+ } else {
+ callControlEnableSpeaker.getFrontImageView().setImageDrawable(getResources().getDrawable(R.drawable
+ .ic_hearing_white_24dp));
+ }
+ }
+ }
+
@OnClick(R.id.call_control_microphone)
public void onMicrophoneClick() {
if (getActivity() != null && EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_MICROPHONE)) {
diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java
index 3fa5cadff..5afa153a7 100644
--- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java
+++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java
@@ -59,7 +59,7 @@ public class MagicAudioManager {
private static final String SPEAKERPHONE_FALSE = "false";
private final Context magicContext;
// Contains speakerphone setting: auto, true or false
- private final String useSpeakerphone;
+ private String useSpeakerphone;
// Handles all tasks related to Bluetooth headset devices.
private final MagicBluetoothManager bluetoothManager;
private AudioManager audioManager;
@@ -96,7 +96,23 @@ public class MagicAudioManager {
// Callback method for changes in audio focus.
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener;
- private MagicAudioManager(Context context) {
+ public void toggleUseSpeakerphone() {
+ if (useSpeakerphone.equals(SPEAKERPHONE_FALSE)) {
+ useSpeakerphone = SPEAKERPHONE_AUTO;
+ setDefaultAudioDevice(AudioDevice.SPEAKER_PHONE);
+ } else {
+ useSpeakerphone = SPEAKERPHONE_FALSE;
+ setDefaultAudioDevice(AudioDevice.EARPIECE);
+ }
+
+ updateAudioDeviceState();
+ }
+
+ public boolean isSpeakerphoneAutoOn() {
+ return (useSpeakerphone.equals(SPEAKERPHONE_AUTO));
+ }
+
+ private MagicAudioManager(Context context, boolean useProximitySensor) {
Log.d(TAG, "ctor");
ThreadUtils.checkIsOnMainThread();
magicContext = context;
@@ -105,7 +121,13 @@ public class MagicAudioManager {
wiredHeadsetReceiver = new WiredHeadsetReceiver();
amState = AudioManagerState.UNINITIALIZED;
- useSpeakerphone = SPEAKERPHONE_AUTO;
+ if (useProximitySensor) {
+ useSpeakerphone = SPEAKERPHONE_AUTO;
+ } else {
+ useSpeakerphone = SPEAKERPHONE_FALSE;
+ }
+
+
if (useSpeakerphone.equals(SPEAKERPHONE_FALSE)) {
defaultAudioDevice = AudioDevice.EARPIECE;
} else {
@@ -130,8 +152,8 @@ public class MagicAudioManager {
/**
* Construction.
*/
- public static MagicAudioManager create(Context context) {
- return new MagicAudioManager(context);
+ public static MagicAudioManager create(Context context, boolean useProximitySensor) {
+ return new MagicAudioManager(context, useProximitySensor);
}
/**
@@ -140,14 +162,6 @@ public class MagicAudioManager {
*/
private void onProximitySensorChangedState() {
- if (proximitySensor.sensorReportsNearState()) {
- EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
- .SENSOR_NEAR, null, null, null));
- } else {
- EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
- .SENSOR_FAR, null, null, null));
- }
-
if (!useSpeakerphone.equals(SPEAKERPHONE_AUTO)) {
return;
}
@@ -160,10 +174,17 @@ public class MagicAudioManager {
// Sensor reports that a "handset is being held up to a person's ear",
// or "something is covering the light sensor".
setAudioDeviceInternal(MagicAudioManager.AudioDevice.EARPIECE);
+
+ EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
+ .SENSOR_FAR, null, null, null));
+
} else {
// Sensor reports that a "handset is removed from a person's ear", or
// "the light sensor is no longer covered".
setAudioDeviceInternal(MagicAudioManager.AudioDevice.SPEAKER_PHONE);
+
+ EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
+ .SENSOR_NEAR, null, null, null));
}
}
}
diff --git a/app/src/main/res/drawable/ic_hearing_white_24dp.xml b/app/src/main/res/drawable/ic_hearing_white_24dp.xml
new file mode 100644
index 000000000..d335efbba
--- /dev/null
+++ b/app/src/main/res/drawable/ic_hearing_white_24dp.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_speaker_white_24dp.xml b/app/src/main/res/drawable/ic_speaker_white_24dp.xml
new file mode 100644
index 000000000..b06e76e66
--- /dev/null
+++ b/app/src/main/res/drawable/ic_speaker_white_24dp.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/controller_call.xml b/app/src/main/res/layout/controller_call.xml
index 9c7bddd45..7aa7485cd 100644
--- a/app/src/main/res/layout/controller_call.xml
+++ b/app/src/main/res/layout/controller_call.xml
@@ -140,6 +140,19 @@
app:enableInitialAnimation="false"
app:frontBackgroundColor="@color/nc_darkRed"
app:frontImage="@drawable/ic_call_end_white_24px"/>
+
+
+
-
\ No newline at end of file
+