aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/de/pixart/messenger/entities/Account.java2
-rw-r--r--src/main/java/de/pixart/messenger/entities/Presences.java2
-rw-r--r--src/main/java/de/pixart/messenger/parser/AbstractParser.java26
-rw-r--r--src/main/java/de/pixart/messenger/parser/IqParser.java1
-rw-r--r--src/main/java/de/pixart/messenger/parser/PresenceParser.java8
-rw-r--r--src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java18
-rw-r--r--src/main/java/de/pixart/messenger/services/AvatarService.java21
-rw-r--r--src/main/java/de/pixart/messenger/services/MessageArchiveService.java16
-rw-r--r--src/main/java/de/pixart/messenger/services/NotificationService.java9
-rw-r--r--src/main/java/de/pixart/messenger/services/ShortcutService.java131
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java16
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationActivity.java1
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java7
-rw-r--r--src/main/java/de/pixart/messenger/ui/StartConversationActivity.java11
-rw-r--r--src/main/java/de/pixart/messenger/xml/XmlReader.java12
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/XmppConnection.java55
16 files changed, 287 insertions, 49 deletions
diff --git a/src/main/java/de/pixart/messenger/entities/Account.java b/src/main/java/de/pixart/messenger/entities/Account.java
index 4907d26b6..437dfa47a 100644
--- a/src/main/java/de/pixart/messenger/entities/Account.java
+++ b/src/main/java/de/pixart/messenger/entities/Account.java
@@ -183,7 +183,7 @@ public class Account extends AbstractEntity {
case SESSION_FAILURE:
return R.string.session_failure;
case DOWNGRADE_ATTACK:
- return R.string.downgrade_attack;
+ return R.string.sasl_downgrade;
case HOST_UNKNOWN:
return R.string.account_status_host_unknown;
case POLICY_VIOLATION:
diff --git a/src/main/java/de/pixart/messenger/entities/Presences.java b/src/main/java/de/pixart/messenger/entities/Presences.java
index 3f3f670da..d57515392 100644
--- a/src/main/java/de/pixart/messenger/entities/Presences.java
+++ b/src/main/java/de/pixart/messenger/entities/Presences.java
@@ -144,6 +144,6 @@ public class Presences {
}
}
}
- return new Pair(typeMap, nameMap);
+ return new Pair<>(typeMap, nameMap);
}
}
diff --git a/src/main/java/de/pixart/messenger/parser/AbstractParser.java b/src/main/java/de/pixart/messenger/parser/AbstractParser.java
index 21da7fe67..8fd106922 100644
--- a/src/main/java/de/pixart/messenger/parser/AbstractParser.java
+++ b/src/main/java/de/pixart/messenger/parser/AbstractParser.java
@@ -22,18 +22,26 @@ public abstract class AbstractParser {
}
public static Long parseTimestamp(Element element, Long d) {
- Element delay = element.findChild("delay", "urn:xmpp:delay");
- if (delay != null) {
- String stamp = delay.getAttribute("stamp");
- if (stamp != null) {
- try {
- return AbstractParser.parseTimestamp(delay.getAttribute("stamp"));
- } catch (ParseException e) {
- return d;
+ long min = Long.MAX_VALUE;
+ boolean returnDefault = true;
+ for (Element child : element.getChildren()) {
+ if ("delay".equals(child.getName()) && "urn:xmpp:delay".equals(child.getNamespace())) {
+ String stamp = child.getAttribute("stamp");
+ if (stamp != null) {
+ try {
+ min = Math.min(min, AbstractParser.parseTimestamp(stamp));
+ returnDefault = false;
+ } catch (ParseException e) {
+ //ignore
+ }
}
}
}
- return d;
+ if (returnDefault) {
+ return d;
+ } else {
+ return min;
+ }
}
public static long parseTimestamp(Element element) {
diff --git a/src/main/java/de/pixart/messenger/parser/IqParser.java b/src/main/java/de/pixart/messenger/parser/IqParser.java
index bfb2fa71e..1783fed07 100644
--- a/src/main/java/de/pixart/messenger/parser/IqParser.java
+++ b/src/main/java/de/pixart/messenger/parser/IqParser.java
@@ -83,6 +83,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
}
mXmppConnectionService.updateConversationUi();
mXmppConnectionService.updateRosterUi();
+ mXmppConnectionService.getShortcutService().refresh();
}
public String avatarData(final IqPacket packet) {
diff --git a/src/main/java/de/pixart/messenger/parser/PresenceParser.java b/src/main/java/de/pixart/messenger/parser/PresenceParser.java
index 8e1b0b006..a4534439e 100644
--- a/src/main/java/de/pixart/messenger/parser/PresenceParser.java
+++ b/src/main/java/de/pixart/messenger/parser/PresenceParser.java
@@ -213,12 +213,14 @@ public class PresenceParser extends AbstractParser implements
final Element idle = packet.findChild("idle", Namespace.IDLE);
if (idle != null) {
- contact.flagInactive();
- final String since = idle.getAttribute("since");
try {
+ final String since = idle.getAttribute("since");
contact.setLastseen(AbstractParser.parseTimestamp(since));
+ contact.flagInactive();
} catch (NullPointerException | ParseException e) {
- contact.setLastseen(System.currentTimeMillis());
+ if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) {
+ contact.flagActive();
+ }
}
} else {
if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) {
diff --git a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
index ddf516f93..7b49eb376 100644
--- a/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
+++ b/src/main/java/de/pixart/messenger/persistance/DatabaseBackend.java
@@ -48,6 +48,7 @@ import de.pixart.messenger.entities.Message;
import de.pixart.messenger.entities.PresenceTemplate;
import de.pixart.messenger.entities.Roster;
import de.pixart.messenger.entities.ServiceDiscoveryResult;
+import de.pixart.messenger.services.ShortcutService;
import de.pixart.messenger.xmpp.jid.InvalidJidException;
import de.pixart.messenger.xmpp.jid.Jid;
import de.pixart.messenger.xmpp.mam.MamReference;
@@ -1432,4 +1433,21 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.execSQL("delete from " + START_TIMES_TABLE);
}
}
+
+ public List<ShortcutService.FrequentContact> getFrequentContacts(int days) {
+ SQLiteDatabase db = this.getReadableDatabase();
+ final String SQL = "select " + Conversation.TABLENAME + "." + Conversation.ACCOUNT + "," + Conversation.TABLENAME + "." + Conversation.CONTACTJID + " from " + Conversation.TABLENAME + " join " + Message.TABLENAME + " on conversations.uuid=messages.conversationUuid where messages.status!=0 and carbon==0 and conversations.mode=0 and messages.timeSent>=? group by conversations.uuid order by count(body) desc limit 4;";
+ String[] whereArgs = new String[]{String.valueOf(System.currentTimeMillis() - (Config.MILLISECONDS_IN_DAY * days))};
+ Cursor cursor = db.rawQuery(SQL, whereArgs);
+ ArrayList<ShortcutService.FrequentContact> contacts = new ArrayList<>();
+ while (cursor.moveToNext()) {
+ try {
+ contacts.add(new ShortcutService.FrequentContact(cursor.getString(0), Jid.fromString(cursor.getString(1))));
+ } catch (Exception e) {
+ Log.d(Config.LOGTAG, e.getMessage());
+ }
+ }
+ cursor.close();
+ return contacts;
+ }
}
diff --git a/src/main/java/de/pixart/messenger/services/AvatarService.java b/src/main/java/de/pixart/messenger/services/AvatarService.java
index 15c49940f..3d3af8d26 100644
--- a/src/main/java/de/pixart/messenger/services/AvatarService.java
+++ b/src/main/java/de/pixart/messenger/services/AvatarService.java
@@ -3,9 +3,12 @@ package de.pixart.messenger.services;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.net.Uri;
+import android.util.DisplayMetrics;
import android.util.Log;
import java.util.ArrayList;
@@ -69,6 +72,24 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
return avatar;
}
+ public Bitmap getRoundedShortcut(final Contact contact) {
+ DisplayMetrics metrics = mXmppConnectionService.getResources().getDisplayMetrics();
+ int size = Math.round(metrics.density * 48);
+ Bitmap bitmap = get(contact, size);
+ Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(output);
+
+ final Paint paint = new Paint();
+ final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+
+ paint.setAntiAlias(true);
+ canvas.drawARGB(0, 0, 0, 0);
+ canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+ canvas.drawBitmap(bitmap, rect, rect, paint);
+ return output;
+ }
+
public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) {
Contact c = user.getContact();
if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null || user.getAvatar() == null)) {
diff --git a/src/main/java/de/pixart/messenger/services/MessageArchiveService.java b/src/main/java/de/pixart/messenger/services/MessageArchiveService.java
index e90bb8d07..b5ee9ac52 100644
--- a/src/main/java/de/pixart/messenger/services/MessageArchiveService.java
+++ b/src/main/java/de/pixart/messenger/services/MessageArchiveService.java
@@ -101,6 +101,22 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
}
}
+ public boolean isCatchingUp(Conversation conversation) {
+ final Account account = conversation.getAccount();
+ if (account.getXmppConnection().isWaitingForSmCatchup()) {
+ return true;
+ } else {
+ synchronized (this.queries) {
+ for (Query query : this.queries) {
+ if (query.getAccount() == account && query.isCatchup() && ((conversation.getMode() == Conversation.MODE_SINGLE && query.getWith() == null) || query.getConversation() == conversation)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
public Query query(final Conversation conversation, long end, boolean allowCatchup) {
return this.query(conversation, conversation.getLastMessageTransmitted(), end, allowCatchup);
}
diff --git a/src/main/java/de/pixart/messenger/services/NotificationService.java b/src/main/java/de/pixart/messenger/services/NotificationService.java
index 917bc9c30..ace144942 100644
--- a/src/main/java/de/pixart/messenger/services/NotificationService.java
+++ b/src/main/java/de/pixart/messenger/services/NotificationService.java
@@ -52,13 +52,14 @@ import de.pixart.messenger.xmpp.XmppConnection;
public class NotificationService {
+ public static final Object CATCHUP_LOCK = new Object();
+ private static final String CONVERSATIONS_GROUP = "de.pixart.messenger";
+ private final XmppConnectionService mXmppConnectionService;
+ private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>();
private static final int NOTIFICATION_ID_MULTIPLIER = 1024 * 1024;
public static final int NOTIFICATION_ID = 2 * NOTIFICATION_ID_MULTIPLIER;
public static final int FOREGROUND_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 4;
public static final int ERROR_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 6;
- private static final String CONVERSATIONS_GROUP = "de.pixart.messenger";
- private final XmppConnectionService mXmppConnectionService;
- private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>();
private Conversation mOpenConversation;
private boolean mIsInForeground;
private long mLastNotification;
@@ -179,7 +180,7 @@ public class NotificationService {
}
public void push(final Message message) {
- synchronized (message.getConversation().getAccount()) {
+ synchronized (CATCHUP_LOCK) {
final XmppConnection connection = message.getConversation().getAccount().getXmppConnection();
if (connection.isWaitingForSmCatchup()) {
connection.incrementSmCatchupMessageCounter();
diff --git a/src/main/java/de/pixart/messenger/services/ShortcutService.java b/src/main/java/de/pixart/messenger/services/ShortcutService.java
new file mode 100644
index 000000000..56345c663
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/services/ShortcutService.java
@@ -0,0 +1,131 @@
+package de.pixart.messenger.services;
+
+import android.annotation.TargetApi;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Build;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import de.pixart.messenger.Config;
+import de.pixart.messenger.entities.Account;
+import de.pixart.messenger.entities.Contact;
+import de.pixart.messenger.ui.StartConversationActivity;
+import de.pixart.messenger.utils.ReplacingSerialSingleThreadExecutor;
+import de.pixart.messenger.xmpp.jid.Jid;
+
+public class ShortcutService {
+ private final XmppConnectionService xmppConnectionService;
+ private final ReplacingSerialSingleThreadExecutor replacingSerialSingleThreadExecutor = new ReplacingSerialSingleThreadExecutor(false);
+
+ public ShortcutService(XmppConnectionService xmppConnectionService) {
+ this.xmppConnectionService = xmppConnectionService;
+ }
+
+ public void refresh() {
+ refresh(false);
+ }
+
+ public void refresh(final boolean forceUpdate) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
+ final Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ refreshImpl(forceUpdate);
+ }
+ };
+ replacingSerialSingleThreadExecutor.execute(r);
+ }
+ }
+
+ @TargetApi(25)
+ public void report(Contact contact) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
+ ShortcutManager shortcutManager = xmppConnectionService.getSystemService(ShortcutManager.class);
+ shortcutManager.reportShortcutUsed(getShortcutId(contact));
+ }
+ }
+
+ @TargetApi(25)
+ private void refreshImpl(boolean forceUpdate) {
+ List<FrequentContact> frequentContacts = xmppConnectionService.databaseBackend.getFrequentContacts(30);
+ HashMap<String, Account> accounts = new HashMap<>();
+ for (Account account : xmppConnectionService.getAccounts()) {
+ accounts.put(account.getUuid(), account);
+ }
+ List<Contact> contacts = new ArrayList<>();
+ for (FrequentContact frequentContact : frequentContacts) {
+ Account account = accounts.get(frequentContact.account);
+ if (account != null) {
+ contacts.add(account.getRoster().getContact(frequentContact.contact));
+ }
+ }
+ ShortcutManager shortcutManager = xmppConnectionService.getSystemService(ShortcutManager.class);
+ boolean needsUpdate = forceUpdate || contactsChanged(contacts, shortcutManager.getDynamicShortcuts());
+ if (!needsUpdate) {
+ Log.d(Config.LOGTAG, "skipping shortcut update");
+ return;
+ }
+ List<ShortcutInfo> newDynamicShortCuts = new ArrayList<>();
+ for (Contact contact : contacts) {
+ ShortcutInfo shortcut = new ShortcutInfo.Builder(xmppConnectionService, getShortcutId(contact))
+ .setShortLabel(contact.getDisplayName())
+ .setIntent(getShortcutIntent(contact))
+ .setIcon(Icon.createWithBitmap(xmppConnectionService.getAvatarService().getRoundedShortcut(contact)))
+ .build();
+ newDynamicShortCuts.add(shortcut);
+ }
+ if (shortcutManager.setDynamicShortcuts(newDynamicShortCuts)) {
+ Log.d(Config.LOGTAG, "updated dynamic shortcuts");
+ } else {
+ Log.d(Config.LOGTAG, "unable to update dynamic shortcuts");
+ }
+ }
+
+ private static boolean contactsChanged(List<Contact> needles, List<ShortcutInfo> haystack) {
+ for (Contact needle : needles) {
+ if (!contactExists(needle, haystack)) {
+ return true;
+ }
+ }
+ return needles.size() != haystack.size();
+ }
+
+ @TargetApi(25)
+ private static boolean contactExists(Contact needle, List<ShortcutInfo> haystack) {
+ for (ShortcutInfo shortcutInfo : haystack) {
+ if (getShortcutId(needle).equals(shortcutInfo.getId()) && needle.getDisplayName().equals(shortcutInfo.getShortLabel())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static String getShortcutId(Contact contact) {
+ return contact.getAccount().getJid().toBareJid().toPreppedString() + "#" + contact.getJid().toBareJid().toPreppedString();
+ }
+
+ private Intent getShortcutIntent(Contact contact) {
+ Intent intent = new Intent(xmppConnectionService, StartConversationActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse("xmpp:" + contact.getJid().toBareJid().toString()));
+ intent.putExtra("account", contact.getAccount().getJid().toBareJid().toString());
+ return intent;
+ }
+
+ public static class FrequentContact {
+ private final String account;
+ private final Jid contact;
+
+ public FrequentContact(String account, Jid contact) {
+ this.account = account;
+ this.contact = contact;
+ }
+ }
+}
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index 61a9d2318..27412e1ea 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -70,6 +70,7 @@ import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import de.duenndns.ssl.MemorizingTrustManager;
@@ -189,8 +190,9 @@ public class XmppConnectionService extends Service {
};
private FileBackend fileBackend = new FileBackend(this);
private MemorizingTrustManager mMemorizingTrustManager;
- private NotificationService mNotificationService = new NotificationService(
- this);
+ private NotificationService mNotificationService = new NotificationService(this);
+ private ShortcutService mShortcutService = new ShortcutService(this);
+ private AtomicBoolean mInitialAddressbookSyncCompleted = new AtomicBoolean(false);
private OnMessagePacketReceived mMessageParser = new MessageParser(this);
private OnPresencePacketReceived mPresenceParser = new PresenceParser(this);
private IqParser mIqParser = new IqParser(this);
@@ -1663,6 +1665,7 @@ public class XmppConnectionService extends Service {
}
}
Log.d(Config.LOGTAG, "finished merging phone contacts");
+ mShortcutService.refresh(mInitialAddressbookSyncCompleted.compareAndSet(false, true));
updateAccountUi();
}
});
@@ -3788,10 +3791,11 @@ public class XmppConnectionService extends Service {
return this.mMessageArchiveService;
}
- public List<Contact> findContacts(Jid jid) {
+ public List<Contact> findContacts(Jid jid, String accountJid) {
ArrayList<Contact> contacts = new ArrayList<>();
for (Account account : getAccounts()) {
- if (!account.isOptionSet(Account.OPTION_DISABLED)) {
+ if (!account.isOptionSet(Account.OPTION_DISABLED)
+ && (accountJid == null || accountJid.equals(account.getJid().toBareJid().toString()))) {
Contact contact = account.getRoster().getContactFromRoster(jid);
if (contact != null) {
contacts.add(contact);
@@ -4176,6 +4180,10 @@ public class XmppConnectionService extends Service {
}
}
+ public ShortcutService getShortcutService() {
+ return mShortcutService;
+ }
+
public interface OnMamPreferencesFetched {
void onPreferencesFetched(Element prefs);
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
index 52899f21e..96645c1e7 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
@@ -901,6 +901,7 @@ public class ConversationActivity extends XmppActivity
.findViewById(R.id.end_conversation_checkbox);
if (conversation.getMode() == Conversation.MODE_SINGLE) {
endConversationCheckBox.setVisibility(View.VISIBLE);
+ endConversationCheckBox.setChecked(true);
}
builder.setView(dialogView);
builder.setNegativeButton(getString(R.string.cancel), null);
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
index 084c27a99..bfdcd41f1 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
@@ -1307,9 +1307,10 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
action = SendButtonAction.TEXT;
}
}
- if (activity.useSendButtonToIndicateStatus() && c != null
- && c.getAccount().getStatus() == Account.State.ONLINE) {
- if (c.getMode() == Conversation.MODE_SINGLE) {
+ if (activity.useSendButtonToIndicateStatus() && c.getAccount().getStatus() == Account.State.ONLINE) {
+ if (activity.xmppConnectionService != null && activity.xmppConnectionService.getMessageArchiveService().isCatchingUp(c)) {
+ status = Presence.Status.OFFLINE;
+ } else if (c.getMode() == Conversation.MODE_SINGLE) {
status = c.getContact().getShownStatus();
} else {
status = c.getMucOptions().online() ? Presence.Status.ONLINE : Presence.Status.OFFLINE;
diff --git a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
index f3cbf7be9..73400dde3 100644
--- a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
@@ -831,7 +831,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
case Intent.ACTION_VIEW:
Uri uri = intent.getData();
if (uri != null) {
- return new Invite(intent.getData(), false).invite();
+ Invite invite = new Invite(intent.getData(), false);
+ invite.account = intent.getStringExtra("account");
+ return invite.invite();
} else {
return false;
}
@@ -870,7 +872,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
finish();
return true;
}
- List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid());
+ List<Contact> contacts = xmppConnectionService.findContacts(invite.getJid(), invite.account);
if (invite.isMuc()) {
Conversation muc = xmppConnectionService.findFirstMuc(invite.getJid());
if (muc != null) {
@@ -893,6 +895,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
Toast.makeText(this,R.string.verified_fingerprints,Toast.LENGTH_SHORT).show();
}
}
+ if (invite.account != null) {
+ xmppConnectionService.getShortcutService().report(contact);
+ }
switchToConversation(contact, invite.getBody());
}
return true;
@@ -1182,6 +1187,8 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
super(uri, safeSource);
}
+ public String account;
+
boolean invite() {
if (getJid() != null) {
return handleJid(this);
diff --git a/src/main/java/de/pixart/messenger/xml/XmlReader.java b/src/main/java/de/pixart/messenger/xml/XmlReader.java
index efd4dcc95..440fdd2fe 100644
--- a/src/main/java/de/pixart/messenger/xml/XmlReader.java
+++ b/src/main/java/de/pixart/messenger/xml/XmlReader.java
@@ -65,11 +65,17 @@ public class XmlReader {
wakeLock.acquire();
if (parser.getEventType() == XmlPullParser.START_TAG) {
Tag tag = Tag.start(parser.getName());
+ final String xmlns = parser.getNamespace();
for (int i = 0; i < parser.getAttributeCount(); ++i) {
- tag.setAttribute(parser.getAttributeName(i),
- parser.getAttributeValue(i));
+ final String prefix = parser.getAttributePrefix(i);
+ String name;
+ if (prefix != null && !prefix.isEmpty()) {
+ name = prefix + ":" + parser.getAttributeName(i);
+ } else {
+ name = parser.getAttributeName(i);
+ }
+ tag.setAttribute(name, parser.getAttributeValue(i));
}
- String xmlns = parser.getNamespace();
if (xmlns != null) {
tag.setAttribute("xmlns", xmlns);
}
diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
index 75eb63e5e..09b90b3ba 100644
--- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
+++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
@@ -65,6 +65,7 @@ import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Message;
import de.pixart.messenger.entities.ServiceDiscoveryResult;
import de.pixart.messenger.generator.IqGenerator;
+import de.pixart.messenger.services.NotificationService;
import de.pixart.messenger.services.XmppConnectionService;
import de.pixart.messenger.ui.EditAccountActivity;
import de.pixart.messenger.utils.DNSHelper;
@@ -165,7 +166,8 @@ public class XmppConnection implements Runnable {
@Override
public String[] getClientAliases(String s, Principal[] principals) {
- return new String[0];
+ final String alias = account.getPrivateKeyAlias();
+ return alias != null ? new String[]{alias} : new String[0];
}
@Override
@@ -226,26 +228,30 @@ public class XmppConnection implements Runnable {
mXmppConnectionService = service;
}
- protected synchronized void changeStatus(final Account.State nextStatus) {
- if (Thread.currentThread().isInterrupted()) {
- Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": not changing status to " + nextStatus + " because thread was interrupted");
- return;
- }
- if (account.getStatus() != nextStatus) {
- if ((nextStatus == Account.State.OFFLINE)
- && (account.getStatus() != Account.State.CONNECTING)
- && (account.getStatus() != Account.State.ONLINE)
- && (account.getStatus() != Account.State.DISABLED)) {
+ protected void changeStatus(final Account.State nextStatus) {
+ synchronized (this) {
+ if (Thread.currentThread().isInterrupted()) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": not changing status to " + nextStatus + " because thread was interrupted");
return;
}
- if (nextStatus == Account.State.ONLINE) {
- this.attempt = 0;
- }
- account.setStatus(nextStatus);
- if (statusListener != null) {
- statusListener.onStatusChanged(account);
+ if (account.getStatus() != nextStatus) {
+ if ((nextStatus == Account.State.OFFLINE)
+ && (account.getStatus() != Account.State.CONNECTING)
+ && (account.getStatus() != Account.State.ONLINE)
+ && (account.getStatus() != Account.State.DISABLED)) {
+ return;
+ }
+ if (nextStatus == Account.State.ONLINE) {
+ this.attempt = 0;
+ }
+ account.setStatus(nextStatus);
+ } else {
+ return;
}
}
+ if (statusListener != null) {
+ statusListener.onStatusChanged(account);
+ }
}
public void prepareNewConnection() {
@@ -647,15 +653,20 @@ public class XmppConnection implements Runnable {
final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
tagWriter.writeStanzaAsync(ack);
} else if (nextTag.isStart("a")) {
- synchronized (account) {
+ boolean accountUiNeedsRefresh = false;
+ synchronized (NotificationService.CATCHUP_LOCK) {
if (mWaitingForSmCatchup.compareAndSet(true, false)) {
int count = mSmCatchupMessageCounter.get();
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": SM catchup complete (" + count + ")");
+ accountUiNeedsRefresh = true;
if (count > 0) {
mXmppConnectionService.getNotificationService().finishBacklog(true, account);
}
}
}
+ if (accountUiNeedsRefresh) {
+ mXmppConnectionService.updateAccountUi();
+ }
final Element ack = tagReader.readElement(nextTag);
lastPacketReceived = SystemClock.elapsedRealtime();
try {
@@ -1063,7 +1074,13 @@ public class XmppConnection implements Runnable {
} else {
Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString());
}
- account.setResource(account.getResource().split("\\.")[0]);
+ final Element error = packet.findChild("error");
+ final String resource = account.getResource().split("\\.")[0];
+ if (packet.getType() == IqPacket.TYPE.ERROR && error != null && error.hasChild("conflict")) {
+ account.setResource(resource + "." + nextRandomId());
+ } else {
+ account.setResource(resource);
+ }
throw new StateChangingError(Account.State.BIND_FAILURE);
}
});