A src/cheogram/java/com/cheogram/android/FinishOnboarding.java => src/cheogram/java/com/cheogram/android/FinishOnboarding.java +119 -0
@@ 0,0 1,119 @@
+package com.cheogram.android;
+
+import android.util.Log;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xml.Namespace;
+import eu.siacs.conversations.xmpp.Jid;
+import eu.siacs.conversations.xmpp.forms.Data;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
+
+public class FinishOnboarding {
+ private static final AtomicBoolean WORKING = new AtomicBoolean(false);
+ private static ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
+
+ private static void retry(final XmppConnectionService xmppConnectionService, final XmppActivity activity, final Account onboardAccount, final Account newAccount) {
+ WORKING.set(false);
+ SCHEDULER.schedule(() -> {
+ finish(xmppConnectionService, activity, onboardAccount, newAccount);
+ }, 3, TimeUnit.SECONDS);
+ }
+
+ public static void finish(final XmppConnectionService xmppConnectionService, final XmppActivity activity, final Account onboardAccount, final Account newAccount) {
+ if (!WORKING.compareAndSet(false, true)) return;
+
+ final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
+ packet.setTo(Jid.of("cheogram.com"));
+ final Element c = packet.addChild("command", Namespace.COMMANDS);
+ c.setAttribute("node", "change jabber id");
+ c.setAttribute("action", "execute");
+
+ Log.d(Config.LOGTAG, "" + packet);
+ xmppConnectionService.sendIqPacket(onboardAccount, packet, (a, iq) -> {
+ Element command = iq.findChild("command", "http://jabber.org/protocol/commands");
+ if (command == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq);
+ retry(xmppConnectionService, activity, onboardAccount, newAccount);
+ return;
+ }
+
+ Element form = command.findChild("x", "jabber:x:data");
+ Data dataForm = form == null ? null : Data.parse(form);
+ if (dataForm == null || dataForm.getFieldByName("new-jid") == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq);
+ retry(xmppConnectionService, activity, onboardAccount, newAccount);
+ return;
+ }
+
+ dataForm.put("new-jid", newAccount.getJid().toEscapedString());
+ dataForm.submit();
+ command.setAttribute("action", "execute");
+ iq.setTo(iq.getFrom());
+ iq.setAttribute("type", "set");
+ iq.removeAttribute("from");
+ iq.removeAttribute("id");
+ xmppConnectionService.sendIqPacket(a, iq, (a2, iq2) -> {
+ Element command2 = iq2.findChild("command", "http://jabber.org/protocol/commands");
+ if (command2 != null && command2.getAttribute("status") != null && command2.getAttribute("status").equals("completed")) {
+ final IqPacket regPacket = new IqPacket(IqPacket.TYPE.SET);
+ regPacket.setTo(Jid.of("cheogram.com/CHEOGRAM%jabber:iq:register"));
+ final Element c2 = regPacket.addChild("command", Namespace.COMMANDS);
+ c2.setAttribute("node", "jabber:iq:register");
+ c2.setAttribute("action", "execute");
+ xmppConnectionService.sendIqPacket(newAccount, regPacket, (a3, iq3) -> {
+ Element command3 = iq3.findChild("command", "http://jabber.org/protocol/commands");
+ if (command3 == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq3);
+ retry(xmppConnectionService, activity, onboardAccount, newAccount);
+ return;
+ }
+
+ Element form3 = command3.findChild("x", "jabber:x:data");
+ Data dataForm3 = form3 == null ? null : Data.parse(form3);
+ if (dataForm3 == null || dataForm3.getFieldByName("confirm") == null) {
+ Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq3);
+ retry(xmppConnectionService, activity, onboardAccount, newAccount);
+ return;
+ }
+
+ dataForm3.put("confirm", "true");
+ dataForm3.submit();
+ command3.setAttribute("action", "execute");
+ iq3.setTo(iq3.getFrom());
+ iq3.setAttribute("type", "set");
+ iq3.removeAttribute("from");
+ iq3.removeAttribute("id");
+ xmppConnectionService.sendIqPacket(newAccount, iq3, (a4, iq4) -> {
+ Element command4 = iq4.findChild("command", "http://jabber.org/protocol/commands");
+ if (command4 != null && command4.getAttribute("status") != null && command4.getAttribute("status").equals("completed")) {
+ xmppConnectionService.createContact(newAccount.getRoster().getContact(iq4.getFrom().asBareJid()), true);
+ Conversation withCheogram = xmppConnectionService.findOrCreateConversation(newAccount, iq4.getFrom().asBareJid(), true, true, true);
+ xmppConnectionService.markRead(withCheogram);
+ xmppConnectionService.clearConversationHistory(withCheogram);
+ xmppConnectionService.deleteAccount(onboardAccount);
+ activity.switchToConversation(withCheogram, null, false, null, false, false, "command");
+ // We don't set WORKING back to false because we suceeded so it should never run again anyway
+ } else {
+ Log.e(Config.LOGTAG, "Error confirming jid switch, got: " + iq4);
+ retry(xmppConnectionService, activity, onboardAccount, newAccount);
+ }
+ });
+ });
+ } else {
+ Log.e(Config.LOGTAG, "Error during jid switch, got: " + iq2);
+ retry(xmppConnectionService, activity, onboardAccount, newAccount);
+ }
+ });
+ });
+ }
+}
M src/main/java/eu/siacs/conversations/services/XmppConnectionService.java => src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +19 -0
@@ 1994,6 1994,25 @@ public class XmppConnectionService extends Service {
sendMessage(message, true, false, delay);
}
+ public Pair<Account,Account> onboardingIncomplete() {
+ if (getAccounts().size() != 2) return null;
+ Account onboarding = null;
+ Account newAccount = null;
+ for (final Account account : getAccounts()) {
+ if (account.getJid().getDomain().equals(Config.ONBOARDING_DOMAIN)) {
+ onboarding = account;
+ } else {
+ newAccount = account;
+ }
+ }
+
+ if (onboarding != null && newAccount != null) {
+ return new Pair<>(onboarding, newAccount);
+ }
+
+ return null;
+ }
+
public boolean isOnboarding() {
return getAccounts().size() == 1 && getAccounts().get(0).getJid().getDomain().equals(Config.ONBOARDING_DOMAIN);
}
M src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java => src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +6 -0
@@ 48,6 48,7 @@ import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
@@ 62,6 63,7 @@ import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import com.cheogram.android.DownloadDefaultStickers;
+import com.cheogram.android.FinishOnboarding;
import com.google.common.collect.ImmutableList;
@@ 223,6 225,10 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
}
private void showDialogsIfMainIsOverview() {
+ Pair<Account, Account> incomplete = null;
+ if (xmppConnectionService != null && (incomplete = xmppConnectionService.onboardingIncomplete()) != null) {
+ FinishOnboarding.finish(xmppConnectionService, this, incomplete.first, incomplete.second);
+ }
if (xmppConnectionService == null || xmppConnectionService.isOnboarding()) {
return;
}
M src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java => src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +3 -77
@@ 57,6 57,8 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
+import com.cheogram.android.FinishOnboarding;
+
import com.google.android.material.textfield.TextInputLayout;
import com.leinardi.android.speeddial.SpeedDialActionItem;
import com.leinardi.android.speeddial.SpeedDialView;
@@ 955,83 957,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
if (!hasPstnOrSms) {
if (onboardingAccount != null && !selectedAccount.getJid().equals(onboardingAccount.getJid())) {
- final Account onboardAccount = onboardingAccount;
- final Account newAccount = selectedAccount;
- final IqPacket packet = new IqPacket(IqPacket.TYPE.SET);
- packet.setTo(Jid.of("cheogram.com"));
- final Element c = packet.addChild("command", Namespace.COMMANDS);
- c.setAttribute("node", "change jabber id");
- c.setAttribute("action", "execute");
-
- xmppConnectionService.sendIqPacket(onboardingAccount, packet, (a, iq) -> {
- Element command = iq.findChild("command", "http://jabber.org/protocol/commands");
- if (command == null) {
- Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq);
- return;
- }
-
- Element form = command.findChild("x", "jabber:x:data");
- Data dataForm = form == null ? null : Data.parse(form);
- if (dataForm == null || dataForm.getFieldByName("new-jid") == null) {
- Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq);
- return;
- }
-
- dataForm.put("new-jid", newAccount.getJid().toEscapedString());
- dataForm.submit();
- command.setAttribute("action", "execute");
- iq.setTo(iq.getFrom());
- iq.setAttribute("type", "set");
- iq.removeAttribute("from");
- iq.removeAttribute("id");
- xmppConnectionService.sendIqPacket(a, iq, (a2, iq2) -> {
- Element command2 = iq2.findChild("command", "http://jabber.org/protocol/commands");
- if (command2 != null && command2.getAttribute("status") != null && command2.getAttribute("status").equals("completed")) {
- final IqPacket regPacket = new IqPacket(IqPacket.TYPE.SET);
- regPacket.setTo(Jid.of("cheogram.com/CHEOGRAM%jabber:iq:register"));
- final Element c2 = regPacket.addChild("command", Namespace.COMMANDS);
- c2.setAttribute("node", "jabber:iq:register");
- c2.setAttribute("action", "execute");
- xmppConnectionService.sendIqPacket(newAccount, regPacket, (a3, iq3) -> {
- Element command3 = iq3.findChild("command", "http://jabber.org/protocol/commands");
- if (command3 == null) {
- Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq3);
- return;
- }
-
- Element form3 = command3.findChild("x", "jabber:x:data");
- Data dataForm3 = form3 == null ? null : Data.parse(form3);
- if (dataForm3 == null || dataForm3.getFieldByName("confirm") == null) {
- Log.e(Config.LOGTAG, "Did not get expected data form from cheogram, got: " + iq3);
- return;
- }
-
- dataForm3.put("confirm", "true");
- dataForm3.submit();
- command3.setAttribute("action", "execute");
- iq3.setTo(iq3.getFrom());
- iq3.setAttribute("type", "set");
- iq3.removeAttribute("from");
- iq3.removeAttribute("id");
- xmppConnectionService.sendIqPacket(newAccount, iq3, (a4, iq4) -> {
- Element command4 = iq2.findChild("command", "http://jabber.org/protocol/commands");
- if (command4 != null && command4.getAttribute("status") != null && command4.getAttribute("status").equals("completed")) {
- xmppConnectionService.createContact(newAccount.getRoster().getContact(iq4.getFrom().asBareJid()), true);
- Conversation withCheogram = xmppConnectionService.findOrCreateConversation(newAccount, iq4.getFrom().asBareJid(), true, true, true);
- xmppConnectionService.markRead(withCheogram);
- xmppConnectionService.clearConversationHistory(withCheogram);
- xmppConnectionService.deleteAccount(onboardAccount);
- switchToConversation(withCheogram, null, false, null, false, false, "command");
- } else {
- Log.e(Config.LOGTAG, "Error confirming jid switch, got: " + iq4);
- }
- });
- });
- } else {
- Log.e(Config.LOGTAG, "Error during jid switch, got: " + iq2);
- }
- });
- });
+ FinishOnboarding.finish(xmppConnectionService, this, onboardingAccount, selectedAccount);
} else {
startCommand(selectedAccount, Jid.of("cheogram.com/CHEOGRAM%jabber:iq:register"), "jabber:iq:register");
finish();