From f16690ae1f2f5849ccc1279569af39fb52a3375a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 9 Feb 2016 13:01:17 +0100 Subject: allow user to set MAM preferences --- .../services/XmppConnectionService.java | 27 +++++++++ .../conversations/ui/EditAccountActivity.java | 64 +++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 4fa5ddfff..3c9fd50ad 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -3024,6 +3024,33 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + public void fetchMamPreferences(Account account, final OnMamPreferencesFetched callback) { + IqPacket request = new IqPacket(IqPacket.TYPE.GET); + request.addChild("prefs","urn:xmpp:mam:0"); + sendIqPacket(account, request, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + Element prefs = packet.findChild("prefs","urn:xmpp:mam:0"); + if (packet.getType() == IqPacket.TYPE.RESULT && prefs != null) { + callback.onPreferencesFetched(prefs); + } else { + callback.onPreferencesFetchFailed(); + } + } + }); + } + + public interface OnMamPreferencesFetched { + void onPreferencesFetched(Element prefs); + void onPreferencesFetchFailed(); + } + + public void pushMamPreferences(Account account, Element prefs) { + IqPacket set = new IqPacket(IqPacket.TYPE.SET); + set.addChild(prefs); + sendIqPacket(account, set, null); + } + public interface OnAccountCreated { void onAccountCreated(Account account); diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 5c783f54f..d30fbda2c 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -32,7 +32,10 @@ import android.widget.TableLayout; import android.widget.TextView; import android.widget.Toast; +import java.util.Arrays; +import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; @@ -44,6 +47,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.XmppConnection.Features; import eu.siacs.conversations.xmpp.forms.Data; @@ -52,7 +56,7 @@ import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.pep.Avatar; public class EditAccountActivity extends XmppActivity implements OnAccountUpdate, - OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast { + OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast, XmppConnectionService.OnMamPreferencesFetched { private AutoCompleteTextView mAccountJid; private EditText mPassword; @@ -218,6 +222,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate finish(); } }; + private Toast mFetchingMamPrefsToast; public void refreshUiReal() { invalidateOptionsMenu(); @@ -465,6 +470,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate final MenuItem changePassword = menu.findItem(R.id.action_change_password_on_server); final MenuItem clearDevices = menu.findItem(R.id.action_clear_devices); final MenuItem renewCertificate = menu.findItem(R.id.action_renew_certificate); + final MenuItem mamPrefs = menu.findItem(R.id.action_mam_prefs); renewCertificate.setVisible(mAccount != null && mAccount.getPrivateKeyAlias() != null); @@ -475,6 +481,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate if (!mAccount.getXmppConnection().getFeatures().register()) { changePassword.setVisible(false); } + mamPrefs.setVisible(mAccount.getXmppConnection().getFeatures().mam()); Set otherDevices = mAccount.getAxolotlService().getOwnDeviceIds(); if (otherDevices == null || otherDevices.isEmpty()) { clearDevices.setVisible(false); @@ -485,6 +492,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate showMoreInfo.setVisible(false); changePassword.setVisible(false); clearDevices.setVisible(false); + mamPrefs.setVisible(false); } return true; } @@ -568,6 +576,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate changePasswordIntent.putExtra(EXTRA_ACCOUNT, mAccount.getJid().toString()); startActivity(changePasswordIntent); break; + case R.id.action_mam_prefs: + editMamPrefs(); + break; case R.id.action_clear_devices: showWipePepDialog(); break; @@ -799,6 +810,12 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate builder.create().show(); } + private void editMamPrefs() { + this.mFetchingMamPrefsToast = Toast.makeText(this, R.string.fetching_mam_prefs, Toast.LENGTH_LONG); + this.mFetchingMamPrefsToast.show(); + xmppConnectionService.fetchMamPreferences(mAccount, this); + } + @Override public void onKeyStatusUpdated(AxolotlService.FetchStatus report) { refreshUi(); @@ -878,4 +895,49 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } }); } + + @Override + public void onPreferencesFetched(final Element prefs) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (mFetchingMamPrefsToast != null) { + mFetchingMamPrefsToast.cancel(); + } + AlertDialog.Builder builder = new Builder(EditAccountActivity.this); + builder.setTitle(R.string.mam_prefs); + String defaultAttr = prefs.getAttribute("default"); + final List defaults = Arrays.asList("never", "roster", "always"); + final AtomicInteger choice = new AtomicInteger(Math.max(0,defaults.indexOf(defaultAttr))); + builder.setSingleChoiceItems(R.array.mam_prefs, choice.get(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + choice.set(which); + } + }); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + prefs.setAttribute("default",defaults.get(choice.get())); + xmppConnectionService.pushMamPreferences(mAccount, prefs); + } + }); + builder.create().show(); + } + }); + } + + @Override + public void onPreferencesFetchFailed() { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (mFetchingMamPrefsToast != null) { + mFetchingMamPrefsToast.cancel(); + } + Toast.makeText(EditAccountActivity.this,R.string.unable_to_fetch_mam_prefs,Toast.LENGTH_LONG).show(); + } + }); + } } -- cgit v1.2.3 From 1bb38e25f2e9d7fbe03ba7cd9173f780b42fe5d4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 10 Feb 2016 09:53:48 +0100 Subject: send muc messages after join --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 3c9fd50ad..9c2aa50c0 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -282,7 +282,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } List conversations = getConversations(); for (Conversation conversation : conversations) { - if (conversation.getAccount() == account) { + if (conversation.getAccount() == account && conversation.getMode() == Conversation.MODE_SINGLE) { conversation.startOtrIfNeeded(); sendUnsentMessages(conversation); } @@ -1776,6 +1776,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (conversation.getMucOptions().mamSupport()) { getMessageArchiveService().catchupMUC(conversation); } + sendUnsentMessages(conversation); } @Override -- cgit v1.2.3 From f37098a54f8c5655356cf2f3469cd8547769c34a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 11 Feb 2016 12:26:43 +0100 Subject: catch all axolotl parse exception at once. fixes #1692 --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 09bbabebe..5903d5116 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -6,7 +6,6 @@ import android.util.Log; import android.util.Pair; import org.whispersystems.libaxolotl.IdentityKey; -import org.whispersystems.libaxolotl.InvalidKeyException; import org.whispersystems.libaxolotl.ecc.Curve; import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.state.PreKeyBundle; @@ -142,7 +141,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } try { publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0); - } catch (InvalidKeyException | IllegalArgumentException | NullPointerException e) { + } catch (Throwable e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid signedPreKeyPublic in PEP: " + e.getMessage()); } return publicKey; @@ -155,7 +154,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } try { return Base64.decode(signedPreKeySignature.getContent(), Base64.DEFAULT); - } catch (IllegalArgumentException e) { + } catch (Throwable e) { Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : Invalid base64 in signedPreKeySignature"); return null; } @@ -169,7 +168,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } try { identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0); - } catch (InvalidKeyException | IllegalArgumentException | NullPointerException e) { + } catch (Throwable e) { Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : "+"Invalid identityKey in PEP: "+e.getMessage()); } return identityKey; @@ -200,7 +199,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { try { ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0); preKeyRecords.put(preKeyId, preKeyPublic); - } catch (InvalidKeyException | IllegalArgumentException | NullPointerException e) { + } catch (Throwable e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); continue; } -- cgit v1.2.3 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 ++++------ 5 files changed, 60 insertions(+), 15 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') 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() { -- cgit v1.2.3 From c430848adedabfd8d2cd05bc12a5888ab8d92bcf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 12 Feb 2016 23:37:42 +0100 Subject: push gcm token on bind instead of every connect --- .../eu/siacs/conversations/services/XmppConnectionService.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e985fe07d..69a59aa04 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -259,6 +259,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa fetchRosterFromServer(account); fetchBookmarks(account); sendPresence(account); + if (mPushManagementService.pushAvailable(account)) { + mPushManagementService.registerPushTokenOnServer(account); + } mMessageArchiveService.executePendingQueries(account); connectMultiModeConversations(account); syncDirtyContacts(account); @@ -298,11 +301,6 @@ 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)) { -- cgit v1.2.3 From c7a14092a818262b8479a5bfff45c45689f6e755 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 13 Feb 2016 00:03:57 +0100 Subject: fixed compile bug in free version --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 4 ++-- src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 69a59aa04..3ca235ef5 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -259,7 +259,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa fetchRosterFromServer(account); fetchBookmarks(account); sendPresence(account); - if (mPushManagementService.pushAvailable(account)) { + if (mPushManagementService.available(account)) { mPushManagementService.registerPushTokenOnServer(account); } mMessageArchiveService.executePendingQueries(account); @@ -2856,7 +2856,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private void refreshAllGcmTokens() { for(Account account : getAccounts()) { - if (account.isOnlineAndConnected() && mPushManagementService.pushAvailable(account)) { + if (account.isOnlineAndConnected() && mPushManagementService.available(account)) { mPushManagementService.registerPushTokenOnServer(account); } } diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index cfa1889a0..9b6e40763 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -686,7 +686,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate this.mServerInfoHttpUpload.setText(R.string.server_info_unavailable); } - this.mPushRow.setVisibility(xmppConnectionService.getPushManagementService().available() ? View.VISIBLE : View.GONE); + this.mPushRow.setVisibility(xmppConnectionService.getPushManagementService().available(mAccount) ? View.VISIBLE : View.GONE); if (features.push()) { this.mServerInfoPush.setText(R.string.server_info_available); -- cgit v1.2.3 From 6f9f87192867d676890fed0221fb4279ac9375ec Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 13 Feb 2016 14:20:07 +0100 Subject: send push enable to server. simplified logging --- .../eu/siacs/conversations/generator/AbstractGenerator.java | 2 ++ .../java/eu/siacs/conversations/generator/IqGenerator.java | 13 +++++++++++++ src/main/java/eu/siacs/conversations/xmpp/forms/Data.java | 9 +++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 5741af533..d50596056 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -15,6 +15,8 @@ import java.util.TimeZone; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.PhoneHelper; +import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.stanzas.IqPacket; public abstract class AbstractGenerator { private final String[] FEATURES = { diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index dc9472c50..258897a19 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -25,6 +25,7 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.forms.Data; +import eu.siacs.conversations.xmpp.forms.Field; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.stanzas.IqPacket; @@ -321,4 +322,16 @@ public class IqGenerator extends AbstractGenerator { command.addChild(data); return packet; } + + public IqPacket enablePush(Jid jid, String node, String secret) { + IqPacket packet = new IqPacket(IqPacket.TYPE.SET); + Element enable = packet.addChild("enable","urn:xmpp:push:0"); + enable.setAttribute("jid",jid.toString()); + enable.setAttribute("node", node); + Data data = new Data(); + data.setFormType("http://jabber.org/protocol/pubsub#publish-options"); + data.put("secret",secret); + enable.addChild(data); + return packet; + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/forms/Data.java b/src/main/java/eu/siacs/conversations/xmpp/forms/Data.java index 50a418921..380f02808 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/forms/Data.java +++ b/src/main/java/eu/siacs/conversations/xmpp/forms/Data.java @@ -80,8 +80,13 @@ public class Data extends Element { } public String getFormType() { - Field typeFiled = this.getFieldByName("FORM_TYPE"); - return typeFiled == null ? "" : typeFiled.getValue(); + String type = getValue("FORM_TYPE"); + return type == null ? "" : type; + } + + public String getValue(String name) { + Field field = this.getFieldByName(name); + return field == null ? null : field.getValue(); } public String getTitle() { -- cgit v1.2.3 From 251f2479c2df4510690a8ef4be9d4b7d2b9e04f7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 14 Feb 2016 13:20:23 +0100 Subject: optional mode to close tcp connection when going into background acts only when push is available. disable all non-push accounts to test properly --- src/main/java/eu/siacs/conversations/Config.java | 2 + .../services/XmppConnectionService.java | 32 ++++++++---- .../siacs/conversations/xmpp/XmppConnection.java | 58 ++++++++++++++-------- 3 files changed, 63 insertions(+), 29 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 056dd7f00..4d64c3aa5 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -31,6 +31,8 @@ public final class Config { public static final int CARBON_GRACE_PERIOD = 90; public static final int MINI_GRACE_PERIOD = 750; + public static final boolean CLOSE_TCP_WHEN_SWITCHING_TO_BACKGROUND = false; + public static final int AVATAR_SIZE = 192; public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 3ca235ef5..16d7f139c 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -303,7 +303,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa scheduleWakeUpCall(Config.PING_MAX_INTERVAL, account.getUuid().hashCode()); } else if (account.getStatus() == Account.State.OFFLINE) { resetSendingToWaiting(account); - if (!account.isOptionSet(Account.OPTION_DISABLED)) { + final boolean disabled = account.isOptionSet(Account.OPTION_DISABLED); + final boolean pushMode = Config.CLOSE_TCP_WHEN_SWITCHING_TO_BACKGROUND + && mPushManagementService.available(account) + && checkListeners(); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": push mode "+Boolean.toString(pushMode)); + if (!disabled && !pushMode) { int timeToReconnect = mRandom.nextInt(20) + 10; scheduleWakeUpCall(timeToReconnect, account.getUuid().hashCode()); } @@ -469,6 +474,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final String action = intent == null ? null : intent.getAction(); boolean interactive = false; if (action != null) { + Log.d(Config.LOGTAG,"start reason: "+action); switch (action) { case ConnectivityManager.CONNECTIVITY_ACTION: if (hasInternetConnection() && Config.RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE) { @@ -762,18 +768,20 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa disconnect(account, false); } }).start(); - + cancelWakeUpCall(account.getUuid().hashCode()); } } - Context context = getApplicationContext(); - AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); - Intent intent = new Intent(context, EventReceiver.class); - alarmManager.cancel(PendingIntent.getBroadcast(context, 0, intent, 0)); Log.d(Config.LOGTAG, "good bye"); stopSelf(); } + private void cancelWakeUpCall(int requestCode) { + final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + final Intent intent = new Intent(this, EventReceiver.class); + intent.setAction("ping"); + alarmManager.cancel(PendingIntent.getBroadcast(this, requestCode, intent, 0)); + } + public void scheduleWakeUpCall(int seconds, int requestCode) { final long timeToWake = SystemClock.elapsedRealtime() + (seconds < 0 ? 1 : seconds + 1) * 1000; @@ -1719,8 +1727,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa for (Account account : getAccounts()) { if (account.getStatus() == Account.State.ONLINE) { XmppConnection connection = account.getXmppConnection(); - if (connection != null && connection.getFeatures().csi()) { - connection.sendInactive(); + if (connection != null) { + if (connection.getFeatures().csi()) { + connection.sendInactive(); + } + if (Config.CLOSE_TCP_WHEN_SWITCHING_TO_BACKGROUND && mPushManagementService.available(account)) { + connection.waitForPush(); + cancelWakeUpCall(account.getUuid().hashCode()); + } } } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 3a9c87a30..889457ffb 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -61,7 +61,6 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.ServiceDiscoveryResult; import eu.siacs.conversations.generator.IqGenerator; import eu.siacs.conversations.services.XmppConnectionService; -import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.DNSHelper; import eu.siacs.conversations.utils.SSLSocketHelper; import eu.siacs.conversations.utils.SocksSocketFactory; @@ -352,13 +351,7 @@ public class XmppConnection implements Runnable { this.changeStatus(Account.State.OFFLINE); this.attempt--; //don't count attempt when reconnecting instantly anyway } finally { - if (socket != null) { - try { - socket.close(); - } catch (IOException e) { - - } - } + forceCloseSocket(); if (wakeLock.isHeld()) { try { wakeLock.release(); @@ -430,13 +423,7 @@ public class XmppConnection implements Runnable { @Override public void run() { - try { - if (socket != null) { - socket.close(); - } - } catch (final IOException ignored) { - - } + forceCloseSocket(); connect(); } @@ -1283,14 +1270,45 @@ public class XmppConnection implements Runnable { } } - public void disconnect(final boolean force) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting force="+Boolean.valueOf(force)); - if (force) { + public void waitForPush() { + if (tagWriter.isActive()) { + tagWriter.finish(); + new Thread(new Runnable() { + @Override + public void run() { + try { + while(!tagWriter.finished()) { + Thread.sleep(10); + } + socket.close(); + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": closed tcp without closing stream"); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }).start(); + } else { + forceCloseSocket(); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": closed tcp without closing stream (no waiting)"); + } + } + + private void forceCloseSocket() { + if (socket != null) { try { socket.close(); - } catch(Exception e) { - Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": exception during force close ("+e.getMessage()+")"); + } catch (IOException e) { + e.printStackTrace(); } + } + } + + public void disconnect(final boolean force) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting force="+Boolean.valueOf(force)); + if (force) { + forceCloseSocket(); return; } else { if (tagWriter.isActive()) { -- cgit v1.2.3