put 'video' in ongoing video call notification
This commit is contained in:
parent
d7e93e18e5
commit
36e117979a
|
@ -372,10 +372,15 @@ public class NotificationService {
|
|||
notify(INCOMING_CALL_NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
public Notification getOngoingCallNotification(final AbstractJingleConnection.Id id) {
|
||||
public Notification getOngoingCallNotification(final AbstractJingleConnection.Id id, final Set<Media> media) {
|
||||
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls");
|
||||
if (media.contains(Media.VIDEO)) {
|
||||
builder.setSmallIcon(R.drawable.ic_videocam_white_24dp);
|
||||
builder.setContentTitle(mXmppConnectionService.getString(R.string.ongoing_video_call));
|
||||
} else {
|
||||
builder.setSmallIcon(R.drawable.ic_call_white_24dp);
|
||||
builder.setContentTitle(mXmppConnectionService.getString(R.string.ongoing_call));
|
||||
}
|
||||
builder.setContentText(id.account.getRoster().getContact(id.with).getDisplayName());
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||
|
|
|
@ -42,6 +42,7 @@ import android.util.Log;
|
|||
import android.util.LruCache;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import org.conscrypt.Conscrypt;
|
||||
|
@ -145,6 +146,7 @@ import eu.siacs.conversations.xmpp.chatstate.ChatState;
|
|||
import eu.siacs.conversations.xmpp.forms.Data;
|
||||
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
|
||||
import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
|
||||
import eu.siacs.conversations.xmpp.jingle.Media;
|
||||
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
|
||||
import eu.siacs.conversations.xmpp.mam.MamReference;
|
||||
import eu.siacs.conversations.xmpp.pep.Avatar;
|
||||
|
@ -209,7 +211,7 @@ public class XmppConnectionService extends Service {
|
|||
private AtomicBoolean mInitialAddressbookSyncCompleted = new AtomicBoolean(false);
|
||||
private AtomicBoolean mForceForegroundService = new AtomicBoolean(false);
|
||||
private AtomicBoolean mForceDuringOnCreate = new AtomicBoolean(false);
|
||||
private AtomicReference<AbstractJingleConnection.Id> ongoingCall = new AtomicReference<>();
|
||||
private AtomicReference<OngoingCall> ongoingCall = new AtomicReference<>();
|
||||
private OnMessagePacketReceived mMessageParser = new MessageParser(this);
|
||||
private OnPresencePacketReceived mPresenceParser = new PresenceParser(this);
|
||||
private IqParser mIqParser = new IqParser(this);
|
||||
|
@ -1228,24 +1230,23 @@ public class XmppConnectionService extends Service {
|
|||
toggleForegroundService(false);
|
||||
}
|
||||
|
||||
public void setOngoingCall(AbstractJingleConnection.Id id) {
|
||||
ongoingCall.set(id);
|
||||
public void setOngoingCall(AbstractJingleConnection.Id id, Set<Media> media) {
|
||||
ongoingCall.set(new OngoingCall(id, media));
|
||||
toggleForegroundService(false);
|
||||
}
|
||||
|
||||
public void removeOngoingCall(AbstractJingleConnection.Id id) {
|
||||
if (ongoingCall.compareAndSet(id, null)) {
|
||||
public void removeOngoingCall() {
|
||||
ongoingCall.set(null);
|
||||
toggleForegroundService(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleForegroundService(boolean force) {
|
||||
final boolean status;
|
||||
final AbstractJingleConnection.Id ongoing = ongoingCall.get();
|
||||
final OngoingCall ongoing = ongoingCall.get();
|
||||
if (force || mForceDuringOnCreate.get() || mForceForegroundService.get() || ongoing != null || (Compatibility.keepForegroundService(this) && hasEnabledAccounts())) {
|
||||
final Notification notification;
|
||||
if (ongoing != null) {
|
||||
notification = this.mNotificationService.getOngoingCallNotification(ongoing);
|
||||
notification = this.mNotificationService.getOngoingCallNotification(ongoing.id, ongoing.media);
|
||||
startForeground(NotificationService.ONGOING_CALL_NOTIFICATION_ID, notification);
|
||||
mNotificationService.cancel(NotificationService.FOREGROUND_NOTIFICATION_ID);
|
||||
} else {
|
||||
|
@ -4753,4 +4754,27 @@ public class XmppConnectionService extends Service {
|
|||
onStartCommand(intent, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static class OngoingCall {
|
||||
private final AbstractJingleConnection.Id id;
|
||||
private final Set<Media> media;
|
||||
|
||||
public OngoingCall(AbstractJingleConnection.Id id, Set<Media> media) {
|
||||
this.id = id;
|
||||
this.media = media;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
OngoingCall that = (OngoingCall) o;
|
||||
return Objects.equal(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,12 @@ import static java.util.Arrays.asList;
|
|||
|
||||
public class RtpSessionActivity extends XmppActivity implements XmppConnectionService.OnJingleRtpConnectionUpdate {
|
||||
|
||||
private static final List<RtpEndUserState> END_CARD = Arrays.asList(
|
||||
RtpEndUserState.APPLICATION_ERROR,
|
||||
RtpEndUserState.DECLINED_OR_BUSY,
|
||||
RtpEndUserState.CONNECTIVITY_ERROR
|
||||
);
|
||||
|
||||
private static final String PROXIMITY_WAKE_LOCK_TAG = "conversations:in-rtp-session";
|
||||
|
||||
private static final int REQUEST_ACCEPT_CALL = 0x1111;
|
||||
|
@ -116,23 +122,27 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
|||
permissions = ImmutableList.of(Manifest.permission.RECORD_AUDIO);
|
||||
}
|
||||
if (PermissionUtils.hasPermission(this, permissions, REQUEST_ACCEPT_CALL)) {
|
||||
//TODO like wise the propose; we might just wait here for the audio manager to come up
|
||||
putScreenInCallMode();
|
||||
requireRtpConnection().acceptCall();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("WakelockTimeout")
|
||||
private void putScreenInCallMode() {
|
||||
//TODO for video calls we actually do want to keep the screen on
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
putScreenInCallMode(requireRtpConnection().getMedia());
|
||||
}
|
||||
|
||||
private void putScreenInCallMode(final Set<Media> media) {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
if (!media.contains(Media.VIDEO)) {
|
||||
final JingleRtpConnection rtpConnection = rtpConnectionReference != null ? rtpConnectionReference.get() : null;
|
||||
final AppRTCAudioManager audioManager = rtpConnection == null ? null : rtpConnection.getAudioManager();
|
||||
if (audioManager == null || audioManager.getSelectedAudioDevice() == AppRTCAudioManager.AudioDevice.EARPIECE) {
|
||||
acquireProximityWakeLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("WakelockTimeout")
|
||||
private void acquireProximityWakeLock() {
|
||||
final PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
if (powerManager == null) {
|
||||
|
@ -234,8 +244,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
|||
|
||||
private void proposeJingleRtpSession(final Account account, final Jid with, final Set<Media> media) {
|
||||
xmppConnectionService.getJingleConnectionManager().proposeJingleRtpSession(account, with, media);
|
||||
//TODO maybe we don’t want to acquire a wake lock just yet and wait for audio manager to discover what speaker we are using
|
||||
putScreenInCallMode();
|
||||
putScreenInCallMode(media);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -570,10 +579,12 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
|||
|
||||
@Override
|
||||
public void onJingleRtpConnectionUpdate(Account account, Jid with, final String sessionId, RtpEndUserState state) {
|
||||
if (Arrays.asList(RtpEndUserState.APPLICATION_ERROR, RtpEndUserState.DECLINED_OR_BUSY, RtpEndUserState.DECLINED_OR_BUSY).contains(state)) {
|
||||
releaseProximityWakeLock();
|
||||
}
|
||||
Log.d(Config.LOGTAG, "onJingleRtpConnectionUpdate(" + state + ")");
|
||||
if (END_CARD.contains(state)) {
|
||||
Log.d(Config.LOGTAG,"end card reached");
|
||||
releaseProximityWakeLock();
|
||||
runOnUiThread(()-> getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON));
|
||||
}
|
||||
if (with.isBareJid()) {
|
||||
updateRtpSessionProposalState(account, with, state);
|
||||
return;
|
||||
|
@ -588,7 +599,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
|||
if (state == RtpEndUserState.ENDED) {
|
||||
finish();
|
||||
return;
|
||||
} else if (asList(RtpEndUserState.APPLICATION_ERROR, RtpEndUserState.DECLINED_OR_BUSY, RtpEndUserState.CONNECTIVITY_ERROR).contains(state)) {
|
||||
} else if (END_CARD.contains(state)) {
|
||||
//todo remember if we were video
|
||||
resetIntent(account, with, state);
|
||||
}
|
||||
|
@ -608,14 +619,22 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
|||
public void onAudioDeviceChanged(AppRTCAudioManager.AudioDevice selectedAudioDevice, Set<AppRTCAudioManager.AudioDevice> availableAudioDevices) {
|
||||
Log.d(Config.LOGTAG, "onAudioDeviceChanged in activity: selected:" + selectedAudioDevice + ", available:" + availableAudioDevices);
|
||||
try {
|
||||
if (requireRtpConnection().getEndUserState() == RtpEndUserState.CONNECTED && !getMedia().contains(Media.VIDEO)) {
|
||||
if (getMedia().contains(Media.VIDEO)) {
|
||||
Log.d(Config.LOGTAG,"nothing to do; in video mode");
|
||||
return;
|
||||
}
|
||||
final RtpEndUserState endUserState = requireRtpConnection().getEndUserState();
|
||||
if (endUserState == RtpEndUserState.CONNECTED) {
|
||||
final AppRTCAudioManager audioManager = requireRtpConnection().getAudioManager();
|
||||
updateInCallButtonConfigurationSpeaker(
|
||||
audioManager.getSelectedAudioDevice(),
|
||||
audioManager.getAudioDevices().size()
|
||||
);
|
||||
}
|
||||
} else if (END_CARD.contains(endUserState)) {
|
||||
Log.d(Config.LOGTAG,"onAudioDeviceChanged() nothing to do because end card has been reached");
|
||||
} else {
|
||||
putProximityWakeLockInProperState();
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
Log.d(Config.LOGTAG, "RTP connection was not available when audio device changed");
|
||||
}
|
||||
|
|
|
@ -289,9 +289,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
} else {
|
||||
target = State.SESSION_INITIALIZED;
|
||||
}
|
||||
if (transition(target)) {
|
||||
if (transition(target, () -> this.initiatorRtpContentMap = contentMap)) {
|
||||
respondOk(jinglePacket);
|
||||
this.initiatorRtpContentMap = contentMap;
|
||||
if (target == State.SESSION_INITIALIZED_PRE_APPROVED) {
|
||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": automatically accepting session-initiate");
|
||||
sendSessionAccept();
|
||||
|
@ -323,6 +322,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
sendSessionTerminate(Reason.FAILED_APPLICATION, e.getMessage());
|
||||
return;
|
||||
}
|
||||
//TODO check that session accept content media matched ours
|
||||
Log.d(Config.LOGTAG, "processing session-accept with " + contentMap.contents.size() + " contents");
|
||||
if (transition(State.SESSION_ACCEPTED)) {
|
||||
respondOk(jinglePacket);
|
||||
|
@ -500,7 +500,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
final boolean originatedFromMyself = from.asBareJid().equals(id.account.getJid().asBareJid());
|
||||
if (originatedFromMyself) {
|
||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": saw proposal from mysql. ignoring");
|
||||
} else if (isInState(State.NULL)) {
|
||||
} else if (transition(State.PROPOSED, () -> {
|
||||
final Collection<RtpDescription> descriptions = Collections2.transform(
|
||||
Collections2.filter(propose.getDescriptions(), d -> d instanceof RtpDescription),
|
||||
input -> (RtpDescription) input
|
||||
|
@ -509,7 +509,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
Preconditions.checkState(!media.contains(Media.UNKNOWN), "RTP descriptions contain unknown media");
|
||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received session proposal from " + from + " for " + media);
|
||||
this.proposedMedia = Sets.newHashSet(media);
|
||||
transitionOrThrow(State.PROPOSED);
|
||||
})) {
|
||||
if (serverMsgId != null) {
|
||||
this.message.setServerMsgId(serverMsgId);
|
||||
}
|
||||
|
@ -720,10 +720,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
return RtpEndUserState.CONNECTING;
|
||||
} else if (state == PeerConnection.PeerConnectionState.CLOSED) {
|
||||
return RtpEndUserState.ENDING_CALL;
|
||||
} else if (state == PeerConnection.PeerConnectionState.FAILED) {
|
||||
return RtpEndUserState.CONNECTIVITY_ERROR;
|
||||
} else {
|
||||
return RtpEndUserState.ENDING_CALL;
|
||||
return RtpEndUserState.CONNECTIVITY_ERROR;
|
||||
}
|
||||
case REJECTED:
|
||||
case TERMINATED_DECLINED_OR_BUSY:
|
||||
|
@ -876,10 +874,17 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
return Arrays.asList(state).contains(this.state);
|
||||
}
|
||||
|
||||
private synchronized boolean transition(final State target) {
|
||||
private boolean transition(final State target) {
|
||||
return transition(target, null);
|
||||
}
|
||||
|
||||
private synchronized boolean transition(final State target, final Runnable runnable) {
|
||||
final Collection<State> validTransitions = VALID_TRANSITIONS.get(this.state);
|
||||
if (validTransitions != null && validTransitions.contains(target)) {
|
||||
this.state = target;
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": transitioned into " + target);
|
||||
updateEndUserState();
|
||||
updateOngoingCallNotification();
|
||||
|
@ -909,7 +914,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
if (newState == PeerConnection.PeerConnectionState.CONNECTED && this.rtpConnectionStarted == 0) {
|
||||
this.rtpConnectionStarted = SystemClock.elapsedRealtime();
|
||||
}
|
||||
if (newState == PeerConnection.PeerConnectionState.FAILED) {
|
||||
if (Arrays.asList(PeerConnection.PeerConnectionState.FAILED, PeerConnection.PeerConnectionState.DISCONNECTED).contains(newState)) {
|
||||
if (TERMINATED.contains(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;
|
||||
|
@ -949,9 +954,9 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
|||
|
||||
private void updateOngoingCallNotification() {
|
||||
if (STATES_SHOWING_ONGOING_CALL.contains(this.state)) {
|
||||
xmppConnectionService.setOngoingCall(id);
|
||||
xmppConnectionService.setOngoingCall(id, getMedia());
|
||||
} else {
|
||||
xmppConnectionService.removeOngoingCall(id);
|
||||
xmppConnectionService.removeOngoingCall();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -903,6 +903,7 @@
|
|||
<string name="rtp_state_application_failure">Application failure</string>
|
||||
<string name="hang_up">Hang up</string>
|
||||
<string name="ongoing_call">Ongoing call</string>
|
||||
<string name="ongoing_video_call">Ongoing video call</string>
|
||||
<string name="disable_tor_to_make_call">Disable Tor to make calls</string>
|
||||
<string name="incoming_call">Incoming call</string>
|
||||
<string name="incoming_call_duration">Incoming call · %s</string>
|
||||
|
|
Loading…
Reference in New Issue