diff --git a/src/free/java/eu/siacs/conversations/services/PushManagementService.java b/src/free/java/eu/siacs/conversations/services/PushManagementService.java index b1cbe6e28..9fac3655e 100644 --- a/src/free/java/eu/siacs/conversations/services/PushManagementService.java +++ b/src/free/java/eu/siacs/conversations/services/PushManagementService.java @@ -19,6 +19,10 @@ public class PushManagementService { //stub implementation. only affects playstore flavor } + void unregisterChannel(Account account, String hash) { + //stub implementation. only affects playstore flavor + } + void disablePushOnServer(Conversation conversation) { //stub implementation. only affects playstore flavor } diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index 35528ab2c..69f78c913 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -2,7 +2,6 @@ package eu.siacs.conversations.crypto; import android.app.PendingIntent; import android.content.Intent; -import android.os.Parcelable; import android.support.annotation.StringRes; import android.util.Log; @@ -94,7 +93,7 @@ public class PgpEngine { break; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), message); + callback.userInputRequired(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), message); break; case OpenPgpApi.RESULT_CODE_ERROR: OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); @@ -133,7 +132,7 @@ public class PgpEngine { callback.success(message); break; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), message); + callback.userInputRequired(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), message); break; case OpenPgpApi.RESULT_CODE_ERROR: logError(conversation.getAccount(), result.getParcelableExtra(OpenPgpApi.RESULT_ERROR)); @@ -200,7 +199,7 @@ public class PgpEngine { callback.success(account); return; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), account); + callback.userInputRequired(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), account); return; case OpenPgpApi.RESULT_CODE_ERROR: logError(account, result.getParcelableExtra(OpenPgpApi.RESULT_ERROR)); @@ -249,7 +248,7 @@ public class PgpEngine { callback.success(signatureBuilder.toString()); return; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), status); + callback.userInputRequired(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), status); return; case OpenPgpApi.RESULT_CODE_ERROR: OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); @@ -276,7 +275,7 @@ public class PgpEngine { callback.success(contact); return; case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - callback.userInputRequried(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), contact); + callback.userInputRequired(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), contact); return; case OpenPgpApi.RESULT_CODE_ERROR: logError(contact.getAccount(), result.getParcelableExtra(OpenPgpApi.RESULT_ERROR)); diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 40742e231..42f68819f 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -443,6 +443,20 @@ public class IqGenerator extends AbstractGenerator { return packet; } + public IqPacket unregisterChannelOnAppServer(Jid appServer, String deviceId, String channel) { + final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); + packet.setTo(appServer); + final Element command = packet.addChild("command", Namespace.COMMANDS); + command.setAttribute("node", "unregister-push-fcm"); + command.setAttribute("action", "execute"); + final Data data = new Data(); + data.put("channel", channel); + data.put("android-id", deviceId); + data.submit(); + command.addChild(data); + return packet; + } + public IqPacket enablePush(final Jid jid, final String node, final String secret) { IqPacket packet = new IqPacket(IqPacket.TYPE.SET); Element enable = packet.addChild("enable", Namespace.PUSH); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 9a8c7e62a..df4f198aa 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -592,6 +592,7 @@ public class XmppConnectionService extends Service { toggleForegroundService(true); } String pushedAccountHash = null; + String pushedChannelHash = null; boolean interactive = false; if (action != null) { final String uuid = intent.getStringExtra("uuid"); @@ -704,6 +705,7 @@ public class XmppConnectionService extends Service { break; case ACTION_FCM_MESSAGE_RECEIVED: pushedAccountHash = intent.getStringExtra("account"); + pushedChannelHash = intent.getStringExtra("channel"); Log.d(Config.LOGTAG, "push message arrived in service. account=" + pushedAccountHash); break; case Intent.ACTION_SEND: @@ -717,13 +719,18 @@ public class XmppConnectionService extends Service { synchronized (this) { WakeLockHelper.acquire(wakeLock); boolean pingNow = ConnectivityManager.CONNECTIVITY_ACTION.equals(action) || (Config.POST_CONNECTIVITY_CHANGE_PING_INTERVAL > 0 && ACTION_POST_CONNECTIVITY_CHANGE.equals(action)); - HashSet pingCandidates = new HashSet<>(); + final HashSet pingCandidates = new HashSet<>(); + final String androidId = PhoneHelper.getAndroidId(this); for (Account account : accounts) { + final boolean pushWasMeantForThisAccount = CryptoHelper.getAccountFingerprint(account, androidId).equals(pushedAccountHash); pingNow |= processAccountState(account, interactive, "ui".equals(action), - CryptoHelper.getAccountFingerprint(account, PhoneHelper.getAndroidId(this)).equals(pushedAccountHash), + pushWasMeantForThisAccount, pingCandidates); + if (pushWasMeantForThisAccount && pushedChannelHash != null) { + checkMucStillJoined(account, pushedAccountHash, androidId); + } } if (pingNow) { for (Account account : pingCandidates) { @@ -816,6 +823,20 @@ public class XmppConnectionService extends Service { return pingNow; } + private void checkMucStillJoined(final Account account, final String hash, final String androidId) { + for(final Conversation conversation : this.conversations) { + if (conversation.getAccount() == account && conversation.getMode() == Conversational.MODE_MULTI) { + Jid jid = conversation.getJid().asBareJid(); + final String currentHash = CryptoHelper.getFingerprint(jid, androidId); + if (currentHash.equals(hash)) { + Log.d(Config.LOGTAG,account.getJid().asBareJid()+": received cloud push notification for MUC "+jid); + return; + } + } + } + mPushManagementService.unregisterChannel(account, hash); + } + public void reinitializeMuclumbusService() { mChannelDiscoveryService.initializeMuclumbusService(); } @@ -854,7 +875,7 @@ public class XmppConnectionService extends Service { } @Override - public void userInputRequried(PendingIntent pi, Message object) { + public void userInputRequired(PendingIntent pi, Message object) { } }); diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 48abb03fe..ee2a15379 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -83,7 +83,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } @Override - public void userInputRequried(PendingIntent pi, Conversation object) { + public void userInputRequired(PendingIntent pi, Conversation object) { } }; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 7a25a9d4d..92ce0c9c6 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -632,7 +632,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } @Override - public void userInputRequried(PendingIntent pi, Message object) { + public void userInputRequired(PendingIntent pi, Message object) { } }); @@ -666,7 +666,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } @Override - public void userInputRequried(PendingIntent pi, Message message) { + public void userInputRequired(PendingIntent pi, Message message) { hidePrepareFileToast(prepareFileToast); } }); @@ -688,7 +688,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke new UiCallback() { @Override - public void userInputRequried(PendingIntent pi, Message object) { + public void userInputRequired(PendingIntent pi, Message object) { hidePrepareFileToast(prepareFileToast); } @@ -1326,7 +1326,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke new UiCallback() { @Override - public void userInputRequried(PendingIntent pi, Contact contact) { + public void userInputRequired(PendingIntent pi, Contact contact) { startPendingIntent(pi, attachmentChoice); } @@ -2456,7 +2456,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke new UiCallback() { @Override - public void userInputRequried(PendingIntent pi, Contact contact) { + public void userInputRequired(PendingIntent pi, Contact contact) { startPendingIntent(pi, REQUEST_ENCRYPT_MESSAGE); } @@ -2512,7 +2512,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke new UiCallback() { @Override - public void userInputRequried(PendingIntent pi, Message message) { + public void userInputRequired(PendingIntent pi, Message message) { startPendingIntent(pi, REQUEST_SEND_MESSAGE); } diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 71a4b9ae3..d8c208dd4 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -104,7 +104,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat private final UiCallback mAvatarFetchCallback = new UiCallback() { @Override - public void userInputRequried(final PendingIntent pi, final Avatar avatar) { + public void userInputRequired(final PendingIntent pi, final Avatar avatar) { finishInitialSetup(avatar); } @@ -917,7 +917,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat } @Override - public void userInputRequried(PendingIntent pi, String object) { + public void userInputRequired(PendingIntent pi, String object) { mPendingPresenceTemplate.push(template); try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_CHANGE_STATUS, null, 0, 0, 0); diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index a05c707c9..a48dd230b 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -174,7 +174,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne } @Override - public void userInputRequried(PendingIntent pi, Conversation object) { + public void userInputRequired(PendingIntent pi, Conversation object) { } }; @@ -1085,7 +1085,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne } @Override - public void userInputRequried(PendingIntent pi, Conversation object) { + public void userInputRequired(PendingIntent pi, Conversation object) { } }); diff --git a/src/main/java/eu/siacs/conversations/ui/UiCallback.java b/src/main/java/eu/siacs/conversations/ui/UiCallback.java index d056d6289..c690b4105 100644 --- a/src/main/java/eu/siacs/conversations/ui/UiCallback.java +++ b/src/main/java/eu/siacs/conversations/ui/UiCallback.java @@ -7,5 +7,5 @@ public interface UiCallback { void error(int errorCode, T object); - void userInputRequried(PendingIntent pi, T object); + void userInputRequired(PendingIntent pi, T object); } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 1bf41d4d2..f476736fa 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -137,7 +137,7 @@ public abstract class XmppActivity extends ActionBarActivity { } @Override - public void userInputRequried(PendingIntent pi, Conversation object) { + public void userInputRequired(PendingIntent pi, Conversation object) { } }; @@ -565,7 +565,7 @@ public abstract class XmppActivity extends ActionBarActivity { xmppConnectionService.getPgpEngine().generateSignature(intent, account, status, new UiCallback() { @Override - public void userInputRequried(PendingIntent pi, String signature) { + public void userInputRequired(PendingIntent pi, String signature) { try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); } catch (final SendIntentException ignored) { @@ -625,7 +625,7 @@ public abstract class XmppActivity extends ActionBarActivity { } @Override - public void userInputRequried(PendingIntent pi, Account object) { + public void userInputRequired(PendingIntent pi, Account object) { try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_CHOOSE_PGP_ID, null, 0, 0, 0); diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 40b3cad65..2b15812f3 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -246,8 +246,12 @@ public final class CryptoHelper { return prettifyFingerprintCert(bytesToHex(fingerprint)); } + public static String getFingerprint(Jid jid, String androidId) { + return getFingerprint(jid.toEscapedString() + "\00" + androidId); + } + public static String getAccountFingerprint(Account account, String androidId) { - return getFingerprint(account.getJid().asBareJid().toEscapedString() + "\00" + androidId); + return getFingerprint(account.getJid().asBareJid(), androidId); } public static String getFingerprint(String value) { diff --git a/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java b/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java index e500a1ac3..2a3d1a648 100644 --- a/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java +++ b/src/playstore/java/eu/siacs/conversations/services/PushManagementService.java @@ -63,6 +63,19 @@ public class PushManagementService { }); } + public void unregisterChannel(final Account account, final String channel) { + final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService); + final Jid appServer = getAppServer(); + final IqPacket packet = mXmppConnectionService.getIqGenerator().unregisterChannelOnAppServer(appServer, androidId, channel); + mXmppConnectionService.sendIqPacket(account, packet, (a, response) -> { + if (response.getType() == IqPacket.TYPE.RESULT) { + Log.d(Config.LOGTAG,a.getJid().asBareJid()+": successfully unregistered channel"); + } else if (response.getType() == IqPacket.TYPE.ERROR) { + Log.d(Config.LOGTAG, a.getJid().asBareJid()+": unable to unregister channel with hash "+channel); + } + }); + } + void registerPushTokenOnServer(final Conversation conversation) { Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": room "+conversation.getJid().asBareJid()+" has push support"); retrieveFcmInstanceToken(token -> {