PushManagementService.java

  1package eu.siacs.conversations.services;
  2
  3import android.provider.Settings;
  4import android.util.Log;
  5
  6import com.google.android.gms.common.ConnectionResult;
  7import com.google.android.gms.common.GoogleApiAvailability;
  8import com.google.android.gms.gcm.GoogleCloudMessaging;
  9import com.google.android.gms.iid.InstanceID;
 10
 11import eu.siacs.conversations.Config;
 12import eu.siacs.conversations.R;
 13import eu.siacs.conversations.entities.Account;
 14import eu.siacs.conversations.xml.Element;
 15import eu.siacs.conversations.xml.Namespace;
 16import eu.siacs.conversations.xmpp.XmppConnection;
 17import eu.siacs.conversations.xmpp.forms.Data;
 18import eu.siacs.conversations.xmpp.jid.InvalidJidException;
 19import eu.siacs.conversations.xmpp.jid.Jid;
 20import eu.siacs.conversations.xmpp.stanzas.IqPacket;
 21
 22public class PushManagementService {
 23
 24	private static final String APP_SERVER = "push.siacs.eu";
 25
 26	protected final XmppConnectionService mXmppConnectionService;
 27
 28	public PushManagementService(XmppConnectionService service) {
 29		this.mXmppConnectionService = service;
 30	}
 31
 32	public void registerPushTokenOnServer(final Account account) {
 33		Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": has push support");
 34		retrieveGcmInstanceToken(token -> {
 35			try {
 36				final String deviceId = Settings.Secure.getString(mXmppConnectionService.getContentResolver(), Settings.Secure.ANDROID_ID);
 37				IqPacket packet = mXmppConnectionService.getIqGenerator().pushTokenToAppServer(Jid.fromString(APP_SERVER), token, deviceId);
 38				mXmppConnectionService.sendIqPacket(account, packet, (a, p) -> {
 39					Element command = p.findChild("command","http://jabber.org/protocol/commands");
 40					if (p.getType() == IqPacket.TYPE.RESULT && command != null) {
 41						Element x = command.findChild("x", Namespace.DATA);
 42						if (x != null) {
 43							Data data = Data.parse(x);
 44							try {
 45								String node = data.getValue("node");
 46								String secret = data.getValue("secret");
 47								Jid jid = Jid.fromString(data.getValue("jid"));
 48								if (node != null && secret != null) {
 49									enablePushOnServer(a, jid, node, secret);
 50								}
 51							} catch (InvalidJidException e) {
 52								e.printStackTrace();
 53							}
 54						}
 55					} else {
 56						Log.d(Config.LOGTAG, a.getJid().toBareJid()+": invalid response from app server");
 57					}
 58				});
 59			} catch (InvalidJidException ignored) {
 60
 61			}
 62		});
 63	}
 64
 65	private void enablePushOnServer(final Account account, final Jid jid, final String node, final String secret) {
 66		IqPacket enable = mXmppConnectionService.getIqGenerator().enablePush(jid, node, secret);
 67		mXmppConnectionService.sendIqPacket(account, enable, (a, p) -> {
 68			if (p.getType() == IqPacket.TYPE.RESULT) {
 69				Log.d(Config.LOGTAG, a.getJid().toBareJid() + ": successfully enabled push on server");
 70			} else if (p.getType() == IqPacket.TYPE.ERROR) {
 71				Log.d(Config.LOGTAG, a.getJid().toBareJid() + ": enabling push on server failed");
 72			}
 73		});
 74	}
 75
 76	private void retrieveGcmInstanceToken(final OnGcmInstanceTokenRetrieved instanceTokenRetrieved) {
 77		new Thread(() -> {
 78			InstanceID instanceID = InstanceID.getInstance(mXmppConnectionService);
 79			try {
 80				String token = instanceID.getToken(mXmppConnectionService.getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
 81				instanceTokenRetrieved.onGcmInstanceTokenRetrieved(token);
 82			} catch (Exception e) {
 83				Log.d(Config.LOGTAG,"unable to get push token");
 84			}
 85		}).start();
 86
 87	}
 88
 89
 90	public boolean available(Account account) {
 91		final XmppConnection connection = account.getXmppConnection();
 92		return connection != null
 93				&& connection.getFeatures().sm()
 94				&& connection.getFeatures().push()
 95				&& playServicesAvailable();
 96	}
 97
 98	private boolean playServicesAvailable() {
 99		return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(mXmppConnectionService) == ConnectionResult.SUCCESS;
100	}
101
102	public boolean isStub() {
103		return false;
104	}
105
106	interface OnGcmInstanceTokenRetrieved {
107		void onGcmInstanceTokenRetrieved(String token);
108	}
109}