From 32da65f910207f08f50b57ba59af9474eaad75d8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 12 Feb 2016 11:39:27 +0100 Subject: client side support for XEP-0357: Push Notifications --- src/main/java/eu/siacs/conversations/Config.java | 1 - .../siacs/conversations/generator/IqGenerator.java | 16 ++++++++++- .../services/XmppConnectionService.java | 31 +++++++++++++++++++--- .../conversations/ui/EditAccountActivity.java | 13 +++++++++ .../siacs/conversations/xmpp/XmppConnection.java | 14 ++++------ src/main/res/layout/activity_edit_account.xml | 23 ++++++++++++++-- src/main/res/values/strings.xml | 1 + 7 files changed, 82 insertions(+), 17 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 3d32a2cb3..056dd7f00 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -109,6 +109,5 @@ public final class Config { }; private Config() { - } } diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 345f68ae3..dc9472c50 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -289,7 +289,7 @@ public class IqGenerator extends AbstractGenerator { public IqPacket requestHttpUploadSlot(Jid host, DownloadableFile file, String mime) { IqPacket packet = new IqPacket(IqPacket.TYPE.GET); packet.setTo(host); - Element request = packet.addChild("request",Xmlns.HTTP_UPLOAD); + Element request = packet.addChild("request", Xmlns.HTTP_UPLOAD); request.addChild("filename").setContent(file.getName()); request.addChild("size").setContent(String.valueOf(file.getExpectedSize())); if (mime != null) { @@ -307,4 +307,18 @@ public class IqGenerator extends AbstractGenerator { return register; } + + public IqPacket pushTokenToAppServer(Jid appServer, String token, String deviceId) { + IqPacket packet = new IqPacket(IqPacket.TYPE.SET); + packet.setTo(appServer); + Element command = packet.addChild("command", "http://jabber.org/protocol/commands"); + command.setAttribute("node","register-push-gcm"); + command.setAttribute("action","execute"); + Data data = new Data(); + data.put("token", token); + data.put("device-id", deviceId); + data.submit(); + command.addChild(data); + return packet; + } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 9c2aa50c0..e985fe07d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -73,7 +73,6 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; import eu.siacs.conversations.entities.Presence; -import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.entities.Roster; import eu.siacs.conversations.entities.ServiceDiscoveryResult; import eu.siacs.conversations.entities.Transferable; @@ -127,6 +126,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public static final String ACTION_TRY_AGAIN = "try_again"; public static final String ACTION_DISABLE_ACCOUNT = "disable_account"; private static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; + public static final String ACTION_GCM_TOKEN_REFRESH = "gcm_token_refresh"; + public static final String ACTION_GCM_MESSAGE_RECEIVED = "gcm_message_received"; private final SerialSingleThreadExecutor mFileAddingExecutor = new SerialSingleThreadExecutor(); private final SerialSingleThreadExecutor mDatabaseExecutor = new SerialSingleThreadExecutor(); private final IBinder mBinder = new XmppConnectionBinder(); @@ -198,6 +199,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this); private AvatarService mAvatarService = new AvatarService(this); private MessageArchiveService mMessageArchiveService = new MessageArchiveService(this); + private PushManagementService mPushManagementService = new PushManagementService(this); private OnConversationUpdate mOnConversationUpdate = null; private final FileObserver fileObserver = new FileObserver( FileBackend.getConversationsImageDirectory()) { @@ -265,7 +267,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private OnStatusChanged statusListener = new OnStatusChanged() { @Override - public void onStatusChanged(Account account) { + public void onStatusChanged(final Account account) { XmppConnection connection = account.getXmppConnection(); if (mOnAccountUpdate != null) { mOnAccountUpdate.onAccountUpdate(); @@ -296,6 +298,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } account.pendingConferenceJoins.clear(); scheduleWakeUpCall(Config.PING_MAX_INTERVAL, account.getUuid().hashCode()); + + if (mPushManagementService.pushAvailable(account)) { + mPushManagementService.registerPushTokenOnServer(account); + } + } else if (account.getStatus() == Account.State.OFFLINE) { resetSendingToWaiting(account); if (!account.isOptionSet(Account.OPTION_DISABLED)) { @@ -512,6 +519,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa refreshAllPresences(); } break; + case ACTION_GCM_TOKEN_REFRESH: + refreshAllGcmTokens(); + break; + case ACTION_GCM_MESSAGE_RECEIVED: + Log.d(Config.LOGTAG,"gcm push message arrived in service. extras="+intent.getExtras()); } } this.wakeLock.acquire(); @@ -572,7 +584,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa reconnectAccount(account, true, interactive); } } - } if (mOnAccountUpdate != null) { mOnAccountUpdate.onAccountUpdate(); @@ -2845,6 +2856,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + private void refreshAllGcmTokens() { + for(Account account : getAccounts()) { + if (account.isOnlineAndConnected() && mPushManagementService.pushAvailable(account)) { + mPushManagementService.registerPushTokenOnServer(account); + } + } + } + public void sendOfflinePresence(final Account account) { sendPresencePacket(account, mPresenceGenerator.sendOfflinePresence(account)); } @@ -3005,7 +3024,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa databaseBackend.insertDiscoveryResult(disco); injectServiceDiscorveryResult(account.getRoster(), presence.getHash(), presence.getVer(), disco); } else { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": mismatch in caps for contact " + jid+" "+presence.getVer()+" vs "+disco.getVer()); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": mismatch in caps for contact " + jid + " " + presence.getVer() + " vs " + disco.getVer()); } } account.inProgressDiscoFetches.remove(key); @@ -3041,6 +3060,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } + public PushManagementService getPushManagementService() { + return mPushManagementService; + } + public interface OnMamPreferencesFetched { void onPreferencesFetched(Element prefs); void onPreferencesFetchFailed(); diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index d30fbda2c..cfa1889a0 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -29,6 +29,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TableLayout; +import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; @@ -77,6 +78,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate private TextView mServerInfoBlocking; private TextView mServerInfoPep; private TextView mServerInfoHttpUpload; + private TextView mServerInfoPush; private TextView mSessionEst; private TextView mOtrFingerprint; private TextView mAxolotlFingerprint; @@ -223,6 +225,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } }; private Toast mFetchingMamPrefsToast; + private TableRow mPushRow; public void refreshUiReal() { invalidateOptionsMenu(); @@ -422,6 +425,8 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate this.mServerInfoSm = (TextView) findViewById(R.id.server_info_sm); this.mServerInfoPep = (TextView) findViewById(R.id.server_info_pep); this.mServerInfoHttpUpload = (TextView) findViewById(R.id.server_info_http_upload); + this.mPushRow = (TableRow) findViewById(R.id.push_row); + this.mServerInfoPush = (TextView) findViewById(R.id.server_info_push); this.mOtrFingerprint = (TextView) findViewById(R.id.otr_fingerprint); this.mOtrFingerprintBox = (RelativeLayout) findViewById(R.id.otr_fingerprint_box); this.mOtrFingerprintToClipboardButton = (ImageButton) findViewById(R.id.action_copy_to_clipboard); @@ -680,6 +685,14 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } else { this.mServerInfoHttpUpload.setText(R.string.server_info_unavailable); } + + this.mPushRow.setVisibility(xmppConnectionService.getPushManagementService().available() ? View.VISIBLE : View.GONE); + + if (features.push()) { + this.mServerInfoPush.setText(R.string.server_info_available); + } else { + this.mServerInfoPush.setText(R.string.server_info_unavailable); + } final String otrFingerprint = this.mAccount.getOtrFingerprint(); if (otrFingerprint != null) { this.mOtrFingerprintBox.setVisibility(View.VISIBLE); diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 8b7eae397..3a9c87a30 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1495,17 +1495,13 @@ public class XmppConnection implements Runnable { } public boolean mam() { - if (hasDiscoFeature(account.getJid().toBareJid(), "urn:xmpp:mam:0")) { - return true; - } else { - return hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0"); - } + return hasDiscoFeature(account.getJid().toBareJid(), "urn:xmpp:mam:0") + || hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0"); } - public boolean advancedStreamFeaturesLoaded() { - synchronized (XmppConnection.this.disco) { - return disco.containsKey(account.getServer()); - } + public boolean push() { + return hasDiscoFeature(account.getJid().toBareJid(), "urn:xmpp:push:0") + || hasDiscoFeature(account.getServer(), "urn:xmpp:push:0"); } public boolean rosterVersioning() { diff --git a/src/main/res/layout/activity_edit_account.xml b/src/main/res/layout/activity_edit_account.xml index ed9358192..d308b4ce7 100644 --- a/src/main/res/layout/activity_edit_account.xml +++ b/src/main/res/layout/activity_edit_account.xml @@ -399,6 +399,26 @@ android:textSize="?attr/TextSizeBody" tools:ignore="RtlHardcoded"/> + + + + + + @@ -416,8 +436,7 @@ android:layout_height="wrap_content" android:layout_gravity="right" android:textColor="@color/black87" - android:textSize="?attr/TextSizeBody" - tools:ignore="RtlHardcoded"/> + android:textSize="?attr/TextSizeBody"/> diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 8da14a4a3..0b726ae7c 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -193,6 +193,7 @@ XEP-0198: Stream Management XEP-0163: PEP (Avatars / OMEMO) XEP-0363: HTTP File Upload + XEP-0357: Push available unavailable Missing public key announcements -- cgit v1.2.3