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