diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 806232a22..9b92438eb 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -114,6 +114,8 @@
+
+
diff --git a/src/main/java/eu/siacs/conversations/services/UnifiedPushBroker.java b/src/main/java/eu/siacs/conversations/services/UnifiedPushBroker.java
index 7d2d90dd5..f27bf7fc5 100644
--- a/src/main/java/eu/siacs/conversations/services/UnifiedPushBroker.java
+++ b/src/main/java/eu/siacs/conversations/services/UnifiedPushBroker.java
@@ -4,6 +4,9 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.common.base.Optional;
@@ -62,7 +65,7 @@ public class UnifiedPushBroker {
Log.d(
Config.LOGTAG,
account.getJid().asBareJid() + ": trigger endpoint renewal on bind");
- renewUnifiedEndpoint(transportOptional.get());
+ renewUnifiedEndpoint(transportOptional.get(), null);
}
}
}
@@ -74,11 +77,15 @@ public class UnifiedPushBroker {
}
public Optional renewUnifiedPushEndpoints() {
+ return renewUnifiedPushEndpoints(null);
+ }
+
+ public Optional renewUnifiedPushEndpoints(final PushTargetMessenger pushTargetMessenger) {
final Optional transportOptional = getTransport();
if (transportOptional.isPresent()) {
final Transport transport = transportOptional.get();
if (transport.account.isEnabled()) {
- renewUnifiedEndpoint(transportOptional.get());
+ renewUnifiedEndpoint(transportOptional.get(), pushTargetMessenger);
} else {
Log.d(Config.LOGTAG, "skipping UnifiedPush endpoint renewal. Account is disabled");
}
@@ -88,7 +95,7 @@ public class UnifiedPushBroker {
return transportOptional;
}
- private void renewUnifiedEndpoint(final Transport transport) {
+ private void renewUnifiedEndpoint(final Transport transport, final PushTargetMessenger pushTargetMessenger) {
final Account account = transport.account;
final UnifiedPushDatabase unifiedPushDatabase = UnifiedPushDatabase.getInstance(service);
final List renewals =
@@ -114,16 +121,23 @@ public class UnifiedPushBroker {
final Element register = registration.addChild("register", Namespace.UNIFIED_PUSH);
register.setAttribute("application", hashedApplication);
register.setAttribute("instance", hashedInstance);
+ final Messenger messenger;
+ if (pushTargetMessenger != null && renewal.equals(pushTargetMessenger.pushTarget)) {
+ messenger = pushTargetMessenger.messenger;
+ } else {
+ messenger = null;
+ }
this.service.sendIqPacket(
account,
registration,
- (a, response) -> processRegistration(transport, renewal, response));
+ (a, response) -> processRegistration(transport, renewal, messenger, response));
}
}
private void processRegistration(
final Transport transport,
final UnifiedPushDatabase.PushTarget renewal,
+ final Messenger messenger,
final IqPacket response) {
if (response.getType() == IqPacket.TYPE.RESULT) {
final Element registered = response.findChild("registered", Namespace.UNIFIED_PUSH);
@@ -142,7 +156,7 @@ public class UnifiedPushBroker {
Log.d(Config.LOGTAG, "could not parse expiration", e);
return;
}
- renewUnifiedPushEndpoint(transport, renewal, endpoint, expiration);
+ renewUnifiedPushEndpoint(transport, renewal, messenger, endpoint, expiration);
} else {
Log.d(Config.LOGTAG, "could not register UP endpoint " + response.getErrorCondition());
}
@@ -151,6 +165,7 @@ public class UnifiedPushBroker {
private void renewUnifiedPushEndpoint(
final Transport transport,
final UnifiedPushDatabase.PushTarget renewal,
+ final Messenger messenger,
final String endpoint,
final long expiration) {
Log.d(Config.LOGTAG, "registered endpoint " + endpoint + " expiration=" + expiration);
@@ -171,9 +186,24 @@ public class UnifiedPushBroker {
+ renewal.instance
+ " was updated to "
+ endpoint);
- broadcastEndpoint(
- renewal.instance,
- new UnifiedPushDatabase.ApplicationEndpoint(renewal.application, endpoint));
+ final UnifiedPushDatabase.ApplicationEndpoint applicationEndpoint = new UnifiedPushDatabase.ApplicationEndpoint(renewal.application, endpoint);
+ sendEndpoint(messenger, renewal.instance, applicationEndpoint);
+ }
+ }
+
+ private void sendEndpoint(final Messenger messenger, String instance, final UnifiedPushDatabase.ApplicationEndpoint applicationEndpoint) {
+ if (messenger != null) {
+ Log.d(Config.LOGTAG,"using messenger instead of broadcast to communicate endpoint to "+applicationEndpoint.application);
+ final Message message = new Message();
+ message.obj = endpointIntent(instance, applicationEndpoint);
+ try {
+ messenger.send(message);
+ } catch (final RemoteException e) {
+ Log.d(Config.LOGTAG,"messenger failed. falling back to broadcast");
+ broadcastEndpoint(instance, applicationEndpoint);
+ }
+ } else {
+ broadcastEndpoint(instance, applicationEndpoint);
}
}
@@ -302,14 +332,19 @@ public class UnifiedPushBroker {
private void broadcastEndpoint(
final String instance, final UnifiedPushDatabase.ApplicationEndpoint endpoint) {
Log.d(Config.LOGTAG, "broadcasting endpoint to " + endpoint.application);
- final Intent updateIntent = new Intent(UnifiedPushDistributor.ACTION_NEW_ENDPOINT);
- updateIntent.setPackage(endpoint.application);
- updateIntent.putExtra("token", instance);
- updateIntent.putExtra("endpoint", endpoint.endpoint);
+ final Intent updateIntent = endpointIntent(instance, endpoint);
service.sendBroadcast(updateIntent);
}
- public void rebroadcastEndpoint(final String instance, final Transport transport) {
+ private static Intent endpointIntent(final String instance, final UnifiedPushDatabase.ApplicationEndpoint endpoint) {
+ final Intent intent = new Intent(UnifiedPushDistributor.ACTION_NEW_ENDPOINT);
+ intent.setPackage(endpoint.application);
+ intent.putExtra("token", instance);
+ intent.putExtra("endpoint", endpoint.endpoint);
+ return intent;
+ }
+
+ public void rebroadcastEndpoint(final Messenger messenger, final String instance, final Transport transport) {
final UnifiedPushDatabase unifiedPushDatabase = UnifiedPushDatabase.getInstance(service);
final UnifiedPushDatabase.ApplicationEndpoint endpoint =
unifiedPushDatabase.getEndpoint(
@@ -317,7 +352,7 @@ public class UnifiedPushBroker {
transport.transport.toEscapedString(),
instance);
if (endpoint != null) {
- broadcastEndpoint(instance, endpoint);
+ sendEndpoint(messenger, instance, endpoint);
}
}
@@ -330,4 +365,14 @@ public class UnifiedPushBroker {
this.transport = transport;
}
}
+
+ public static class PushTargetMessenger {
+ private final UnifiedPushDatabase.PushTarget pushTarget;
+ private final Messenger messenger;
+
+ public PushTargetMessenger(UnifiedPushDatabase.PushTarget pushTarget, Messenger messenger) {
+ this.pushTarget = pushTarget;
+ this.messenger = messenger;
+ }
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/services/UnifiedPushDistributor.java b/src/main/java/eu/siacs/conversations/services/UnifiedPushDistributor.java
index 64c16dbcd..c5402dec6 100644
--- a/src/main/java/eu/siacs/conversations/services/UnifiedPushDistributor.java
+++ b/src/main/java/eu/siacs/conversations/services/UnifiedPushDistributor.java
@@ -1,10 +1,13 @@
package eu.siacs.conversations.services;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.net.Uri;
+import android.os.Messenger;
+import android.os.Parcelable;
import android.util.Log;
import com.google.common.base.Charsets;
@@ -46,12 +49,21 @@ public class UnifiedPushDistributor extends BroadcastReceiver {
return;
}
final String action = intent.getAction();
- final String application = intent.getStringExtra("application");
+ final String application;
+ final Parcelable appByPendingIntent = intent.getParcelableExtra("app");
+ if (appByPendingIntent instanceof PendingIntent) {
+ final PendingIntent pendingIntent = (PendingIntent) appByPendingIntent;
+ application = pendingIntent.getIntentSender().getCreatorPackage();
+ Log.d(Config.LOGTAG,"received application name via pending intent "+ application);
+ } else {
+ application = intent.getStringExtra("application");
+ }
+ final Parcelable messenger = intent.getParcelableExtra("messenger");
final String instance = intent.getStringExtra("token");
final List features = intent.getStringArrayListExtra("features");
switch (Strings.nullToEmpty(action)) {
case ACTION_REGISTER:
- register(context, application, instance, features);
+ register(context, application, instance, features, messenger);
break;
case ACTION_UNREGISTER:
unregister(context, instance);
@@ -69,7 +81,8 @@ public class UnifiedPushDistributor extends BroadcastReceiver {
final Context context,
final String application,
final String instance,
- final Collection features) {
+ final Collection features,
+ final Parcelable messenger) {
if (Strings.isNullOrEmpty(application) || Strings.isNullOrEmpty(instance)) {
Log.w(Config.LOGTAG, "ignoring invalid UnifiedPush registration");
return;
@@ -92,6 +105,10 @@ public class UnifiedPushDistributor extends BroadcastReceiver {
final Intent serviceIntent = new Intent(context, XmppConnectionService.class);
serviceIntent.setAction(XmppConnectionService.ACTION_RENEW_UNIFIED_PUSH_ENDPOINTS);
serviceIntent.putExtra("instance", instance);
+ serviceIntent.putExtra("application", application);
+ if (messenger instanceof Messenger) {
+ serviceIntent.putExtra("messenger", messenger);
+ }
Compatibility.startService(context, serviceIntent);
} else {
Log.d(Config.LOGTAG, "not successful. sending error message back to application");
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index ebbbef4c4..dcb613399 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -32,6 +32,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
+import android.os.Messenger;
+import android.os.Parcelable;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
@@ -815,9 +817,18 @@ public class XmppConnectionService extends Service {
break;
case ACTION_RENEW_UNIFIED_PUSH_ENDPOINTS:
final String instance = intent.getStringExtra("instance");
- final Optional transport = renewUnifiedPushEndpoints();
+ final String application = intent.getStringExtra("application");
+ final Messenger messenger = intent.getParcelableExtra("messenger");
+ final UnifiedPushBroker.PushTargetMessenger pushTargetMessenger;
+ if (messenger != null && application != null && instance != null) {
+ pushTargetMessenger = new UnifiedPushBroker.PushTargetMessenger(new UnifiedPushDatabase.PushTarget(application, instance),messenger);
+ Log.d(Config.LOGTAG,"found push target messenger");
+ } else {
+ pushTargetMessenger = null;
+ }
+ final Optional transport = renewUnifiedPushEndpoints(pushTargetMessenger);
if (instance != null && transport.isPresent()) {
- unifiedPushBroker.rebroadcastEndpoint(instance, transport.get());
+ unifiedPushBroker.rebroadcastEndpoint(messenger, instance, transport.get());
}
break;
case ACTION_IDLE_PING:
@@ -2363,8 +2374,12 @@ public class XmppConnectionService extends Service {
return this.unifiedPushBroker.reconfigurePushDistributor();
}
+ private Optional renewUnifiedPushEndpoints(final UnifiedPushBroker.PushTargetMessenger pushTargetMessenger) {
+ return this.unifiedPushBroker.renewUnifiedPushEndpoints(pushTargetMessenger);
+ }
+
public Optional renewUnifiedPushEndpoints() {
- return this.unifiedPushBroker.renewUnifiedPushEndpoints();
+ return this.unifiedPushBroker.renewUnifiedPushEndpoints(null);
}
private void provisionAccount(final String address, final String password) {