Add support for online only delivery

This commit is contained in:
Moxie Marlinspike 2018-10-08 04:08:26 -07:00
parent 7e026a7072
commit ab276a6a61
6 changed files with 32 additions and 24 deletions

View File

@ -129,7 +129,7 @@ public class MessageController {
Optional<Device> destinationDevice = destination.get().getDevice(incomingMessage.getDestinationDeviceId());
if (destinationDevice.isPresent()) {
sendMessage(source, destination.get(), destinationDevice.get(), messages.getTimestamp(), incomingMessage);
sendMessage(source, destination.get(), destinationDevice.get(), messages.getTimestamp(), messages.isOnline(), incomingMessage);
}
}
@ -215,6 +215,7 @@ public class MessageController {
Account destinationAccount,
Device destinationDevice,
long timestamp,
boolean online,
IncomingMessage incomingMessage)
throws NoSuchUserException
{
@ -240,7 +241,7 @@ public class MessageController {
messageBuilder.setContent(ByteString.copyFrom(messageContent.get()));
}
pushSender.sendMessage(destinationAccount, destinationDevice, messageBuilder.build());
pushSender.sendMessage(destinationAccount, destinationDevice, messageBuilder.build(), online);
} catch (NotPushRegisteredException e) {
if (destinationDevice.isMaster()) throw new NoSuchUserException(e);
else logger.debug("Not registered", e);

View File

@ -1,4 +1,4 @@
/**
/*
* Copyright (C) 2013 Open WhisperSystems
*
* This program is free software: you can redistribute it and/or modify
@ -32,6 +32,9 @@ public class IncomingMessageList {
@JsonProperty
private long timestamp;
@JsonProperty
private boolean online;
public IncomingMessageList() {}
public List<IncomingMessage> getMessages() {
@ -41,4 +44,8 @@ public class IncomingMessageList {
public long getTimestamp() {
return timestamp;
}
public boolean isOnline() {
return online;
}
}

View File

@ -62,7 +62,7 @@ public class PushSender implements Managed {
(Gauge<Integer>) executor::getSize);
}
public void sendMessage(final Account account, final Device device, final Envelope message)
public void sendMessage(final Account account, final Device device, final Envelope message, boolean online)
throws NotPushRegisteredException
{
if (device.getGcmId() == null && device.getApnId() == null && !device.getFetchesMessages()) {
@ -70,9 +70,9 @@ public class PushSender implements Managed {
}
if (queueSize > 0) {
executor.execute(() -> sendSynchronousMessage(account, device, message));
executor.execute(() -> sendSynchronousMessage(account, device, message, online));
} else {
sendSynchronousMessage(account, device, message);
sendSynchronousMessage(account, device, message, online);
}
}
@ -88,17 +88,17 @@ public class PushSender implements Managed {
return webSocketSender;
}
private void sendSynchronousMessage(Account account, Device device, Envelope message) {
if (device.getGcmId() != null) sendGcmMessage(account, device, message);
else if (device.getApnId() != null) sendApnMessage(account, device, message);
else if (device.getFetchesMessages()) sendWebSocketMessage(account, device, message);
private void sendSynchronousMessage(Account account, Device device, Envelope message, boolean online) {
if (device.getGcmId() != null) sendGcmMessage(account, device, message, online);
else if (device.getApnId() != null) sendApnMessage(account, device, message, online);
else if (device.getFetchesMessages()) sendWebSocketMessage(account, device, message, online);
else throw new AssertionError();
}
private void sendGcmMessage(Account account, Device device, Envelope message) {
DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, message, WebsocketSender.Type.GCM);
private void sendGcmMessage(Account account, Device device, Envelope message, boolean online) {
DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, message, WebsocketSender.Type.GCM, online);
if (!deliveryStatus.isDelivered()) {
if (!deliveryStatus.isDelivered() && !online) {
sendGcmNotification(account, device);
}
}
@ -110,10 +110,10 @@ public class PushSender implements Managed {
gcmSender.sendMessage(gcmMessage);
}
private void sendApnMessage(Account account, Device device, Envelope outgoingMessage) {
DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.APN);
private void sendApnMessage(Account account, Device device, Envelope outgoingMessage, boolean online) {
DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.APN, online);
if (!deliveryStatus.isDelivered() && outgoingMessage.getType() != Envelope.Type.RECEIPT) {
if (!deliveryStatus.isDelivered() && outgoingMessage.getType() != Envelope.Type.RECEIPT && !online) {
sendApnNotification(account, device, false);
}
}
@ -135,9 +135,9 @@ public class PushSender implements Managed {
apnSender.sendMessage(apnMessage);
}
private void sendWebSocketMessage(Account account, Device device, Envelope outgoingMessage)
private void sendWebSocketMessage(Account account, Device device, Envelope outgoingMessage, boolean online)
{
webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.WEB);
webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.WEB, online);
}
@Override

View File

@ -41,7 +41,7 @@ public class ReceiptSender {
}
for (Device destinationDevice : destinationDevices) {
pushSender.sendMessage(destinationAccount, destinationDevice, message.build());
pushSender.sendMessage(destinationAccount, destinationDevice, message.build(), false);
}
}

View File

@ -68,7 +68,7 @@ public class WebsocketSender {
this.pubSubManager = pubSubManager;
}
public DeliveryStatus sendMessage(Account account, Device device, Envelope message, Type channel) {
public DeliveryStatus sendMessage(Account account, Device device, Envelope message, Type channel, boolean online) {
WebsocketAddress address = new WebsocketAddress(account.getNumber(), device.getId());
PubSubMessage pubSubMessage = PubSubMessage.newBuilder()
.setType(PubSubMessage.Type.DELIVER)
@ -86,7 +86,7 @@ public class WebsocketSender {
else if (channel == Type.GCM) gcmOfflineMeter.mark();
else websocketOfflineMeter.mark();
queueMessage(account, device, message);
if (!online) queueMessage(account, device, message);
return new DeliveryStatus(false);
}
}

View File

@ -109,7 +109,7 @@ public class MessageControllerTest {
assertThat("Good Response", response.getStatus(), is(equalTo(200)));
ArgumentCaptor<Envelope> captor = ArgumentCaptor.forClass(Envelope.class);
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture());
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture(), eq(false));
assertTrue(captor.getValue().hasSource());
assertTrue(captor.getValue().hasSourceDevice());
@ -128,7 +128,7 @@ public class MessageControllerTest {
assertThat("Good Response", response.getStatus(), is(equalTo(200)));
ArgumentCaptor<Envelope> captor = ArgumentCaptor.forClass(Envelope.class);
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture());
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture(), eq(false));
assertFalse(captor.getValue().hasSource());
assertFalse(captor.getValue().hasSourceDevice());
@ -197,7 +197,7 @@ public class MessageControllerTest {
assertThat("Good Response Code", response.getStatus(), is(equalTo(200)));
verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class));
verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class), eq(false));
}
@Test