PushManagementService.java

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