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}