mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-27 22:55:08 +01:00
Merge pull request #2590 from nextcloud/add-observer-for-peer-connections
Add observer for peer connections
This commit is contained in:
commit
1b70006b5b
@ -63,9 +63,8 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||
import com.nextcloud.talk.data.user.model.User;
|
||||
import com.nextcloud.talk.databinding.CallActivityBinding;
|
||||
import com.nextcloud.talk.events.ConfigurationChangeEvent;
|
||||
import com.nextcloud.talk.events.MediaStreamEvent;
|
||||
import com.nextcloud.talk.events.NetworkEvent;
|
||||
import com.nextcloud.talk.events.PeerConnectionEvent;
|
||||
import com.nextcloud.talk.events.ProximitySensorEvent;
|
||||
import com.nextcloud.talk.events.WebSocketCommunicationEvent;
|
||||
import com.nextcloud.talk.models.ExternalSignalingServer;
|
||||
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall;
|
||||
@ -74,7 +73,6 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall;
|
||||
import com.nextcloud.talk.models.json.conversations.RoomsOverall;
|
||||
import com.nextcloud.talk.models.json.generic.GenericOverall;
|
||||
import com.nextcloud.talk.models.json.participants.Participant;
|
||||
import com.nextcloud.talk.models.json.participants.ParticipantsOverall;
|
||||
import com.nextcloud.talk.models.json.signaling.DataChannelMessage;
|
||||
import com.nextcloud.talk.models.json.signaling.NCMessagePayload;
|
||||
import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||
@ -236,7 +234,7 @@ public class CallActivity extends CallBaseActivity {
|
||||
private MediaStream localStream;
|
||||
private String credentials;
|
||||
private List<PeerConnectionWrapper> peerConnectionWrapperList = new ArrayList<>();
|
||||
private Map<String, Participant> participantMap = new HashMap<>();
|
||||
private Map<String, String> userIdsBySessionId = new HashMap<>();
|
||||
|
||||
private boolean videoOn = false;
|
||||
private boolean microphoneOn = false;
|
||||
@ -270,6 +268,8 @@ public class CallActivity extends CallBaseActivity {
|
||||
|
||||
private Map<String, PeerConnectionWrapper.DataChannelMessageListener> dataChannelMessageListeners = new HashMap<>();
|
||||
|
||||
private Map<String, PeerConnectionWrapper.PeerConnectionObserver> peerConnectionObservers = new HashMap<>();
|
||||
|
||||
private SignalingMessageReceiver.ParticipantListMessageListener participantListMessageListener = new SignalingMessageReceiver.ParticipantListMessageListener() {
|
||||
|
||||
@Override
|
||||
@ -1775,7 +1775,7 @@ public class CallActivity extends CallBaseActivity {
|
||||
Log.d(TAG, "processUsersInRoom");
|
||||
List<String> newSessions = new ArrayList<>();
|
||||
Set<String> oldSessions = new HashSet<>();
|
||||
Map<String, String> userIdsBySessionId = new HashMap<>();
|
||||
userIdsBySessionId = new HashMap<>();
|
||||
|
||||
hasMCU = hasExternalSignalingServer && webSocketClient != null && webSocketClient.hasMCU();
|
||||
Log.d(TAG, " hasMCU is " + hasMCU);
|
||||
@ -1844,10 +1844,6 @@ public class CallActivity extends CallBaseActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newSessions.size() > 0 && !hasMCU) {
|
||||
getPeersForCall();
|
||||
}
|
||||
|
||||
if (hasMCU) {
|
||||
// Ensure that own publishing peer is set up.
|
||||
getOrCreatePeerConnectionWrapperForSessionIdAndType(webSocketClient.getSessionId(), VIDEO_STREAM_TYPE_VIDEO, true);
|
||||
@ -1858,15 +1854,22 @@ public class CallActivity extends CallBaseActivity {
|
||||
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false);
|
||||
|
||||
String userId = userIdsBySessionId.get(sessionId);
|
||||
|
||||
runOnUiThread(() -> {
|
||||
setupVideoStreamForLayout(
|
||||
null,
|
||||
sessionId,
|
||||
userId,
|
||||
false,
|
||||
VIDEO_STREAM_TYPE_VIDEO);
|
||||
});
|
||||
if (userId != null) {
|
||||
runOnUiThread(() -> {
|
||||
boolean notifyDataSetChanged = false;
|
||||
if (participantDisplayItems.get(sessionId + "-video") != null) {
|
||||
participantDisplayItems.get(sessionId + "-video").setUserId(userId);
|
||||
notifyDataSetChanged = true;
|
||||
}
|
||||
if (participantDisplayItems.get(sessionId + "-screen") != null) {
|
||||
participantDisplayItems.get(sessionId + "-screen").setUserId(userId);
|
||||
notifyDataSetChanged = true;
|
||||
}
|
||||
if (notifyDataSetChanged) {
|
||||
participantsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (newSessions.size() > 0 && currentCallStatus != CallStatus.IN_CONVERSATION) {
|
||||
@ -1879,43 +1882,6 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void getPeersForCall() {
|
||||
Log.d(TAG, "getPeersForCall");
|
||||
int apiVersion = ApiUtils.getCallApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
|
||||
|
||||
ncApi.getPeersForCall(
|
||||
credentials,
|
||||
ApiUtils.getUrlForCall(
|
||||
apiVersion,
|
||||
baseUrl,
|
||||
roomToken))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(new Observer<ParticipantsOverall>() {
|
||||
@Override
|
||||
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
|
||||
// unused atm
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@io.reactivex.annotations.NonNull ParticipantsOverall participantsOverall) {
|
||||
participantMap = new HashMap<>();
|
||||
for (Participant participant : participantsOverall.getOcs().getData()) {
|
||||
participantMap.put(participant.getSessionId(), participant);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
|
||||
Log.e(TAG, "error while executing getPeersForCall", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void deletePeerConnection(PeerConnectionWrapper peerConnectionWrapper) {
|
||||
peerConnectionWrapper.removePeerConnection();
|
||||
peerConnectionWrapperList.remove(peerConnectionWrapper);
|
||||
@ -2018,12 +1984,29 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
|
||||
if (!publisher && !hasExternalSignalingServer && offerAnswerNickProviders.get(sessionId) == null) {
|
||||
OfferAnswerNickProvider offerAnswerNickProvider = new OfferAnswerNickProvider();
|
||||
OfferAnswerNickProvider offerAnswerNickProvider = new OfferAnswerNickProvider(sessionId);
|
||||
offerAnswerNickProviders.put(sessionId, offerAnswerNickProvider);
|
||||
signalingMessageReceiver.addListener(offerAnswerNickProvider.getVideoWebRtcMessageListener(), sessionId, "video");
|
||||
signalingMessageReceiver.addListener(offerAnswerNickProvider.getScreenWebRtcMessageListener(), sessionId, "screen");
|
||||
}
|
||||
|
||||
PeerConnectionWrapper.PeerConnectionObserver peerConnectionObserver =
|
||||
new CallActivityPeerConnectionObserver(sessionId, type);
|
||||
peerConnectionObservers.put(sessionId + "-" + type, peerConnectionObserver);
|
||||
peerConnectionWrapper.addObserver(peerConnectionObserver);
|
||||
|
||||
if (!publisher) {
|
||||
runOnUiThread(() -> {
|
||||
// userId is unknown here, but it will be got based on the session id, and the stream will be
|
||||
// updated once it is added to the connection.
|
||||
setupVideoStreamForLayout(
|
||||
null,
|
||||
sessionId,
|
||||
false,
|
||||
type);
|
||||
});
|
||||
}
|
||||
|
||||
if (publisher) {
|
||||
startSendingNick();
|
||||
}
|
||||
@ -2054,6 +2037,9 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
String videoStreamType = peerConnectionWrapper.getVideoStreamType();
|
||||
if (VIDEO_STREAM_TYPE_SCREEN.equals(videoStreamType) || !justScreen) {
|
||||
PeerConnectionWrapper.PeerConnectionObserver peerConnectionObserver = peerConnectionObservers.remove(sessionId + "-" + videoStreamType);
|
||||
peerConnectionWrapper.removeObserver(peerConnectionObserver);
|
||||
|
||||
runOnUiThread(() -> removeMediaStream(sessionId, videoStreamType));
|
||||
deletePeerConnection(peerConnectionWrapper);
|
||||
}
|
||||
@ -2138,48 +2124,37 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onMessageEvent(PeerConnectionEvent peerConnectionEvent) {
|
||||
String sessionId = peerConnectionEvent.getSessionId();
|
||||
String participantDisplayItemId = sessionId + "-" + peerConnectionEvent.getVideoStreamType();
|
||||
public void onMessageEvent(ProximitySensorEvent proximitySensorEvent) {
|
||||
if (!isVoiceOnlyCall) {
|
||||
boolean enableVideo = proximitySensorEvent.getProximitySensorEventType() ==
|
||||
ProximitySensorEvent.ProximitySensorEventType.SENSOR_FAR && videoOn;
|
||||
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA) &&
|
||||
(currentCallStatus == CallStatus.CONNECTING || isConnectionEstablished()) && videoOn
|
||||
&& enableVideo != localVideoTrack.enabled()) {
|
||||
toggleMedia(enableVideo, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||
PeerConnectionEvent.PeerConnectionEventType.PEER_CONNECTED) {
|
||||
if (webSocketClient != null && webSocketClient.getSessionId() != null && webSocketClient.getSessionId().equals(sessionId)) {
|
||||
updateSelfVideoViewConnected(true);
|
||||
} else if (participantDisplayItems.get(participantDisplayItemId) != null) {
|
||||
participantDisplayItems.get(participantDisplayItemId).setConnected(true);
|
||||
participantsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||
PeerConnectionEvent.PeerConnectionEventType.PEER_DISCONNECTED) {
|
||||
if (webSocketClient != null && webSocketClient.getSessionId() != null && webSocketClient.getSessionId().equals(sessionId)) {
|
||||
updateSelfVideoViewConnected(false);
|
||||
} else if (participantDisplayItems.get(participantDisplayItemId) != null) {
|
||||
participantDisplayItems.get(participantDisplayItemId).setConnected(false);
|
||||
participantsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||
PeerConnectionEvent.PeerConnectionEventType.PEER_CLOSED) {
|
||||
endPeerConnection(sessionId, VIDEO_STREAM_TYPE_SCREEN.equals(peerConnectionEvent.getVideoStreamType()));
|
||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||
PeerConnectionEvent.PeerConnectionEventType.SENSOR_FAR ||
|
||||
peerConnectionEvent.getPeerConnectionEventType() ==
|
||||
PeerConnectionEvent.PeerConnectionEventType.SENSOR_NEAR) {
|
||||
private void handlePeerConnected(String sessionId, String videoStreamType) {
|
||||
String participantDisplayItemId = sessionId + "-" + videoStreamType;
|
||||
|
||||
if (!isVoiceOnlyCall) {
|
||||
boolean enableVideo = peerConnectionEvent.getPeerConnectionEventType() ==
|
||||
PeerConnectionEvent.PeerConnectionEventType.SENSOR_FAR && videoOn;
|
||||
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_CAMERA) &&
|
||||
(currentCallStatus == CallStatus.CONNECTING || isConnectionEstablished()) && videoOn
|
||||
&& enableVideo != localVideoTrack.enabled()) {
|
||||
toggleMedia(enableVideo, true);
|
||||
}
|
||||
}
|
||||
} else if (peerConnectionEvent.getPeerConnectionEventType() ==
|
||||
PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED) {
|
||||
setCallState(CallStatus.PUBLISHER_FAILED);
|
||||
webSocketClient.clearResumeId();
|
||||
hangup(false);
|
||||
if (webSocketClient != null && webSocketClient.getSessionId() != null && webSocketClient.getSessionId().equals(sessionId)) {
|
||||
updateSelfVideoViewConnected(true);
|
||||
} else if (participantDisplayItems.get(participantDisplayItemId) != null) {
|
||||
participantDisplayItems.get(participantDisplayItemId).setConnected(true);
|
||||
participantsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePeerDisconnected(String sessionId, String videoStreamType) {
|
||||
String participantDisplayItemId = sessionId + "-" + videoStreamType;
|
||||
|
||||
if (webSocketClient != null && webSocketClient.getSessionId() != null && webSocketClient.getSessionId().equals(sessionId)) {
|
||||
updateSelfVideoViewConnected(false);
|
||||
} else if (participantDisplayItems.get(participantDisplayItemId) != null) {
|
||||
participantDisplayItems.get(participantDisplayItemId).setConnected(false);
|
||||
participantsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2223,28 +2198,6 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onMessageEvent(MediaStreamEvent mediaStreamEvent) {
|
||||
if (mediaStreamEvent.getMediaStream() != null) {
|
||||
boolean hasAtLeastOneVideoStream = mediaStreamEvent.getMediaStream().videoTracks != null
|
||||
&& mediaStreamEvent.getMediaStream().videoTracks.size() > 0;
|
||||
|
||||
setupVideoStreamForLayout(
|
||||
mediaStreamEvent.getMediaStream(),
|
||||
mediaStreamEvent.getSession(),
|
||||
null,
|
||||
hasAtLeastOneVideoStream,
|
||||
mediaStreamEvent.getVideoStreamType());
|
||||
} else {
|
||||
setupVideoStreamForLayout(
|
||||
null,
|
||||
mediaStreamEvent.getSession(),
|
||||
null,
|
||||
false,
|
||||
mediaStreamEvent.getVideoStreamType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
@ -2256,7 +2209,6 @@ public class CallActivity extends CallBaseActivity {
|
||||
|
||||
private void setupVideoStreamForLayout(@Nullable MediaStream mediaStream,
|
||||
String session,
|
||||
String userId,
|
||||
boolean videoStreamEnabled,
|
||||
String videoStreamType) {
|
||||
PeerConnectionWrapper peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(session,
|
||||
@ -2276,20 +2228,12 @@ public class CallActivity extends CallBaseActivity {
|
||||
nick = offerAnswerNickProviders.get(session) != null ? offerAnswerNickProviders.get(session).getNick() : "";
|
||||
}
|
||||
|
||||
String userId4Usage = userId;
|
||||
|
||||
if (userId4Usage == null) {
|
||||
if (hasMCU) {
|
||||
userId4Usage = webSocketClient.getUserIdForSession(session);
|
||||
} else if (participantMap.get(session) != null && participantMap.get(session).getCalculatedActorType() == Participant.ActorType.USERS) {
|
||||
userId4Usage = participantMap.get(session).getCalculatedActorId();
|
||||
}
|
||||
}
|
||||
String userId = userIdsBySessionId.get(session);
|
||||
|
||||
String defaultGuestNick = getResources().getString(R.string.nc_nick_guest);
|
||||
|
||||
ParticipantDisplayItem participantDisplayItem = new ParticipantDisplayItem(baseUrl,
|
||||
userId4Usage,
|
||||
userId,
|
||||
session,
|
||||
connected,
|
||||
nick,
|
||||
@ -2570,18 +2514,18 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private static class OfferAnswerNickProvider {
|
||||
private class OfferAnswerNickProvider {
|
||||
|
||||
private class WebRtcMessageListener implements SignalingMessageReceiver.WebRtcMessageListener {
|
||||
|
||||
@Override
|
||||
public void onOffer(String sdp, String nick) {
|
||||
(OfferAnswerNickProvider.this).nick = nick;
|
||||
onOfferOrAnswer(nick);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnswer(String sdp, String nick) {
|
||||
(OfferAnswerNickProvider.this).nick = nick;
|
||||
onOfferOrAnswer(nick);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2596,8 +2540,31 @@ public class CallActivity extends CallBaseActivity {
|
||||
private final WebRtcMessageListener videoWebRtcMessageListener = new WebRtcMessageListener();
|
||||
private final WebRtcMessageListener screenWebRtcMessageListener = new WebRtcMessageListener();
|
||||
|
||||
private final String sessionId;
|
||||
|
||||
private String nick;
|
||||
|
||||
private OfferAnswerNickProvider(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
private void onOfferOrAnswer(String nick) {
|
||||
this.nick = nick;
|
||||
|
||||
boolean notifyDataSetChanged = false;
|
||||
if (participantDisplayItems.get(sessionId + "-video") != null) {
|
||||
participantDisplayItems.get(sessionId + "-video").setNick(nick);
|
||||
notifyDataSetChanged = true;
|
||||
}
|
||||
if (participantDisplayItems.get(sessionId + "-screen") != null) {
|
||||
participantDisplayItems.get(sessionId + "-screen").setNick(nick);
|
||||
notifyDataSetChanged = true;
|
||||
}
|
||||
if (notifyDataSetChanged) {
|
||||
participantsAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public WebRtcMessageListener getVideoWebRtcMessageListener() {
|
||||
return videoWebRtcMessageListener;
|
||||
}
|
||||
@ -2685,6 +2652,85 @@ public class CallActivity extends CallBaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private class CallActivityPeerConnectionObserver implements PeerConnectionWrapper.PeerConnectionObserver {
|
||||
|
||||
private final String sessionId;
|
||||
private final String videoStreamType;
|
||||
private final String participantDisplayItemId;
|
||||
|
||||
private CallActivityPeerConnectionObserver(String sessionId, String videoStreamType) {
|
||||
this.sessionId = sessionId;
|
||||
this.videoStreamType = videoStreamType;
|
||||
this.participantDisplayItemId = sessionId + "-" + videoStreamType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamAdded(MediaStream mediaStream) {
|
||||
handleStream(mediaStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamRemoved(MediaStream mediaStream) {
|
||||
handleStream(null);
|
||||
}
|
||||
|
||||
private void handleStream(MediaStream mediaStream) {
|
||||
runOnUiThread(() -> {
|
||||
if (participantDisplayItems.get(participantDisplayItemId) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasAtLeastOneVideoStream = false;
|
||||
if (mediaStream != null) {
|
||||
hasAtLeastOneVideoStream = mediaStream.videoTracks != null && mediaStream.videoTracks.size() > 0;
|
||||
}
|
||||
|
||||
ParticipantDisplayItem participantDisplayItem = participantDisplayItems.get(participantDisplayItemId);
|
||||
participantDisplayItem.setMediaStream(mediaStream);
|
||||
participantDisplayItem.setStreamEnabled(hasAtLeastOneVideoStream);
|
||||
participantsAdapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIceConnectionStateChanged(PeerConnection.IceConnectionState iceConnectionState) {
|
||||
runOnUiThread(() -> {
|
||||
if (iceConnectionState == PeerConnection.IceConnectionState.CONNECTED ||
|
||||
iceConnectionState == PeerConnection.IceConnectionState.COMPLETED) {
|
||||
handlePeerConnected(sessionId, videoStreamType);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (iceConnectionState == PeerConnection.IceConnectionState.DISCONNECTED ||
|
||||
iceConnectionState == PeerConnection.IceConnectionState.NEW ||
|
||||
iceConnectionState == PeerConnection.IceConnectionState.CHECKING) {
|
||||
handlePeerDisconnected(sessionId, videoStreamType);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (iceConnectionState == PeerConnection.IceConnectionState.CLOSED) {
|
||||
endPeerConnection(sessionId, VIDEO_STREAM_TYPE_SCREEN.equals(videoStreamType));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (iceConnectionState == PeerConnection.IceConnectionState.FAILED) {
|
||||
if (webSocketClient != null && webSocketClient.getSessionId() != null && webSocketClient.getSessionId().equals(sessionId)) {
|
||||
setCallState(CallStatus.PUBLISHER_FAILED);
|
||||
webSocketClient.clearResumeId();
|
||||
hangup(false);
|
||||
} else {
|
||||
handlePeerDisconnected(sessionId, videoStreamType);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalSignalingMessageSender implements SignalingMessageSender {
|
||||
|
||||
@Override
|
||||
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.events;
|
||||
|
||||
import org.webrtc.MediaStream;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class MediaStreamEvent {
|
||||
private final MediaStream mediaStream;
|
||||
private final String session;
|
||||
private final String videoStreamType;
|
||||
|
||||
public MediaStreamEvent(@Nullable MediaStream mediaStream, String session, String videoStreamType) {
|
||||
this.mediaStream = mediaStream;
|
||||
this.session = session;
|
||||
this.videoStreamType = videoStreamType;
|
||||
}
|
||||
|
||||
public MediaStream getMediaStream() {
|
||||
return this.mediaStream;
|
||||
}
|
||||
|
||||
public String getSession() {
|
||||
return this.session;
|
||||
}
|
||||
|
||||
public String getVideoStreamType() {
|
||||
return this.videoStreamType;
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof MediaStreamEvent)) {
|
||||
return false;
|
||||
}
|
||||
final MediaStreamEvent other = (MediaStreamEvent) o;
|
||||
if (!other.canEqual((Object) this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$mediaStream = this.getMediaStream();
|
||||
final Object other$mediaStream = other.getMediaStream();
|
||||
if (this$mediaStream == null ? other$mediaStream != null : !this$mediaStream.equals(other$mediaStream)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$session = this.getSession();
|
||||
final Object other$session = other.getSession();
|
||||
if (this$session == null ? other$session != null : !this$session.equals(other$session)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$videoStreamType = this.getVideoStreamType();
|
||||
final Object other$videoStreamType = other.getVideoStreamType();
|
||||
|
||||
return this$videoStreamType == null ? other$videoStreamType == null : this$videoStreamType.equals(other$videoStreamType);
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
return other instanceof MediaStreamEvent;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
final Object $mediaStream = this.getMediaStream();
|
||||
result = result * PRIME + ($mediaStream == null ? 43 : $mediaStream.hashCode());
|
||||
final Object $session = this.getSession();
|
||||
result = result * PRIME + ($session == null ? 43 : $session.hashCode());
|
||||
final Object $videoStreamType = this.getVideoStreamType();
|
||||
result = result * PRIME + ($videoStreamType == null ? 43 : $videoStreamType.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "MediaStreamEvent(mediaStream=" + this.getMediaStream() + ", session=" + this.getSession() + ", videoStreamType=" + this.getVideoStreamType() + ")";
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.events;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class PeerConnectionEvent {
|
||||
private final PeerConnectionEventType peerConnectionEventType;
|
||||
private final String sessionId;
|
||||
private final String nick;
|
||||
private final Boolean changeValue;
|
||||
private final String videoStreamType;
|
||||
|
||||
public PeerConnectionEvent(PeerConnectionEventType peerConnectionEventType, @Nullable String sessionId,
|
||||
@Nullable String nick, Boolean changeValue, @Nullable String videoStreamType) {
|
||||
this.peerConnectionEventType = peerConnectionEventType;
|
||||
this.nick = nick;
|
||||
this.changeValue = changeValue;
|
||||
this.sessionId = sessionId;
|
||||
this.videoStreamType = videoStreamType;
|
||||
}
|
||||
|
||||
public PeerConnectionEventType getPeerConnectionEventType() {
|
||||
return this.peerConnectionEventType;
|
||||
}
|
||||
|
||||
public String getSessionId() {
|
||||
return this.sessionId;
|
||||
}
|
||||
|
||||
public String getNick() {
|
||||
return this.nick;
|
||||
}
|
||||
|
||||
public Boolean getChangeValue() {
|
||||
return this.changeValue;
|
||||
}
|
||||
|
||||
public String getVideoStreamType() {
|
||||
return this.videoStreamType;
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PeerConnectionEvent)) {
|
||||
return false;
|
||||
}
|
||||
final PeerConnectionEvent other = (PeerConnectionEvent) o;
|
||||
if (!other.canEqual((Object) this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$peerConnectionEventType = this.getPeerConnectionEventType();
|
||||
final Object other$peerConnectionEventType = other.getPeerConnectionEventType();
|
||||
if (this$peerConnectionEventType == null ? other$peerConnectionEventType != null : !this$peerConnectionEventType.equals(other$peerConnectionEventType)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$sessionId = this.getSessionId();
|
||||
final Object other$sessionId = other.getSessionId();
|
||||
if (this$sessionId == null ? other$sessionId != null : !this$sessionId.equals(other$sessionId)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$nick = this.getNick();
|
||||
final Object other$nick = other.getNick();
|
||||
if (this$nick == null ? other$nick != null : !this$nick.equals(other$nick)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$changeValue = this.getChangeValue();
|
||||
final Object other$changeValue = other.getChangeValue();
|
||||
if (this$changeValue == null ? other$changeValue != null : !this$changeValue.equals(other$changeValue)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$videoStreamType = this.getVideoStreamType();
|
||||
final Object other$videoStreamType = other.getVideoStreamType();
|
||||
|
||||
return this$videoStreamType == null ? other$videoStreamType == null : this$videoStreamType.equals(other$videoStreamType);
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
return other instanceof PeerConnectionEvent;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
final Object $peerConnectionEventType = this.getPeerConnectionEventType();
|
||||
result = result * PRIME + ($peerConnectionEventType == null ? 43 : $peerConnectionEventType.hashCode());
|
||||
final Object $sessionId = this.getSessionId();
|
||||
result = result * PRIME + ($sessionId == null ? 43 : $sessionId.hashCode());
|
||||
final Object $nick = this.getNick();
|
||||
result = result * PRIME + ($nick == null ? 43 : $nick.hashCode());
|
||||
final Object $changeValue = this.getChangeValue();
|
||||
result = result * PRIME + ($changeValue == null ? 43 : $changeValue.hashCode());
|
||||
final Object $videoStreamType = this.getVideoStreamType();
|
||||
result = result * PRIME + ($videoStreamType == null ? 43 : $videoStreamType.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "PeerConnectionEvent(peerConnectionEventType=" + this.getPeerConnectionEventType() + ", sessionId=" + this.getSessionId() + ", nick=" + this.getNick() + ", changeValue=" + this.getChangeValue() + ", videoStreamType=" + this.getVideoStreamType() + ")";
|
||||
}
|
||||
|
||||
public enum PeerConnectionEventType {
|
||||
PEER_CONNECTED, PEER_DISCONNECTED, PEER_CLOSED, SENSOR_FAR, SENSOR_NEAR, PUBLISHER_FAILED
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Mario Danic
|
||||
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.events;
|
||||
|
||||
public class ProximitySensorEvent {
|
||||
private final ProximitySensorEventType proximitySensorEventType;
|
||||
|
||||
public ProximitySensorEvent(ProximitySensorEventType proximitySensorEventType) {
|
||||
this.proximitySensorEventType = proximitySensorEventType;
|
||||
}
|
||||
|
||||
public ProximitySensorEventType getProximitySensorEventType() {
|
||||
return this.proximitySensorEventType;
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ProximitySensorEvent)) {
|
||||
return false;
|
||||
}
|
||||
final ProximitySensorEvent other = (ProximitySensorEvent) o;
|
||||
if (!other.canEqual((Object) this)) {
|
||||
return false;
|
||||
}
|
||||
final Object this$proximitySensorEventType = this.getProximitySensorEventType();
|
||||
final Object other$proximitySensorEventType = other.getProximitySensorEventType();
|
||||
if (this$proximitySensorEventType == null ? other$proximitySensorEventType != null : !this$proximitySensorEventType.equals(other$proximitySensorEventType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean canEqual(final Object other) {
|
||||
return other instanceof ProximitySensorEvent;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
final Object $proximitySensorEventType = this.getProximitySensorEventType();
|
||||
result = result * PRIME + ($proximitySensorEventType == null ? 43 : $proximitySensorEventType.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ProximitySensorEvent(proximitySensorEventType=" + this.getProximitySensorEventType() + ")";
|
||||
}
|
||||
|
||||
public enum ProximitySensorEventType {
|
||||
SENSOR_FAR, SENSOR_NEAR
|
||||
}
|
||||
}
|
@ -386,17 +386,6 @@ public class MagicWebSocketInstance extends WebSocketListener {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getUserIdForSession(String session) {
|
||||
Participant participant = usersHashMap.get(session);
|
||||
if (participant != null) {
|
||||
if (participant.getCalculatedActorType() == USERS) {
|
||||
return participant.getCalculatedActorId();
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||
public void onMessageEvent(NetworkEvent networkEvent) {
|
||||
if (networkEvent.getNetworkConnectionEvent() == NetworkEvent.NetworkConnectionEvent.NETWORK_CONNECTED && !isConnected()) {
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Nextcloud Talk application
|
||||
*
|
||||
* @author Daniel Calviño Sánchez
|
||||
* Copyright (C) 2022 Daniel Calviño Sánchez <danxuliu@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.nextcloud.talk.webrtc;
|
||||
|
||||
import org.webrtc.MediaStream;
|
||||
import org.webrtc.PeerConnection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Helper class to register and notify PeerConnectionObserver.
|
||||
*
|
||||
* This class is only meant for internal use by PeerConnectionWrapper; observers must register themselves against
|
||||
* a PeerConnectionWrapper rather than against a PeerConnectionNotifier.
|
||||
*/
|
||||
public class PeerConnectionNotifier {
|
||||
|
||||
private final Set<PeerConnectionWrapper.PeerConnectionObserver> peerConnectionObservers = new LinkedHashSet<>();
|
||||
|
||||
public synchronized void addObserver(PeerConnectionWrapper.PeerConnectionObserver observer) {
|
||||
if (observer == null) {
|
||||
throw new IllegalArgumentException("PeerConnectionObserver can not be null");
|
||||
}
|
||||
|
||||
peerConnectionObservers.add(observer);
|
||||
}
|
||||
|
||||
public synchronized void removeObserver(PeerConnectionWrapper.PeerConnectionObserver observer) {
|
||||
peerConnectionObservers.remove(observer);
|
||||
}
|
||||
|
||||
public synchronized void notifyStreamAdded(MediaStream stream) {
|
||||
for (PeerConnectionWrapper.PeerConnectionObserver observer : new ArrayList<>(peerConnectionObservers)) {
|
||||
observer.onStreamAdded(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void notifyStreamRemoved(MediaStream stream) {
|
||||
for (PeerConnectionWrapper.PeerConnectionObserver observer : new ArrayList<>(peerConnectionObservers)) {
|
||||
observer.onStreamRemoved(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void notifyIceConnectionStateChanged(PeerConnection.IceConnectionState state) {
|
||||
for (PeerConnectionWrapper.PeerConnectionObserver observer : new ArrayList<>(peerConnectionObservers)) {
|
||||
observer.onIceConnectionStateChanged(state);
|
||||
}
|
||||
}
|
||||
}
|
@ -28,8 +28,6 @@ import android.util.Log;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
||||
import com.nextcloud.talk.events.MediaStreamEvent;
|
||||
import com.nextcloud.talk.events.PeerConnectionEvent;
|
||||
import com.nextcloud.talk.models.json.signaling.DataChannelMessage;
|
||||
import com.nextcloud.talk.models.json.signaling.NCIceCandidate;
|
||||
import com.nextcloud.talk.models.json.signaling.NCMessagePayload;
|
||||
@ -37,7 +35,6 @@ import com.nextcloud.talk.models.json.signaling.NCSignalingMessage;
|
||||
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
|
||||
import com.nextcloud.talk.signaling.SignalingMessageSender;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.webrtc.AudioTrack;
|
||||
import org.webrtc.DataChannel;
|
||||
import org.webrtc.IceCandidate;
|
||||
@ -85,6 +82,21 @@ public class PeerConnectionWrapper {
|
||||
void onNickChanged(String nick);
|
||||
}
|
||||
|
||||
/**
|
||||
* Observer for changes on the peer connection.
|
||||
*
|
||||
* The changes are bound to a specific peer connection, so each observer is expected to handle messages only for
|
||||
* a single peer connection.
|
||||
*
|
||||
* All methods are called on the so called "signaling" thread of WebRTC, which is an internal thread created by the
|
||||
* WebRTC library and NOT the same thread where signaling messages are received.
|
||||
*/
|
||||
public interface PeerConnectionObserver {
|
||||
void onStreamAdded(MediaStream mediaStream);
|
||||
void onStreamRemoved(MediaStream mediaStream);
|
||||
void onIceConnectionStateChanged(PeerConnection.IceConnectionState iceConnectionState);
|
||||
}
|
||||
|
||||
private static final String TAG = PeerConnectionWrapper.class.getCanonicalName();
|
||||
|
||||
private final SignalingMessageReceiver signalingMessageReceiver;
|
||||
@ -94,13 +106,14 @@ public class PeerConnectionWrapper {
|
||||
|
||||
private final DataChannelMessageNotifier dataChannelMessageNotifier = new DataChannelMessageNotifier();
|
||||
|
||||
private final PeerConnectionNotifier peerConnectionNotifier = new PeerConnectionNotifier();
|
||||
|
||||
private List<IceCandidate> iceCandidates = new ArrayList<>();
|
||||
private PeerConnection peerConnection;
|
||||
private String sessionId;
|
||||
private final MediaConstraints mediaConstraints;
|
||||
private DataChannel dataChannel;
|
||||
private final MagicSdpObserver magicSdpObserver;
|
||||
private MediaStream remoteStream;
|
||||
|
||||
private final boolean hasInitiated;
|
||||
|
||||
@ -187,6 +200,21 @@ public class PeerConnectionWrapper {
|
||||
dataChannelMessageNotifier.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an observer for peer connection changes.
|
||||
*
|
||||
* An observer is expected to be added only once. If the same observer is added again it will be notified just once.
|
||||
*
|
||||
* @param observer the PeerConnectionObserver
|
||||
*/
|
||||
public void addObserver(PeerConnectionObserver observer) {
|
||||
peerConnectionNotifier.addObserver(observer);
|
||||
}
|
||||
|
||||
public void removeObserver(PeerConnectionObserver observer) {
|
||||
peerConnectionNotifier.removeObserver(observer);
|
||||
}
|
||||
|
||||
public String getVideoStreamType() {
|
||||
return videoStreamType;
|
||||
}
|
||||
@ -413,34 +441,12 @@ public class PeerConnectionWrapper {
|
||||
|
||||
Log.d("iceConnectionChangeTo: ", iceConnectionState.name() + " over " + peerConnection.hashCode() + " " + sessionId);
|
||||
if (iceConnectionState == PeerConnection.IceConnectionState.CONNECTED) {
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_CONNECTED,
|
||||
sessionId, null, null, videoStreamType));
|
||||
|
||||
if (!isMCUPublisher) {
|
||||
EventBus.getDefault().post(new MediaStreamEvent(remoteStream, sessionId, videoStreamType));
|
||||
}
|
||||
|
||||
if (hasInitiated) {
|
||||
sendInitialMediaStatus();
|
||||
}
|
||||
} else if (iceConnectionState == PeerConnection.IceConnectionState.COMPLETED) {
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_CONNECTED,
|
||||
sessionId, null, null, videoStreamType));
|
||||
} else if (iceConnectionState == PeerConnection.IceConnectionState.CLOSED) {
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
||||
.PEER_CLOSED, sessionId, null, null, videoStreamType));
|
||||
} else if (iceConnectionState == PeerConnection.IceConnectionState.DISCONNECTED ||
|
||||
iceConnectionState == PeerConnection.IceConnectionState.NEW ||
|
||||
iceConnectionState == PeerConnection.IceConnectionState.CHECKING) {
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_DISCONNECTED,
|
||||
sessionId, null, null, videoStreamType));
|
||||
} else if (iceConnectionState == PeerConnection.IceConnectionState.FAILED) {
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PEER_DISCONNECTED,
|
||||
sessionId, null, null, videoStreamType));
|
||||
if (isMCUPublisher) {
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED, sessionId, null, null, videoStreamType));
|
||||
}
|
||||
}
|
||||
|
||||
peerConnectionNotifier.notifyIceConnectionStateChanged(iceConnectionState);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -477,14 +483,12 @@ public class PeerConnectionWrapper {
|
||||
|
||||
@Override
|
||||
public void onAddStream(MediaStream mediaStream) {
|
||||
remoteStream = mediaStream;
|
||||
peerConnectionNotifier.notifyStreamAdded(mediaStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveStream(MediaStream mediaStream) {
|
||||
if (!isMCUPublisher) {
|
||||
EventBus.getDefault().post(new MediaStreamEvent(null, sessionId, videoStreamType));
|
||||
}
|
||||
peerConnectionNotifier.notifyStreamRemoved(mediaStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,7 +43,7 @@ import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.nextcloud.talk.events.PeerConnectionEvent;
|
||||
import com.nextcloud.talk.events.ProximitySensorEvent;
|
||||
import com.nextcloud.talk.utils.power.PowerManagerUtils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
@ -136,15 +136,13 @@ public class WebRtcAudioManager {
|
||||
setAudioDeviceInternal(AudioDevice.EARPIECE);
|
||||
Log.d(TAG, "switched to EARPIECE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=near");
|
||||
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
||||
.SENSOR_NEAR, null, null, null, null));
|
||||
EventBus.getDefault().post(new ProximitySensorEvent(ProximitySensorEvent.ProximitySensorEventType.SENSOR_NEAR));
|
||||
|
||||
} else {
|
||||
setAudioDeviceInternal(WebRtcAudioManager.AudioDevice.SPEAKER_PHONE);
|
||||
Log.d(TAG, "switched to SPEAKER_PHONE because userSelectedAudioDevice was SPEAKER_PHONE and proximity=far");
|
||||
|
||||
EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType
|
||||
.SENSOR_FAR, null, null, null, null));
|
||||
EventBus.getDefault().post(new ProximitySensorEvent(ProximitySensorEvent.ProximitySensorEventType.SENSOR_FAR));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user