commit
a94663aaa4
|
@ -50,9 +50,11 @@ run your own XMPP server for you and your friends. These XEP's are:
|
||||||
* XEP-0313: Message Archive Management synchronize message history with the
|
* XEP-0313: Message Archive Management synchronize message history with the
|
||||||
server. Catch up with messages that were sent while Conversations was
|
server. Catch up with messages that were sent while Conversations was
|
||||||
offline.
|
offline.
|
||||||
* XEP-0352: Client State Indication let the server know whether or not
|
* XEP-0352: Client State Indication lets the server know whether or not
|
||||||
Conversations is in the background. Allows the server to save bandwidth by
|
Conversations is in the background. Allows the server to save bandwidth by
|
||||||
withholding unimportant packages.
|
withholding unimportant packages.
|
||||||
|
* XEP-0191: Blocking command lets you blacklist spammers or block contacts
|
||||||
|
without removing them from your roster.
|
||||||
|
|
||||||
## Team
|
## Team
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,4 @@
|
||||||
* XEP-0313: Message Archive Management
|
* XEP-0313: Message Archive Management
|
||||||
* XEP-0333: Chat Markers
|
* XEP-0333: Chat Markers
|
||||||
* XEP-0352: Client State Indication
|
* XEP-0352: Client State Indication
|
||||||
|
* XEP-0191: Blocking command
|
||||||
|
|
|
@ -76,6 +76,9 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ChooseContactActivity"
|
android:name=".ui.ChooseContactActivity"
|
||||||
android:label="@string/title_activity_choose_contact" />
|
android:label="@string/title_activity_choose_contact" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.BlocklistActivity"
|
||||||
|
android:label="@string/title_activity_block_list" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ManageAccountActivity"
|
android:name=".ui.ManageAccountActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
|
|
|
@ -11,8 +11,10 @@ import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.security.interfaces.DSAPublicKey;
|
import java.security.interfaces.DSAPublicKey;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
@ -56,7 +58,7 @@ public class Account extends AbstractEntity {
|
||||||
SECURITY_ERROR(true),
|
SECURITY_ERROR(true),
|
||||||
INCOMPATIBLE_SERVER(true);
|
INCOMPATIBLE_SERVER(true);
|
||||||
|
|
||||||
private boolean isError;
|
private final boolean isError;
|
||||||
|
|
||||||
public boolean isError() {
|
public boolean isError() {
|
||||||
return this.isError;
|
return this.isError;
|
||||||
|
@ -120,6 +122,7 @@ public class Account extends AbstractEntity {
|
||||||
private String otrFingerprint;
|
private String otrFingerprint;
|
||||||
private final Roster roster = new Roster(this);
|
private final Roster roster = new Roster(this);
|
||||||
private List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
|
private List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
|
||||||
|
private final Collection<Jid> blocklist = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
public Account() {
|
public Account() {
|
||||||
this.uuid = "0";
|
this.uuid = "0";
|
||||||
|
@ -279,7 +282,7 @@ public class Account extends AbstractEntity {
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initOtrEngine(XmppConnectionService context) {
|
public void initOtrEngine(final XmppConnectionService context) {
|
||||||
this.otrEngine = new OtrEngine(context, this);
|
this.otrEngine = new OtrEngine(context, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +294,7 @@ public class Account extends AbstractEntity {
|
||||||
return this.xmppConnection;
|
return this.xmppConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setXmppConnection(XmppConnection connection) {
|
public void setXmppConnection(final XmppConnection connection) {
|
||||||
this.xmppConnection = connection;
|
this.xmppConnection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +326,7 @@ public class Account extends AbstractEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRosterVersion(String version) {
|
public void setRosterVersion(final String version) {
|
||||||
this.rosterVersion = version;
|
this.rosterVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +354,7 @@ public class Account extends AbstractEntity {
|
||||||
return this.bookmarks;
|
return this.bookmarks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBookmarks(List<Bookmark> bookmarks) {
|
public void setBookmarks(final List<Bookmark> bookmarks) {
|
||||||
this.bookmarks = bookmarks;
|
this.bookmarks = bookmarks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,4 +402,21 @@ public class Account extends AbstractEntity {
|
||||||
return "xmpp:" + this.getJid().toBareJid().toString();
|
return "xmpp:" + this.getJid().toBareJid().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBlocked(final ListItem contact) {
|
||||||
|
final Jid jid = contact.getJid();
|
||||||
|
return jid != null && (blocklist.contains(jid.toBareJid()) || blocklist.contains(jid.toDomainJid()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBlocked(final Jid jid) {
|
||||||
|
return jid != null && blocklist.contains(jid.toBareJid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Jid> getBlocklist() {
|
||||||
|
return this.blocklist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearBlocklist() {
|
||||||
|
getBlocklist().clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package eu.siacs.conversations.entities;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
|
public interface Blockable {
|
||||||
|
public boolean isBlocked();
|
||||||
|
public boolean isDomainBlocked();
|
||||||
|
public Jid getBlockedJid();
|
||||||
|
public Jid getJid();
|
||||||
|
public Account getAccount();
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ import java.util.Locale;
|
||||||
|
|
||||||
import eu.siacs.conversations.utils.UIHelper;
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
public class Bookmark extends Element implements ListItem {
|
public class Bookmark extends Element implements ListItem {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
public class Contact implements ListItem {
|
public class Contact implements ListItem, Blockable {
|
||||||
public static final String TABLENAME = "contacts";
|
public static final String TABLENAME = "contacts";
|
||||||
|
|
||||||
public static final String SYSTEMNAME = "systemname";
|
public static final String SYSTEMNAME = "systemname";
|
||||||
|
@ -47,8 +47,8 @@ public class Contact implements ListItem {
|
||||||
protected Account account;
|
protected Account account;
|
||||||
|
|
||||||
public Contact(final String account, final String systemName, final String serverName,
|
public Contact(final String account, final String systemName, final String serverName,
|
||||||
final Jid jid, final int subscription, final String photoUri,
|
final Jid jid, final int subscription, final String photoUri,
|
||||||
final String systemAccount, final String keys, final String avatar, final Lastseen lastseen, final String groups) {
|
final String systemAccount, final String keys, final String avatar, final Lastseen lastseen, final String groups) {
|
||||||
this.accountUuid = account;
|
this.accountUuid = account;
|
||||||
this.systemName = systemName;
|
this.systemName = systemName;
|
||||||
this.serverName = serverName;
|
this.serverName = serverName;
|
||||||
|
@ -122,11 +122,10 @@ public class Contact implements ListItem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Tag> getTags() {
|
public List<Tag> getTags() {
|
||||||
ArrayList<Tag> tags = new ArrayList<Tag>();
|
final ArrayList<Tag> tags = new ArrayList<>();
|
||||||
for (String group : getGroups()) {
|
for (final String group : getGroups()) {
|
||||||
tags.add(new Tag(group, UIHelper.getColorForName(group)));
|
tags.add(new Tag(group, UIHelper.getColorForName(group)));
|
||||||
}
|
}
|
||||||
int status = getMostAvailableStatus();
|
|
||||||
switch (getMostAvailableStatus()) {
|
switch (getMostAvailableStatus()) {
|
||||||
case Presences.CHAT:
|
case Presences.CHAT:
|
||||||
case Presences.ONLINE:
|
case Presences.ONLINE:
|
||||||
|
@ -142,6 +141,9 @@ public class Contact implements ListItem {
|
||||||
tags.add(new Tag("dnd", 0xffe51c23));
|
tags.add(new Tag("dnd", 0xffe51c23));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (isBlocked()) {
|
||||||
|
tags.add(new Tag("blocked", 0xff2e2f3b));
|
||||||
|
}
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +178,7 @@ public class Contact implements ListItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentValues getContentValues() {
|
public ContentValues getContentValues() {
|
||||||
ContentValues values = new ContentValues();
|
final ContentValues values = new ContentValues();
|
||||||
values.put(ACCOUNT, accountUuid);
|
values.put(ACCOUNT, accountUuid);
|
||||||
values.put(SYSTEMNAME, systemName);
|
values.put(SYSTEMNAME, systemName);
|
||||||
values.put(SERVERNAME, serverName);
|
values.put(SERVERNAME, serverName);
|
||||||
|
@ -213,11 +215,11 @@ public class Contact implements ListItem {
|
||||||
this.presences = pres;
|
this.presences = pres;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePresence(String resource, int status) {
|
public void updatePresence(final String resource, final int status) {
|
||||||
this.presences.updatePresence(resource, status);
|
this.presences.updatePresence(resource, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removePresence(String resource) {
|
public void removePresence(final String resource) {
|
||||||
this.presences.removePresence(resource);
|
this.presences.removePresence(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,8 +339,8 @@ public class Contact implements ListItem {
|
||||||
|
|
||||||
public boolean showInRoster() {
|
public boolean showInRoster() {
|
||||||
return (this.getOption(Contact.Options.IN_ROSTER) && (!this
|
return (this.getOption(Contact.Options.IN_ROSTER) && (!this
|
||||||
.getOption(Contact.Options.DIRTY_DELETE)))
|
.getOption(Contact.Options.DIRTY_DELETE)))
|
||||||
|| (this.getOption(Contact.Options.DIRTY_PUSH));
|
|| (this.getOption(Contact.Options.DIRTY_PUSH));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseSubscriptionFromElement(Element item) {
|
public void parseSubscriptionFromElement(Element item) {
|
||||||
|
@ -428,7 +430,7 @@ public class Contact implements ListItem {
|
||||||
if (this.keys.has("otr_fingerprints")) {
|
if (this.keys.has("otr_fingerprints")) {
|
||||||
JSONArray newPrints = new JSONArray();
|
JSONArray newPrints = new JSONArray();
|
||||||
JSONArray oldPrints = this.keys
|
JSONArray oldPrints = this.keys
|
||||||
.getJSONArray("otr_fingerprints");
|
.getJSONArray("otr_fingerprints");
|
||||||
for (int i = 0; i < oldPrints.length(); ++i) {
|
for (int i = 0; i < oldPrints.length(); ++i) {
|
||||||
if (!oldPrints.getString(i).equals(fingerprint)) {
|
if (!oldPrints.getString(i).equals(fingerprint)) {
|
||||||
newPrints.put(oldPrints.getString(i));
|
newPrints.put(oldPrints.getString(i));
|
||||||
|
@ -457,22 +459,40 @@ public class Contact implements ListItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBlocked() {
|
||||||
|
return getAccount().isBlocked(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDomainBlocked() {
|
||||||
|
return getAccount().isBlocked(this.getJid().toDomainJid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Jid getBlockedJid() {
|
||||||
|
if (isDomainBlocked()) {
|
||||||
|
return getJid().toDomainJid();
|
||||||
|
} else {
|
||||||
|
return getJid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class Lastseen {
|
public static class Lastseen {
|
||||||
public long time;
|
public long time;
|
||||||
public String presence;
|
public String presence;
|
||||||
|
|
||||||
public Lastseen() {
|
public Lastseen() {
|
||||||
time = 0;
|
this(null, 0);
|
||||||
presence = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Lastseen(final String presence, final long time) {
|
public Lastseen(final String presence, final long time) {
|
||||||
this.time = time;
|
|
||||||
this.presence = presence;
|
this.presence = presence;
|
||||||
|
this.time = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Options {
|
public final class Options {
|
||||||
public static final int TO = 0;
|
public static final int TO = 0;
|
||||||
public static final int FROM = 1;
|
public static final int FROM = 1;
|
||||||
public static final int ASKING = 2;
|
public static final int ASKING = 2;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package eu.siacs.conversations.entities;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import net.java.otr4j.OtrException;
|
import net.java.otr4j.OtrException;
|
||||||
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
|
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
|
||||||
|
@ -25,7 +24,7 @@ import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
public class Conversation extends AbstractEntity {
|
public class Conversation extends AbstractEntity implements Blockable {
|
||||||
public static final String TABLENAME = "conversations";
|
public static final String TABLENAME = "conversations";
|
||||||
|
|
||||||
public static final int STATUS_AVAILABLE = 0;
|
public static final int STATUS_AVAILABLE = 0;
|
||||||
|
@ -105,7 +104,7 @@ public class Conversation extends AbstractEntity {
|
||||||
if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE)
|
if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE)
|
||||||
&& message.getEncryption() != Message.ENCRYPTION_PGP) {
|
&& message.getEncryption() != Message.ENCRYPTION_PGP) {
|
||||||
onMessageFound.onMessageFound(message);
|
onMessageFound.onMessageFound(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +116,7 @@ public class Conversation extends AbstractEntity {
|
||||||
&& message.getEncryption() != Message.ENCRYPTION_PGP
|
&& message.getEncryption() != Message.ENCRYPTION_PGP
|
||||||
&& message.getUuid().equals(uuid)) {
|
&& message.getUuid().equals(uuid)) {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -145,7 +144,7 @@ public class Conversation extends AbstractEntity {
|
||||||
if ((message.getStatus() == Message.STATUS_UNSEND || message.getStatus() == Message.STATUS_WAITING)
|
if ((message.getStatus() == Message.STATUS_UNSEND || message.getStatus() == Message.STATUS_WAITING)
|
||||||
&& (message.getEncryption() == Message.ENCRYPTION_OTR)) {
|
&& (message.getEncryption() == Message.ENCRYPTION_OTR)) {
|
||||||
onMessageFound.onMessageFound(message);
|
onMessageFound.onMessageFound(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +155,7 @@ public class Conversation extends AbstractEntity {
|
||||||
if (message.getType() != Message.TYPE_IMAGE
|
if (message.getType() != Message.TYPE_IMAGE
|
||||||
&& message.getStatus() == Message.STATUS_UNSEND) {
|
&& message.getStatus() == Message.STATUS_UNSEND) {
|
||||||
onMessageFound.onMessageFound(message);
|
onMessageFound.onMessageFound(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,21 +165,37 @@ public class Conversation extends AbstractEntity {
|
||||||
for (Message message : this.messages) {
|
for (Message message : this.messages) {
|
||||||
if (uuid.equals(message.getUuid())
|
if (uuid.equals(message.getUuid())
|
||||||
|| (message.getStatus() >= Message.STATUS_SEND && uuid
|
|| (message.getStatus() >= Message.STATUS_SEND && uuid
|
||||||
.equals(message.getRemoteMsgId()))) {
|
.equals(message.getRemoteMsgId()))) {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void populateWithMessages(List<Message> messages) {
|
public void populateWithMessages(final List<Message> messages) {
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
messages.clear();
|
messages.clear();
|
||||||
messages.addAll(this.messages);
|
messages.addAll(this.messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBlocked() {
|
||||||
|
return getContact().isBlocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDomainBlocked() {
|
||||||
|
return getContact().isDomainBlocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Jid getBlockedJid() {
|
||||||
|
return getContact().getBlockedJid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface OnMessageFound {
|
public interface OnMessageFound {
|
||||||
public void onMessageFound(final Message message);
|
public void onMessageFound(final Message message);
|
||||||
}
|
}
|
||||||
|
@ -212,8 +227,8 @@ public class Conversation extends AbstractEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRead() {
|
public boolean isRead() {
|
||||||
return (this.messages == null) || (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead();
|
return (this.messages == null) || (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markRead() {
|
public void markRead() {
|
||||||
if (this.messages == null) {
|
if (this.messages == null) {
|
||||||
|
@ -239,7 +254,7 @@ public class Conversation extends AbstractEntity {
|
||||||
} else {
|
} else {
|
||||||
return this.messages.get(i);
|
return this.messages.get(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +282,7 @@ public class Conversation extends AbstractEntity {
|
||||||
if (generatedName != null) {
|
if (generatedName != null) {
|
||||||
return generatedName;
|
return generatedName;
|
||||||
} else {
|
} else {
|
||||||
return getContactJid().getLocalpart();
|
return getJid().getLocalpart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -287,11 +302,12 @@ public class Conversation extends AbstractEntity {
|
||||||
return this.account.getRoster().getContact(this.contactJid);
|
return this.account.getRoster().getContact(this.contactJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccount(Account account) {
|
public void setAccount(final Account account) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid getContactJid() {
|
@Override
|
||||||
|
public Jid getJid() {
|
||||||
return this.contactJid;
|
return this.contactJid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,14 +334,14 @@ public class Conversation extends AbstractEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Conversation fromCursor(Cursor cursor) {
|
public static Conversation fromCursor(Cursor cursor) {
|
||||||
Jid jid;
|
Jid jid;
|
||||||
try {
|
try {
|
||||||
jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(CONTACTJID)));
|
jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(CONTACTJID)));
|
||||||
} catch (final InvalidJidException e) {
|
} catch (final InvalidJidException e) {
|
||||||
// Borked DB..
|
// Borked DB..
|
||||||
jid = null;
|
jid = null;
|
||||||
}
|
}
|
||||||
return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)),
|
return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)),
|
||||||
cursor.getString(cursor.getColumnIndex(NAME)),
|
cursor.getString(cursor.getColumnIndex(NAME)),
|
||||||
cursor.getString(cursor.getColumnIndex(CONTACT)),
|
cursor.getString(cursor.getColumnIndex(CONTACT)),
|
||||||
cursor.getString(cursor.getColumnIndex(ACCOUNT)),
|
cursor.getString(cursor.getColumnIndex(ACCOUNT)),
|
||||||
|
@ -352,9 +368,9 @@ public class Conversation extends AbstractEntity {
|
||||||
if (this.otrSession != null) {
|
if (this.otrSession != null) {
|
||||||
return this.otrSession;
|
return this.otrSession;
|
||||||
} else {
|
} else {
|
||||||
final SessionID sessionId = new SessionID(this.getContactJid().toBareJid().toString(),
|
final SessionID sessionId = new SessionID(this.getJid().toBareJid().toString(),
|
||||||
presence,
|
presence,
|
||||||
"xmpp");
|
"xmpp");
|
||||||
this.otrSession = new SessionImpl(sessionId, getAccount().getOtrEngine());
|
this.otrSession = new SessionImpl(sessionId, getAccount().getOtrEngine());
|
||||||
try {
|
try {
|
||||||
if (sendStart) {
|
if (sendStart) {
|
||||||
|
@ -393,7 +409,7 @@ public class Conversation extends AbstractEntity {
|
||||||
} catch (OtrException e) {
|
} catch (OtrException e) {
|
||||||
this.resetOtrSession();
|
this.resetOtrSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean endOtrIfNeeded() {
|
public boolean endOtrIfNeeded() {
|
||||||
|
@ -427,7 +443,7 @@ public class Conversation extends AbstractEntity {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession()
|
DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession()
|
||||||
.getRemotePublicKey();
|
.getRemotePublicKey();
|
||||||
StringBuilder builder = new StringBuilder(
|
StringBuilder builder = new StringBuilder(
|
||||||
new OtrCryptoEngineImpl().getFingerprint(remotePubKey));
|
new OtrCryptoEngineImpl().getFingerprint(remotePubKey));
|
||||||
builder.insert(8, " ");
|
builder.insert(8, " ");
|
||||||
|
|
|
@ -12,10 +12,10 @@ public interface ListItem extends Comparable<ListItem> {
|
||||||
public List<Tag> getTags();
|
public List<Tag> getTags();
|
||||||
|
|
||||||
public final class Tag {
|
public final class Tag {
|
||||||
private String name;
|
private final String name;
|
||||||
private int color;
|
private final int color;
|
||||||
|
|
||||||
public Tag(String name, int color) {
|
public Tag(final String name, final int color) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
@ -28,4 +28,6 @@ public interface ListItem extends Comparable<ListItem> {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean match(final String needle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class Message extends AbstractEntity {
|
||||||
public Message(Conversation conversation, String body, int encryption, int status) {
|
public Message(Conversation conversation, String body, int encryption, int status) {
|
||||||
this(java.util.UUID.randomUUID().toString(),
|
this(java.util.UUID.randomUUID().toString(),
|
||||||
conversation.getUuid(),
|
conversation.getUuid(),
|
||||||
conversation.getContactJid() == null ? null : conversation.getContactJid().toBareJid(),
|
conversation.getJid() == null ? null : conversation.getJid().toBareJid(),
|
||||||
null,
|
null,
|
||||||
body,
|
body,
|
||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
|
@ -91,9 +91,9 @@ public class Message extends AbstractEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Message(final String uuid, final String conversationUUid, final Jid counterpart,
|
private Message(final String uuid, final String conversationUUid, final Jid counterpart,
|
||||||
final Jid trueCounterpart, final String body, final long timeSent,
|
final Jid trueCounterpart, final String body, final long timeSent,
|
||||||
final int encryption, final int status, final int type, final String remoteMsgId,
|
final int encryption, final int status, final int type, final String remoteMsgId,
|
||||||
final String relativeFilePath, final String serverMsgId) {
|
final String relativeFilePath, final String serverMsgId) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.conversationUuid = conversationUUid;
|
this.conversationUuid = conversationUUid;
|
||||||
this.counterpart = counterpart;
|
this.counterpart = counterpart;
|
||||||
|
@ -206,7 +206,7 @@ public class Message extends AbstractEntity {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return this.conversation.getAccount().getRoster()
|
return this.conversation.getAccount().getRoster()
|
||||||
.getContactFromRoster(this.trueCounterpart);
|
.getContactFromRoster(this.trueCounterpart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,10 +312,10 @@ public class Message extends AbstractEntity {
|
||||||
return this.serverMsgId.equals(message.getServerMsgId());
|
return this.serverMsgId.equals(message.getServerMsgId());
|
||||||
} else {
|
} else {
|
||||||
return this.body != null
|
return this.body != null
|
||||||
&& this.counterpart != null
|
&& this.counterpart != null
|
||||||
&& ((this.remoteMsgId != null && this.remoteMsgId.equals(message.getRemoteMsgId()))
|
&& ((this.remoteMsgId != null && this.remoteMsgId.equals(message.getRemoteMsgId()))
|
||||||
|| this.uuid.equals(message.getRemoteMsgId())) && this.body.equals(message.getBody())
|
|| this.uuid.equals(message.getRemoteMsgId())) && this.body.equals(message.getBody())
|
||||||
&& this.counterpart.equals(message.getCounterpart());
|
&& this.counterpart.equals(message.getCounterpart());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ public class Message extends AbstractEntity {
|
||||||
if (!url.getProtocol().equalsIgnoreCase("http")
|
if (!url.getProtocol().equalsIgnoreCase("http")
|
||||||
&& !url.getProtocol().equalsIgnoreCase("https")) {
|
&& !url.getProtocol().equalsIgnoreCase("https")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (url.getPath() == null) {
|
if (url.getPath() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -402,14 +402,14 @@ public class Message extends AbstractEntity {
|
||||||
String[] extensionParts = filename.split("\\.");
|
String[] extensionParts = filename.split("\\.");
|
||||||
if (extensionParts.length == 2
|
if (extensionParts.length == 2
|
||||||
&& Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(
|
&& Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(
|
||||||
extensionParts[extensionParts.length - 1])) {
|
extensionParts[extensionParts.length - 1])) {
|
||||||
return true;
|
return true;
|
||||||
} else if (extensionParts.length == 3
|
} else if (extensionParts.length == 3
|
||||||
&& Arrays
|
&& Arrays
|
||||||
.asList(Downloadable.VALID_CRYPTO_EXTENSIONS)
|
.asList(Downloadable.VALID_CRYPTO_EXTENSIONS)
|
||||||
.contains(extensionParts[extensionParts.length - 1])
|
.contains(extensionParts[extensionParts.length - 1])
|
||||||
&& Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(
|
&& Arrays.asList(Downloadable.VALID_IMAGE_EXTENSIONS).contains(
|
||||||
extensionParts[extensionParts.length - 2])) {
|
extensionParts[extensionParts.length - 2])) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -80,20 +80,20 @@ public class MucOptions {
|
||||||
|
|
||||||
public void setRole(String role) {
|
public void setRole(String role) {
|
||||||
role = role.toLowerCase();
|
role = role.toLowerCase();
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case "moderator":
|
case "moderator":
|
||||||
this.role = ROLE_MODERATOR;
|
this.role = ROLE_MODERATOR;
|
||||||
break;
|
break;
|
||||||
case "participant":
|
case "participant":
|
||||||
this.role = ROLE_PARTICIPANT;
|
this.role = ROLE_PARTICIPANT;
|
||||||
break;
|
break;
|
||||||
case "visitor":
|
case "visitor":
|
||||||
this.role = ROLE_VISITOR;
|
this.role = ROLE_VISITOR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.role = ROLE_NONE;
|
this.role = ROLE_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAffiliation() {
|
public int getAffiliation() {
|
||||||
|
@ -164,7 +164,7 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processPacket(PresencePacket packet, PgpEngine pgp) {
|
public void processPacket(PresencePacket packet, PgpEngine pgp) {
|
||||||
final Jid from = packet.getFrom();
|
final Jid from = packet.getFrom();
|
||||||
if (!from.isBareJid()) {
|
if (!from.isBareJid()) {
|
||||||
final String name = from.getResourcepart();
|
final String name = from.getResourcepart();
|
||||||
final String type = packet.getAttribute("type");
|
final String type = packet.getAttribute("type");
|
||||||
|
@ -179,7 +179,7 @@ public class MucOptions {
|
||||||
user.setAffiliation(item.getAttribute("affiliation"));
|
user.setAffiliation(item.getAttribute("affiliation"));
|
||||||
user.setRole(item.getAttribute("role"));
|
user.setRole(item.getAttribute("role"));
|
||||||
user.setJid(item.getAttributeAsJid("jid"));
|
user.setJid(item.getAttributeAsJid("jid"));
|
||||||
if (codes.contains(STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(this.conversation.getContactJid())) {
|
if (codes.contains(STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(this.conversation.getJid())) {
|
||||||
this.isOnline = true;
|
this.isOnline = true;
|
||||||
this.error = ERROR_NO_ERROR;
|
this.error = ERROR_NO_ERROR;
|
||||||
self = user;
|
self = user;
|
||||||
|
@ -204,14 +204,14 @@ public class MucOptions {
|
||||||
msg = "";
|
msg = "";
|
||||||
}
|
}
|
||||||
user.setPgpKeyId(pgp.fetchKeyId(account, msg,
|
user.setPgpKeyId(pgp.fetchKeyId(account, msg,
|
||||||
signed.getContent()));
|
signed.getContent()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type.equals("unavailable")) {
|
} else if (type.equals("unavailable")) {
|
||||||
if (codes.contains(STATUS_CODE_SELF_PRESENCE) ||
|
if (codes.contains(STATUS_CODE_SELF_PRESENCE) ||
|
||||||
packet.getFrom().equals(this.conversation.getContactJid())) {
|
packet.getFrom().equals(this.conversation.getJid())) {
|
||||||
if (codes.contains(STATUS_CODE_CHANGED_NICK)) {
|
if (codes.contains(STATUS_CODE_CHANGED_NICK)) {
|
||||||
this.mNickChangingInProgress = true;
|
this.mNickChangingInProgress = true;
|
||||||
} else if (codes.contains(STATUS_CODE_KICKED)) {
|
} else if (codes.contains(STATUS_CODE_KICKED)) {
|
||||||
|
@ -282,8 +282,8 @@ public class MucOptions {
|
||||||
&& conversation.getBookmark().getNick() != null
|
&& conversation.getBookmark().getNick() != null
|
||||||
&& !conversation.getBookmark().getNick().isEmpty()) {
|
&& !conversation.getBookmark().getNick().isEmpty()) {
|
||||||
return conversation.getBookmark().getNick();
|
return conversation.getBookmark().getNick();
|
||||||
} else if (!conversation.getContactJid().isBareJid()) {
|
} else if (!conversation.getJid().isBareJid()) {
|
||||||
return conversation.getContactJid().getResourcepart();
|
return conversation.getJid().getResourcepart();
|
||||||
} else {
|
} else {
|
||||||
return account.getUsername();
|
return account.getUsername();
|
||||||
}
|
}
|
||||||
|
@ -334,14 +334,14 @@ public class MucOptions {
|
||||||
public String createNameFromParticipants() {
|
public String createNameFromParticipants() {
|
||||||
if (users.size() >= 2) {
|
if (users.size() >= 2) {
|
||||||
List<String> names = new ArrayList<String>();
|
List<String> names = new ArrayList<String>();
|
||||||
for (User user : users) {
|
for (User user : users) {
|
||||||
Contact contact = user.getContact();
|
Contact contact = user.getContact();
|
||||||
if (contact != null && !contact.getDisplayName().isEmpty()) {
|
if (contact != null && !contact.getDisplayName().isEmpty()) {
|
||||||
names.add(contact.getDisplayName().split("\\s+")[0]);
|
names.add(contact.getDisplayName().split("\\s+")[0]);
|
||||||
} else {
|
} else {
|
||||||
names.add(user.getName());
|
names.add(user.getName());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (int i = 0; i < names.size(); ++i) {
|
for (int i = 0; i < names.size(); ++i) {
|
||||||
builder.append(names.get(i));
|
builder.append(names.get(i));
|
||||||
|
@ -388,12 +388,12 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid createJoinJid(String nick) {
|
public Jid createJoinJid(String nick) {
|
||||||
try {
|
try {
|
||||||
return Jid.fromString(this.conversation.getContactJid().toBareJid().toString() + "/"+nick);
|
return Jid.fromString(this.conversation.getJid().toBareJid().toString() + "/"+nick);
|
||||||
} catch (final InvalidJidException e) {
|
} catch (final InvalidJidException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid getTrueCounterpart(String counterpart) {
|
public Jid getTrueCounterpart(String counterpart) {
|
||||||
for (User user : this.getUsers()) {
|
for (User user : this.getUsers()) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
public class Roster {
|
public class Roster {
|
||||||
Account account;
|
final Account account;
|
||||||
final ConcurrentHashMap<String, Contact> contacts = new ConcurrentHashMap<>();
|
final ConcurrentHashMap<String, Contact> contacts = new ConcurrentHashMap<>();
|
||||||
private String version = null;
|
private String version = null;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ public class Roster {
|
||||||
if (jid == null) {
|
if (jid == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Contact contact = contacts.get(jid.toBareJid().toString());
|
final Contact contact = contacts.get(jid.toBareJid().toString());
|
||||||
if (contact != null && contact.showInRoster()) {
|
if (contact != null && contact.showInRoster()) {
|
||||||
return contact;
|
return contact;
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,7 +32,7 @@ public class Roster {
|
||||||
if (contacts.containsKey(bareJid.toString())) {
|
if (contacts.containsKey(bareJid.toString())) {
|
||||||
return contacts.get(bareJid.toString());
|
return contacts.get(bareJid.toString());
|
||||||
} else {
|
} else {
|
||||||
Contact contact = new Contact(bareJid);
|
final Contact contact = new Contact(bareJid);
|
||||||
contact.setAccount(account);
|
contact.setAccount(account);
|
||||||
contacts.put(bareJid.toString(), contact);
|
contacts.put(bareJid.toString(), contact);
|
||||||
return contact;
|
return contact;
|
||||||
|
@ -46,13 +46,13 @@ public class Roster {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAllAsNotInRoster() {
|
public void markAllAsNotInRoster() {
|
||||||
for (Contact contact : getContacts()) {
|
for (final Contact contact : getContacts()) {
|
||||||
contact.resetOption(Contact.Options.IN_ROSTER);
|
contact.resetOption(Contact.Options.IN_ROSTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearSystemAccounts() {
|
public void clearSystemAccounts() {
|
||||||
for (Contact contact : getContacts()) {
|
for (final Contact contact : getContacts()) {
|
||||||
contact.setPhotoUri(null);
|
contact.setPhotoUri(null);
|
||||||
contact.setSystemName(null);
|
contact.setSystemName(null);
|
||||||
contact.setSystemAccount(null);
|
contact.setSystemAccount(null);
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package eu.siacs.conversations.generator;
|
package eu.siacs.conversations.generator;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
import eu.siacs.conversations.services.MessageArchiveService;
|
import eu.siacs.conversations.services.MessageArchiveService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
|
import eu.siacs.conversations.utils.Xmlns;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xmpp.forms.Data;
|
import eu.siacs.conversations.xmpp.forms.Data;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
@ -17,44 +15,44 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||||
|
|
||||||
public class IqGenerator extends AbstractGenerator {
|
public class IqGenerator extends AbstractGenerator {
|
||||||
|
|
||||||
public IqGenerator(XmppConnectionService service) {
|
public IqGenerator(final XmppConnectionService service) {
|
||||||
super(service);
|
super(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket discoResponse(IqPacket request) {
|
public IqPacket discoResponse(final IqPacket request) {
|
||||||
IqPacket packet = new IqPacket(IqPacket.TYPE_RESULT);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE_RESULT);
|
||||||
packet.setId(request.getId());
|
packet.setId(request.getId());
|
||||||
packet.setTo(request.getFrom());
|
packet.setTo(request.getFrom());
|
||||||
Element query = packet.addChild("query",
|
final Element query = packet.addChild("query",
|
||||||
"http://jabber.org/protocol/disco#info");
|
"http://jabber.org/protocol/disco#info");
|
||||||
query.setAttribute("node", request.query().getAttribute("node"));
|
query.setAttribute("node", request.query().getAttribute("node"));
|
||||||
Element identity = query.addChild("identity");
|
final Element identity = query.addChild("identity");
|
||||||
identity.setAttribute("category", "client");
|
identity.setAttribute("category", "client");
|
||||||
identity.setAttribute("type", this.IDENTITY_TYPE);
|
identity.setAttribute("type", this.IDENTITY_TYPE);
|
||||||
identity.setAttribute("name", IDENTITY_NAME);
|
identity.setAttribute("name", IDENTITY_NAME);
|
||||||
List<String> features = Arrays.asList(FEATURES);
|
final List<String> features = Arrays.asList(FEATURES);
|
||||||
Collections.sort(features);
|
Collections.sort(features);
|
||||||
for (String feature : features) {
|
for (final String feature : features) {
|
||||||
query.addChild("feature").setAttribute("var", feature);
|
query.addChild("feature").setAttribute("var", feature);
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IqPacket publish(String node, Element item) {
|
protected IqPacket publish(final String node, final Element item) {
|
||||||
IqPacket packet = new IqPacket(IqPacket.TYPE_SET);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE_SET);
|
||||||
Element pubsub = packet.addChild("pubsub",
|
final Element pubsub = packet.addChild("pubsub",
|
||||||
"http://jabber.org/protocol/pubsub");
|
"http://jabber.org/protocol/pubsub");
|
||||||
Element publish = pubsub.addChild("publish");
|
final Element publish = pubsub.addChild("publish");
|
||||||
publish.setAttribute("node", node);
|
publish.setAttribute("node", node);
|
||||||
publish.addChild(item);
|
publish.addChild(item);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IqPacket retrieve(String node, Element item) {
|
protected IqPacket retrieve(String node, Element item) {
|
||||||
IqPacket packet = new IqPacket(IqPacket.TYPE_GET);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE_GET);
|
||||||
Element pubsub = packet.addChild("pubsub",
|
final Element pubsub = packet.addChild("pubsub",
|
||||||
"http://jabber.org/protocol/pubsub");
|
"http://jabber.org/protocol/pubsub");
|
||||||
Element items = pubsub.addChild("items");
|
final Element items = pubsub.addChild("items");
|
||||||
items.setAttribute("node", node);
|
items.setAttribute("node", node);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
items.addChild(item);
|
items.addChild(item);
|
||||||
|
@ -63,19 +61,19 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket publishAvatar(Avatar avatar) {
|
public IqPacket publishAvatar(Avatar avatar) {
|
||||||
Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
item.setAttribute("id", avatar.sha1sum);
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
Element data = item.addChild("data", "urn:xmpp:avatar:data");
|
final Element data = item.addChild("data", "urn:xmpp:avatar:data");
|
||||||
data.setContent(avatar.image);
|
data.setContent(avatar.image);
|
||||||
return publish("urn:xmpp:avatar:data", item);
|
return publish("urn:xmpp:avatar:data", item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket publishAvatarMetadata(Avatar avatar) {
|
public IqPacket publishAvatarMetadata(final Avatar avatar) {
|
||||||
Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
item.setAttribute("id", avatar.sha1sum);
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
Element metadata = item
|
final Element metadata = item
|
||||||
.addChild("metadata", "urn:xmpp:avatar:metadata");
|
.addChild("metadata", "urn:xmpp:avatar:metadata");
|
||||||
Element info = metadata.addChild("info");
|
final Element info = metadata.addChild("info");
|
||||||
info.setAttribute("bytes", avatar.size);
|
info.setAttribute("bytes", avatar.size);
|
||||||
info.setAttribute("id", avatar.sha1sum);
|
info.setAttribute("id", avatar.sha1sum);
|
||||||
info.setAttribute("height", avatar.height);
|
info.setAttribute("height", avatar.height);
|
||||||
|
@ -84,10 +82,10 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
return publish("urn:xmpp:avatar:metadata", item);
|
return publish("urn:xmpp:avatar:metadata", item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket retrieveAvatar(Avatar avatar) {
|
public IqPacket retrieveAvatar(final Avatar avatar) {
|
||||||
Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
item.setAttribute("id", avatar.sha1sum);
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
IqPacket packet = retrieve("urn:xmpp:avatar:data", item);
|
final IqPacket packet = retrieve("urn:xmpp:avatar:data", item);
|
||||||
packet.setTo(avatar.owner);
|
packet.setTo(avatar.owner);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
@ -100,11 +98,11 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket queryMessageArchiveManagement(MessageArchiveService.Query mam) {
|
public IqPacket queryMessageArchiveManagement(final MessageArchiveService.Query mam) {
|
||||||
final IqPacket packet = new IqPacket(IqPacket.TYPE_SET);
|
final IqPacket packet = new IqPacket(IqPacket.TYPE_SET);
|
||||||
Element query = packet.query("urn:xmpp:mam:0");
|
final Element query = packet.query("urn:xmpp:mam:0");
|
||||||
query.setAttribute("queryid",mam.getQueryId());
|
query.setAttribute("queryid",mam.getQueryId());
|
||||||
Data data = new Data();
|
final Data data = new Data();
|
||||||
data.setFormType("urn:xmpp:mam:0");
|
data.setFormType("urn:xmpp:mam:0");
|
||||||
if (mam.getWith()!=null) {
|
if (mam.getWith()!=null) {
|
||||||
data.put("with", mam.getWith().toString());
|
data.put("with", mam.getWith().toString());
|
||||||
|
@ -119,4 +117,25 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
}
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IqPacket generateGetBlockList() {
|
||||||
|
final IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
|
||||||
|
iq.addChild("blocklist", Xmlns.BLOCKING);
|
||||||
|
|
||||||
|
return iq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IqPacket generateSetBlockRequest(final Jid jid) {
|
||||||
|
final IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
|
||||||
|
final Element block = iq.addChild("block", Xmlns.BLOCKING);
|
||||||
|
block.addChild("item").setAttribute("jid", jid.toBareJid().toString());
|
||||||
|
return iq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IqPacket generateSetUnblockRequest(final Jid jid) {
|
||||||
|
final IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
|
||||||
|
final Element block = iq.addChild("unblock", Xmlns.BLOCKING);
|
||||||
|
block.addChild("item").setAttribute("jid", jid.toBareJid().toString());
|
||||||
|
return iq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ public class MessageGenerator extends AbstractGenerator {
|
||||||
private MessagePacket generateError(MessagePacket origin) {
|
private MessagePacket generateError(MessagePacket origin) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setId(origin.getId());
|
packet.setId(origin.getId());
|
||||||
packet.setTo(origin.getFrom());
|
packet.setTo(origin.getFrom());
|
||||||
packet.setBody(origin.getBody());
|
packet.setBody(origin.getBody());
|
||||||
packet.setType(MessagePacket.TYPE_ERROR);
|
packet.setType(MessagePacket.TYPE_ERROR);
|
||||||
return packet;
|
return packet;
|
||||||
|
@ -135,7 +135,7 @@ public class MessageGenerator extends AbstractGenerator {
|
||||||
String subject) {
|
String subject) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setType(MessagePacket.TYPE_GROUPCHAT);
|
packet.setType(MessagePacket.TYPE_GROUPCHAT);
|
||||||
packet.setTo(conversation.getContactJid().toBareJid());
|
packet.setTo(conversation.getJid().toBareJid());
|
||||||
Element subjectChild = new Element("subject");
|
Element subjectChild = new Element("subject");
|
||||||
subjectChild.setContent(subject);
|
subjectChild.setContent(subject);
|
||||||
packet.addChild(subjectChild);
|
packet.addChild(subjectChild);
|
||||||
|
@ -149,13 +149,13 @@ public class MessageGenerator extends AbstractGenerator {
|
||||||
packet.setTo(contact);
|
packet.setTo(contact);
|
||||||
packet.setFrom(conversation.getAccount().getJid());
|
packet.setFrom(conversation.getAccount().getJid());
|
||||||
Element x = packet.addChild("x", "jabber:x:conference");
|
Element x = packet.addChild("x", "jabber:x:conference");
|
||||||
x.setAttribute("jid", conversation.getContactJid().toBareJid().toString());
|
x.setAttribute("jid", conversation.getJid().toBareJid().toString());
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessagePacket invite(Conversation conversation, Jid contact) {
|
public MessagePacket invite(Conversation conversation, Jid contact) {
|
||||||
MessagePacket packet = new MessagePacket();
|
MessagePacket packet = new MessagePacket();
|
||||||
packet.setTo(conversation.getContactJid().toBareJid());
|
packet.setTo(conversation.getJid().toBareJid());
|
||||||
packet.setFrom(conversation.getAccount().getJid());
|
packet.setFrom(conversation.getAccount().getJid());
|
||||||
Element x = new Element("x");
|
Element x = new Element("x");
|
||||||
x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user");
|
x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user");
|
||||||
|
@ -170,7 +170,7 @@ public class MessageGenerator extends AbstractGenerator {
|
||||||
MessagePacket originalMessage, String namespace) {
|
MessagePacket originalMessage, String namespace) {
|
||||||
MessagePacket receivedPacket = new MessagePacket();
|
MessagePacket receivedPacket = new MessagePacket();
|
||||||
receivedPacket.setType(MessagePacket.TYPE_NORMAL);
|
receivedPacket.setType(MessagePacket.TYPE_NORMAL);
|
||||||
receivedPacket.setTo(originalMessage.getFrom());
|
receivedPacket.setTo(originalMessage.getFrom());
|
||||||
receivedPacket.setFrom(account.getJid());
|
receivedPacket.setFrom(account.getJid());
|
||||||
Element received = receivedPacket.addChild("received", namespace);
|
Element received = receivedPacket.addChild("received", namespace);
|
||||||
received.setAttribute("id", originalMessage.getId());
|
received.setAttribute("id", originalMessage.getId());
|
||||||
|
|
|
@ -53,10 +53,10 @@ public abstract class AbstractParser {
|
||||||
|
|
||||||
protected void updateLastseen(final Element packet, final Account account,
|
protected void updateLastseen(final Element packet, final Account account,
|
||||||
final boolean presenceOverwrite) {
|
final boolean presenceOverwrite) {
|
||||||
Jid from = packet.getAttributeAsJid("from");
|
final Jid from = packet.getAttributeAsJid("from");
|
||||||
String presence = from == null || from.isBareJid() ? "" : from.getResourcepart();
|
final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart();
|
||||||
Contact contact = account.getRoster().getContact(from);
|
final Contact contact = account.getRoster().getContact(from);
|
||||||
long timestamp = getTimestamp(packet);
|
final long timestamp = getTimestamp(packet);
|
||||||
if (timestamp >= contact.lastseen.time) {
|
if (timestamp >= contact.lastseen.time) {
|
||||||
contact.lastseen.time = timestamp;
|
contact.lastseen.time = timestamp;
|
||||||
if (!presence.isEmpty() && presenceOverwrite) {
|
if (!presence.isEmpty() && presenceOverwrite) {
|
||||||
|
|
|
@ -2,36 +2,40 @@ package eu.siacs.conversations.parser;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
|
import eu.siacs.conversations.utils.Xmlns;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||||
|
|
||||||
public class IqParser extends AbstractParser implements OnIqPacketReceived {
|
public class IqParser extends AbstractParser implements OnIqPacketReceived {
|
||||||
|
|
||||||
public IqParser(XmppConnectionService service) {
|
public IqParser(final XmppConnectionService service) {
|
||||||
super(service);
|
super(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rosterItems(Account account, Element query) {
|
public void rosterItems(final Account account, final Element query) {
|
||||||
String version = query.getAttribute("ver");
|
final String version = query.getAttribute("ver");
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
account.getRoster().setVersion(version);
|
account.getRoster().setVersion(version);
|
||||||
}
|
}
|
||||||
for (Element item : query.getChildren()) {
|
for (final Element item : query.getChildren()) {
|
||||||
if (item.getName().equals("item")) {
|
if (item.getName().equals("item")) {
|
||||||
final Jid jid = item.getAttributeAsJid("jid");
|
final Jid jid = item.getAttributeAsJid("jid");
|
||||||
if (jid == null) {
|
if (jid == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String name = item.getAttribute("name");
|
final String name = item.getAttribute("name");
|
||||||
String subscription = item.getAttribute("subscription");
|
final String subscription = item.getAttribute("subscription");
|
||||||
Contact contact = account.getRoster().getContact(jid);
|
final Contact contact = account.getRoster().getContact(jid);
|
||||||
if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
|
if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
|
||||||
contact.setServerName(name);
|
contact.setServerName(name);
|
||||||
contact.parseGroupsFromElement(item);
|
contact.parseGroupsFromElement(item);
|
||||||
|
@ -54,13 +58,13 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
|
||||||
mXmppConnectionService.updateRosterUi();
|
mXmppConnectionService.updateRosterUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String avatarData(IqPacket packet) {
|
public String avatarData(final IqPacket packet) {
|
||||||
Element pubsub = packet.findChild("pubsub",
|
final Element pubsub = packet.findChild("pubsub",
|
||||||
"http://jabber.org/protocol/pubsub");
|
"http://jabber.org/protocol/pubsub");
|
||||||
if (pubsub == null) {
|
if (pubsub == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Element items = pubsub.findChild("items");
|
final Element items = pubsub.findChild("items");
|
||||||
if (items == null) {
|
if (items == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -68,13 +72,76 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
if (packet.hasChild("query", "jabber:iq:roster")) {
|
if (packet.hasChild("query", "jabber:iq:roster")) {
|
||||||
final Jid from = packet.getFrom();
|
final Jid from = packet.getFrom();
|
||||||
if ((from == null) || (from.equals(account.getJid().toBareJid()))) {
|
if ((from == null) || (from.equals(account.getJid().toBareJid()))) {
|
||||||
Element query = packet.findChild("query");
|
final Element query = packet.findChild("query");
|
||||||
this.rosterItems(account, query);
|
this.rosterItems(account, query);
|
||||||
}
|
}
|
||||||
|
} else if (packet.hasChild("block", Xmlns.BLOCKING) || packet.hasChild("blocklist", Xmlns.BLOCKING)) {
|
||||||
|
// Only accept block list changes from the server.
|
||||||
|
// The server should probably prevent other people from faking a blocklist push,
|
||||||
|
// but just in case let's prevent it client side as well.
|
||||||
|
final Jid from = packet.getFrom();
|
||||||
|
if (from == null || from.equals(account.getServer()) || from.equals(account.getJid().toBareJid())) {
|
||||||
|
Log.d(Config.LOGTAG, "Received blocklist update from server");
|
||||||
|
final Element blocklist = packet.findChild("blocklist", Xmlns.BLOCKING);
|
||||||
|
final Element block = packet.findChild("block", Xmlns.BLOCKING);
|
||||||
|
final Collection<Element> items = blocklist != null ? blocklist.getChildren() :
|
||||||
|
(block != null ? block.getChildren() : null);
|
||||||
|
// If this is a response to a blocklist query, clear the block list and replace with the new one.
|
||||||
|
// Otherwise, just update the existing blocklist.
|
||||||
|
if (packet.getType() == IqPacket.TYPE_RESULT) {
|
||||||
|
account.clearBlocklist();
|
||||||
|
}
|
||||||
|
if (items != null) {
|
||||||
|
final Collection<Jid> jids = new ArrayList<>(items.size());
|
||||||
|
// Create a collection of Jids from the packet
|
||||||
|
for (final Element item : items) {
|
||||||
|
if (item.getName().equals("item")) {
|
||||||
|
final Jid jid = item.getAttributeAsJid("jid");
|
||||||
|
if (jid != null) {
|
||||||
|
jids.add(jid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
account.getBlocklist().addAll(jids);
|
||||||
|
}
|
||||||
|
// Update the UI
|
||||||
|
mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED);
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, "Received blocklist update from invalid jid: " + from.toString());
|
||||||
|
}
|
||||||
|
} else if (packet.hasChild("unblock", Xmlns.BLOCKING)) {
|
||||||
|
final Jid from = packet.getFrom();
|
||||||
|
if ((from == null || from.equals(account.getServer()) || from.equals(account.getJid().toBareJid())) &&
|
||||||
|
packet.getType() == IqPacket.TYPE_SET) {
|
||||||
|
Log.d(Config.LOGTAG, "Received unblock update from server");
|
||||||
|
final Collection<Element> items = packet.getChildren().get(0).getChildren();
|
||||||
|
if (items.size() == 0) {
|
||||||
|
// No children to unblock == unblock all
|
||||||
|
account.getBlocklist().clear();
|
||||||
|
} else {
|
||||||
|
final Collection<Jid> jids = new ArrayList<>(items.size());
|
||||||
|
for (final Element item : items) {
|
||||||
|
if (item.getName().equals("item")) {
|
||||||
|
final Jid jid = item.getAttributeAsJid("jid");
|
||||||
|
if (jid != null) {
|
||||||
|
jids.add(jid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
account.getBlocklist().removeAll(jids);
|
||||||
|
mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.UNBLOCKED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (packet.getType() == IqPacket.TYPE_SET) {
|
||||||
|
Log.d(Config.LOGTAG, "Received unblock update from invalid jid " + from.toString());
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, "Received unblock update with invalid type " + packet.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (packet.getFrom() == null) {
|
if (packet.getFrom() == null) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": received iq with invalid from "+packet.toString());
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": received iq with invalid from "+packet.toString());
|
||||||
|
@ -82,24 +149,24 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
|
||||||
} else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
|
} else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
|
||||||
|| packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
|
|| packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
|
||||||
mXmppConnectionService.getJingleConnectionManager()
|
mXmppConnectionService.getJingleConnectionManager()
|
||||||
.deliverIbbPacket(account, packet);
|
.deliverIbbPacket(account, packet);
|
||||||
} else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
|
} else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
|
||||||
IqPacket response = mXmppConnectionService.getIqGenerator()
|
final IqPacket response = mXmppConnectionService.getIqGenerator()
|
||||||
.discoResponse(packet);
|
.discoResponse(packet);
|
||||||
account.getXmppConnection().sendIqPacket(response, null);
|
account.getXmppConnection().sendIqPacket(response, null);
|
||||||
} else if (packet.hasChild("ping", "urn:xmpp:ping")) {
|
} else if (packet.hasChild("ping", "urn:xmpp:ping")) {
|
||||||
IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
|
final IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
|
||||||
mXmppConnectionService.sendIqPacket(account, response, null);
|
mXmppConnectionService.sendIqPacket(account, response, null);
|
||||||
} else {
|
} else {
|
||||||
if ((packet.getType() == IqPacket.TYPE_GET)
|
if ((packet.getType() == IqPacket.TYPE_GET)
|
||||||
|| (packet.getType() == IqPacket.TYPE_SET)) {
|
|| (packet.getType() == IqPacket.TYPE_SET)) {
|
||||||
IqPacket response = packet.generateRespone(IqPacket.TYPE_ERROR);
|
final IqPacket response = packet.generateRespone(IqPacket.TYPE_ERROR);
|
||||||
Element error = response.addChild("error");
|
final Element error = response.addChild("error");
|
||||||
error.setAttribute("type", "cancel");
|
error.setAttribute("type", "cancel");
|
||||||
error.addChild("feature-not-implemented",
|
error.addChild("feature-not-implemented",
|
||||||
"urn:ietf:params:xml:ns:xmpp-stanzas");
|
"urn:ietf:params:xml:ns:xmpp-stanzas");
|
||||||
account.getXmppConnection().sendIqPacket(response, null);
|
account.getXmppConnection().sendIqPacket(response, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,9 +228,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateConversation(Conversation conversation) {
|
public void updateConversation(final Conversation conversation) {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
final SQLiteDatabase db = this.getWritableDatabase();
|
||||||
String[] args = { conversation.getUuid() };
|
final String[] args = { conversation.getUuid() };
|
||||||
db.update(Conversation.TABLENAME, conversation.getContentValues(),
|
db.update(Conversation.TABLENAME, conversation.getContentValues(),
|
||||||
Conversation.UUID + "=?", args);
|
Conversation.UUID + "=?", args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
public Query(Conversation conversation, long start, long end) {
|
public Query(Conversation conversation, long start, long end) {
|
||||||
this(conversation.getAccount(), start, end);
|
this(conversation.getAccount(), start, end);
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
this.with = conversation.getContactJid().toBareJid();
|
this.with = conversation.getJid().toBareJid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Query(Conversation conversation, long start, long end, PagingOrder order) {
|
public Query(Conversation conversation, long start, long end, PagingOrder order) {
|
||||||
|
|
|
@ -35,11 +35,13 @@ import org.openintents.openpgp.util.OpenPgpServiceConnection;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import de.duenndns.ssl.MemorizingTrustManager;
|
import de.duenndns.ssl.MemorizingTrustManager;
|
||||||
|
@ -47,11 +49,11 @@ import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.crypto.PgpEngine;
|
import eu.siacs.conversations.crypto.PgpEngine;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
import eu.siacs.conversations.entities.Blockable;
|
||||||
import eu.siacs.conversations.entities.Bookmark;
|
import eu.siacs.conversations.entities.Bookmark;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Downloadable;
|
import eu.siacs.conversations.entities.Downloadable;
|
||||||
import eu.siacs.conversations.entities.DownloadableFile;
|
|
||||||
import eu.siacs.conversations.entities.DownloadablePlaceholder;
|
import eu.siacs.conversations.entities.DownloadablePlaceholder;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.entities.MucOptions;
|
import eu.siacs.conversations.entities.MucOptions;
|
||||||
|
@ -77,7 +79,11 @@ import eu.siacs.conversations.xmpp.OnBindListener;
|
||||||
import eu.siacs.conversations.xmpp.OnContactStatusChanged;
|
import eu.siacs.conversations.xmpp.OnContactStatusChanged;
|
||||||
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
||||||
import eu.siacs.conversations.xmpp.OnMessageAcknowledged;
|
import eu.siacs.conversations.xmpp.OnMessageAcknowledged;
|
||||||
|
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
|
||||||
|
import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
|
||||||
import eu.siacs.conversations.xmpp.OnStatusChanged;
|
import eu.siacs.conversations.xmpp.OnStatusChanged;
|
||||||
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
|
import eu.siacs.conversations.xmpp.PacketReceived;
|
||||||
import eu.siacs.conversations.xmpp.XmppConnection;
|
import eu.siacs.conversations.xmpp.XmppConnection;
|
||||||
import eu.siacs.conversations.xmpp.forms.Data;
|
import eu.siacs.conversations.xmpp.forms.Data;
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
import eu.siacs.conversations.xmpp.forms.Field;
|
||||||
|
@ -93,9 +99,10 @@ import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
|
||||||
|
|
||||||
public class XmppConnectionService extends Service implements OnPhoneContactsLoadedListener {
|
public class XmppConnectionService extends Service implements OnPhoneContactsLoadedListener {
|
||||||
|
|
||||||
public static String ACTION_CLEAR_NOTIFICATION = "clear_notification";
|
public static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
|
||||||
private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
|
private static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
|
||||||
public static String ACTION_DISABLE_FOREGROUND = "disable_foreground";
|
public static final String ACTION_DISABLE_FOREGROUND = "disable_foreground";
|
||||||
|
|
||||||
private ContentObserver contactObserver = new ContentObserver(null) {
|
private ContentObserver contactObserver = new ContentObserver(null) {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
|
@ -129,13 +136,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
private MemorizingTrustManager mMemorizingTrustManager;
|
private MemorizingTrustManager mMemorizingTrustManager;
|
||||||
private NotificationService mNotificationService = new NotificationService(
|
private NotificationService mNotificationService = new NotificationService(
|
||||||
this);
|
this);
|
||||||
private MessageParser mMessageParser = new MessageParser(this);
|
private OnMessagePacketReceived mMessageParser = new MessageParser(this);
|
||||||
private PresenceParser mPresenceParser = new PresenceParser(this);
|
private OnPresencePacketReceived mPresenceParser = new PresenceParser(this);
|
||||||
private IqParser mIqParser = new IqParser(this);
|
private IqParser mIqParser = new IqParser(this);
|
||||||
private MessageGenerator mMessageGenerator = new MessageGenerator(this);
|
private MessageGenerator mMessageGenerator = new MessageGenerator(this);
|
||||||
private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this);
|
private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this);
|
||||||
private List<Account> accounts;
|
private List<Account> accounts;
|
||||||
private final CopyOnWriteArrayList<Conversation> conversations = new CopyOnWriteArrayList<Conversation>();
|
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
|
||||||
private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager(
|
private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager(
|
||||||
this);
|
this);
|
||||||
private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager(
|
private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager(
|
||||||
|
@ -208,6 +215,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
|
|
||||||
private int accountChangedListenerCount = 0;
|
private int accountChangedListenerCount = 0;
|
||||||
private OnRosterUpdate mOnRosterUpdate = null;
|
private OnRosterUpdate mOnRosterUpdate = null;
|
||||||
|
private OnUpdateBlocklist mOnUpdateBlocklist = null;
|
||||||
|
private int updateBlocklistListenerCount = 0;
|
||||||
private int rosterChangedListenerCount = 0;
|
private int rosterChangedListenerCount = 0;
|
||||||
private OnMucRosterUpdate mOnMucRosterUpdate = null;
|
private OnMucRosterUpdate mOnMucRosterUpdate = null;
|
||||||
private int mucRosterChangedListenerCount = 0;
|
private int mucRosterChangedListenerCount = 0;
|
||||||
|
@ -354,13 +363,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
DownloadableFile file = getFileBackend().copyImageToPrivateStorage(message, uri);
|
getFileBackend().copyImageToPrivateStorage(message, uri);
|
||||||
if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
|
if (conversation.getNextEncryption(forceEncryption()) == Message.ENCRYPTION_PGP) {
|
||||||
getPgpEngine().encrypt(message, callback);
|
getPgpEngine().encrypt(message, callback);
|
||||||
} else {
|
} else {
|
||||||
callback.success(message);
|
callback.success(message);
|
||||||
}
|
}
|
||||||
} catch (FileBackend.FileCopyException e) {
|
} catch (final FileBackend.FileCopyException e) {
|
||||||
callback.error(e.getResId(), message);
|
callback.error(e.getResId(), message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,11 +582,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmppConnection createConnection(Account account) {
|
public XmppConnection createConnection(final Account account) {
|
||||||
SharedPreferences sharedPref = getPreferences();
|
final SharedPreferences sharedPref = getPreferences();
|
||||||
account.setResource(sharedPref.getString("resource", "mobile")
|
account.setResource(sharedPref.getString("resource", "mobile")
|
||||||
.toLowerCase(Locale.getDefault()));
|
.toLowerCase(Locale.getDefault()));
|
||||||
XmppConnection connection = new XmppConnection(account, this);
|
final XmppConnection connection = new XmppConnection(account, this);
|
||||||
connection.setOnMessagePacketReceivedListener(this.mMessageParser);
|
connection.setOnMessagePacketReceivedListener(this.mMessageParser);
|
||||||
connection.setOnStatusChangedListener(this.statusListener);
|
connection.setOnStatusChangedListener(this.statusListener);
|
||||||
connection.setOnPresencePacketReceivedListener(this.mPresenceParser);
|
connection.setOnPresencePacketReceivedListener(this.mPresenceParser);
|
||||||
|
@ -589,10 +598,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(Message message) {
|
public void sendMessage(final Message message) {
|
||||||
Account account = message.getConversation().getAccount();
|
final Account account = message.getConversation().getAccount();
|
||||||
account.deactivateGracePeriod();
|
account.deactivateGracePeriod();
|
||||||
Conversation conv = message.getConversation();
|
final Conversation conv = message.getConversation();
|
||||||
MessagePacket packet = null;
|
MessagePacket packet = null;
|
||||||
boolean saveInDb = true;
|
boolean saveInDb = true;
|
||||||
boolean send = false;
|
boolean send = false;
|
||||||
|
@ -694,7 +703,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
updateConversationUi();
|
updateConversationUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendUnsentMessages(Conversation conversation) {
|
private void sendUnsentMessages(final Conversation conversation) {
|
||||||
conversation.findWaitingMessages(new Conversation.OnMessageFound() {
|
conversation.findWaitingMessages(new Conversation.OnMessageFound() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -704,7 +713,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resendMessage(Message message) {
|
private void resendMessage(final Message message) {
|
||||||
Account account = message.getConversation().getAccount();
|
Account account = message.getConversation().getAccount();
|
||||||
MessagePacket packet = null;
|
MessagePacket packet = null;
|
||||||
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
|
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
|
||||||
|
@ -731,7 +740,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
} else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
|
} else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
|
||||||
mJingleConnectionManager.createNewConnection(message);
|
mJingleConnectionManager.createNewConnection(message);
|
||||||
}
|
}
|
||||||
} catch (InvalidJidException e) {
|
} catch (final InvalidJidException ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -774,8 +783,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchRosterFromServer(Account account) {
|
public void fetchRosterFromServer(final Account account) {
|
||||||
IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
|
final IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
|
||||||
if (!"".equals(account.getRosterVersion())) {
|
if (!"".equals(account.getRosterVersion())) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
||||||
+ ": fetching roster version " + account.getRosterVersion());
|
+ ": fetching roster version " + account.getRosterVersion());
|
||||||
|
@ -789,8 +798,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(final Account account,
|
public void onIqPacketReceived(final Account account,
|
||||||
IqPacket packet) {
|
final IqPacket packet) {
|
||||||
Element query = packet.findChild("query");
|
final Element query = packet.findChild("query");
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
account.getRoster().markAllAsNotInRoster();
|
account.getRoster().markAllAsNotInRoster();
|
||||||
mIqParser.rosterItems(account, query);
|
mIqParser.rosterItems(account, query);
|
||||||
|
@ -799,22 +808,22 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchBookmarks(Account account) {
|
public void fetchBookmarks(final Account account) {
|
||||||
IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
|
final IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
|
||||||
Element query = iqPacket.query("jabber:iq:private");
|
final Element query = iqPacket.query("jabber:iq:private");
|
||||||
query.addChild("storage", "storage:bookmarks");
|
query.addChild("storage", "storage:bookmarks");
|
||||||
OnIqPacketReceived callback = new OnIqPacketReceived() {
|
final PacketReceived callback = new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
Element query = packet.query();
|
final Element query = packet.query();
|
||||||
List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
|
final List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
|
||||||
Element storage = query.findChild("storage",
|
final Element storage = query.findChild("storage",
|
||||||
"storage:bookmarks");
|
"storage:bookmarks");
|
||||||
if (storage != null) {
|
if (storage != null) {
|
||||||
for (Element item : storage.getChildren()) {
|
for (final Element item : storage.getChildren()) {
|
||||||
if (item.getName().equals("conference")) {
|
if (item.getName().equals("conference")) {
|
||||||
Bookmark bookmark = Bookmark.parse(item, account);
|
final Bookmark bookmark = Bookmark.parse(item, account);
|
||||||
bookmarks.add(bookmark);
|
bookmarks.add(bookmark);
|
||||||
Conversation conversation = find(bookmark);
|
Conversation conversation = find(bookmark);
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
|
@ -832,7 +841,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sendIqPacket(account, iqPacket, callback);
|
sendIqPacket(account, iqPacket, callback);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushBookmarks(Account account) {
|
public void pushBookmarks(Account account) {
|
||||||
|
@ -868,8 +876,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
final Contact contact = account.getRoster().getContact(jid);
|
final Contact contact = account.getRoster().getContact(jid);
|
||||||
String systemAccount = phoneContact.getInt("phoneid")
|
String systemAccount = phoneContact.getInt("phoneid")
|
||||||
+ "#"
|
+ "#"
|
||||||
+ phoneContact.getString("lookup");
|
+ phoneContact.getString("lookup");
|
||||||
contact.setSystemAccount(systemAccount);
|
contact.setSystemAccount(systemAccount);
|
||||||
contact.setPhotoUri(phoneContact.getString("photouri"));
|
contact.setPhotoUri(phoneContact.getString("photouri"));
|
||||||
getAvatarService().clear(contact);
|
getAvatarService().clear(contact);
|
||||||
|
@ -885,7 +893,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
|
|
||||||
private void initConversations() {
|
private void initConversations() {
|
||||||
synchronized (this.conversations) {
|
synchronized (this.conversations) {
|
||||||
Hashtable<String, Account> accountLookupTable = new Hashtable<>();
|
final Map<String, Account> accountLookupTable = new Hashtable<>();
|
||||||
for (Account account : this.accounts) {
|
for (Account account : this.accounts) {
|
||||||
accountLookupTable.put(account.getUuid(), account);
|
accountLookupTable.put(account.getUuid(), account);
|
||||||
}
|
}
|
||||||
|
@ -992,8 +1000,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return this.accounts;
|
return this.accounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Conversation find(List<Conversation> haystack, Contact contact) {
|
public Conversation find(final Iterable<Conversation> haystack, final Contact contact) {
|
||||||
for (Conversation conversation : haystack) {
|
for (final Conversation conversation : haystack) {
|
||||||
if (conversation.getContact() == contact) {
|
if (conversation.getContact() == contact) {
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
|
@ -1001,15 +1009,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Conversation find(final List<Conversation> haystack,
|
public Conversation find(final Iterable<Conversation> haystack, final Account account, final Jid jid) {
|
||||||
final Account account,
|
|
||||||
final Jid jid) {
|
|
||||||
if (jid == null ) {
|
if (jid == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (Conversation conversation : haystack) {
|
for (final Conversation conversation : haystack) {
|
||||||
if ((account == null || conversation.getAccount() == account)
|
if ((account == null || conversation.getAccount() == account)
|
||||||
&& (conversation.getContactJid().toBareJid().equals(jid.toBareJid()))) {
|
&& (conversation.getJid().toBareJid().equals(jid.toBareJid()))) {
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1177,7 +1183,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnRosterUpdateListener(OnRosterUpdate listener) {
|
public void setOnRosterUpdateListener(final OnRosterUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
switchToForeground();
|
switchToForeground();
|
||||||
|
@ -1202,6 +1208,31 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnUpdateBlocklistListener(final OnUpdateBlocklist listener) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (checkListeners()) {
|
||||||
|
switchToForeground();
|
||||||
|
}
|
||||||
|
this.mOnUpdateBlocklist = listener;
|
||||||
|
if (this.updateBlocklistListenerCount < 2) {
|
||||||
|
this.updateBlocklistListenerCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeOnUpdateBlocklistListener() {
|
||||||
|
synchronized (this) {
|
||||||
|
this.updateBlocklistListenerCount--;
|
||||||
|
if (this.updateBlocklistListenerCount <= 0) {
|
||||||
|
this.updateBlocklistListenerCount = 0;
|
||||||
|
this.mOnUpdateBlocklist = null;
|
||||||
|
if (checkListeners()) {
|
||||||
|
switchToBackground();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) {
|
public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (checkListeners()) {
|
if (checkListeners()) {
|
||||||
|
@ -1264,7 +1295,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
&& (conversation.getAccount() == account)) {
|
&& (conversation.getAccount() == account)) {
|
||||||
conversation.resetMucOptions();
|
conversation.resetMucOptions();
|
||||||
joinMuc(conversation);
|
joinMuc(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1293,7 +1324,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
packet.addChild("x", "jabber:x:signed").setContent(sig);
|
packet.addChild("x", "jabber:x:signed").setContent(sig);
|
||||||
}
|
}
|
||||||
sendPresencePacket(account, packet);
|
sendPresencePacket(account, packet);
|
||||||
if (!joinJid.equals(conversation.getContactJid())) {
|
if (!joinJid.equals(conversation.getJid())) {
|
||||||
conversation.setContactJid(joinJid);
|
conversation.setContactJid(joinJid);
|
||||||
databaseBackend.updateConversation(conversation);
|
databaseBackend.updateConversation(conversation);
|
||||||
}
|
}
|
||||||
|
@ -1369,14 +1400,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
account.pendingConferenceLeaves.remove(conversation);
|
account.pendingConferenceLeaves.remove(conversation);
|
||||||
if (account.getStatus() == Account.State.ONLINE) {
|
if (account.getStatus() == Account.State.ONLINE) {
|
||||||
PresencePacket packet = new PresencePacket();
|
PresencePacket packet = new PresencePacket();
|
||||||
packet.setTo(conversation.getContactJid());
|
packet.setTo(conversation.getJid());
|
||||||
packet.setFrom(conversation.getAccount().getJid());
|
packet.setFrom(conversation.getAccount().getJid());
|
||||||
packet.setAttribute("type", "unavailable");
|
packet.setAttribute("type", "unavailable");
|
||||||
sendPresencePacket(conversation.getAccount(), packet);
|
sendPresencePacket(conversation.getAccount(), packet);
|
||||||
conversation.getMucOptions().setOffline();
|
conversation.getMucOptions().setOffline();
|
||||||
conversation.deregisterWithBookmark();
|
conversation.deregisterWithBookmark();
|
||||||
Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid()
|
Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid()
|
||||||
+ ": leaving muc " + conversation.getContactJid());
|
+ ": leaving muc " + conversation.getJid());
|
||||||
} else {
|
} else {
|
||||||
account.pendingConferenceLeaves.add(conversation);
|
account.pendingConferenceLeaves.add(conversation);
|
||||||
}
|
}
|
||||||
|
@ -1401,7 +1432,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createAdhocConference(final Account account, final List<Jid> jids, final UiCallback<Conversation> callback) {
|
public void createAdhocConference(final Account account, final Iterable<Jid> jids, final UiCallback<Conversation> callback) {
|
||||||
Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": creating adhoc conference with "+ jids.toString());
|
Log.d(Config.LOGTAG,account.getJid().toBareJid().toString()+": creating adhoc conference with "+ jids.toString());
|
||||||
if (account.getStatus() == Account.State.ONLINE) {
|
if (account.getStatus() == Account.State.ONLINE) {
|
||||||
try {
|
try {
|
||||||
|
@ -1454,7 +1485,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
|
|
||||||
public void pushConferenceConfiguration(final Conversation conversation,final Bundle options, final OnConferenceOptionsPushed callback) {
|
public void pushConferenceConfiguration(final Conversation conversation,final Bundle options, final OnConferenceOptionsPushed callback) {
|
||||||
IqPacket request = new IqPacket(IqPacket.TYPE_GET);
|
IqPacket request = new IqPacket(IqPacket.TYPE_GET);
|
||||||
request.setTo(conversation.getContactJid().toBareJid());
|
request.setTo(conversation.getJid().toBareJid());
|
||||||
request.query("http://jabber.org/protocol/muc#owner");
|
request.query("http://jabber.org/protocol/muc#owner");
|
||||||
sendIqPacket(conversation.getAccount(),request,new OnIqPacketReceived() {
|
sendIqPacket(conversation.getAccount(),request,new OnIqPacketReceived() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1468,7 +1499,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
data.submit();
|
data.submit();
|
||||||
IqPacket set = new IqPacket(IqPacket.TYPE_SET);
|
IqPacket set = new IqPacket(IqPacket.TYPE_SET);
|
||||||
set.setTo(conversation.getContactJid().toBareJid());
|
set.setTo(conversation.getJid().toBareJid());
|
||||||
set.query("http://jabber.org/protocol/muc#owner").addChild(data);
|
set.query("http://jabber.org/protocol/muc#owner").addChild(data);
|
||||||
sendIqPacket(account, set, new OnIqPacketReceived() {
|
sendIqPacket(account, set, new OnIqPacketReceived() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1506,7 +1537,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
if (conversation.endOtrIfNeeded()) {
|
if (conversation.endOtrIfNeeded()) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
||||||
+ ": ended otr session with "
|
+ ": ended otr session with "
|
||||||
+ conversation.getContactJid());
|
+ conversation.getJid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1552,8 +1583,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
final Session otrSession = conversation.getOtrSession();
|
final Session otrSession = conversation.getOtrSession();
|
||||||
Log.d(Config.LOGTAG,
|
Log.d(Config.LOGTAG,
|
||||||
account.getJid().toBareJid() + " otr session established with "
|
account.getJid().toBareJid() + " otr session established with "
|
||||||
+ conversation.getContactJid() + "/"
|
+ conversation.getJid() + "/"
|
||||||
+ otrSession.getSessionID().getUserID());
|
+ otrSession.getSessionID().getUserID());
|
||||||
conversation.findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() {
|
conversation.findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1698,7 +1729,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket result) {
|
public void onIqPacketReceived(Account account, IqPacket result) {
|
||||||
final String ERROR = account.getJid().toBareJid()
|
final String ERROR = account.getJid().toBareJid()
|
||||||
+ ": fetching avatar for " + avatar.owner + " failed ";
|
+ ": fetching avatar for " + avatar.owner + " failed ";
|
||||||
if (result.getType() == IqPacket.TYPE_RESULT) {
|
if (result.getType() == IqPacket.TYPE_RESULT) {
|
||||||
avatar.image = mIqParser.avatarData(result);
|
avatar.image = mIqParser.avatarData(result);
|
||||||
if (avatar.image != null) {
|
if (avatar.image != null) {
|
||||||
|
@ -1712,7 +1743,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
updateAccountUi();
|
updateAccountUi();
|
||||||
} else {
|
} else {
|
||||||
Contact contact = account.getRoster()
|
Contact contact = account.getRoster()
|
||||||
.getContact(avatar.owner);
|
.getContact(avatar.owner);
|
||||||
contact.setAvatar(avatar.getFilename());
|
contact.setAvatar(avatar.getFilename());
|
||||||
getAvatarService().clear(contact);
|
getAvatarService().clear(contact);
|
||||||
updateConversationUi();
|
updateConversationUi();
|
||||||
|
@ -1848,7 +1879,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
for (Conversation conversation : getConversations()) {
|
for (Conversation conversation : getConversations()) {
|
||||||
if (conversation.getContactJid().equals(recipient)
|
if (conversation.getJid().equals(recipient)
|
||||||
&& conversation.getAccount().equals(account)) {
|
&& conversation.getAccount().equals(account)) {
|
||||||
return markMessage(conversation, uuid, status);
|
return markMessage(conversation, uuid, status);
|
||||||
}
|
}
|
||||||
|
@ -1922,6 +1953,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateBlocklistUi(final OnUpdateBlocklist.Status status) {
|
||||||
|
if (mOnUpdateBlocklist != null) {
|
||||||
|
mOnUpdateBlocklist.OnUpdateBlocklist(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void updateMucRosterUi() {
|
public void updateMucRosterUi() {
|
||||||
if (mOnMucRosterUpdate != null) {
|
if (mOnMucRosterUpdate != null) {
|
||||||
mOnMucRosterUpdate.onMucRosterUpdate();
|
mOnMucRosterUpdate.onMucRosterUpdate();
|
||||||
|
@ -2034,9 +2071,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendIqPacket(Account account, IqPacket packet,
|
public void sendIqPacket(final Account account, final IqPacket packet, final PacketReceived callback) {
|
||||||
OnIqPacketReceived callback) {
|
final XmppConnection connection = account.getXmppConnection();
|
||||||
XmppConnection connection = account.getXmppConnection();
|
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
connection.sendIqPacket(packet, callback);
|
connection.sendIqPacket(packet, callback);
|
||||||
}
|
}
|
||||||
|
@ -2054,6 +2090,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return this.mIqGenerator;
|
return this.mIqGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IqParser getIqParser() { return this.mIqParser; }
|
||||||
|
|
||||||
public JingleConnectionManager getJingleConnectionManager() {
|
public JingleConnectionManager getJingleConnectionManager() {
|
||||||
return this.mJingleConnectionManager;
|
return this.mJingleConnectionManager;
|
||||||
}
|
}
|
||||||
|
@ -2083,8 +2121,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return this.mHttpConnectionManager;
|
return this.mHttpConnectionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resendFailedMessages(Message message) {
|
public void resendFailedMessages(final Message message) {
|
||||||
List<Message> messages = new ArrayList<>();
|
final Collection<Message> messages = new ArrayList<>();
|
||||||
Message current = message;
|
Message current = message;
|
||||||
while (current.getStatus() == Message.STATUS_SEND_FAILED) {
|
while (current.getStatus() == Message.STATUS_SEND_FAILED) {
|
||||||
messages.add(current);
|
messages.add(current);
|
||||||
|
@ -2094,7 +2132,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Message msg : messages) {
|
for (final Message msg : messages) {
|
||||||
markMessage(msg, Message.STATUS_WAITING);
|
markMessage(msg, Message.STATUS_WAITING);
|
||||||
this.resendMessage(msg);
|
this.resendMessage(msg);
|
||||||
}
|
}
|
||||||
|
@ -2136,4 +2174,35 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return XmppConnectionService.this;
|
return XmppConnectionService.this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendBlockRequest(final Blockable blockable) {
|
||||||
|
if (blockable != null && blockable.getBlockedJid() != null) {
|
||||||
|
final Jid jid = blockable.getBlockedJid();
|
||||||
|
this.sendIqPacket(blockable.getAccount(), getIqGenerator().generateSetBlockRequest(jid), new OnIqPacketReceived() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
|
if (packet.getType() == IqPacket.TYPE_RESULT) {
|
||||||
|
account.getBlocklist().add(jid);
|
||||||
|
updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendUnblockRequest(final Blockable blockable) {
|
||||||
|
if (blockable != null && blockable.getJid() != null) {
|
||||||
|
final Jid jid = blockable.getBlockedJid();
|
||||||
|
this.sendIqPacket(blockable.getAccount(), getIqGenerator().generateSetUnblockRequest(jid), new OnIqPacketReceived() {
|
||||||
|
@Override
|
||||||
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
|
if (packet.getType() == IqPacket.TYPE_RESULT) {
|
||||||
|
account.getBlocklist().remove(jid);
|
||||||
|
updateBlocklistUi(OnUpdateBlocklist.Status.UNBLOCKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.entities.ListItem;
|
||||||
|
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
|
||||||
|
|
||||||
|
public abstract class AbstractSearchableListItemActivity extends XmppActivity {
|
||||||
|
private ListView mListView;
|
||||||
|
private final List<ListItem> listItems = new ArrayList<>();
|
||||||
|
private ArrayAdapter<ListItem> mListItemsAdapter;
|
||||||
|
|
||||||
|
private EditText mSearchEditText;
|
||||||
|
|
||||||
|
private final MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemActionExpand(final MenuItem item) {
|
||||||
|
mSearchEditText.post(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mSearchEditText.requestFocus();
|
||||||
|
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(mSearchEditText,
|
||||||
|
InputMethodManager.SHOW_IMPLICIT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemActionCollapse(final MenuItem item) {
|
||||||
|
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(),
|
||||||
|
InputMethodManager.HIDE_IMPLICIT_ONLY);
|
||||||
|
mSearchEditText.setText("");
|
||||||
|
filterContacts();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final TextWatcher mSearchTextWatcher = new TextWatcher() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(final Editable editable) {
|
||||||
|
filterContacts(editable.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(final CharSequence s, final int start, final int count,
|
||||||
|
final int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(final CharSequence s, final int start, final int before,
|
||||||
|
final int count) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public ListView getListView() {
|
||||||
|
return mListView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ListItem> getListItems() {
|
||||||
|
return listItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditText getSearchEditText() {
|
||||||
|
return mSearchEditText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayAdapter<ListItem> getListItemAdapter() {
|
||||||
|
return mListItemsAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_choose_contact);
|
||||||
|
mListView = (ListView) findViewById(R.id.choose_contact_list);
|
||||||
|
mListView.setFastScrollEnabled(true);
|
||||||
|
mListItemsAdapter = new ListItemAdapter(this, listItems);
|
||||||
|
mListView.setAdapter(mListItemsAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.choose_contact, menu);
|
||||||
|
final MenuItem menuSearchView = menu.findItem(R.id.action_search);
|
||||||
|
final View mSearchView = menuSearchView.getActionView();
|
||||||
|
mSearchEditText = (EditText) mSearchView
|
||||||
|
.findViewById(R.id.search_field);
|
||||||
|
mSearchEditText.addTextChangedListener(mSearchTextWatcher);
|
||||||
|
menuSearchView.setOnActionExpandListener(mOnActionExpandListener);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void filterContacts() {
|
||||||
|
filterContacts(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void filterContacts(final String needle);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void onBackendConnected() {
|
||||||
|
filterContacts();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.entities.Blockable;
|
||||||
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
|
|
||||||
|
public final class BlockContactDialog {
|
||||||
|
public static void show(final Context context,
|
||||||
|
final XmppConnectionService xmppConnectionService,
|
||||||
|
final Blockable blockable) {
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
final boolean isBlocked = blockable.isBlocked();
|
||||||
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
|
|
||||||
|
if (blockable.getJid().isDomainJid() || blockable.getAccount().isBlocked(blockable.getJid().toDomainJid())) {
|
||||||
|
builder.setTitle(isBlocked ? R.string.action_unblock_domain : R.string.action_block_domain);
|
||||||
|
builder.setMessage(context.getResources().getString(isBlocked ? R.string.unblock_domain_text : R.string.block_domain_text,
|
||||||
|
blockable.getJid().toDomainJid()));
|
||||||
|
} else {
|
||||||
|
builder.setTitle(isBlocked ? R.string.action_unblock_contact : R.string.action_block_contact);
|
||||||
|
builder.setMessage(context.getResources().getString(isBlocked ? R.string.unblock_contact_text : R.string.block_contact_text,
|
||||||
|
blockable.getJid().toBareJid()));
|
||||||
|
}
|
||||||
|
builder.setPositiveButton(isBlocked ? R.string.unblock : R.string.block, new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(final DialogInterface dialog, final int which) {
|
||||||
|
if (isBlocked) {
|
||||||
|
xmppConnectionService.sendUnblockRequest(blockable);
|
||||||
|
} else {
|
||||||
|
xmppConnectionService.sendBlockRequest(blockable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.create().show();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
import eu.siacs.conversations.entities.Contact;
|
||||||
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
|
public class BlocklistActivity extends AbstractSearchableListItemActivity implements OnUpdateBlocklist {
|
||||||
|
|
||||||
|
private Account account = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onItemLongClick(final AdapterView<?> parent,
|
||||||
|
final View view,
|
||||||
|
final int position,
|
||||||
|
final long id) {
|
||||||
|
BlockContactDialog.show(parent.getContext(), xmppConnectionService,(Contact) getListItems().get(position));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackendConnected() {
|
||||||
|
for (final Account account : xmppConnectionService.getAccounts()) {
|
||||||
|
if (account.getJid().toString().equals(getIntent().getStringExtra("account"))) {
|
||||||
|
this.account = account;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterContacts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void filterContacts(final String needle) {
|
||||||
|
getListItems().clear();
|
||||||
|
if (account != null) {
|
||||||
|
for (final Jid jid : account.getBlocklist()) {
|
||||||
|
final Contact contact = account.getRoster().getContact(jid);
|
||||||
|
if (contact.match(needle) && contact.isBlocked()) {
|
||||||
|
getListItems().add(contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(getListItems());
|
||||||
|
}
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getListItemAdapter().notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void OnUpdateBlocklist(final OnUpdateBlocklist.Status status) {
|
||||||
|
final Editable editable = getSearchEditText().getText();
|
||||||
|
if (editable != null) {
|
||||||
|
filterContacts(editable.toString());
|
||||||
|
} else {
|
||||||
|
filterContacts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,101 +1,33 @@
|
||||||
package eu.siacs.conversations.ui;
|
package eu.siacs.conversations.ui;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.EditText;
|
import java.util.Collections;
|
||||||
import android.widget.ListView;
|
|
||||||
import eu.siacs.conversations.R;
|
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.ListItem;
|
import eu.siacs.conversations.entities.ListItem;
|
||||||
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
|
|
||||||
|
|
||||||
public class ChooseContactActivity extends XmppActivity {
|
|
||||||
|
|
||||||
private ListView mListView;
|
|
||||||
private ArrayList<ListItem> contacts = new ArrayList<>();
|
|
||||||
private ArrayAdapter<ListItem> mContactsAdapter;
|
|
||||||
|
|
||||||
private EditText mSearchEditText;
|
|
||||||
|
|
||||||
private TextWatcher mSearchTextWatcher = new TextWatcher() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable editable) {
|
|
||||||
filterContacts(editable.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count,
|
|
||||||
int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before,
|
|
||||||
int count) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemActionExpand(MenuItem item) {
|
|
||||||
mSearchEditText.post(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mSearchEditText.requestFocus();
|
|
||||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
||||||
imm.showSoftInput(mSearchEditText,
|
|
||||||
InputMethodManager.SHOW_IMPLICIT);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemActionCollapse(MenuItem item) {
|
|
||||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
||||||
imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(),
|
|
||||||
InputMethodManager.HIDE_IMPLICIT_ONLY);
|
|
||||||
mSearchEditText.setText("");
|
|
||||||
filterContacts(null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
public class ChooseContactActivity extends AbstractSearchableListItemActivity {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_choose_contact);
|
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
mListView = (ListView) findViewById(R.id.choose_contact_list);
|
|
||||||
mListView.setFastScrollEnabled(true);
|
|
||||||
mContactsAdapter = new ListItemAdapter(this, contacts);
|
|
||||||
mListView.setAdapter(mContactsAdapter);
|
|
||||||
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> arg0, View arg1,
|
public void onItemClick(final AdapterView<?> parent, final View view,
|
||||||
int position, long arg3) {
|
final int position, final long id) {
|
||||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(),
|
imm.hideSoftInputFromWindow(getSearchEditText().getWindowToken(),
|
||||||
InputMethodManager.HIDE_IMPLICIT_ONLY);
|
InputMethodManager.HIDE_IMPLICIT_ONLY);
|
||||||
Intent request = getIntent();
|
final Intent request = getIntent();
|
||||||
Intent data = new Intent();
|
final Intent data = new Intent();
|
||||||
ListItem mListItem = contacts.get(position);
|
final ListItem mListItem = getListItems().get(position);
|
||||||
data.putExtra("contact", mListItem.getJid().toString());
|
data.putExtra("contact", mListItem.getJid().toString());
|
||||||
String account = request.getStringExtra("account");
|
String account = request.getStringExtra("account");
|
||||||
if (account == null && mListItem instanceof Contact) {
|
if (account == null && mListItem instanceof Contact) {
|
||||||
|
@ -108,38 +40,21 @@ public class ChooseContactActivity extends XmppActivity {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void filterContacts(final String needle) {
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
getListItems().clear();
|
||||||
getMenuInflater().inflate(R.menu.choose_contact, menu);
|
for (final Account account : xmppConnectionService.getAccounts()) {
|
||||||
MenuItem menuSearchView = menu.findItem(R.id.action_search);
|
|
||||||
View mSearchView = menuSearchView.getActionView();
|
|
||||||
mSearchEditText = (EditText) mSearchView
|
|
||||||
.findViewById(R.id.search_field);
|
|
||||||
mSearchEditText.addTextChangedListener(mSearchTextWatcher);
|
|
||||||
menuSearchView.setOnActionExpandListener(mOnActionExpandListener);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void onBackendConnected() {
|
|
||||||
filterContacts(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void filterContacts(String needle) {
|
|
||||||
this.contacts.clear();
|
|
||||||
for (Account account : xmppConnectionService.getAccounts()) {
|
|
||||||
if (account.getStatus() != Account.State.DISABLED) {
|
if (account.getStatus() != Account.State.DISABLED) {
|
||||||
for (Contact contact : account.getRoster().getContacts()) {
|
for (final Contact contact : account.getRoster().getContacts()) {
|
||||||
if (contact.showInRoster() && contact.match(needle)) {
|
if (contact.showInRoster() && contact.match(needle)) {
|
||||||
this.contacts.add(contact);
|
getListItems().add(contact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(this.contacts);
|
Collections.sort(getListItems());
|
||||||
mContactsAdapter.notifyDataSetChanged();
|
getListItemAdapter().notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,8 +157,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
@Override
|
@Override
|
||||||
public void onValueEdited(String value) {
|
public void onValueEdited(String value) {
|
||||||
MessagePacket packet = xmppConnectionService
|
MessagePacket packet = xmppConnectionService
|
||||||
.getMessageGenerator().conferenceSubject(
|
.getMessageGenerator().conferenceSubject(
|
||||||
mConversation, value);
|
mConversation, value);
|
||||||
xmppConnectionService.sendMessagePacket(
|
xmppConnectionService.sendMessagePacket(
|
||||||
mConversation.getAccount(), packet);
|
mConversation.getAccount(), packet);
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
@Override
|
@Override
|
||||||
protected String getShareableUri() {
|
protected String getShareableUri() {
|
||||||
if (mConversation != null) {
|
if (mConversation != null) {
|
||||||
return "xmpp:" + mConversation.getContactJid().toBareJid().toString() + "?join";
|
return "xmpp:" + mConversation.getJid().toBareJid().toString() + "?join";
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
MenuItem menuItemSaveBookmark = menu.findItem(R.id.action_save_as_bookmark);
|
MenuItem menuItemSaveBookmark = menu.findItem(R.id.action_save_as_bookmark);
|
||||||
MenuItem menuItemDeleteBookmark = menu.findItem(R.id.action_delete_bookmark);
|
MenuItem menuItemDeleteBookmark = menu.findItem(R.id.action_delete_bookmark);
|
||||||
Account account = mConversation.getAccount();
|
Account account = mConversation.getAccount();
|
||||||
if (account.hasBookmarkFor(mConversation.getContactJid().toBareJid())) {
|
if (account.hasBookmarkFor(mConversation.getJid().toBareJid())) {
|
||||||
menuItemSaveBookmark.setVisible(false);
|
menuItemSaveBookmark.setVisible(false);
|
||||||
menuItemDeleteBookmark.setVisible(true);
|
menuItemDeleteBookmark.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -263,9 +263,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
|
|
||||||
protected void saveAsBookmark() {
|
protected void saveAsBookmark() {
|
||||||
Account account = mConversation.getAccount();
|
Account account = mConversation.getAccount();
|
||||||
Bookmark bookmark = new Bookmark(account, mConversation.getContactJid().toBareJid());
|
Bookmark bookmark = new Bookmark(account, mConversation.getJid().toBareJid());
|
||||||
if (!mConversation.getContactJid().isBareJid()) {
|
if (!mConversation.getJid().isBareJid()) {
|
||||||
bookmark.setNick(mConversation.getContactJid().getResourcepart());
|
bookmark.setNick(mConversation.getJid().getResourcepart());
|
||||||
}
|
}
|
||||||
bookmark.setAutojoin(true);
|
bookmark.setAutojoin(true);
|
||||||
account.getBookmarks().add(bookmark);
|
account.getBookmarks().add(bookmark);
|
||||||
|
@ -288,7 +288,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
}
|
}
|
||||||
if (uuid != null) {
|
if (uuid != null) {
|
||||||
this.mConversation = xmppConnectionService
|
this.mConversation = xmppConnectionService
|
||||||
.findConversationByUuid(uuid);
|
.findConversationByUuid(uuid);
|
||||||
if (this.mConversation != null) {
|
if (this.mConversation != null) {
|
||||||
populateView();
|
populateView();
|
||||||
}
|
}
|
||||||
|
@ -297,11 +297,11 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
|
|
||||||
private void populateView() {
|
private void populateView() {
|
||||||
mAccountJid.setText(getString(R.string.using_account, mConversation
|
mAccountJid.setText(getString(R.string.using_account, mConversation
|
||||||
.getAccount().getJid().toBareJid()));
|
.getAccount().getJid().toBareJid()));
|
||||||
mYourPhoto.setImageBitmap(avatarService().get(
|
mYourPhoto.setImageBitmap(avatarService().get(
|
||||||
mConversation.getAccount(), getPixel(48)));
|
mConversation.getAccount(), getPixel(48)));
|
||||||
setTitle(mConversation.getName());
|
setTitle(mConversation.getName());
|
||||||
mFullJid.setText(mConversation.getContactJid().toBareJid().toString());
|
mFullJid.setText(mConversation.getJid().toBareJid().toString());
|
||||||
mYourNick.setText(mConversation.getMucOptions().getActualNick());
|
mYourNick.setText(mConversation.getMucOptions().getActualNick());
|
||||||
mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
|
mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
|
||||||
if (mConversation.getMucOptions().online()) {
|
if (mConversation.getMucOptions().online()) {
|
||||||
|
@ -338,7 +338,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
registerForContextMenu(view);
|
registerForContextMenu(view);
|
||||||
view.setTag(user);
|
view.setTag(user);
|
||||||
TextView name = (TextView) view
|
TextView name = (TextView) view
|
||||||
.findViewById(R.id.contact_display_name);
|
.findViewById(R.id.contact_display_name);
|
||||||
TextView key = (TextView) view.findViewById(R.id.key);
|
TextView key = (TextView) view.findViewById(R.id.key);
|
||||||
TextView role = (TextView) view.findViewById(R.id.contact_jid);
|
TextView role = (TextView) view.findViewById(R.id.contact_jid);
|
||||||
if (user.getPgpKeyId() != 0) {
|
if (user.getPgpKeyId() != 0) {
|
||||||
|
|
|
@ -38,10 +38,11 @@ import eu.siacs.conversations.entities.ListItem;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
|
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
|
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
|
||||||
import eu.siacs.conversations.utils.UIHelper;
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
public class ContactDetailsActivity extends XmppActivity implements OnAccountUpdate, OnRosterUpdate {
|
public class ContactDetailsActivity extends XmppActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist {
|
||||||
public static final String ACTION_VIEW_CONTACT = "view_contact";
|
public static final String ACTION_VIEW_CONTACT = "view_contact";
|
||||||
|
|
||||||
private Contact contact;
|
private Contact contact;
|
||||||
|
@ -50,7 +51,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
ContactDetailsActivity.this.xmppConnectionService
|
ContactDetailsActivity.this.xmppConnectionService
|
||||||
.deleteContactOnServer(contact);
|
.deleteContactOnServer(contact);
|
||||||
ContactDetailsActivity.this.finish();
|
ContactDetailsActivity.this.finish();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -58,14 +59,14 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView,
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
boolean isChecked) {
|
boolean isChecked) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
if (contact
|
if (contact
|
||||||
.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
|
.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
|
||||||
xmppConnectionService.sendPresencePacket(contact
|
xmppConnectionService.sendPresencePacket(contact
|
||||||
.getAccount(),
|
.getAccount(),
|
||||||
xmppConnectionService.getPresenceGenerator()
|
xmppConnectionService.getPresenceGenerator()
|
||||||
.sendPresenceUpdatesTo(contact));
|
.sendPresenceUpdatesTo(contact));
|
||||||
} else {
|
} else {
|
||||||
contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
|
contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +74,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
|
contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
|
||||||
xmppConnectionService.sendPresencePacket(contact.getAccount(),
|
xmppConnectionService.sendPresencePacket(contact.getAccount(),
|
||||||
xmppConnectionService.getPresenceGenerator()
|
xmppConnectionService.getPresenceGenerator()
|
||||||
.stopPresenceUpdatesTo(contact));
|
.stopPresenceUpdatesTo(contact));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -81,15 +82,15 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView,
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
boolean isChecked) {
|
boolean isChecked) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
xmppConnectionService.sendPresencePacket(contact.getAccount(),
|
xmppConnectionService.sendPresencePacket(contact.getAccount(),
|
||||||
xmppConnectionService.getPresenceGenerator()
|
xmppConnectionService.getPresenceGenerator()
|
||||||
.requestPresenceUpdatesFrom(contact));
|
.requestPresenceUpdatesFrom(contact));
|
||||||
} else {
|
} else {
|
||||||
xmppConnectionService.sendPresencePacket(contact.getAccount(),
|
xmppConnectionService.sendPresencePacket(contact.getAccount(),
|
||||||
xmppConnectionService.getPresenceGenerator()
|
xmppConnectionService.getPresenceGenerator()
|
||||||
.stopPresenceUpdatesFrom(contact));
|
.stopPresenceUpdatesFrom(contact));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -127,7 +128,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
ContactDetailsActivity.this);
|
ContactDetailsActivity.this);
|
||||||
builder.setTitle(getString(R.string.action_add_phone_book));
|
builder.setTitle(getString(R.string.action_add_phone_book));
|
||||||
builder.setMessage(getString(R.string.add_phone_book_text,
|
builder.setMessage(getString(R.string.add_phone_book_text,
|
||||||
contact.getJid()));
|
contact.getJid()));
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
builder.setPositiveButton(getString(R.string.add), addToPhonebook);
|
builder.setPositiveButton(getString(R.string.add), addToPhonebook);
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
|
@ -166,7 +167,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
|
if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
|
||||||
try {
|
try {
|
||||||
|
@ -188,15 +189,17 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
badge = (QuickContactBadge) findViewById(R.id.details_contact_badge);
|
badge = (QuickContactBadge) findViewById(R.id.details_contact_badge);
|
||||||
keys = (LinearLayout) findViewById(R.id.details_contact_keys);
|
keys = (LinearLayout) findViewById(R.id.details_contact_keys);
|
||||||
tags = (LinearLayout) findViewById(R.id.tags);
|
tags = (LinearLayout) findViewById(R.id.tags);
|
||||||
getActionBar().setHomeButtonEnabled(true);
|
if (getActionBar() != null) {
|
||||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
getActionBar().setHomeButtonEnabled(true);
|
||||||
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
this.showDynamicTags = preferences.getBoolean("show_dynamic_tags",false);
|
this.showDynamicTags = preferences.getBoolean("show_dynamic_tags",false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem menuItem) {
|
public boolean onOptionsItemSelected(final MenuItem menuItem) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
switch (menuItem.getItemId()) {
|
switch (menuItem.getItemId()) {
|
||||||
|
@ -205,11 +208,11 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
break;
|
break;
|
||||||
case R.id.action_delete_contact:
|
case R.id.action_delete_contact:
|
||||||
builder.setTitle(getString(R.string.action_delete_contact))
|
builder.setTitle(getString(R.string.action_delete_contact))
|
||||||
.setMessage(
|
.setMessage(
|
||||||
getString(R.string.remove_contact_text,
|
getString(R.string.remove_contact_text,
|
||||||
contact.getJid()))
|
contact.getJid()))
|
||||||
.setPositiveButton(getString(R.string.delete),
|
.setPositiveButton(getString(R.string.delete),
|
||||||
removeFromRoster).create().show();
|
removeFromRoster).create().show();
|
||||||
break;
|
break;
|
||||||
case R.id.action_edit_contact:
|
case R.id.action_edit_contact:
|
||||||
if (contact.getSystemAccount() == null) {
|
if (contact.getSystemAccount() == null) {
|
||||||
|
@ -219,7 +222,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
public void onValueEdited(String value) {
|
public void onValueEdited(String value) {
|
||||||
contact.setServerName(value);
|
contact.setServerName(value);
|
||||||
ContactDetailsActivity.this.xmppConnectionService
|
ContactDetailsActivity.this.xmppConnectionService
|
||||||
.pushContactToServer(contact);
|
.pushContactToServer(contact);
|
||||||
populateView();
|
populateView();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -285,7 +288,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange);
|
receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange);
|
||||||
|
|
||||||
lastseen.setText(UIHelper.lastseen(getApplicationContext(),
|
lastseen.setText(UIHelper.lastseen(getApplicationContext(),
|
||||||
contact.lastseen.time));
|
contact.lastseen.time));
|
||||||
|
|
||||||
if (contact.getPresences().size() > 1) {
|
if (contact.getPresences().size() > 1) {
|
||||||
contactJidTv.setText(contact.getJid() + " ("
|
contactJidTv.setText(contact.getJid() + " ("
|
||||||
|
@ -294,7 +297,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
contactJidTv.setText(contact.getJid().toString());
|
contactJidTv.setText(contact.getJid().toString());
|
||||||
}
|
}
|
||||||
accountJidTv.setText(getString(R.string.using_account, contact
|
accountJidTv.setText(getString(R.string.using_account, contact
|
||||||
.getAccount().getJid().toBareJid()));
|
.getAccount().getJid().toBareJid()));
|
||||||
prepareContactBadge(badge, contact);
|
prepareContactBadge(badge, contact);
|
||||||
if (contact.getSystemAccount() == null) {
|
if (contact.getSystemAccount() == null) {
|
||||||
badge.setOnClickListener(onBadgeClick);
|
badge.setOnClickListener(onBadgeClick);
|
||||||
|
@ -309,7 +312,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
TextView key = (TextView) view.findViewById(R.id.key);
|
TextView key = (TextView) view.findViewById(R.id.key);
|
||||||
TextView keyType = (TextView) view.findViewById(R.id.key_type);
|
TextView keyType = (TextView) view.findViewById(R.id.key_type);
|
||||||
ImageButton remove = (ImageButton) view
|
ImageButton remove = (ImageButton) view
|
||||||
.findViewById(R.id.button_remove);
|
.findViewById(R.id.button_remove);
|
||||||
remove.setVisibility(View.VISIBLE);
|
remove.setVisibility(View.VISIBLE);
|
||||||
keyType.setText("OTR Fingerprint");
|
keyType.setText("OTR Fingerprint");
|
||||||
key.setText(otrFingerprint);
|
key.setText(otrFingerprint);
|
||||||
|
@ -334,7 +337,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
PgpEngine pgp = ContactDetailsActivity.this.xmppConnectionService
|
PgpEngine pgp = ContactDetailsActivity.this.xmppConnectionService
|
||||||
.getPgpEngine();
|
.getPgpEngine();
|
||||||
if (pgp != null) {
|
if (pgp != null) {
|
||||||
PendingIntent intent = pgp.getIntentForKey(contact);
|
PendingIntent intent = pgp.getIntentForKey(contact);
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
|
@ -363,8 +366,8 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
} else {
|
} else {
|
||||||
tags.setVisibility(View.VISIBLE);
|
tags.setVisibility(View.VISIBLE);
|
||||||
tags.removeAllViewsInLayout();
|
tags.removeAllViewsInLayout();
|
||||||
for(ListItem.Tag tag : tagList) {
|
for(final ListItem.Tag tag : tagList) {
|
||||||
TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag,tags,false);
|
final TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag,tags,false);
|
||||||
tv.setText(tag.getName());
|
tv.setText(tag.getName());
|
||||||
tv.setBackgroundColor(tag.getColor());
|
tv.setBackgroundColor(tag.getColor());
|
||||||
tags.addView(tv);
|
tags.addView(tv);
|
||||||
|
@ -406,7 +409,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
public void onBackendConnected() {
|
public void onBackendConnected() {
|
||||||
if ((accountJid != null) && (contactJid != null)) {
|
if ((accountJid != null) && (contactJid != null)) {
|
||||||
Account account = xmppConnectionService
|
Account account = xmppConnectionService
|
||||||
.findAccountByJid(accountJid);
|
.findAccountByJid(accountJid);
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -414,4 +417,15 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
||||||
populateView();
|
populateView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void OnUpdateBlocklist(final Status status) {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
populateView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import android.os.SystemClock;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.support.v4.widget.SlidingPaneLayout;
|
import android.support.v4.widget.SlidingPaneLayout;
|
||||||
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
|
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -32,6 +31,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
|
import eu.siacs.conversations.entities.Blockable;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
|
@ -40,9 +40,10 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat
|
||||||
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
|
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
|
||||||
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
|
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
|
||||||
import eu.siacs.conversations.utils.ExceptionHelper;
|
import eu.siacs.conversations.utils.ExceptionHelper;
|
||||||
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
|
|
||||||
public class ConversationActivity extends XmppActivity implements
|
public class ConversationActivity extends XmppActivity
|
||||||
OnAccountUpdate, OnConversationUpdate, OnRosterUpdate {
|
implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist {
|
||||||
|
|
||||||
public static final String VIEW_CONVERSATION = "viewConversation";
|
public static final String VIEW_CONVERSATION = "viewConversation";
|
||||||
public static final String CONVERSATION = "conversationUuid";
|
public static final String CONVERSATION = "conversationUuid";
|
||||||
|
@ -144,12 +145,12 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
if (savedInstanceState != null) {mOpenConverstaion = savedInstanceState.getString(
|
if (savedInstanceState != null) {mOpenConverstaion = savedInstanceState.getString(
|
||||||
STATE_OPEN_CONVERSATION, null);
|
STATE_OPEN_CONVERSATION, null);
|
||||||
mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true);
|
mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true);
|
||||||
String pending = savedInstanceState.getString(STATE_PENDING_URI, null);
|
String pending = savedInstanceState.getString(STATE_PENDING_URI, null);
|
||||||
if (pending != null) {
|
if (pending != null) {
|
||||||
mPendingImageUri = Uri.parse(pending);
|
mPendingImageUri = Uri.parse(pending);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentView(R.layout.fragment_conversations_overview);
|
setContentView(R.layout.fragment_conversations_overview);
|
||||||
|
@ -172,7 +173,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> arg0, View clickedView,
|
public void onItemClick(AdapterView<?> arg0, View clickedView,
|
||||||
int position, long arg3) {
|
int position, long arg3) {
|
||||||
if (getSelectedConversation() != conversationList.get(position)) {
|
if (getSelectedConversation() != conversationList.get(position)) {
|
||||||
setSelectedConversation(conversationList.get(position));
|
setSelectedConversation(conversationList.get(position));
|
||||||
ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
|
ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
|
||||||
|
@ -188,7 +189,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
|
SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView;
|
||||||
mSlidingPaneLayout.setParallaxDistance(150);
|
mSlidingPaneLayout.setParallaxDistance(150);
|
||||||
mSlidingPaneLayout
|
mSlidingPaneLayout
|
||||||
.setShadowResource(R.drawable.es_slidingpane_shadow);
|
.setShadowResource(R.drawable.es_slidingpane_shadow);
|
||||||
mSlidingPaneLayout.setSliderFadeColor(0);
|
mSlidingPaneLayout.setSliderFadeColor(0);
|
||||||
mSlidingPaneLayout.setPanelSlideListener(new PanelSlideListener() {
|
mSlidingPaneLayout.setPanelSlideListener(new PanelSlideListener() {
|
||||||
|
|
||||||
|
@ -199,7 +200,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
if (xmppConnectionServiceBound) {
|
if (xmppConnectionServiceBound) {
|
||||||
xmppConnectionService.getNotificationService()
|
xmppConnectionService.getNotificationService()
|
||||||
.setOpenConversation(null);
|
.setOpenConversation(null);
|
||||||
}
|
}
|
||||||
closeContextMenu();
|
closeContextMenu();
|
||||||
}
|
}
|
||||||
|
@ -244,7 +245,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
if (conversation.getMode() == Conversation.MODE_SINGLE || useSubjectToIdentifyConference()) {
|
if (conversation.getMode() == Conversation.MODE_SINGLE || useSubjectToIdentifyConference()) {
|
||||||
ab.setTitle(conversation.getName());
|
ab.setTitle(conversation.getName());
|
||||||
} else {
|
} else {
|
||||||
ab.setTitle(conversation.getContactJid().toBareJid().toString());
|
ab.setTitle(conversation.getJid().toBareJid().toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ab.setDisplayHomeAsUpEnabled(false);
|
ab.setDisplayHomeAsUpEnabled(false);
|
||||||
|
@ -269,17 +270,18 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.conversations, menu);
|
getMenuInflater().inflate(R.menu.conversations, menu);
|
||||||
MenuItem menuSecure = menu.findItem(R.id.action_security);
|
final MenuItem menuSecure = menu.findItem(R.id.action_security);
|
||||||
MenuItem menuArchive = menu.findItem(R.id.action_archive);
|
final MenuItem menuArchive = menu.findItem(R.id.action_archive);
|
||||||
MenuItem menuMucDetails = menu.findItem(R.id.action_muc_details);
|
final MenuItem menuMucDetails = menu.findItem(R.id.action_muc_details);
|
||||||
MenuItem menuContactDetails = menu
|
final MenuItem menuContactDetails = menu.findItem(R.id.action_contact_details);
|
||||||
.findItem(R.id.action_contact_details);
|
final MenuItem menuAttach = menu.findItem(R.id.action_attach_file);
|
||||||
MenuItem menuAttach = menu.findItem(R.id.action_attach_file);
|
final MenuItem menuClearHistory = menu.findItem(R.id.action_clear_history);
|
||||||
MenuItem menuClearHistory = menu.findItem(R.id.action_clear_history);
|
final MenuItem menuAdd = menu.findItem(R.id.action_add);
|
||||||
MenuItem menuAdd = menu.findItem(R.id.action_add);
|
final MenuItem menuInviteContact = menu.findItem(R.id.action_invite);
|
||||||
MenuItem menuInviteContact = menu.findItem(R.id.action_invite);
|
final MenuItem menuMute = menu.findItem(R.id.action_mute);
|
||||||
MenuItem menuMute = menu.findItem(R.id.action_mute);
|
final MenuItem menuUnmute = menu.findItem(R.id.action_unmute);
|
||||||
MenuItem menuUnmute = menu.findItem(R.id.action_unmute);
|
final MenuItem menuBlock = menu.findItem(R.id.action_block);
|
||||||
|
final MenuItem menuUnblock = menu.findItem(R.id.action_unblock);
|
||||||
|
|
||||||
if (isConversationsOverviewVisable()
|
if (isConversationsOverviewVisable()
|
||||||
&& isConversationsOverviewHideable()) {
|
&& isConversationsOverviewHideable()) {
|
||||||
|
@ -292,19 +294,32 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
menuClearHistory.setVisible(false);
|
menuClearHistory.setVisible(false);
|
||||||
menuMute.setVisible(false);
|
menuMute.setVisible(false);
|
||||||
menuUnmute.setVisible(false);
|
menuUnmute.setVisible(false);
|
||||||
|
menuBlock.setVisible(false);
|
||||||
|
menuUnblock.setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
menuAdd.setVisible(!isConversationsOverviewHideable());
|
menuAdd.setVisible(!isConversationsOverviewHideable());
|
||||||
if (this.getSelectedConversation() != null) {
|
if (this.getSelectedConversation() != null) {
|
||||||
if (this.getSelectedConversation().getLatestMessage()
|
if (this.getSelectedConversation().getLatestMessage()
|
||||||
.getEncryption() != Message.ENCRYPTION_NONE) {
|
.getEncryption() != Message.ENCRYPTION_NONE) {
|
||||||
menuSecure.setIcon(R.drawable.ic_action_secure);
|
menuSecure.setIcon(R.drawable.ic_action_secure);
|
||||||
}
|
}
|
||||||
if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
|
if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
|
||||||
menuContactDetails.setVisible(false);
|
menuContactDetails.setVisible(false);
|
||||||
menuAttach.setVisible(false);
|
menuAttach.setVisible(false);
|
||||||
|
menuBlock.setVisible(false);
|
||||||
|
menuUnblock.setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
menuMucDetails.setVisible(false);
|
menuMucDetails.setVisible(false);
|
||||||
menuInviteContact.setTitle(R.string.conference_with);
|
menuInviteContact.setTitle(R.string.conference_with);
|
||||||
|
if (this.getSelectedConversation().isBlocked()) {
|
||||||
|
menuBlock.setVisible(false);
|
||||||
|
} else {
|
||||||
|
menuUnblock.setVisible(false);
|
||||||
|
}
|
||||||
|
if (!this.getSelectedConversation().getAccount().getXmppConnection().getFeatures().blocking()) {
|
||||||
|
menuBlock.setVisible(false);
|
||||||
|
menuUnblock.setVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.getSelectedConversation().isMuted()) {
|
if (this.getSelectedConversation().isMuted()) {
|
||||||
menuMute.setVisible(false);
|
menuMute.setVisible(false);
|
||||||
|
@ -323,7 +338,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
public void onPresenceSelected() {
|
public void onPresenceSelected() {
|
||||||
if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO) {
|
if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO) {
|
||||||
mPendingImageUri = xmppConnectionService.getFileBackend()
|
mPendingImageUri = xmppConnectionService.getFileBackend()
|
||||||
.getTakePhotoUri();
|
.getTakePhotoUri();
|
||||||
Intent takePictureIntent = new Intent(
|
Intent takePictureIntent = new Intent(
|
||||||
MediaStore.ACTION_IMAGE_CAPTURE);
|
MediaStore.ACTION_IMAGE_CAPTURE);
|
||||||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
|
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
|
||||||
|
@ -364,7 +379,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void userInputRequried(PendingIntent pi,
|
public void userInputRequried(PendingIntent pi,
|
||||||
Contact contact) {
|
Contact contact) {
|
||||||
ConversationActivity.this.runIntent(pi,
|
ConversationActivity.this.runIntent(pi,
|
||||||
attachmentChoice);
|
attachmentChoice);
|
||||||
}
|
}
|
||||||
|
@ -381,18 +396,18 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
|
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
|
||||||
.findFragmentByTag("conversation");
|
.findFragmentByTag("conversation");
|
||||||
if (fragment != null) {
|
if (fragment != null) {
|
||||||
fragment.showNoPGPKeyDialog(false,
|
fragment.showNoPGPKeyDialog(false,
|
||||||
new OnClickListener() {
|
new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog,
|
public void onClick(DialogInterface dialog,
|
||||||
int which) {
|
int which) {
|
||||||
conversation
|
conversation
|
||||||
.setNextEncryption(Message.ENCRYPTION_NONE);
|
.setNextEncryption(Message.ENCRYPTION_NONE);
|
||||||
xmppConnectionService.databaseBackend
|
xmppConnectionService.databaseBackend
|
||||||
.updateConversation(conversation);
|
.updateConversation(conversation);
|
||||||
selectPresenceToAttachFile(attachmentChoice);
|
selectPresenceToAttachFile(attachmentChoice);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -402,7 +417,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
showInstallPgpDialog();
|
showInstallPgpDialog();
|
||||||
}
|
}
|
||||||
} else if (getSelectedConversation().getNextEncryption(
|
} else if (getSelectedConversation().getNextEncryption(
|
||||||
forceEncryption()) == Message.ENCRYPTION_NONE) {
|
forceEncryption()) == Message.ENCRYPTION_NONE) {
|
||||||
selectPresenceToAttachFile(attachmentChoice);
|
selectPresenceToAttachFile(attachmentChoice);
|
||||||
} else {
|
} else {
|
||||||
selectPresenceToAttachFile(attachmentChoice);
|
selectPresenceToAttachFile(attachmentChoice);
|
||||||
|
@ -410,7 +425,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
if (item.getItemId() == android.R.id.home) {
|
if (item.getItemId() == android.R.id.home) {
|
||||||
showConversationsOverview();
|
showConversationsOverview();
|
||||||
return true;
|
return true;
|
||||||
|
@ -455,6 +470,12 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
case R.id.action_unmute:
|
case R.id.action_unmute:
|
||||||
unmuteConversation(getSelectedConversation());
|
unmuteConversation(getSelectedConversation());
|
||||||
break;
|
break;
|
||||||
|
case R.id.action_block:
|
||||||
|
BlockContactDialog.show(this, xmppConnectionService, getSelectedConversation());
|
||||||
|
break;
|
||||||
|
case R.id.action_unblock:
|
||||||
|
BlockContactDialog.show(this, xmppConnectionService, getSelectedConversation());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +504,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
View dialogView = getLayoutInflater().inflate(
|
View dialogView = getLayoutInflater().inflate(
|
||||||
R.layout.dialog_clear_history, null);
|
R.layout.dialog_clear_history, null);
|
||||||
final CheckBox endConversationCheckBox = (CheckBox) dialogView
|
final CheckBox endConversationCheckBox = (CheckBox) dialogView
|
||||||
.findViewById(R.id.end_conversation_checkbox);
|
.findViewById(R.id.end_conversation_checkbox);
|
||||||
builder.setView(dialogView);
|
builder.setView(dialogView);
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
builder.setPositiveButton(getString(R.string.delete_messages),
|
builder.setPositiveButton(getString(R.string.delete_messages),
|
||||||
|
@ -511,24 +532,24 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
PopupMenu attachFilePopup = new PopupMenu(this, menuAttachFile);
|
PopupMenu attachFilePopup = new PopupMenu(this, menuAttachFile);
|
||||||
attachFilePopup.inflate(R.menu.attachment_choices);
|
attachFilePopup.inflate(R.menu.attachment_choices);
|
||||||
attachFilePopup
|
attachFilePopup
|
||||||
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
.setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.attach_choose_picture:
|
case R.id.attach_choose_picture:
|
||||||
attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
|
attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
|
||||||
break;
|
break;
|
||||||
case R.id.attach_take_picture:
|
case R.id.attach_take_picture:
|
||||||
attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
|
attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
|
||||||
break;
|
break;
|
||||||
case R.id.attach_record_voice:
|
case R.id.attach_record_voice:
|
||||||
attachFile(ATTACHMENT_CHOICE_CHOOSE_FILE);
|
attachFile(ATTACHMENT_CHOICE_CHOOSE_FILE);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
});
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
attachFilePopup.show();
|
attachFilePopup.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +560,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
}
|
}
|
||||||
PopupMenu popup = new PopupMenu(this, menuItemView);
|
PopupMenu popup = new PopupMenu(this, menuItemView);
|
||||||
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
|
final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
|
||||||
.findFragmentByTag("conversation");
|
.findFragmentByTag("conversation");
|
||||||
if (fragment != null) {
|
if (fragment != null) {
|
||||||
popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||||
|
|
||||||
|
@ -559,7 +580,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
if (conversation.getAccount().getKeys()
|
if (conversation.getAccount().getKeys()
|
||||||
.has("pgp_signature")) {
|
.has("pgp_signature")) {
|
||||||
conversation
|
conversation
|
||||||
.setNextEncryption(Message.ENCRYPTION_PGP);
|
.setNextEncryption(Message.ENCRYPTION_PGP);
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
} else {
|
} else {
|
||||||
announcePgp(conversation.getAccount(),
|
announcePgp(conversation.getAccount(),
|
||||||
|
@ -574,7 +595,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
xmppConnectionService.databaseBackend
|
xmppConnectionService.databaseBackend
|
||||||
.updateConversation(conversation);
|
.updateConversation(conversation);
|
||||||
fragment.updateChatMsgHint();
|
fragment.updateChatMsgHint();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -599,11 +620,11 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
break;
|
break;
|
||||||
case Message.ENCRYPTION_PGP:
|
case Message.ENCRYPTION_PGP:
|
||||||
popup.getMenu().findItem(R.id.encryption_choice_pgp)
|
popup.getMenu().findItem(R.id.encryption_choice_pgp)
|
||||||
.setChecked(true);
|
.setChecked(true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
popup.getMenu().findItem(R.id.encryption_choice_none)
|
popup.getMenu().findItem(R.id.encryption_choice_none)
|
||||||
.setChecked(true);
|
.setChecked(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
popup.show();
|
popup.show();
|
||||||
|
@ -619,17 +640,17 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
new OnClickListener() {
|
new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(final DialogInterface dialog, final int which) {
|
||||||
long till;
|
final long till;
|
||||||
if (durations[which] == -1) {
|
if (durations[which] == -1) {
|
||||||
till = Long.MAX_VALUE;
|
till = Long.MAX_VALUE;
|
||||||
} else {
|
} else {
|
||||||
till = SystemClock.elapsedRealtime()
|
till = SystemClock.elapsedRealtime()
|
||||||
+ (durations[which] * 1000);
|
+ (durations[which] * 1000);
|
||||||
}
|
}
|
||||||
conversation.setMutedTill(till);
|
conversation.setMutedTill(till);
|
||||||
ConversationActivity.this.xmppConnectionService.databaseBackend
|
ConversationActivity.this.xmppConnectionService.databaseBackend
|
||||||
.updateConversation(conversation);
|
.updateConversation(conversation);
|
||||||
updateConversationList();
|
updateConversationList();
|
||||||
ConversationActivity.this.mConversationFragment.updateMessages();
|
ConversationActivity.this.mConversationFragment.updateMessages();
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
|
@ -763,11 +784,11 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectConversationByUuid(String uuid) {
|
private void selectConversationByUuid(String uuid) {
|
||||||
for (Conversation aConversationList : conversationList) {
|
for (Conversation aConversationList : conversationList) {
|
||||||
if (aConversationList.getUuid().equals(uuid)) {
|
if (aConversationList.getUuid().equals(uuid)) {
|
||||||
setSelectedConversation(aConversationList);
|
setSelectedConversation(aConversationList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -778,7 +799,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode,
|
protected void onActivityResult(int requestCode, int resultCode,
|
||||||
final Intent data) {
|
final Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
if (requestCode == REQUEST_DECRYPT_PGP) {
|
if (requestCode == REQUEST_DECRYPT_PGP) {
|
||||||
|
@ -859,7 +880,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void userInputRequried(PendingIntent pi,
|
public void userInputRequried(PendingIntent pi,
|
||||||
Message object) {
|
Message object) {
|
||||||
hidePrepareFileToast();
|
hidePrepareFileToast();
|
||||||
ConversationActivity.this.runIntent(pi,
|
ConversationActivity.this.runIntent(pi,
|
||||||
ConversationActivity.REQUEST_SEND_PGP_IMAGE);
|
ConversationActivity.REQUEST_SEND_PGP_IMAGE);
|
||||||
|
@ -892,7 +913,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
|
|
||||||
public void updateConversationList() {
|
public void updateConversationList() {
|
||||||
xmppConnectionService
|
xmppConnectionService
|
||||||
.populateWithOrderedConversations(conversationList);
|
.populateWithOrderedConversations(conversationList);
|
||||||
listAdapter.notifyDataSetChanged();
|
listAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,7 +931,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void userInputRequried(PendingIntent pi,
|
public void userInputRequried(PendingIntent pi,
|
||||||
Message message) {
|
Message message) {
|
||||||
ConversationActivity.this.runIntent(pi,
|
ConversationActivity.this.runIntent(pi,
|
||||||
ConversationActivity.REQUEST_SEND_MESSAGE);
|
ConversationActivity.REQUEST_SEND_MESSAGE);
|
||||||
}
|
}
|
||||||
|
@ -962,7 +983,7 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
updateConversationList();
|
updateConversationList();
|
||||||
if (conversationList.size() == 0) {
|
if (conversationList.size() == 0) {
|
||||||
startActivity(new Intent(getApplicationContext(),
|
startActivity(new Intent(getApplicationContext(),
|
||||||
StartConversationActivity.class));
|
StartConversationActivity.class));
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
ConversationActivity.this.mConversationFragment.updateMessages();
|
ConversationActivity.this.mConversationFragment.updateMessages();
|
||||||
|
@ -975,12 +996,31 @@ public class ConversationActivity extends XmppActivity implements
|
||||||
public void onRosterUpdate() {
|
public void onRosterUpdate() {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
updateConversationList();
|
updateConversationList();
|
||||||
ConversationActivity.this.mConversationFragment.updateMessages();
|
ConversationActivity.this.mConversationFragment.updateMessages();
|
||||||
updateActionBarTitle();
|
updateActionBarTitle();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void OnUpdateBlocklist(Status status) {
|
||||||
|
invalidateOptionsMenu();
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ConversationActivity.this.mConversationFragment.updateMessages();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unblockConversation(final Blockable conversation) {
|
||||||
|
xmppConnectionService.sendUnblockRequest(conversation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void blockConversation(final Blockable conversation) {
|
||||||
|
xmppConnectionService.sendBlockRequest(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import android.content.Intent;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
import android.content.IntentSender.SendIntentException;
|
import android.content.IntentSender.SendIntentException;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
@ -39,7 +38,6 @@ import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.crypto.PgpEngine;
|
import eu.siacs.conversations.crypto.PgpEngine;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
@ -118,7 +116,7 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScroll(AbsListView view, int firstVisibleItem,
|
public void onScroll(AbsListView view, int firstVisibleItem,
|
||||||
int visibleItemCount, int totalItemCount) {
|
int visibleItemCount, int totalItemCount) {
|
||||||
synchronized (ConversationFragment.this.messageList) {
|
synchronized (ConversationFragment.this.messageList) {
|
||||||
if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) {
|
if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) {
|
||||||
long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent();
|
long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent();
|
||||||
|
@ -223,7 +221,7 @@ public class ConversationFragment extends Fragment {
|
||||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
||||||
InputMethodManager imm = (InputMethodManager) v.getContext()
|
InputMethodManager imm = (InputMethodManager) v.getContext()
|
||||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
||||||
sendMessage();
|
sendMessage();
|
||||||
return true;
|
return true;
|
||||||
|
@ -266,7 +264,7 @@ public class ConversationFragment extends Fragment {
|
||||||
}
|
}
|
||||||
Message message = new Message(conversation, mEditMessage.getText()
|
Message message = new Message(conversation, mEditMessage.getText()
|
||||||
.toString(), conversation.getNextEncryption(activity
|
.toString(), conversation.getNextEncryption(activity
|
||||||
.forceEncryption()));
|
.forceEncryption()));
|
||||||
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
||||||
if (conversation.getNextCounterpart() != null) {
|
if (conversation.getNextCounterpart() != null) {
|
||||||
message.setCounterpart(conversation.getNextCounterpart());
|
message.setCounterpart(conversation.getNextCounterpart());
|
||||||
|
@ -287,13 +285,13 @@ public class ConversationFragment extends Fragment {
|
||||||
if (conversation.getMode() == Conversation.MODE_MULTI
|
if (conversation.getMode() == Conversation.MODE_MULTI
|
||||||
&& conversation.getNextCounterpart() != null) {
|
&& conversation.getNextCounterpart() != null) {
|
||||||
this.mEditMessage.setHint(getString(
|
this.mEditMessage.setHint(getString(
|
||||||
R.string.send_private_message_to,
|
R.string.send_private_message_to,
|
||||||
conversation.getNextCounterpart().getResourcepart()));
|
conversation.getNextCounterpart().getResourcepart()));
|
||||||
} else {
|
} else {
|
||||||
switch (conversation.getNextEncryption(activity.forceEncryption())) {
|
switch (conversation.getNextEncryption(activity.forceEncryption())) {
|
||||||
case Message.ENCRYPTION_NONE:
|
case Message.ENCRYPTION_NONE:
|
||||||
mEditMessage
|
mEditMessage
|
||||||
.setHint(getString(R.string.send_plain_text_message));
|
.setHint(getString(R.string.send_plain_text_message));
|
||||||
break;
|
break;
|
||||||
case Message.ENCRYPTION_OTR:
|
case Message.ENCRYPTION_OTR:
|
||||||
mEditMessage.setHint(getString(R.string.send_otr_message));
|
mEditMessage.setHint(getString(R.string.send_otr_message));
|
||||||
|
@ -309,7 +307,7 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(final LayoutInflater inflater,
|
public View onCreateView(final LayoutInflater inflater,
|
||||||
ViewGroup container, Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
final View view = inflater.inflate(R.layout.fragment_conversation,
|
final View view = inflater.inflate(R.layout.fragment_conversation,
|
||||||
container, false);
|
container, false);
|
||||||
mEditMessage = (EditMessage) view.findViewById(R.id.textinput);
|
mEditMessage = (EditMessage) view.findViewById(R.id.textinput);
|
||||||
|
@ -342,49 +340,49 @@ public class ConversationFragment extends Fragment {
|
||||||
messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList);
|
messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList);
|
||||||
messageListAdapter.setOnContactPictureClicked(new OnContactPictureClicked() {
|
messageListAdapter.setOnContactPictureClicked(new OnContactPictureClicked() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactPictureClicked(Message message) {
|
public void onContactPictureClicked(Message message) {
|
||||||
if (message.getStatus() <= Message.STATUS_RECEIVED) {
|
if (message.getStatus() <= Message.STATUS_RECEIVED) {
|
||||||
if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
||||||
if (message.getCounterpart() != null) {
|
if (message.getCounterpart() != null) {
|
||||||
if (!message.getCounterpart().isBareJid()) {
|
if (!message.getCounterpart().isBareJid()) {
|
||||||
highlightInConference(message.getCounterpart().getResourcepart());
|
highlightInConference(message.getCounterpart().getResourcepart());
|
||||||
} else {
|
|
||||||
highlightInConference(message.getCounterpart().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Contact contact = message.getConversation()
|
highlightInConference(message.getCounterpart().toString());
|
||||||
.getContact();
|
|
||||||
if (contact.showInRoster()) {
|
|
||||||
activity.switchToContactDetails(contact);
|
|
||||||
} else {
|
|
||||||
activity.showAddToRosterDialog(message
|
|
||||||
.getConversation());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Contact contact = message.getConversation()
|
||||||
|
.getContact();
|
||||||
|
if (contact.showInRoster()) {
|
||||||
|
activity.switchToContactDetails(contact);
|
||||||
} else {
|
} else {
|
||||||
Account account = message.getConversation().getAccount();
|
activity.showAddToRosterDialog(message
|
||||||
Intent intent = new Intent(activity, EditAccountActivity.class);
|
.getConversation());
|
||||||
intent.putExtra("jid", account.getJid().toBareJid().toString());
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
Account account = message.getConversation().getAccount();
|
||||||
|
Intent intent = new Intent(activity, EditAccountActivity.class);
|
||||||
|
intent.putExtra("jid", account.getJid().toBareJid().toString());
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
messageListAdapter
|
messageListAdapter
|
||||||
.setOnContactPictureLongClicked(new OnContactPictureLongClicked() {
|
.setOnContactPictureLongClicked(new OnContactPictureLongClicked() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContactPictureLongClicked(Message message) {
|
public void onContactPictureLongClicked(Message message) {
|
||||||
if (message.getStatus() <= Message.STATUS_RECEIVED) {
|
if (message.getStatus() <= Message.STATUS_RECEIVED) {
|
||||||
if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
|
||||||
if (message.getCounterpart() != null) {
|
if (message.getCounterpart() != null) {
|
||||||
privateMessageWith(message.getCounterpart());
|
privateMessageWith(message.getCounterpart());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
messagesView.setAdapter(messageListAdapter);
|
messagesView.setAdapter(messageListAdapter);
|
||||||
|
|
||||||
registerForContextMenu(messagesView);
|
registerForContextMenu(messagesView);
|
||||||
|
@ -394,7 +392,7 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
public void onCreateContextMenu(ContextMenu menu, View v,
|
||||||
ContextMenuInfo menuInfo) {
|
ContextMenuInfo menuInfo) {
|
||||||
synchronized (this.messageList) {
|
synchronized (this.messageList) {
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
super.onCreateContextMenu(menu, v, menuInfo);
|
||||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
|
AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
|
||||||
|
@ -416,28 +414,28 @@ public class ConversationFragment extends Fragment {
|
||||||
if (this.selectedMessage.getType() != Message.TYPE_TEXT
|
if (this.selectedMessage.getType() != Message.TYPE_TEXT
|
||||||
|| this.selectedMessage.getDownloadable() != null) {
|
|| this.selectedMessage.getDownloadable() != null) {
|
||||||
copyText.setVisible(false);
|
copyText.setVisible(false);
|
||||||
}
|
}
|
||||||
if (this.selectedMessage.getType() != Message.TYPE_IMAGE
|
if (this.selectedMessage.getType() != Message.TYPE_IMAGE
|
||||||
|| this.selectedMessage.getDownloadable() != null) {
|
|| this.selectedMessage.getDownloadable() != null) {
|
||||||
shareImage.setVisible(false);
|
shareImage.setVisible(false);
|
||||||
}
|
}
|
||||||
if (this.selectedMessage.getStatus() != Message.STATUS_SEND_FAILED) {
|
if (this.selectedMessage.getStatus() != Message.STATUS_SEND_FAILED) {
|
||||||
sendAgain.setVisible(false);
|
sendAgain.setVisible(false);
|
||||||
}
|
}
|
||||||
if ((this.selectedMessage.getType() != Message.TYPE_IMAGE && this.selectedMessage
|
if ((this.selectedMessage.getType() != Message.TYPE_IMAGE && this.selectedMessage
|
||||||
.getDownloadable() == null)
|
.getDownloadable() == null)
|
||||||
|| this.selectedMessage.getImageParams().url == null) {
|
|| this.selectedMessage.getImageParams().url == null) {
|
||||||
copyUrl.setVisible(false);
|
copyUrl.setVisible(false);
|
||||||
}
|
}
|
||||||
if (this.selectedMessage.getType() != Message.TYPE_TEXT
|
if (this.selectedMessage.getType() != Message.TYPE_TEXT
|
||||||
|| this.selectedMessage.getDownloadable() != null
|
|| this.selectedMessage.getDownloadable() != null
|
||||||
|| !this.selectedMessage.bodyContainsDownloadable()) {
|
|| !this.selectedMessage.bodyContainsDownloadable()) {
|
||||||
downloadImage.setVisible(false);
|
downloadImage.setVisible(false);
|
||||||
}
|
}
|
||||||
if (this.selectedMessage.getDownloadable() == null
|
if (this.selectedMessage.getDownloadable() == null
|
||||||
|| this.selectedMessage.getDownloadable() instanceof DownloadablePlaceholder) {
|
|| this.selectedMessage.getDownloadable() instanceof DownloadablePlaceholder) {
|
||||||
cancelTransmission.setVisible(false);
|
cancelTransmission.setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,16 +470,16 @@ public class ConversationFragment extends Fragment {
|
||||||
shareIntent.setAction(Intent.ACTION_SEND);
|
shareIntent.setAction(Intent.ACTION_SEND);
|
||||||
shareIntent.putExtra(Intent.EXTRA_STREAM,
|
shareIntent.putExtra(Intent.EXTRA_STREAM,
|
||||||
activity.xmppConnectionService.getFileBackend()
|
activity.xmppConnectionService.getFileBackend()
|
||||||
.getJingleFileUri(message));
|
.getJingleFileUri(message));
|
||||||
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
shareIntent.setType("image/webp");
|
shareIntent.setType("image/webp");
|
||||||
activity.startActivity(Intent.createChooser(shareIntent,
|
activity.startActivity(Intent.createChooser(shareIntent,
|
||||||
getText(R.string.share_with)));
|
getText(R.string.share_with)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyText(Message message) {
|
private void copyText(Message message) {
|
||||||
if (activity.copyTextToClipboard(message.getMergedBody(),
|
if (activity.copyTextToClipboard(message.getMergedBody(),
|
||||||
R.string.message_text)) {
|
R.string.message_text)) {
|
||||||
Toast.makeText(activity, R.string.message_copied_to_clipboard,
|
Toast.makeText(activity, R.string.message_copied_to_clipboard,
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
@ -501,15 +499,15 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
private void copyUrl(Message message) {
|
private void copyUrl(Message message) {
|
||||||
if (activity.copyTextToClipboard(
|
if (activity.copyTextToClipboard(
|
||||||
message.getImageParams().url.toString(), R.string.image_url)) {
|
message.getImageParams().url.toString(), R.string.image_url)) {
|
||||||
Toast.makeText(activity, R.string.url_copied_to_clipboard,
|
Toast.makeText(activity, R.string.url_copied_to_clipboard,
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadImage(Message message) {
|
private void downloadImage(Message message) {
|
||||||
activity.xmppConnectionService.getHttpConnectionManager()
|
activity.xmppConnectionService.getHttpConnectionManager()
|
||||||
.createNewConnection(message);
|
.createNewConnection(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelTransmission(Message message) {
|
private void cancelTransmission(Message message) {
|
||||||
|
@ -531,9 +529,9 @@ public class ConversationFragment extends Fragment {
|
||||||
mEditMessage.getText().insert(0, nick + ": ");
|
mEditMessage.getText().insert(0, nick + ": ");
|
||||||
} else {
|
} else {
|
||||||
if (mEditMessage.getText().charAt(
|
if (mEditMessage.getText().charAt(
|
||||||
mEditMessage.getSelectionStart() - 1) != ' ') {
|
mEditMessage.getSelectionStart() - 1) != ' ') {
|
||||||
nick = " " + nick;
|
nick = " " + nick;
|
||||||
}
|
}
|
||||||
mEditMessage.getText().insert(mEditMessage.getSelectionStart(),
|
mEditMessage.getText().insert(mEditMessage.getSelectionStart(),
|
||||||
nick + " ");
|
nick + " ");
|
||||||
}
|
}
|
||||||
|
@ -583,12 +581,30 @@ public class ConversationFragment extends Fragment {
|
||||||
final ConversationActivity activity = (ConversationActivity) getActivity();
|
final ConversationActivity activity = (ConversationActivity) getActivity();
|
||||||
if (this.conversation != null) {
|
if (this.conversation != null) {
|
||||||
final Contact contact = this.conversation.getContact();
|
final Contact contact = this.conversation.getContact();
|
||||||
if (this.conversation.isMuted()) {
|
if (this.conversation.isBlocked()) {
|
||||||
|
showSnackbar(R.string.contact_blocked, R.string.unblock,
|
||||||
|
new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(final View v) {
|
||||||
|
v.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
v.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (conversation.isDomainBlocked()) {
|
||||||
|
BlockContactDialog.show(getActivity(), ((ConversationActivity) getActivity()).xmppConnectionService, conversation);
|
||||||
|
} else {
|
||||||
|
((ConversationActivity) getActivity()).unblockConversation(conversation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (this.conversation.isMuted()) {
|
||||||
showSnackbar(R.string.notifications_disabled, R.string.enable,
|
showSnackbar(R.string.notifications_disabled, R.string.enable,
|
||||||
new OnClickListener() {
|
new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(final View v) {
|
||||||
activity.unmuteConversation(conversation);
|
activity.unmuteConversation(conversation);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -601,7 +617,7 @@ public class ConversationFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
activity.xmppConnectionService
|
activity.xmppConnectionService
|
||||||
.createContact(contact);
|
.createContact(contact);
|
||||||
activity.switchToContactDetails(contact);
|
activity.switchToContactDetails(contact);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -638,17 +654,17 @@ public class ConversationFragment extends Fragment {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conversation.populateWithMessages(ConversationFragment.this.messageList);
|
conversation.populateWithMessages(ConversationFragment.this.messageList);
|
||||||
for (Message message : this.messageList) {
|
for (Message message : this.messageList) {
|
||||||
if (message.getEncryption() == Message.ENCRYPTION_PGP
|
if (message.getEncryption() == Message.ENCRYPTION_PGP
|
||||||
&& (message.getStatus() == Message.STATUS_RECEIVED || message
|
&& (message.getStatus() == Message.STATUS_RECEIVED || message
|
||||||
.getStatus() >= Message.STATUS_SEND)
|
.getStatus() >= Message.STATUS_SEND)
|
||||||
&& message.getDownloadable() == null) {
|
&& message.getDownloadable() == null) {
|
||||||
if (!mEncryptedMessages.contains(message)) {
|
if (!mEncryptedMessages.contains(message)) {
|
||||||
mEncryptedMessages.add(message);
|
mEncryptedMessages.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decryptNext();
|
decryptNext();
|
||||||
updateStatusMessages();
|
updateStatusMessages();
|
||||||
|
@ -720,44 +736,44 @@ public class ConversationFragment extends Fragment {
|
||||||
switch (c.getContact().getMostAvailableStatus()) {
|
switch (c.getContact().getMostAvailableStatus()) {
|
||||||
case Presences.CHAT:
|
case Presences.CHAT:
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_online);
|
.setImageResource(R.drawable.ic_action_send_now_online);
|
||||||
break;
|
break;
|
||||||
case Presences.ONLINE:
|
case Presences.ONLINE:
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_online);
|
.setImageResource(R.drawable.ic_action_send_now_online);
|
||||||
break;
|
break;
|
||||||
case Presences.AWAY:
|
case Presences.AWAY:
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_away);
|
.setImageResource(R.drawable.ic_action_send_now_away);
|
||||||
break;
|
break;
|
||||||
case Presences.XA:
|
case Presences.XA:
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_away);
|
.setImageResource(R.drawable.ic_action_send_now_away);
|
||||||
break;
|
break;
|
||||||
case Presences.DND:
|
case Presences.DND:
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_dnd);
|
.setImageResource(R.drawable.ic_action_send_now_dnd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_offline);
|
.setImageResource(R.drawable.ic_action_send_now_offline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (c.getMode() == Conversation.MODE_MULTI) {
|
} else if (c.getMode() == Conversation.MODE_MULTI) {
|
||||||
if (c.getMucOptions().online()) {
|
if (c.getMucOptions().online()) {
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_online);
|
.setImageResource(R.drawable.ic_action_send_now_online);
|
||||||
} else {
|
} else {
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_offline);
|
.setImageResource(R.drawable.ic_action_send_now_offline);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_offline);
|
.setImageResource(R.drawable.ic_action_send_now_offline);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.mSendButton
|
this.mSendButton
|
||||||
.setImageResource(R.drawable.ic_action_send_now_offline);
|
.setImageResource(R.drawable.ic_action_send_now_offline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,15 +800,16 @@ public class ConversationFragment extends Fragment {
|
||||||
} else if (conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED)
|
} else if (conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED)
|
||||||
&& (!conversation.isOtrFingerprintVerified())) {
|
&& (!conversation.isOtrFingerprintVerified())) {
|
||||||
showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify);
|
showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showSnackbar(int message, int action,
|
protected void showSnackbar(final int message, final int action,
|
||||||
OnClickListener clickListener) {
|
final OnClickListener clickListener) {
|
||||||
snackbar.setVisibility(View.VISIBLE);
|
snackbar.setVisibility(View.VISIBLE);
|
||||||
snackbar.setOnClickListener(null);
|
snackbar.setOnClickListener(null);
|
||||||
snackbarMessage.setText(message);
|
snackbarMessage.setText(message);
|
||||||
snackbarMessage.setOnClickListener(null);
|
snackbarMessage.setOnClickListener(null);
|
||||||
|
snackbarAction.setVisibility(View.VISIBLE);
|
||||||
snackbarAction.setText(action);
|
snackbarAction.setText(action);
|
||||||
snackbarAction.setOnClickListener(clickListener);
|
snackbarAction.setOnClickListener(clickListener);
|
||||||
}
|
}
|
||||||
|
@ -819,7 +836,7 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void userInputRequried(PendingIntent pi,
|
public void userInputRequried(PendingIntent pi,
|
||||||
Contact contact) {
|
Contact contact) {
|
||||||
activity.runIntent(
|
activity.runIntent(
|
||||||
pi,
|
pi,
|
||||||
ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
|
ConversationActivity.REQUEST_ENCRYPT_MESSAGE);
|
||||||
|
@ -843,11 +860,11 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog,
|
public void onClick(DialogInterface dialog,
|
||||||
int which) {
|
int which) {
|
||||||
conversation
|
conversation
|
||||||
.setNextEncryption(Message.ENCRYPTION_NONE);
|
.setNextEncryption(Message.ENCRYPTION_NONE);
|
||||||
xmppService.databaseBackend
|
xmppService.databaseBackend
|
||||||
.updateConversation(conversation);
|
.updateConversation(conversation);
|
||||||
message.setEncryption(Message.ENCRYPTION_NONE);
|
message.setEncryption(Message.ENCRYPTION_NONE);
|
||||||
xmppService.sendMessage(message);
|
xmppService.sendMessage(message);
|
||||||
messageSent();
|
messageSent();
|
||||||
|
@ -858,9 +875,9 @@ public class ConversationFragment extends Fragment {
|
||||||
if (conversation.getMucOptions().pgpKeysInUse()) {
|
if (conversation.getMucOptions().pgpKeysInUse()) {
|
||||||
if (!conversation.getMucOptions().everybodyHasKeys()) {
|
if (!conversation.getMucOptions().everybodyHasKeys()) {
|
||||||
Toast warning = Toast
|
Toast warning = Toast
|
||||||
.makeText(getActivity(),
|
.makeText(getActivity(),
|
||||||
R.string.missing_public_keys,
|
R.string.missing_public_keys,
|
||||||
Toast.LENGTH_LONG);
|
Toast.LENGTH_LONG);
|
||||||
warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
|
warning.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
|
||||||
warning.show();
|
warning.show();
|
||||||
}
|
}
|
||||||
|
@ -872,12 +889,12 @@ public class ConversationFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog,
|
public void onClick(DialogInterface dialog,
|
||||||
int which) {
|
int which) {
|
||||||
conversation
|
conversation
|
||||||
.setNextEncryption(Message.ENCRYPTION_NONE);
|
.setNextEncryption(Message.ENCRYPTION_NONE);
|
||||||
message.setEncryption(Message.ENCRYPTION_NONE);
|
message.setEncryption(Message.ENCRYPTION_NONE);
|
||||||
xmppService.databaseBackend
|
xmppService.databaseBackend
|
||||||
.updateConversation(conversation);
|
.updateConversation(conversation);
|
||||||
xmppService.sendMessage(message);
|
xmppService.sendMessage(message);
|
||||||
messageSent();
|
messageSent();
|
||||||
}
|
}
|
||||||
|
@ -890,7 +907,7 @@ public class ConversationFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showNoPGPKeyDialog(boolean plural,
|
public void showNoPGPKeyDialog(boolean plural,
|
||||||
DialogInterface.OnClickListener listener) {
|
DialogInterface.OnClickListener listener) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
builder.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||||
if (plural) {
|
if (plural) {
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
mAccount.setOption(Account.OPTION_DISABLED, false);
|
mAccount.setOption(Account.OPTION_DISABLED, false);
|
||||||
xmppConnectionService.updateAccount(mAccount);
|
xmppConnectionService.updateAccount(mAccount);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Validator.isValidJid(mAccountJid.getText().toString())) {
|
if (!Validator.isValidJid(mAccountJid.getText().toString())) {
|
||||||
mAccountJid.setError(getString(R.string.invalid_jid));
|
mAccountJid.setError(getString(R.string.invalid_jid));
|
||||||
mAccountJid.requestFocus();
|
mAccountJid.requestFocus();
|
||||||
|
@ -87,32 +87,32 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
if (registerNewAccount) {
|
if (registerNewAccount) {
|
||||||
if (!password.equals(passwordConfirm)) {
|
if (!password.equals(passwordConfirm)) {
|
||||||
mPasswordConfirm
|
mPasswordConfirm
|
||||||
.setError(getString(R.string.passwords_do_not_match));
|
.setError(getString(R.string.passwords_do_not_match));
|
||||||
mPasswordConfirm.requestFocus();
|
mPasswordConfirm.requestFocus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mAccount != null) {
|
if (mAccount != null) {
|
||||||
mAccount.setPassword(password);
|
mAccount.setPassword(password);
|
||||||
try {
|
try {
|
||||||
mAccount.setUsername(jid.hasLocalpart() ? jid.getLocalpart() : "");
|
mAccount.setUsername(jid.hasLocalpart() ? jid.getLocalpart() : "");
|
||||||
mAccount.setServer(jid.getDomainpart());
|
mAccount.setServer(jid.getDomainpart());
|
||||||
} catch (final InvalidJidException ignored) {
|
} catch (final InvalidJidException ignored) {
|
||||||
}
|
}
|
||||||
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
|
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
|
||||||
xmppConnectionService.updateAccount(mAccount);
|
xmppConnectionService.updateAccount(mAccount);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (xmppConnectionService.findAccountByJid(Jid.fromString(mAccountJid.getText().toString())) != null) {
|
if (xmppConnectionService.findAccountByJid(Jid.fromString(mAccountJid.getText().toString())) != null) {
|
||||||
mAccountJid
|
mAccountJid
|
||||||
.setError(getString(R.string.account_already_exists));
|
.setError(getString(R.string.account_already_exists));
|
||||||
mAccountJid.requestFocus();
|
mAccountJid.requestFocus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (InvalidJidException e) {
|
} catch (InvalidJidException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAccount = new Account(jid.toBareJid(), password);
|
mAccount = new Account(jid.toBareJid(), password);
|
||||||
mAccount.setOption(Account.OPTION_USETLS, true);
|
mAccount.setOption(Account.OPTION_USETLS, true);
|
||||||
mAccount.setOption(Account.OPTION_USECOMPRESSION, true);
|
mAccount.setOption(Account.OPTION_USECOMPRESSION, true);
|
||||||
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
|
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
|
||||||
|
@ -134,34 +134,34 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@Override
|
@Override
|
||||||
public void onAccountUpdate() {
|
public void onAccountUpdate() {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mAccount != null
|
if (mAccount != null
|
||||||
&& mAccount.getStatus() != Account.State.ONLINE
|
&& mAccount.getStatus() != Account.State.ONLINE
|
||||||
&& mFetchingAvatar) {
|
&& mFetchingAvatar) {
|
||||||
startActivity(new Intent(getApplicationContext(),
|
startActivity(new Intent(getApplicationContext(),
|
||||||
ManageAccountActivity.class));
|
ManageAccountActivity.class));
|
||||||
finish();
|
finish();
|
||||||
} else if (jidToEdit == null && mAccount != null
|
} else if (jidToEdit == null && mAccount != null
|
||||||
&& mAccount.getStatus() == Account.State.ONLINE) {
|
&& mAccount.getStatus() == Account.State.ONLINE) {
|
||||||
if (!mFetchingAvatar) {
|
if (!mFetchingAvatar) {
|
||||||
mFetchingAvatar = true;
|
mFetchingAvatar = true;
|
||||||
xmppConnectionService.checkForAvatar(mAccount,
|
xmppConnectionService.checkForAvatar(mAccount,
|
||||||
mAvatarFetchCallback);
|
mAvatarFetchCallback);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateSaveButton();
|
|
||||||
}
|
|
||||||
if (mAccount != null) {
|
|
||||||
updateAccountInformation();
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
updateSaveButton();
|
||||||
}
|
}
|
||||||
});
|
if (mAccount != null) {
|
||||||
}
|
updateAccountInformation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
private UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() {
|
private UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -179,17 +179,17 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
finishInitialSetup(avatar);
|
finishInitialSetup(avatar);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private TextWatcher mTextWatcher = new TextWatcher() {
|
private TextWatcher mTextWatcher = new TextWatcher() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before,
|
public void onTextChanged(CharSequence s, int start, int before,
|
||||||
int count) {
|
int count) {
|
||||||
updateSaveButton();
|
updateSaveButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count,
|
public void beforeTextChanged(CharSequence s, int start, int count,
|
||||||
int after) {
|
int after) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,9 +264,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
|
|
||||||
protected boolean accountInfoEdited() {
|
protected boolean accountInfoEdited() {
|
||||||
return (!this.mAccount.getJid().toBareJid().equals(
|
return (!this.mAccount.getJid().toBareJid().equals(
|
||||||
this.mAccountJid.getText().toString()))
|
this.mAccountJid.getText().toString()))
|
||||||
|| (!this.mAccount.getPassword().equals(
|
|| (!this.mAccount.getPassword().equals(
|
||||||
this.mPassword.getText().toString()));
|
this.mPassword.getText().toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -303,28 +303,32 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener);
|
this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener);
|
||||||
this.mCancelButton.setOnClickListener(this.mCancelButtonClickListener);
|
this.mCancelButton.setOnClickListener(this.mCancelButtonClickListener);
|
||||||
this.mRegisterNew
|
this.mRegisterNew
|
||||||
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView,
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
boolean isChecked) {
|
boolean isChecked) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
mPasswordConfirm.setVisibility(View.VISIBLE);
|
mPasswordConfirm.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
mPasswordConfirm.setVisibility(View.GONE);
|
mPasswordConfirm.setVisibility(View.GONE);
|
||||||
}
|
|
||||||
updateSaveButton();
|
|
||||||
}
|
}
|
||||||
});
|
updateSaveButton();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||||
super.onCreateOptionsMenu(menu);
|
super.onCreateOptionsMenu(menu);
|
||||||
getMenuInflater().inflate(R.menu.editaccount, menu);
|
getMenuInflater().inflate(R.menu.editaccount, menu);
|
||||||
MenuItem showQrCode = menu.findItem(R.id.action_show_qr_code);
|
final MenuItem showQrCode = menu.findItem(R.id.action_show_qr_code);
|
||||||
|
final MenuItem showBlocklist = menu.findItem(R.id.action_show_block_list);
|
||||||
if (mAccount == null) {
|
if (mAccount == null) {
|
||||||
showQrCode.setVisible(false);
|
showQrCode.setVisible(false);
|
||||||
|
showBlocklist.setVisible(false);
|
||||||
|
} else if (!mAccount.getXmppConnection().getFeatures().blocking()) {
|
||||||
|
showBlocklist.setVisible(false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -333,32 +337,38 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
if (getIntent() != null) {
|
if (getIntent() != null) {
|
||||||
try {
|
try {
|
||||||
this.jidToEdit = Jid.fromString(getIntent().getStringExtra("jid"));
|
this.jidToEdit = Jid.fromString(getIntent().getStringExtra("jid"));
|
||||||
} catch (final InvalidJidException | NullPointerException ignored) {
|
} catch (final InvalidJidException | NullPointerException ignored) {
|
||||||
this.jidToEdit = null;
|
this.jidToEdit = null;
|
||||||
}
|
}
|
||||||
if (this.jidToEdit != null) {
|
if (this.jidToEdit != null) {
|
||||||
this.mRegisterNew.setVisibility(View.GONE);
|
this.mRegisterNew.setVisibility(View.GONE);
|
||||||
getActionBar().setTitle(getString(R.string.account_details));
|
if (getActionBar() != null) {
|
||||||
|
getActionBar().setTitle(getString(R.string.account_details));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.mAvatar.setVisibility(View.GONE);
|
this.mAvatar.setVisibility(View.GONE);
|
||||||
getActionBar().setTitle(R.string.action_add_account);
|
if (getActionBar() != null) {
|
||||||
|
getActionBar().setTitle(R.string.action_add_account);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onBackendConnected() {
|
protected void onBackendConnected() {
|
||||||
KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
|
final KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
|
||||||
android.R.layout.simple_list_item_1,
|
android.R.layout.simple_list_item_1,
|
||||||
xmppConnectionService.getKnownHosts());
|
xmppConnectionService.getKnownHosts());
|
||||||
if (this.jidToEdit != null) {
|
if (this.jidToEdit != null) {
|
||||||
this.mAccount = xmppConnectionService.findAccountByJid(jidToEdit);
|
this.mAccount = xmppConnectionService.findAccountByJid(jidToEdit);
|
||||||
updateAccountInformation();
|
updateAccountInformation();
|
||||||
} else if (this.xmppConnectionService.getAccounts().size() == 0) {
|
} else if (this.xmppConnectionService.getAccounts().size() == 0) {
|
||||||
getActionBar().setDisplayHomeAsUpEnabled(false);
|
if (getActionBar() != null) {
|
||||||
getActionBar().setDisplayShowHomeEnabled(false);
|
getActionBar().setDisplayHomeAsUpEnabled(false);
|
||||||
|
getActionBar().setDisplayShowHomeEnabled(false);
|
||||||
|
}
|
||||||
this.mCancelButton.setEnabled(false);
|
this.mCancelButton.setEnabled(false);
|
||||||
this.mCancelButton.setTextColor(getSecondaryTextColor());
|
this.mCancelButton.setTextColor(getSecondaryTextColor());
|
||||||
}
|
}
|
||||||
|
@ -366,6 +376,18 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
updateSaveButton();
|
updateSaveButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.action_show_block_list:
|
||||||
|
final Intent intent = new Intent(this, BlocklistActivity.class);
|
||||||
|
intent.putExtra("account", mAccount.getJid().toString());
|
||||||
|
startActivity(intent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateAccountInformation() {
|
private void updateAccountInformation() {
|
||||||
this.mAccountJid.setText(this.mAccount.getJid().toBareJid().toString());
|
this.mAccountJid.setText(this.mAccount.getJid().toBareJid().toString());
|
||||||
this.mPassword.setText(this.mAccount.getPassword());
|
this.mPassword.setText(this.mAccount.getPassword());
|
||||||
|
@ -385,14 +407,14 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
&& !this.mFetchingAvatar) {
|
&& !this.mFetchingAvatar) {
|
||||||
this.mStats.setVisibility(View.VISIBLE);
|
this.mStats.setVisibility(View.VISIBLE);
|
||||||
this.mSessionEst.setText(UIHelper.readableTimeDifferenceFull(
|
this.mSessionEst.setText(UIHelper.readableTimeDifferenceFull(
|
||||||
getApplicationContext(), this.mAccount.getXmppConnection()
|
getApplicationContext(), this.mAccount.getXmppConnection()
|
||||||
.getLastSessionEstablished()));
|
.getLastSessionEstablished()));
|
||||||
Features features = this.mAccount.getXmppConnection().getFeatures();
|
final Features features = this.mAccount.getXmppConnection().getFeatures();
|
||||||
if (features.carbons()) {
|
if (features.carbons()) {
|
||||||
this.mServerInfoCarbons.setText(R.string.server_info_available);
|
this.mServerInfoCarbons.setText(R.string.server_info_available);
|
||||||
} else {
|
} else {
|
||||||
this.mServerInfoCarbons
|
this.mServerInfoCarbons
|
||||||
.setText(R.string.server_info_unavailable);
|
.setText(R.string.server_info_unavailable);
|
||||||
}
|
}
|
||||||
if (features.sm()) {
|
if (features.sm()) {
|
||||||
this.mServerInfoSm.setText(R.string.server_info_available);
|
this.mServerInfoSm.setText(R.string.server_info_available);
|
||||||
|
@ -409,21 +431,21 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
|
this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
|
||||||
this.mOtrFingerprint.setText(CryptoHelper.prettifyFingerprint(fingerprint));
|
this.mOtrFingerprint.setText(CryptoHelper.prettifyFingerprint(fingerprint));
|
||||||
this.mOtrFingerprintToClipboardButton
|
this.mOtrFingerprintToClipboardButton
|
||||||
.setVisibility(View.VISIBLE);
|
.setVisibility(View.VISIBLE);
|
||||||
this.mOtrFingerprintToClipboardButton
|
this.mOtrFingerprintToClipboardButton
|
||||||
.setOnClickListener(new View.OnClickListener() {
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
|
||||||
if (copyTextToClipboard(fingerprint, R.string.otr_fingerprint)) {
|
if (copyTextToClipboard(fingerprint, R.string.otr_fingerprint)) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
EditAccountActivity.this,
|
EditAccountActivity.this,
|
||||||
R.string.toast_message_otr_fingerprint,
|
R.string.toast_message_otr_fingerprint,
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.mOtrFingerprintBox.setVisibility(View.GONE);
|
this.mOtrFingerprintBox.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,10 +117,10 @@ public class ShareWithActivity extends XmppActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_add:
|
case R.id.action_add:
|
||||||
Intent intent = new Intent(getApplicationContext(),
|
final Intent intent = new Intent(getApplicationContext(),
|
||||||
ChooseContactActivity.class);
|
ChooseContactActivity.class);
|
||||||
startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION);
|
startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -53,19 +53,21 @@ import java.util.List;
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
import eu.siacs.conversations.entities.Blockable;
|
||||||
import eu.siacs.conversations.entities.Bookmark;
|
import eu.siacs.conversations.entities.Bookmark;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.ListItem;
|
import eu.siacs.conversations.entities.ListItem;
|
||||||
import eu.siacs.conversations.utils.XmppUri;
|
|
||||||
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
|
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
|
||||||
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
||||||
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
|
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
|
||||||
import eu.siacs.conversations.utils.Validator;
|
import eu.siacs.conversations.utils.Validator;
|
||||||
|
import eu.siacs.conversations.utils.XmppUri;
|
||||||
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
public class StartConversationActivity extends XmppActivity implements OnRosterUpdate {
|
public class StartConversationActivity extends XmppActivity implements OnRosterUpdate, OnUpdateBlocklist {
|
||||||
|
|
||||||
public int conference_context_id;
|
public int conference_context_id;
|
||||||
public int contact_context_id;
|
public int contact_context_id;
|
||||||
|
@ -133,7 +135,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
|
private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected(int position) {
|
public void onPageSelected(int position) {
|
||||||
getActionBar().setSelectedNavigationItem(position);
|
if (getActionBar() != null) {
|
||||||
|
getActionBar().setSelectedNavigationItem(position);
|
||||||
|
}
|
||||||
onTabChanged();
|
onTabChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -146,12 +150,12 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count,
|
public void beforeTextChanged(CharSequence s, int start, int count,
|
||||||
int after) {
|
int after) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before,
|
public void onTextChanged(CharSequence s, int start, int before,
|
||||||
int count) {
|
int count) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private MenuItem mMenuSearchView;
|
private MenuItem mMenuSearchView;
|
||||||
|
@ -179,9 +183,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||||
|
|
||||||
mContactsTab = actionBar.newTab().setText(R.string.contacts)
|
mContactsTab = actionBar.newTab().setText(R.string.contacts)
|
||||||
.setTabListener(mTabListener);
|
.setTabListener(mTabListener);
|
||||||
mConferencesTab = actionBar.newTab().setText(R.string.conferences)
|
mConferencesTab = actionBar.newTab().setText(R.string.conferences)
|
||||||
.setTabListener(mTabListener);
|
.setTabListener(mTabListener);
|
||||||
actionBar.addTab(mContactsTab);
|
actionBar.addTab(mContactsTab);
|
||||||
actionBar.addTab(mConferencesTab);
|
actionBar.addTab(mConferencesTab);
|
||||||
|
|
||||||
|
@ -207,35 +211,35 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
mConferenceListFragment.setListAdapter(mConferenceAdapter);
|
mConferenceListFragment.setListAdapter(mConferenceAdapter);
|
||||||
mConferenceListFragment.setContextMenu(R.menu.conference_context);
|
mConferenceListFragment.setContextMenu(R.menu.conference_context);
|
||||||
mConferenceListFragment
|
mConferenceListFragment
|
||||||
.setOnListItemClickListener(new OnItemClickListener() {
|
.setOnListItemClickListener(new OnItemClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> arg0, View arg1,
|
public void onItemClick(AdapterView<?> arg0, View arg1,
|
||||||
int position, long arg3) {
|
int position, long arg3) {
|
||||||
openConversationForBookmark(position);
|
openConversationForBookmark(position);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mContactsAdapter = new ListItemAdapter(this, contacts);
|
mContactsAdapter = new ListItemAdapter(this, contacts);
|
||||||
mContactsListFragment.setListAdapter(mContactsAdapter);
|
mContactsListFragment.setListAdapter(mContactsAdapter);
|
||||||
mContactsListFragment.setContextMenu(R.menu.contact_context);
|
mContactsListFragment.setContextMenu(R.menu.contact_context);
|
||||||
mContactsListFragment
|
mContactsListFragment
|
||||||
.setOnListItemClickListener(new OnItemClickListener() {
|
.setOnListItemClickListener(new OnItemClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> arg0, View arg1,
|
public void onItemClick(AdapterView<?> arg0, View arg1,
|
||||||
int position, long arg3) {
|
int position, long arg3) {
|
||||||
openConversationForContact(position);
|
openConversationForContact(position);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void openConversationForContact(int position) {
|
protected void openConversationForContact(int position) {
|
||||||
Contact contact = (Contact) contacts.get(position);
|
Contact contact = (Contact) contacts.get(position);
|
||||||
Conversation conversation = xmppConnectionService
|
Conversation conversation = xmppConnectionService
|
||||||
.findOrCreateConversation(contact.getAccount(),
|
.findOrCreateConversation(contact.getAccount(),
|
||||||
contact.getJid(), false);
|
contact.getJid(), false);
|
||||||
switchToConversation(conversation);
|
switchToConversation(conversation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +255,8 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
protected void openConversationForBookmark(int position) {
|
protected void openConversationForBookmark(int position) {
|
||||||
Bookmark bookmark = (Bookmark) conferences.get(position);
|
Bookmark bookmark = (Bookmark) conferences.get(position);
|
||||||
Conversation conversation = xmppConnectionService
|
Conversation conversation = xmppConnectionService
|
||||||
.findOrCreateConversation(bookmark.getAccount(),
|
.findOrCreateConversation(bookmark.getAccount(),
|
||||||
bookmark.getJid(), true);
|
bookmark.getJid(), true);
|
||||||
conversation.setBookmark(bookmark);
|
conversation.setBookmark(bookmark);
|
||||||
if (!conversation.getMucOptions().online()) {
|
if (!conversation.getMucOptions().online()) {
|
||||||
xmppConnectionService.joinMuc(conversation);
|
xmppConnectionService.joinMuc(conversation);
|
||||||
|
@ -270,14 +274,19 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
switchToContactDetails(contact);
|
switchToContactDetails(contact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void toggleContactBlock() {
|
||||||
|
final int position = contact_context_id;
|
||||||
|
BlockContactDialog.show(this, xmppConnectionService, (Contact)contacts.get(position));
|
||||||
|
}
|
||||||
|
|
||||||
protected void deleteContact() {
|
protected void deleteContact() {
|
||||||
int position = contact_context_id;
|
final int position = contact_context_id;
|
||||||
final Contact contact = (Contact) contacts.get(position);
|
final Contact contact = (Contact) contacts.get(position);
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
builder.setTitle(R.string.action_delete_contact);
|
builder.setTitle(R.string.action_delete_contact);
|
||||||
builder.setMessage(getString(R.string.remove_contact_text,
|
builder.setMessage(getString(R.string.remove_contact_text,
|
||||||
contact.getJid()));
|
contact.getJid()));
|
||||||
builder.setPositiveButton(R.string.delete, new OnClickListener() {
|
builder.setPositiveButton(R.string.delete, new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -287,7 +296,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void deleteConference() {
|
protected void deleteConference() {
|
||||||
|
@ -298,7 +306,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
builder.setTitle(R.string.delete_bookmark);
|
builder.setTitle(R.string.delete_bookmark);
|
||||||
builder.setMessage(getString(R.string.remove_bookmark_text,
|
builder.setMessage(getString(R.string.remove_bookmark_text,
|
||||||
bookmark.getJid()));
|
bookmark.getJid()));
|
||||||
builder.setPositiveButton(R.string.delete, new OnClickListener() {
|
builder.setPositiveButton(R.string.delete, new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -360,7 +368,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Account account = xmppConnectionService
|
Account account = xmppConnectionService
|
||||||
.findAccountByJid(accountJid);
|
.findAccountByJid(accountJid);
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
return;
|
return;
|
||||||
|
@ -395,7 +403,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
}
|
}
|
||||||
populateAccountSpinner(spinner);
|
populateAccountSpinner(spinner);
|
||||||
final CheckBox bookmarkCheckBox = (CheckBox) dialogView
|
final CheckBox bookmarkCheckBox = (CheckBox) dialogView
|
||||||
.findViewById(R.id.bookmark);
|
.findViewById(R.id.bookmark);
|
||||||
builder.setView(dialogView);
|
builder.setView(dialogView);
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
builder.setNegativeButton(R.string.cancel, null);
|
||||||
builder.setPositiveButton(R.string.join, null);
|
builder.setPositiveButton(R.string.join, null);
|
||||||
|
@ -424,7 +432,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Account account = xmppConnectionService
|
Account account = xmppConnectionService
|
||||||
.findAccountByJid(accountJid);
|
.findAccountByJid(accountJid);
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
return;
|
return;
|
||||||
|
@ -438,22 +446,22 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
bookmark.setAutojoin(true);
|
bookmark.setAutojoin(true);
|
||||||
account.getBookmarks().add(bookmark);
|
account.getBookmarks().add(bookmark);
|
||||||
xmppConnectionService
|
xmppConnectionService
|
||||||
.pushBookmarks(account);
|
.pushBookmarks(account);
|
||||||
Conversation conversation = xmppConnectionService
|
Conversation conversation = xmppConnectionService
|
||||||
.findOrCreateConversation(account,
|
.findOrCreateConversation(account,
|
||||||
conferenceJid, true);
|
conferenceJid, true);
|
||||||
conversation.setBookmark(bookmark);
|
conversation.setBookmark(bookmark);
|
||||||
if (!conversation.getMucOptions().online()) {
|
if (!conversation.getMucOptions().online()) {
|
||||||
xmppConnectionService
|
xmppConnectionService
|
||||||
.joinMuc(conversation);
|
.joinMuc(conversation);
|
||||||
}
|
}
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
switchToConversation(conversation);
|
switchToConversation(conversation);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Conversation conversation = xmppConnectionService
|
Conversation conversation = xmppConnectionService
|
||||||
.findOrCreateConversation(account,
|
.findOrCreateConversation(account,
|
||||||
conferenceJid, true);
|
conferenceJid, true);
|
||||||
if (!conversation.getMucOptions().online()) {
|
if (!conversation.getMucOptions().online()) {
|
||||||
xmppConnectionService.joinMuc(conversation);
|
xmppConnectionService.joinMuc(conversation);
|
||||||
}
|
}
|
||||||
|
@ -469,8 +477,8 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
|
|
||||||
protected void switchToConversation(Contact contact) {
|
protected void switchToConversation(Contact contact) {
|
||||||
Conversation conversation = xmppConnectionService
|
Conversation conversation = xmppConnectionService
|
||||||
.findOrCreateConversation(contact.getAccount(),
|
.findOrCreateConversation(contact.getAccount(),
|
||||||
contact.getJid(), false);
|
contact.getJid(), false);
|
||||||
switchToConversation(conversation);
|
switchToConversation(conversation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,14 +494,14 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
this.mOptionsMenu = menu;
|
this.mOptionsMenu = menu;
|
||||||
getMenuInflater().inflate(R.menu.start_conversation, menu);
|
getMenuInflater().inflate(R.menu.start_conversation, menu);
|
||||||
MenuItem menuCreateContact = menu
|
MenuItem menuCreateContact = menu
|
||||||
.findItem(R.id.action_create_contact);
|
.findItem(R.id.action_create_contact);
|
||||||
MenuItem menuCreateConference = menu
|
MenuItem menuCreateConference = menu
|
||||||
.findItem(R.id.action_join_conference);
|
.findItem(R.id.action_join_conference);
|
||||||
mMenuSearchView = menu.findItem(R.id.action_search);
|
mMenuSearchView = menu.findItem(R.id.action_search);
|
||||||
mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener);
|
mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener);
|
||||||
View mSearchView = mMenuSearchView.getActionView();
|
View mSearchView = mMenuSearchView.getActionView();
|
||||||
mSearchEditText = (EditText) mSearchView
|
mSearchEditText = (EditText) mSearchView
|
||||||
.findViewById(R.id.search_field);
|
.findViewById(R.id.search_field);
|
||||||
mSearchEditText.addTextChangedListener(mSearchTextWatcher);
|
mSearchEditText.addTextChangedListener(mSearchTextWatcher);
|
||||||
if (getActionBar().getSelectedNavigationIndex() == 0) {
|
if (getActionBar().getSelectedNavigationIndex() == 0) {
|
||||||
menuCreateConference.setVisible(false);
|
menuCreateConference.setVisible(false);
|
||||||
|
@ -562,7 +570,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
}
|
}
|
||||||
this.mKnownHosts = xmppConnectionService.getKnownHosts();
|
this.mKnownHosts = xmppConnectionService.getKnownHosts();
|
||||||
this.mKnownConferenceHosts = xmppConnectionService
|
this.mKnownConferenceHosts = xmppConnectionService
|
||||||
.getKnownConferenceHosts();
|
.getKnownConferenceHosts();
|
||||||
if (this.mPendingInvite != null) {
|
if (this.mPendingInvite != null) {
|
||||||
mPendingInvite.invite();
|
mPendingInvite.invite();
|
||||||
this.mPendingInvite = null;
|
this.mPendingInvite = null;
|
||||||
|
@ -604,7 +612,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
byte[] payload = record.getPayload();
|
byte[] payload = record.getPayload();
|
||||||
if (payload[0] == 0) {
|
if (payload[0] == 0) {
|
||||||
return new Invite(Uri.parse(new String(Arrays.copyOfRange(
|
return new Invite(Uri.parse(new String(Arrays.copyOfRange(
|
||||||
payload, 1, payload.length)))).invite();
|
payload, 1, payload.length)))).invite();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,16 +693,29 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void OnUpdateBlocklist(final Status status) {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mSearchEditText != null) {
|
||||||
|
filter(mSearchEditText.getText().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static class MyListFragment extends ListFragment {
|
public static class MyListFragment extends ListFragment {
|
||||||
private AdapterView.OnItemClickListener mOnItemClickListener;
|
private AdapterView.OnItemClickListener mOnItemClickListener;
|
||||||
private int mResContextMenu;
|
private int mResContextMenu;
|
||||||
|
|
||||||
public void setContextMenu(int res) {
|
public void setContextMenu(final int res) {
|
||||||
this.mResContextMenu = res;
|
this.mResContextMenu = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||||
if (mOnItemClickListener != null) {
|
if (mOnItemClickListener != null) {
|
||||||
mOnItemClickListener.onItemClick(l, v, position, id);
|
mOnItemClickListener.onItemClick(l, v, position, id);
|
||||||
}
|
}
|
||||||
|
@ -705,28 +726,38 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(final View view, final Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
registerForContextMenu(getListView());
|
registerForContextMenu(getListView());
|
||||||
getListView().setFastScrollEnabled(true);
|
getListView().setFastScrollEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
public void onCreateContextMenu(final ContextMenu menu, final View v,
|
||||||
ContextMenuInfo menuInfo) {
|
final ContextMenuInfo menuInfo) {
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
super.onCreateContextMenu(menu, v, menuInfo);
|
||||||
StartConversationActivity activity = (StartConversationActivity) getActivity();
|
final StartConversationActivity activity = (StartConversationActivity) getActivity();
|
||||||
activity.getMenuInflater().inflate(mResContextMenu, menu);
|
activity.getMenuInflater().inflate(mResContextMenu, menu);
|
||||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
|
final AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
|
||||||
if (mResContextMenu == R.menu.conference_context) {
|
if (mResContextMenu == R.menu.conference_context) {
|
||||||
activity.conference_context_id = acmi.position;
|
activity.conference_context_id = acmi.position;
|
||||||
} else {
|
} else {
|
||||||
activity.contact_context_id = acmi.position;
|
activity.contact_context_id = acmi.position;
|
||||||
|
final Blockable contact = (Contact) activity.contacts.get(acmi.position);
|
||||||
|
|
||||||
|
final MenuItem blockUnblockItem = menu.findItem(R.id.context_contact_block_unblock);
|
||||||
|
if (blockUnblockItem != null) {
|
||||||
|
if (contact.isBlocked()) {
|
||||||
|
blockUnblockItem.setTitle(R.string.unblock_contact);
|
||||||
|
} else {
|
||||||
|
blockUnblockItem.setTitle(R.string.block_contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onContextItemSelected(MenuItem item) {
|
public boolean onContextItemSelected(final MenuItem item) {
|
||||||
StartConversationActivity activity = (StartConversationActivity) getActivity();
|
StartConversationActivity activity = (StartConversationActivity) getActivity();
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.context_start_conversation:
|
case R.id.context_start_conversation:
|
||||||
|
@ -735,6 +766,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
case R.id.context_contact_details:
|
case R.id.context_contact_details:
|
||||||
activity.openDetailsForContact();
|
activity.openDetailsForContact();
|
||||||
break;
|
break;
|
||||||
|
case R.id.context_contact_block_unblock:
|
||||||
|
activity.toggleContactBlock();
|
||||||
|
break;
|
||||||
case R.id.context_delete_contact:
|
case R.id.context_delete_contact:
|
||||||
activity.deleteContact();
|
activity.deleteContact();
|
||||||
break;
|
break;
|
||||||
|
@ -750,11 +784,11 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
|
||||||
|
|
||||||
private class Invite extends XmppUri {
|
private class Invite extends XmppUri {
|
||||||
|
|
||||||
public Invite(Uri uri) {
|
public Invite(final Uri uri) {
|
||||||
super(uri);
|
super(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Invite(String uri) {
|
public Invite(final String uri) {
|
||||||
super(uri);
|
super(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ import eu.siacs.conversations.services.AvatarService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;
|
import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;
|
||||||
import eu.siacs.conversations.utils.ExceptionHelper;
|
import eu.siacs.conversations.utils.ExceptionHelper;
|
||||||
|
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
|
@ -199,7 +200,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
xmppConnectionServiceBound = false;
|
xmppConnectionServiceBound = false;
|
||||||
}
|
}
|
||||||
stopService(new Intent(XmppActivity.this,
|
stopService(new Intent(XmppActivity.this,
|
||||||
XmppConnectionService.class));
|
XmppConnectionService.class));
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -209,13 +210,13 @@ public abstract class XmppActivity extends Activity {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
Uri uri = Uri
|
Uri uri = Uri
|
||||||
.parse("market://details?id=org.sufficientlysecure.keychain");
|
.parse("market://details?id=org.sufficientlysecure.keychain");
|
||||||
Intent marketIntent = new Intent(Intent.ACTION_VIEW,
|
Intent marketIntent = new Intent(Intent.ACTION_VIEW,
|
||||||
uri);
|
uri);
|
||||||
PackageManager manager = getApplicationContext()
|
PackageManager manager = getApplicationContext()
|
||||||
.getPackageManager();
|
.getPackageManager();
|
||||||
List<ResolveInfo> infos = manager
|
List<ResolveInfo> infos = manager
|
||||||
.queryIntentActivities(marketIntent, 0);
|
.queryIntentActivities(marketIntent, 0);
|
||||||
if (infos.size() > 0) {
|
if (infos.size() > 0) {
|
||||||
startActivity(marketIntent);
|
startActivity(marketIntent);
|
||||||
} else {
|
} else {
|
||||||
|
@ -245,6 +246,9 @@ public abstract class XmppActivity extends Activity {
|
||||||
if (this instanceof XmppConnectionService.OnMucRosterUpdate) {
|
if (this instanceof XmppConnectionService.OnMucRosterUpdate) {
|
||||||
this.xmppConnectionService.setOnMucRosterUpdateListener((XmppConnectionService.OnMucRosterUpdate) this);
|
this.xmppConnectionService.setOnMucRosterUpdateListener((XmppConnectionService.OnMucRosterUpdate) this);
|
||||||
}
|
}
|
||||||
|
if (this instanceof OnUpdateBlocklist) {
|
||||||
|
this.xmppConnectionService.setOnUpdateBlocklistListener((OnUpdateBlocklist) this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void unregisterListeners() {
|
protected void unregisterListeners() {
|
||||||
|
@ -260,9 +264,13 @@ public abstract class XmppActivity extends Activity {
|
||||||
if (this instanceof XmppConnectionService.OnMucRosterUpdate) {
|
if (this instanceof XmppConnectionService.OnMucRosterUpdate) {
|
||||||
this.xmppConnectionService.removeOnMucRosterUpdateListener();
|
this.xmppConnectionService.removeOnMucRosterUpdateListener();
|
||||||
}
|
}
|
||||||
|
if (this instanceof OnUpdateBlocklist) {
|
||||||
|
this.xmppConnectionService.removeOnUpdateBlocklistListener();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_settings:
|
case R.id.action_settings:
|
||||||
startActivity(new Intent(this, SettingsActivity.class));
|
startActivity(new Intent(this, SettingsActivity.class));
|
||||||
|
@ -300,7 +308,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
|
|
||||||
protected SharedPreferences getPreferences() {
|
protected SharedPreferences getPreferences() {
|
||||||
return PreferenceManager
|
return PreferenceManager
|
||||||
.getDefaultSharedPreferences(getApplicationContext());
|
.getDefaultSharedPreferences(getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean useSubjectToIdentifyConference() {
|
public boolean useSubjectToIdentifyConference() {
|
||||||
|
@ -312,7 +320,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void switchToConversation(Conversation conversation, String text,
|
public void switchToConversation(Conversation conversation, String text,
|
||||||
boolean newTask) {
|
boolean newTask) {
|
||||||
switchToConversation(conversation,text,null,newTask);
|
switchToConversation(conversation,text,null,newTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +380,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void userInputRequried(PendingIntent pi,
|
public void userInputRequried(PendingIntent pi,
|
||||||
Account account) {
|
Account account) {
|
||||||
try {
|
try {
|
||||||
startIntentSenderForResult(pi.getIntentSender(),
|
startIntentSenderForResult(pi.getIntentSender(),
|
||||||
REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
|
REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
|
||||||
|
@ -383,15 +391,15 @@ public abstract class XmppActivity extends Activity {
|
||||||
@Override
|
@Override
|
||||||
public void success(Account account) {
|
public void success(Account account) {
|
||||||
xmppConnectionService.databaseBackend
|
xmppConnectionService.databaseBackend
|
||||||
.updateAccount(account);
|
.updateAccount(account);
|
||||||
xmppConnectionService.sendPresencePacket(account,
|
xmppConnectionService.sendPresencePacket(account,
|
||||||
xmppConnectionService.getPresenceGenerator()
|
xmppConnectionService.getPresenceGenerator()
|
||||||
.sendPresence(account));
|
.sendPresence(account));
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
conversation
|
conversation
|
||||||
.setNextEncryption(Message.ENCRYPTION_PGP);
|
.setNextEncryption(Message.ENCRYPTION_PGP);
|
||||||
xmppConnectionService.databaseBackend
|
xmppConnectionService.databaseBackend
|
||||||
.updateConversation(conversation);
|
.updateConversation(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +428,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showAddToRosterDialog(final Conversation conversation) {
|
protected void showAddToRosterDialog(final Conversation conversation) {
|
||||||
final Jid jid = conversation.getContactJid();
|
final Jid jid = conversation.getJid();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(jid.toString());
|
builder.setTitle(jid.toString());
|
||||||
builder.setMessage(getString(R.string.not_in_roster));
|
builder.setMessage(getString(R.string.not_in_roster));
|
||||||
|
@ -430,7 +438,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
final Jid jid = conversation.getContactJid();
|
final Jid jid = conversation.getJid();
|
||||||
Account account = conversation.getAccount();
|
Account account = conversation.getAccount();
|
||||||
Contact contact = account.getRoster().getContact(jid);
|
Contact contact = account.getRoster().getContact(jid);
|
||||||
xmppConnectionService.createContact(contact);
|
xmppConnectionService.createContact(contact);
|
||||||
|
@ -462,7 +470,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void warnMutalPresenceSubscription(final Conversation conversation,
|
private void warnMutalPresenceSubscription(final Conversation conversation,
|
||||||
final OnPresenceSelected listener) {
|
final OnPresenceSelected listener) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(conversation.getContact().getJid().toString());
|
builder.setTitle(conversation.getContact().getJid().toString());
|
||||||
builder.setMessage(R.string.without_mutual_presence_updates);
|
builder.setMessage(R.string.without_mutual_presence_updates);
|
||||||
|
@ -485,13 +493,13 @@ public abstract class XmppActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void quickPasswordEdit(String previousValue,
|
protected void quickPasswordEdit(String previousValue,
|
||||||
OnValueEdited callback) {
|
OnValueEdited callback) {
|
||||||
quickEdit(previousValue, callback, true);
|
quickEdit(previousValue, callback, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
private void quickEdit(final String previousValue,
|
private void quickEdit(final String previousValue,
|
||||||
final OnValueEdited callback, boolean password) {
|
final OnValueEdited callback, boolean password) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
View view = getLayoutInflater().inflate(R.layout.quickedit, null);
|
View view = getLayoutInflater().inflate(R.layout.quickedit, null);
|
||||||
final EditText editor = (EditText) view.findViewById(R.id.editor);
|
final EditText editor = (EditText) view.findViewById(R.id.editor);
|
||||||
|
@ -521,7 +529,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void selectPresence(final Conversation conversation,
|
public void selectPresence(final Conversation conversation,
|
||||||
final OnPresenceSelected listener) {
|
final OnPresenceSelected listener) {
|
||||||
final Contact contact = conversation.getContact();
|
final Contact contact = conversation.getContact();
|
||||||
if (conversation.hasValidOtrSession()) {
|
if (conversation.hasValidOtrSession()) {
|
||||||
SessionID id = conversation.getOtrSession().getSessionID();
|
SessionID id = conversation.getOtrSession().getSessionID();
|
||||||
|
@ -576,7 +584,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog,
|
public void onClick(DialogInterface dialog,
|
||||||
int which) {
|
int which) {
|
||||||
presence.delete(0, presence.length());
|
presence.delete(0, presence.length());
|
||||||
presence.append(presencesArray[which]);
|
presence.append(presencesArray[which]);
|
||||||
}
|
}
|
||||||
|
@ -600,7 +608,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode,
|
protected void onActivityResult(int requestCode, int resultCode,
|
||||||
final Intent data) {
|
final Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
if (requestCode == REQUEST_INVITE_TO_CONVERSATION
|
if (requestCode == REQUEST_INVITE_TO_CONVERSATION
|
||||||
&& resultCode == RESULT_OK) {
|
&& resultCode == RESULT_OK) {
|
||||||
|
@ -608,19 +616,19 @@ public abstract class XmppActivity extends Activity {
|
||||||
Jid jid = Jid.fromString(data.getStringExtra("contact"));
|
Jid jid = Jid.fromString(data.getStringExtra("contact"));
|
||||||
String conversationUuid = data.getStringExtra("conversation");
|
String conversationUuid = data.getStringExtra("conversation");
|
||||||
Conversation conversation = xmppConnectionService
|
Conversation conversation = xmppConnectionService
|
||||||
.findConversationByUuid(conversationUuid);
|
.findConversationByUuid(conversationUuid);
|
||||||
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
if (conversation.getMode() == Conversation.MODE_MULTI) {
|
||||||
xmppConnectionService.invite(conversation, jid);
|
xmppConnectionService.invite(conversation, jid);
|
||||||
} else {
|
} else {
|
||||||
List<Jid> jids = new ArrayList<Jid>();
|
List<Jid> jids = new ArrayList<Jid>();
|
||||||
jids.add(conversation.getContactJid().toBareJid());
|
jids.add(conversation.getJid().toBareJid());
|
||||||
jids.add(jid);
|
jids.add(jid);
|
||||||
xmppConnectionService.createAdhocConference(conversation.getAccount(), jids, adhocCallback);
|
xmppConnectionService.createAdhocConference(conversation.getAccount(), jids, adhocCallback);
|
||||||
}
|
}
|
||||||
} catch (final InvalidJidException ignored) {
|
} catch (final InvalidJidException ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UiCallback<Conversation> adhocCallback = new UiCallback<Conversation>() {
|
private UiCallback<Conversation> adhocCallback = new UiCallback<Conversation>() {
|
||||||
|
@ -688,18 +696,18 @@ public abstract class XmppActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerNdefPushMessageCallback() {
|
protected void registerNdefPushMessageCallback() {
|
||||||
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
||||||
if (nfcAdapter != null && nfcAdapter.isEnabled()) {
|
if (nfcAdapter != null && nfcAdapter.isEnabled()) {
|
||||||
nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
|
nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
|
||||||
@Override
|
@Override
|
||||||
public NdefMessage createNdefMessage(NfcEvent nfcEvent) {
|
public NdefMessage createNdefMessage(NfcEvent nfcEvent) {
|
||||||
return new NdefMessage(new NdefRecord[]{
|
return new NdefMessage(new NdefRecord[]{
|
||||||
NdefRecord.createUri(getShareableUri()),
|
NdefRecord.createUri(getShareableUri()),
|
||||||
NdefRecord.createApplicationRecord("eu.siacs.conversations")
|
NdefRecord.createApplicationRecord("eu.siacs.conversations")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void unregisterNdefPushMessageCallback() {
|
protected void unregisterNdefPushMessageCallback() {
|
||||||
|
@ -831,13 +839,13 @@ public abstract class XmppActivity extends Activity {
|
||||||
try {
|
try {
|
||||||
task.execute(message);
|
task.execute(message);
|
||||||
} catch (final RejectedExecutionException ignored) {
|
} catch (final RejectedExecutionException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean cancelPotentialWork(Message message,
|
public static boolean cancelPotentialWork(Message message,
|
||||||
ImageView imageView) {
|
ImageView imageView) {
|
||||||
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||||
|
|
||||||
if (bitmapWorkerTask != null) {
|
if (bitmapWorkerTask != null) {
|
||||||
|
@ -866,7 +874,7 @@ public abstract class XmppActivity extends Activity {
|
||||||
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
|
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
|
||||||
|
|
||||||
public AsyncDrawable(Resources res, Bitmap bitmap,
|
public AsyncDrawable(Resources res, Bitmap bitmap,
|
||||||
BitmapWorkerTask bitmapWorkerTask) {
|
BitmapWorkerTask bitmapWorkerTask) {
|
||||||
super(res, bitmap);
|
super(res, bitmap);
|
||||||
bitmapWorkerTaskReference = new WeakReference<>(
|
bitmapWorkerTaskReference = new WeakReference<>(
|
||||||
bitmapWorkerTask);
|
bitmapWorkerTask);
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
public View getView(int position, View view, ViewGroup parent) {
|
public View getView(int position, View view, ViewGroup parent) {
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
LayoutInflater inflater = (LayoutInflater) activity
|
LayoutInflater inflater = (LayoutInflater) activity
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
view = inflater.inflate(R.layout.conversation_list_row,
|
view = inflater.inflate(R.layout.conversation_list_row,
|
||||||
parent, false);
|
parent, false);
|
||||||
}
|
}
|
||||||
|
@ -53,19 +53,19 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextView convName = (TextView) view
|
TextView convName = (TextView) view
|
||||||
.findViewById(R.id.conversation_name);
|
.findViewById(R.id.conversation_name);
|
||||||
if (conversation.getMode() == Conversation.MODE_SINGLE
|
if (conversation.getMode() == Conversation.MODE_SINGLE
|
||||||
|| activity.useSubjectToIdentifyConference()) {
|
|| activity.useSubjectToIdentifyConference()) {
|
||||||
convName.setText(conversation.getName());
|
convName.setText(conversation.getName());
|
||||||
} else {
|
} else {
|
||||||
convName.setText(conversation.getContactJid().toBareJid().toString());
|
convName.setText(conversation.getJid().toBareJid().toString());
|
||||||
}
|
}
|
||||||
TextView mLastMessage = (TextView) view
|
TextView mLastMessage = (TextView) view
|
||||||
.findViewById(R.id.conversation_lastmsg);
|
.findViewById(R.id.conversation_lastmsg);
|
||||||
TextView mTimestamp = (TextView) view
|
TextView mTimestamp = (TextView) view
|
||||||
.findViewById(R.id.conversation_lastupdate);
|
.findViewById(R.id.conversation_lastupdate);
|
||||||
ImageView imagePreview = (ImageView) view
|
ImageView imagePreview = (ImageView) view
|
||||||
.findViewById(R.id.conversation_lastimage);
|
.findViewById(R.id.conversation_lastimage);
|
||||||
|
|
||||||
Message message = conversation.getLatestMessage();
|
Message message = conversation.getLatestMessage();
|
||||||
|
|
||||||
|
@ -151,12 +151,12 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|
||||||
imagePreview.setVisibility(View.GONE);
|
imagePreview.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
mTimestamp.setText(UIHelper.readableTimeDifference(getContext(),
|
mTimestamp.setText(UIHelper.readableTimeDifference(getContext(),
|
||||||
conversation.getLatestMessage().getTimeSent()));
|
conversation.getLatestMessage().getTimeSent()));
|
||||||
|
|
||||||
ImageView profilePicture = (ImageView) view
|
ImageView profilePicture = (ImageView) view
|
||||||
.findViewById(R.id.conversation_image);
|
.findViewById(R.id.conversation_image);
|
||||||
profilePicture.setImageBitmap(activity.avatarService().get(
|
profilePicture.setImageBitmap(activity.avatarService().get(
|
||||||
conversation, activity.getPixel(56)));
|
conversation, activity.getPixel(56)));
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package eu.siacs.conversations.utils;
|
||||||
|
|
||||||
|
public final class Xmlns {
|
||||||
|
public static final String BLOCKING = "urn:xmpp:blocking";
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ import android.net.Uri;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
|
|
||||||
|
|
|
@ -62,16 +62,16 @@ public class Element {
|
||||||
if (child.getName().equals(name)
|
if (child.getName().equals(name)
|
||||||
&& (child.getAttribute("xmlns").equals(xmlns))) {
|
&& (child.getAttribute("xmlns").equals(xmlns))) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasChild(String name) {
|
public boolean hasChild(final String name) {
|
||||||
return findChild(name) != null;
|
return findChild(name) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasChild(String name, String xmlns) {
|
public boolean hasChild(final String name, final String xmlns) {
|
||||||
return findChild(name, xmlns) != null;
|
return findChild(name, xmlns) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,15 +110,15 @@ public class Element {
|
||||||
|
|
||||||
public Jid getAttributeAsJid(String name) {
|
public Jid getAttributeAsJid(String name) {
|
||||||
final String jid = this.getAttribute(name);
|
final String jid = this.getAttribute(name);
|
||||||
if (jid != null && !jid.isEmpty()) {
|
if (jid != null && !jid.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
return Jid.fromString(jid);
|
return Jid.fromString(jid);
|
||||||
} catch (final InvalidJidException e) {
|
} catch (final InvalidJidException e) {
|
||||||
Log.e(Config.LOGTAG, "could not parse jid " + jid);
|
Log.e(Config.LOGTAG, "could not parse jid " + jid);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hashtable<String, String> getAttributes() {
|
public Hashtable<String, String> getAttributes() {
|
||||||
|
|
|
@ -3,5 +3,5 @@ package eu.siacs.conversations.xmpp;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
|
|
||||||
public interface OnContactStatusChanged {
|
public interface OnContactStatusChanged {
|
||||||
public void onContactStatusChanged(Contact contact, boolean online);
|
public void onContactStatusChanged(final Contact contact, final boolean online);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package eu.siacs.conversations.xmpp;
|
||||||
|
|
||||||
|
public interface OnUpdateBlocklist {
|
||||||
|
// Use an enum instead of a boolean to make sure we don't run into the boolean trap
|
||||||
|
// (`onUpdateBlocklist(true)' doesn't read well, and could be confusing).
|
||||||
|
public static enum Status {
|
||||||
|
BLOCKED,
|
||||||
|
UNBLOCKED
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodNameSameAsClassName")
|
||||||
|
public void OnUpdateBlocklist(final Status status);
|
||||||
|
}
|
|
@ -30,10 +30,12 @@ import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
|
@ -48,8 +50,10 @@ import eu.siacs.conversations.crypto.sasl.Plain;
|
||||||
import eu.siacs.conversations.crypto.sasl.SaslMechanism;
|
import eu.siacs.conversations.crypto.sasl.SaslMechanism;
|
||||||
import eu.siacs.conversations.crypto.sasl.ScramSha1;
|
import eu.siacs.conversations.crypto.sasl.ScramSha1;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
import eu.siacs.conversations.generator.IqGenerator;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.DNSHelper;
|
import eu.siacs.conversations.utils.DNSHelper;
|
||||||
|
import eu.siacs.conversations.utils.Xmlns;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xml.Tag;
|
import eu.siacs.conversations.xml.Tag;
|
||||||
import eu.siacs.conversations.xml.TagWriter;
|
import eu.siacs.conversations.xml.TagWriter;
|
||||||
|
@ -76,19 +80,19 @@ public class XmppConnection implements Runnable {
|
||||||
private static final int PACKET_PRESENCE = 2;
|
private static final int PACKET_PRESENCE = 2;
|
||||||
private final Context applicationContext;
|
private final Context applicationContext;
|
||||||
protected Account account;
|
protected Account account;
|
||||||
private WakeLock wakeLock;
|
private final WakeLock wakeLock;
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private XmlReader tagReader;
|
private XmlReader tagReader;
|
||||||
private TagWriter tagWriter;
|
private TagWriter tagWriter;
|
||||||
private Features features = new Features(this);
|
private final Features features = new Features(this);
|
||||||
private boolean shouldBind = true;
|
private boolean shouldBind = true;
|
||||||
private boolean shouldAuthenticate = true;
|
private boolean shouldAuthenticate = true;
|
||||||
private Element streamFeatures;
|
private Element streamFeatures;
|
||||||
private HashMap<String, List<String>> disco = new HashMap<>();
|
private final HashMap<String, List<String>> disco = new HashMap<>();
|
||||||
|
|
||||||
private String streamId = null;
|
private String streamId = null;
|
||||||
private int smVersion = 3;
|
private int smVersion = 3;
|
||||||
private SparseArray<String> messageReceipts = new SparseArray<>();
|
private final SparseArray<String> messageReceipts = new SparseArray<>();
|
||||||
|
|
||||||
private boolean enabledEncryption = false;
|
private boolean enabledEncryption = false;
|
||||||
private boolean enabledCarbons = false;
|
private boolean enabledCarbons = false;
|
||||||
|
@ -100,20 +104,20 @@ public class XmppConnection implements Runnable {
|
||||||
private long lastConnect = 0;
|
private long lastConnect = 0;
|
||||||
private long lastSessionStarted = 0;
|
private long lastSessionStarted = 0;
|
||||||
private int attempt = 0;
|
private int attempt = 0;
|
||||||
private Hashtable<String, PacketReceived> packetCallbacks = new Hashtable<>();
|
private final Map<String, PacketReceived> packetCallbacks = new Hashtable<>();
|
||||||
private OnPresencePacketReceived presenceListener = null;
|
private OnPresencePacketReceived presenceListener = null;
|
||||||
private OnJinglePacketReceived jingleListener = null;
|
private OnJinglePacketReceived jingleListener = null;
|
||||||
private OnIqPacketReceived unregisteredIqListener = null;
|
private OnIqPacketReceived unregisteredIqListener = null;
|
||||||
private OnMessagePacketReceived messageListener = null;
|
private OnMessagePacketReceived messageListener = null;
|
||||||
private OnStatusChanged statusListener = null;
|
private OnStatusChanged statusListener = null;
|
||||||
private OnBindListener bindListener = null;
|
private OnBindListener bindListener = null;
|
||||||
private ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
|
private final ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
|
||||||
private OnMessageAcknowledged acknowledgedListener = null;
|
private OnMessageAcknowledged acknowledgedListener = null;
|
||||||
private XmppConnectionService mXmppConnectionService = null;
|
private XmppConnectionService mXmppConnectionService = null;
|
||||||
|
|
||||||
private SaslMechanism saslMechanism;
|
private SaslMechanism saslMechanism;
|
||||||
|
|
||||||
public XmppConnection(Account account, XmppConnectionService service) {
|
public XmppConnection(final Account account, final XmppConnectionService service) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.wakeLock = service.getPowerManager().newWakeLock(
|
this.wakeLock = service.getPowerManager().newWakeLock(
|
||||||
PowerManager.PARTIAL_WAKE_LOCK, account.getJid().toBareJid().toString());
|
PowerManager.PARTIAL_WAKE_LOCK, account.getJid().toBareJid().toString());
|
||||||
|
@ -129,7 +133,7 @@ public class XmppConnection implements Runnable {
|
||||||
&& (account.getStatus() != Account.State.ONLINE)
|
&& (account.getStatus() != Account.State.ONLINE)
|
||||||
&& (account.getStatus() != Account.State.DISABLED)) {
|
&& (account.getStatus() != Account.State.DISABLED)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nextStatus == Account.State.ONLINE) {
|
if (nextStatus == Account.State.ONLINE) {
|
||||||
this.attempt = 0;
|
this.attempt = 0;
|
||||||
}
|
}
|
||||||
|
@ -153,15 +157,15 @@ public class XmppConnection implements Runnable {
|
||||||
tagWriter = new TagWriter();
|
tagWriter = new TagWriter();
|
||||||
packetCallbacks.clear();
|
packetCallbacks.clear();
|
||||||
this.changeStatus(Account.State.CONNECTING);
|
this.changeStatus(Account.State.CONNECTING);
|
||||||
Bundle result = DNSHelper.getSRVRecord(account.getServer());
|
final Bundle result = DNSHelper.getSRVRecord(account.getServer());
|
||||||
ArrayList<Parcelable> values = result.getParcelableArrayList("values");
|
final ArrayList<Parcelable> values = result.getParcelableArrayList("values");
|
||||||
if ("timeout".equals(result.getString("error"))) {
|
if ("timeout".equals(result.getString("error"))) {
|
||||||
throw new IOException("timeout in dns");
|
throw new IOException("timeout in dns");
|
||||||
} else if (values != null) {
|
} else if (values != null) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
boolean socketError = true;
|
boolean socketError = true;
|
||||||
while (socketError && values.size() > i) {
|
while (socketError && values.size() > i) {
|
||||||
Bundle namePort = (Bundle) values.get(i);
|
final Bundle namePort = (Bundle) values.get(i);
|
||||||
try {
|
try {
|
||||||
String srvRecordServer;
|
String srvRecordServer;
|
||||||
try {
|
try {
|
||||||
|
@ -170,9 +174,9 @@ public class XmppConnection implements Runnable {
|
||||||
// TODO: Handle me?`
|
// TODO: Handle me?`
|
||||||
srvRecordServer = "";
|
srvRecordServer = "";
|
||||||
}
|
}
|
||||||
int srvRecordPort = namePort.getInt("port");
|
final int srvRecordPort = namePort.getInt("port");
|
||||||
String srvIpServer = namePort.getString("ip");
|
final String srvIpServer = namePort.getString("ip");
|
||||||
InetSocketAddress addr;
|
final InetSocketAddress addr;
|
||||||
if (srvIpServer != null) {
|
if (srvIpServer != null) {
|
||||||
addr = new InetSocketAddress(srvIpServer, srvRecordPort);
|
addr = new InetSocketAddress(srvIpServer, srvRecordPort);
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
||||||
|
@ -187,10 +191,10 @@ public class XmppConnection implements Runnable {
|
||||||
socket = new Socket();
|
socket = new Socket();
|
||||||
socket.connect(addr, 20000);
|
socket.connect(addr, 20000);
|
||||||
socketError = false;
|
socketError = false;
|
||||||
} catch (UnknownHostException e) {
|
} catch (final UnknownHostException e) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
||||||
i++;
|
i++;
|
||||||
} catch (IOException e) {
|
} catch (final IOException e) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -204,9 +208,9 @@ public class XmppConnection implements Runnable {
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("timeout in dns");
|
throw new IOException("timeout in dns");
|
||||||
}
|
}
|
||||||
OutputStream out = socket.getOutputStream();
|
final OutputStream out = socket.getOutputStream();
|
||||||
tagWriter.setOutputStream(out);
|
tagWriter.setOutputStream(out);
|
||||||
InputStream in = socket.getInputStream();
|
final InputStream in = socket.getInputStream();
|
||||||
tagReader.setInputStream(in);
|
tagReader.setInputStream(in);
|
||||||
tagWriter.beginDocument();
|
tagWriter.beginDocument();
|
||||||
sendStartStream();
|
sendStartStream();
|
||||||
|
@ -222,14 +226,9 @@ public class XmppConnection implements Runnable {
|
||||||
if (socket.isConnected()) {
|
if (socket.isConnected()) {
|
||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
} catch (UnknownHostException e) {
|
} catch (final UnknownHostException | ConnectException e) {
|
||||||
this.changeStatus(Account.State.SERVER_NOT_FOUND);
|
this.changeStatus(Account.State.SERVER_NOT_FOUND);
|
||||||
} catch (final ConnectException e) {
|
} catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) {
|
||||||
this.changeStatus(Account.State.SERVER_NOT_FOUND);
|
|
||||||
} catch (final IOException | XmlPullParserException e) {
|
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
|
||||||
this.changeStatus(Account.State.OFFLINE);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
||||||
this.changeStatus(Account.State.OFFLINE);
|
this.changeStatus(Account.State.OFFLINE);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -268,7 +267,7 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in");
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in");
|
||||||
account.setKey(Account.PINNED_MECHANISM_KEY,
|
account.setKey(Account.PINNED_MECHANISM_KEY,
|
||||||
String.valueOf(saslMechanism.getPriority()));
|
String.valueOf(saslMechanism.getPriority()));
|
||||||
tagReader.reset();
|
tagReader.reset();
|
||||||
sendStartStream();
|
sendStartStream();
|
||||||
processStream(tagReader.readTag());
|
processStream(tagReader.readTag());
|
||||||
|
@ -289,7 +288,7 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
tagWriter.writeElement(response);
|
tagWriter.writeElement(response);
|
||||||
} else if (nextTag.isStart("enabled")) {
|
} else if (nextTag.isStart("enabled")) {
|
||||||
Element enabled = tagReader.readElement(nextTag);
|
final Element enabled = tagReader.readElement(nextTag);
|
||||||
if ("true".equals(enabled.getAttribute("resume"))) {
|
if ("true".equals(enabled.getAttribute("resume"))) {
|
||||||
this.streamId = enabled.getAttribute("id");
|
this.streamId = enabled.getAttribute("id");
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
||||||
|
@ -301,14 +300,14 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
this.lastSessionStarted = SystemClock.elapsedRealtime();
|
this.lastSessionStarted = SystemClock.elapsedRealtime();
|
||||||
this.stanzasReceived = 0;
|
this.stanzasReceived = 0;
|
||||||
RequestPacket r = new RequestPacket(smVersion);
|
final RequestPacket r = new RequestPacket(smVersion);
|
||||||
tagWriter.writeStanzaAsync(r);
|
tagWriter.writeStanzaAsync(r);
|
||||||
} else if (nextTag.isStart("resumed")) {
|
} else if (nextTag.isStart("resumed")) {
|
||||||
lastPaketReceived = SystemClock.elapsedRealtime();
|
lastPaketReceived = SystemClock.elapsedRealtime();
|
||||||
Element resumed = tagReader.readElement(nextTag);
|
final Element resumed = tagReader.readElement(nextTag);
|
||||||
String h = resumed.getAttribute("h");
|
final String h = resumed.getAttribute("h");
|
||||||
try {
|
try {
|
||||||
int serverCount = Integer.parseInt(h);
|
final int serverCount = Integer.parseInt(h);
|
||||||
if (serverCount != stanzasSent) {
|
if (serverCount != stanzasSent) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
||||||
+ ": session resumed with lost packages");
|
+ ": session resumed with lost packages");
|
||||||
|
@ -327,20 +326,19 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
messageReceipts.clear();
|
messageReceipts.clear();
|
||||||
} catch (final NumberFormatException ignored) {
|
} catch (final NumberFormatException ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
sendServiceDiscoveryInfo(account.getServer());
|
sendServiceDiscoveryInfo(account.getServer());
|
||||||
sendServiceDiscoveryItems(account.getServer());
|
sendServiceDiscoveryItems(account.getServer());
|
||||||
sendInitialPing();
|
sendInitialPing();
|
||||||
} else if (nextTag.isStart("r")) {
|
} else if (nextTag.isStart("r")) {
|
||||||
tagReader.readElement(nextTag);
|
tagReader.readElement(nextTag);
|
||||||
AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
|
final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
|
||||||
tagWriter.writeStanzaAsync(ack);
|
tagWriter.writeStanzaAsync(ack);
|
||||||
} else if (nextTag.isStart("a")) {
|
} else if (nextTag.isStart("a")) {
|
||||||
Element ack = tagReader.readElement(nextTag);
|
final Element ack = tagReader.readElement(nextTag);
|
||||||
lastPaketReceived = SystemClock.elapsedRealtime();
|
lastPaketReceived = SystemClock.elapsedRealtime();
|
||||||
int serverSequence = Integer.parseInt(ack.getAttribute("h"));
|
final int serverSequence = Integer.parseInt(ack.getAttribute("h"));
|
||||||
String msgId = this.messageReceipts.get(serverSequence);
|
final String msgId = this.messageReceipts.get(serverSequence);
|
||||||
if (msgId != null) {
|
if (msgId != null) {
|
||||||
if (this.acknowledgedListener != null) {
|
if (this.acknowledgedListener != null) {
|
||||||
this.acknowledgedListener.onMessageAcknowledged(
|
this.acknowledgedListener.onMessageAcknowledged(
|
||||||
|
@ -374,13 +372,12 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
private void sendInitialPing() {
|
private void sendInitialPing() {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": sending intial ping");
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": sending intial ping");
|
||||||
IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
|
final IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
|
||||||
iq.setFrom(account.getJid());
|
iq.setFrom(account.getJid());
|
||||||
iq.addChild("ping", "urn:xmpp:ping");
|
iq.addChild("ping", "urn:xmpp:ping");
|
||||||
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
|
||||||
+ ": online with resource " + account.getResource());
|
+ ": online with resource " + account.getResource());
|
||||||
changeStatus(Account.State.ONLINE);
|
changeStatus(Account.State.ONLINE);
|
||||||
|
@ -388,7 +385,7 @@ public class XmppConnection implements Runnable {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element processPacket(Tag currentTag, int packetType)
|
private Element processPacket(final Tag currentTag, final int packetType)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
Element element;
|
Element element;
|
||||||
switch (packetType) {
|
switch (packetType) {
|
||||||
|
@ -411,8 +408,8 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
while (!nextTag.isEnd(element.getName())) {
|
while (!nextTag.isEnd(element.getName())) {
|
||||||
if (!nextTag.isNo()) {
|
if (!nextTag.isNo()) {
|
||||||
Element child = tagReader.readElement(nextTag);
|
final Element child = tagReader.readElement(nextTag);
|
||||||
String type = currentTag.getAttribute("type");
|
final String type = currentTag.getAttribute("type");
|
||||||
if (packetType == PACKET_IQ
|
if (packetType == PACKET_IQ
|
||||||
&& "jingle".equals(child.getName())
|
&& "jingle".equals(child.getName())
|
||||||
&& ("set".equalsIgnoreCase(type) || "get"
|
&& ("set".equalsIgnoreCase(type) || "get"
|
||||||
|
@ -432,9 +429,9 @@ public class XmppConnection implements Runnable {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processIq(Tag currentTag) throws XmlPullParserException,
|
private void processIq(final Tag currentTag) throws XmlPullParserException,
|
||||||
IOException {
|
IOException {
|
||||||
IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ);
|
final IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ);
|
||||||
|
|
||||||
if (packet.getId() == null) {
|
if (packet.getId() == null) {
|
||||||
return; // an iq packet without id is definitely invalid
|
return; // an iq packet without id is definitely invalid
|
||||||
|
@ -461,11 +458,11 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processMessage(Tag currentTag) throws XmlPullParserException,
|
private void processMessage(final Tag currentTag) throws XmlPullParserException,
|
||||||
IOException {
|
IOException {
|
||||||
MessagePacket packet = (MessagePacket) processPacket(currentTag,
|
final MessagePacket packet = (MessagePacket) processPacket(currentTag,
|
||||||
PACKET_MESSAGE);
|
PACKET_MESSAGE);
|
||||||
String id = packet.getAttribute("id");
|
final String id = packet.getAttribute("id");
|
||||||
if ((id != null) && (packetCallbacks.containsKey(id))) {
|
if ((id != null) && (packetCallbacks.containsKey(id))) {
|
||||||
if (packetCallbacks.get(id) instanceof OnMessagePacketReceived) {
|
if (packetCallbacks.get(id) instanceof OnMessagePacketReceived) {
|
||||||
((OnMessagePacketReceived) packetCallbacks.get(id))
|
((OnMessagePacketReceived) packetCallbacks.get(id))
|
||||||
|
@ -477,11 +474,11 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processPresence(Tag currentTag) throws XmlPullParserException,
|
private void processPresence(final Tag currentTag) throws XmlPullParserException,
|
||||||
IOException {
|
IOException {
|
||||||
PresencePacket packet = (PresencePacket) processPacket(currentTag,
|
PresencePacket packet = (PresencePacket) processPacket(currentTag,
|
||||||
PACKET_PRESENCE);
|
PACKET_PRESENCE);
|
||||||
String id = packet.getAttribute("id");
|
final String id = packet.getAttribute("id");
|
||||||
if ((id != null) && (packetCallbacks.containsKey(id))) {
|
if ((id != null) && (packetCallbacks.containsKey(id))) {
|
||||||
if (packetCallbacks.get(id) instanceof OnPresencePacketReceived) {
|
if (packetCallbacks.get(id) instanceof OnPresencePacketReceived) {
|
||||||
((OnPresencePacketReceived) packetCallbacks.get(id))
|
((OnPresencePacketReceived) packetCallbacks.get(id))
|
||||||
|
@ -494,7 +491,7 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendStartTLS() throws IOException {
|
private void sendStartTLS() throws IOException {
|
||||||
Tag startTLS = Tag.empty("starttls");
|
final Tag startTLS = Tag.empty("starttls");
|
||||||
startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
|
startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
|
||||||
tagWriter.writeTag(startTLS);
|
tagWriter.writeTag(startTLS);
|
||||||
}
|
}
|
||||||
|
@ -512,11 +509,11 @@ public class XmppConnection implements Runnable {
|
||||||
IOException {
|
IOException {
|
||||||
tagReader.readTag();
|
tagReader.readTag();
|
||||||
try {
|
try {
|
||||||
SSLContext sc = SSLContext.getInstance("TLS");
|
final SSLContext sc = SSLContext.getInstance("TLS");
|
||||||
sc.init(null,
|
sc.init(null,
|
||||||
new X509TrustManager[]{this.mXmppConnectionService.getMemorizingTrustManager()},
|
new X509TrustManager[]{this.mXmppConnectionService.getMemorizingTrustManager()},
|
||||||
mXmppConnectionService.getRNG());
|
mXmppConnectionService.getRNG());
|
||||||
SSLSocketFactory factory = sc.getSocketFactory();
|
final SSLSocketFactory factory = sc.getSocketFactory();
|
||||||
|
|
||||||
if (factory == null) {
|
if (factory == null) {
|
||||||
throw new IOException("SSLSocketFactory was null");
|
throw new IOException("SSLSocketFactory was null");
|
||||||
|
@ -541,7 +538,7 @@ public class XmppConnection implements Runnable {
|
||||||
if (enableLegacySSL()) {
|
if (enableLegacySSL()) {
|
||||||
supportProtocols = sslSocket.getSupportedProtocols();
|
supportProtocols = sslSocket.getSupportedProtocols();
|
||||||
} else {
|
} else {
|
||||||
final List<String> supportedProtocols = new LinkedList<>(
|
final Collection<String> supportedProtocols = new LinkedList<>(
|
||||||
Arrays.asList(sslSocket.getSupportedProtocols()));
|
Arrays.asList(sslSocket.getSupportedProtocols()));
|
||||||
supportedProtocols.remove("SSLv3");
|
supportedProtocols.remove("SSLv3");
|
||||||
supportProtocols = new String[supportedProtocols.size()];
|
supportProtocols = new String[supportedProtocols.size()];
|
||||||
|
@ -549,13 +546,13 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
sslSocket.setEnabledProtocols(supportProtocols);
|
sslSocket.setEnabledProtocols(supportProtocols);
|
||||||
|
|
||||||
if (verifier != null
|
if (verifier != null
|
||||||
&& !verifier.verify(account.getServer().getDomainpart(),
|
&& !verifier.verify(account.getServer().getDomainpart(),
|
||||||
sslSocket.getSession())) {
|
sslSocket.getSession())) {
|
||||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed");
|
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed");
|
||||||
disconnect(true);
|
disconnect(true);
|
||||||
changeStatus(Account.State.SECURITY_ERROR);
|
changeStatus(Account.State.SECURITY_ERROR);
|
||||||
}
|
}
|
||||||
tagReader.setInputStream(sslSocket.getInputStream());
|
tagReader.setInputStream(sslSocket.getInputStream());
|
||||||
tagWriter.setOutputStream(sslSocket.getOutputStream());
|
tagWriter.setOutputStream(sslSocket.getOutputStream());
|
||||||
sendStartStream();
|
sendStartStream();
|
||||||
|
@ -569,7 +566,7 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processStreamFeatures(Tag currentTag)
|
private void processStreamFeatures(final Tag currentTag)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
this.streamFeatures = tagReader.readElement(currentTag);
|
this.streamFeatures = tagReader.readElement(currentTag);
|
||||||
if (this.streamFeatures.hasChild("starttls") && !enabledEncryption) {
|
if (this.streamFeatures.hasChild("starttls") && !enabledEncryption) {
|
||||||
|
@ -605,7 +602,7 @@ public class XmppConnection implements Runnable {
|
||||||
"). Possible downgrade attack?");
|
"). Possible downgrade attack?");
|
||||||
disconnect(true);
|
disconnect(true);
|
||||||
changeStatus(Account.State.SECURITY_ERROR);
|
changeStatus(Account.State.SECURITY_ERROR);
|
||||||
}
|
}
|
||||||
} catch (final JSONException e) {
|
} catch (final JSONException e) {
|
||||||
Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism");
|
Log.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism");
|
||||||
}
|
}
|
||||||
|
@ -618,7 +615,7 @@ public class XmppConnection implements Runnable {
|
||||||
} else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:"
|
} else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:"
|
||||||
+ smVersion)
|
+ smVersion)
|
||||||
&& streamId != null) {
|
&& streamId != null) {
|
||||||
ResumePacket resume = new ResumePacket(this.streamId,
|
final ResumePacket resume = new ResumePacket(this.streamId,
|
||||||
stanzasReceived, smVersion);
|
stanzasReceived, smVersion);
|
||||||
this.tagWriter.writeStanzaAsync(resume);
|
this.tagWriter.writeStanzaAsync(resume);
|
||||||
} else if (this.streamFeatures.hasChild("bind") && shouldBind) {
|
} else if (this.streamFeatures.hasChild("bind") && shouldBind) {
|
||||||
|
@ -629,45 +626,44 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> extractMechanisms(Element stream) {
|
private List<String> extractMechanisms(final Element stream) {
|
||||||
ArrayList<String> mechanisms = new ArrayList<>(stream
|
final ArrayList<String> mechanisms = new ArrayList<>(stream
|
||||||
.getChildren().size());
|
.getChildren().size());
|
||||||
for (Element child : stream.getChildren()) {
|
for (final Element child : stream.getChildren()) {
|
||||||
mechanisms.add(child.getContent());
|
mechanisms.add(child.getContent());
|
||||||
}
|
}
|
||||||
return mechanisms;
|
return mechanisms;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendRegistryRequest() {
|
private void sendRegistryRequest() {
|
||||||
IqPacket register = new IqPacket(IqPacket.TYPE_GET);
|
final IqPacket register = new IqPacket(IqPacket.TYPE_GET);
|
||||||
register.query("jabber:iq:register");
|
register.query("jabber:iq:register");
|
||||||
register.setTo(account.getServer());
|
register.setTo(account.getServer());
|
||||||
sendIqPacket(register, new OnIqPacketReceived() {
|
sendIqPacket(register, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
Element instructions = packet.query().findChild("instructions");
|
final Element instructions = packet.query().findChild("instructions");
|
||||||
if (packet.query().hasChild("username")
|
if (packet.query().hasChild("username")
|
||||||
&& (packet.query().hasChild("password"))) {
|
&& (packet.query().hasChild("password"))) {
|
||||||
IqPacket register = new IqPacket(IqPacket.TYPE_SET);
|
final IqPacket register = new IqPacket(IqPacket.TYPE_SET);
|
||||||
Element username = new Element("username")
|
final Element username = new Element("username")
|
||||||
.setContent(account.getUsername());
|
.setContent(account.getUsername());
|
||||||
Element password = new Element("password")
|
final Element password = new Element("password")
|
||||||
.setContent(account.getPassword());
|
.setContent(account.getPassword());
|
||||||
register.query("jabber:iq:register").addChild(username);
|
register.query("jabber:iq:register").addChild(username);
|
||||||
register.query().addChild(password);
|
register.query().addChild(password);
|
||||||
sendIqPacket(register, new OnIqPacketReceived() {
|
sendIqPacket(register, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account,
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
IqPacket packet) {
|
|
||||||
if (packet.getType() == IqPacket.TYPE_RESULT) {
|
if (packet.getType() == IqPacket.TYPE_RESULT) {
|
||||||
account.setOption(Account.OPTION_REGISTER,
|
account.setOption(Account.OPTION_REGISTER,
|
||||||
false);
|
false);
|
||||||
changeStatus(Account.State.REGISTRATION_SUCCESSFUL);
|
changeStatus(Account.State.REGISTRATION_SUCCESSFUL);
|
||||||
} else if (packet.hasChild("error")
|
} else if (packet.hasChild("error")
|
||||||
&& (packet.findChild("error")
|
&& (packet.findChild("error")
|
||||||
.hasChild("conflict"))) {
|
.hasChild("conflict"))) {
|
||||||
changeStatus(Account.State.REGISTRATION_CONFLICT);
|
changeStatus(Account.State.REGISTRATION_CONFLICT);
|
||||||
} else {
|
} else {
|
||||||
changeStatus(Account.State.REGISTRATION_FAILED);
|
changeStatus(Account.State.REGISTRATION_FAILED);
|
||||||
|
@ -687,14 +683,14 @@ public class XmppConnection implements Runnable {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendBindRequest() throws IOException {
|
private void sendBindRequest() {
|
||||||
IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
|
final IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
|
||||||
iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind")
|
iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind")
|
||||||
.addChild("resource").setContent(account.getResource());
|
.addChild("resource").setContent(account.getResource());
|
||||||
this.sendUnboundIqPacket(iq, new OnIqPacketReceived() {
|
this.sendUnboundIqPacket(iq, new OnIqPacketReceived() {
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
Element bind = packet.findChild("bind");
|
final Element bind = packet.findChild("bind");
|
||||||
if (bind != null) {
|
if (bind != null) {
|
||||||
final Element jid = bind.findChild("jid");
|
final Element jid = bind.findChild("jid");
|
||||||
if (jid != null && jid.getContent() != null) {
|
if (jid != null && jid.getContent() != null) {
|
||||||
|
@ -705,14 +701,14 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
|
if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
|
||||||
smVersion = 3;
|
smVersion = 3;
|
||||||
EnablePacket enable = new EnablePacket(smVersion);
|
final EnablePacket enable = new EnablePacket(smVersion);
|
||||||
tagWriter.writeStanzaAsync(enable);
|
tagWriter.writeStanzaAsync(enable);
|
||||||
stanzasSent = 0;
|
stanzasSent = 0;
|
||||||
messageReceipts.clear();
|
messageReceipts.clear();
|
||||||
} else if (streamFeatures.hasChild("sm",
|
} else if (streamFeatures.hasChild("sm",
|
||||||
"urn:xmpp:sm:2")) {
|
"urn:xmpp:sm:2")) {
|
||||||
smVersion = 2;
|
smVersion = 2;
|
||||||
EnablePacket enable = new EnablePacket(smVersion);
|
final EnablePacket enable = new EnablePacket(smVersion);
|
||||||
tagWriter.writeStanzaAsync(enable);
|
tagWriter.writeStanzaAsync(enable);
|
||||||
stanzasSent = 0;
|
stanzasSent = 0;
|
||||||
messageReceipts.clear();
|
messageReceipts.clear();
|
||||||
|
@ -736,7 +732,7 @@ public class XmppConnection implements Runnable {
|
||||||
if (this.streamFeatures.hasChild("session")) {
|
if (this.streamFeatures.hasChild("session")) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
||||||
+ ": sending deprecated session");
|
+ ": sending deprecated session");
|
||||||
IqPacket startSession = new IqPacket(IqPacket.TYPE_SET);
|
final IqPacket startSession = new IqPacket(IqPacket.TYPE_SET);
|
||||||
startSession.addChild("session",
|
startSession.addChild("session",
|
||||||
"urn:ietf:params:xml:ns:xmpp-session");
|
"urn:ietf:params:xml:ns:xmpp-session");
|
||||||
this.sendUnboundIqPacket(startSession, null);
|
this.sendUnboundIqPacket(startSession, null);
|
||||||
|
@ -755,10 +751,10 @@ public class XmppConnection implements Runnable {
|
||||||
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
final List<Element> elements = packet.query().getChildren();
|
final List<Element> elements = packet.query().getChildren();
|
||||||
final List<String> features = new ArrayList<>();
|
final List<String> features = new ArrayList<>();
|
||||||
for (Element element : elements) {
|
for (final Element element : elements) {
|
||||||
if (element.getName().equals("identity")) {
|
if (element.getName().equals("identity")) {
|
||||||
if ("irc".equals(element.getAttribute("type"))) {
|
if ("irc".equals(element.getAttribute("type"))) {
|
||||||
//add fake feature to not confuse irc and real muc
|
//add fake feature to not confuse irc and real muc
|
||||||
|
@ -772,7 +768,7 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
if (account.getServer().equals(server.toDomainJid())) {
|
if (account.getServer().equals(server.toDomainJid())) {
|
||||||
enableAdvancedStreamFeatures();
|
enableAdvancedStreamFeatures();
|
||||||
for(OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
|
for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
|
||||||
listener.onAdvancedStreamFeaturesAvailable(account);
|
listener.onAdvancedStreamFeaturesAvailable(account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -787,6 +783,10 @@ public class XmppConnection implements Runnable {
|
||||||
sendEnableCarbons();
|
sendEnableCarbons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (getFeatures().blocking()) {
|
||||||
|
Log.d(Config.LOGTAG, "Requesting block list");
|
||||||
|
this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendServiceDiscoveryItems(final Jid server) {
|
private void sendServiceDiscoveryItems(final Jid server) {
|
||||||
|
@ -796,9 +796,9 @@ public class XmppConnection implements Runnable {
|
||||||
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
List<Element> elements = packet.query().getChildren();
|
final List<Element> elements = packet.query().getChildren();
|
||||||
for (Element element : elements) {
|
for (final Element element : elements) {
|
||||||
if (element.getName().equals("item")) {
|
if (element.getName().equals("item")) {
|
||||||
final Jid jid = element.getAttributeAsJid("jid");
|
final Jid jid = element.getAttributeAsJid("jid");
|
||||||
if (jid != null && !jid.equals(account.getServer())) {
|
if (jid != null && !jid.equals(account.getServer())) {
|
||||||
|
@ -811,12 +811,12 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendEnableCarbons() {
|
private void sendEnableCarbons() {
|
||||||
IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
|
final IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
|
||||||
iq.addChild("enable", "urn:xmpp:carbons:2");
|
iq.addChild("enable", "urn:xmpp:carbons:2");
|
||||||
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(final Account account, final IqPacket packet) {
|
||||||
if (!packet.hasChild("error")) {
|
if (!packet.hasChild("error")) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
||||||
+ ": successfully enabled carbons");
|
+ ": successfully enabled carbons");
|
||||||
|
@ -829,20 +829,20 @@ public class XmppConnection implements Runnable {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processStreamError(Tag currentTag)
|
private void processStreamError(final Tag currentTag)
|
||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
Element streamError = tagReader.readElement(currentTag);
|
final Element streamError = tagReader.readElement(currentTag);
|
||||||
if (streamError != null && streamError.hasChild("conflict")) {
|
if (streamError != null && streamError.hasChild("conflict")) {
|
||||||
final String resource = account.getResource().split("\\.")[0];
|
final String resource = account.getResource().split("\\.")[0];
|
||||||
account.setResource(resource + "." + nextRandomId());
|
account.setResource(resource + "." + nextRandomId());
|
||||||
Log.d(Config.LOGTAG,
|
Log.d(Config.LOGTAG,
|
||||||
account.getJid().toBareJid() + ": switching resource due to conflict ("
|
account.getJid().toBareJid() + ": switching resource due to conflict ("
|
||||||
+ account.getResource() + ")");
|
+ account.getResource() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendStartStream() throws IOException {
|
private void sendStartStream() throws IOException {
|
||||||
Tag stream = Tag.start("stream:stream");
|
final Tag stream = Tag.start("stream:stream");
|
||||||
stream.setAttribute("from", account.getJid().toBareJid().toString());
|
stream.setAttribute("from", account.getJid().toBareJid().toString());
|
||||||
stream.setAttribute("to", account.getServer().toString());
|
stream.setAttribute("to", account.getServer().toString());
|
||||||
stream.setAttribute("version", "1.0");
|
stream.setAttribute("version", "1.0");
|
||||||
|
@ -856,33 +856,32 @@ public class XmppConnection implements Runnable {
|
||||||
return new BigInteger(50, mXmppConnectionService.getRNG()).toString(32);
|
return new BigInteger(50, mXmppConnectionService.getRNG()).toString(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) {
|
public void sendIqPacket(final IqPacket packet, final PacketReceived callback) {
|
||||||
if (packet.getId() == null) {
|
if (packet.getId() == null) {
|
||||||
String id = nextRandomId();
|
final String id = nextRandomId();
|
||||||
packet.setAttribute("id", id);
|
packet.setAttribute("id", id);
|
||||||
}
|
}
|
||||||
packet.setFrom(account.getJid());
|
packet.setFrom(account.getJid());
|
||||||
this.sendPacket(packet, callback);
|
this.sendPacket(packet, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendUnboundIqPacket(IqPacket packet, OnIqPacketReceived callback) {
|
public void sendUnboundIqPacket(final IqPacket packet, final PacketReceived callback) {
|
||||||
if (packet.getId() == null) {
|
if (packet.getId() == null) {
|
||||||
String id = nextRandomId();
|
final String id = nextRandomId();
|
||||||
packet.setAttribute("id", id);
|
packet.setAttribute("id", id);
|
||||||
}
|
}
|
||||||
this.sendPacket(packet, callback);
|
this.sendPacket(packet, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessagePacket(MessagePacket packet) {
|
public void sendMessagePacket(final MessagePacket packet) {
|
||||||
this.sendPacket(packet, null);
|
this.sendPacket(packet, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendPresencePacket(PresencePacket packet) {
|
public void sendPresencePacket(final PresencePacket packet) {
|
||||||
this.sendPacket(packet, null);
|
this.sendPacket(packet, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void sendPacket(final AbstractStanza packet,
|
private synchronized void sendPacket(final AbstractStanza packet, final PacketReceived callback) {
|
||||||
PacketReceived callback) {
|
|
||||||
if (packet.getName().equals("iq") || packet.getName().equals("message")
|
if (packet.getName().equals("iq") || packet.getName().equals("message")
|
||||||
|| packet.getName().equals("presence")) {
|
|| packet.getName().equals("presence")) {
|
||||||
++stanzasSent;
|
++stanzasSent;
|
||||||
|
@ -907,7 +906,7 @@ public class XmppConnection implements Runnable {
|
||||||
if (streamFeatures.hasChild("sm")) {
|
if (streamFeatures.hasChild("sm")) {
|
||||||
tagWriter.writeStanzaAsync(new RequestPacket(smVersion));
|
tagWriter.writeStanzaAsync(new RequestPacket(smVersion));
|
||||||
} else {
|
} else {
|
||||||
IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
|
final IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
|
||||||
iq.setFrom(account.getJid());
|
iq.setFrom(account.getJid());
|
||||||
iq.addChild("ping", "urn:xmpp:ping");
|
iq.addChild("ping", "urn:xmpp:ping");
|
||||||
this.sendIqPacket(iq, null);
|
this.sendIqPacket(iq, null);
|
||||||
|
@ -916,44 +915,44 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnMessagePacketReceivedListener(
|
public void setOnMessagePacketReceivedListener(
|
||||||
OnMessagePacketReceived listener) {
|
final OnMessagePacketReceived listener) {
|
||||||
this.messageListener = listener;
|
this.messageListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnUnregisteredIqPacketReceivedListener(
|
public void setOnUnregisteredIqPacketReceivedListener(
|
||||||
OnIqPacketReceived listener) {
|
final OnIqPacketReceived listener) {
|
||||||
this.unregisteredIqListener = listener;
|
this.unregisteredIqListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnPresencePacketReceivedListener(
|
public void setOnPresencePacketReceivedListener(
|
||||||
OnPresencePacketReceived listener) {
|
final OnPresencePacketReceived listener) {
|
||||||
this.presenceListener = listener;
|
this.presenceListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnJinglePacketReceivedListener(
|
public void setOnJinglePacketReceivedListener(
|
||||||
OnJinglePacketReceived listener) {
|
final OnJinglePacketReceived listener) {
|
||||||
this.jingleListener = listener;
|
this.jingleListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnStatusChangedListener(OnStatusChanged listener) {
|
public void setOnStatusChangedListener(final OnStatusChanged listener) {
|
||||||
this.statusListener = listener;
|
this.statusListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnBindListener(OnBindListener listener) {
|
public void setOnBindListener(final OnBindListener listener) {
|
||||||
this.bindListener = listener;
|
this.bindListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnMessageAcknowledgeListener(OnMessageAcknowledged listener) {
|
public void setOnMessageAcknowledgeListener(final OnMessageAcknowledged listener) {
|
||||||
this.acknowledgedListener = listener;
|
this.acknowledgedListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addOnAdvancedStreamFeaturesAvailableListener(OnAdvancedStreamFeaturesLoaded listener) {
|
public void addOnAdvancedStreamFeaturesAvailableListener(final OnAdvancedStreamFeaturesLoaded listener) {
|
||||||
if (!this.advancedStreamFeaturesLoadedListeners.contains(listener)) {
|
if (!this.advancedStreamFeaturesLoadedListeners.contains(listener)) {
|
||||||
this.advancedStreamFeaturesLoadedListeners.add(listener);
|
this.advancedStreamFeaturesLoadedListeners.add(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect(boolean force) {
|
public void disconnect(final boolean force) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting");
|
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting");
|
||||||
try {
|
try {
|
||||||
if (force) {
|
if (force) {
|
||||||
|
@ -973,23 +972,23 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
tagWriter.writeTag(Tag.end("stream:stream"));
|
tagWriter.writeTag(Tag.end("stream:stream"));
|
||||||
socket.close();
|
socket.close();
|
||||||
} catch (IOException e) {
|
} catch (final IOException e) {
|
||||||
Log.d(Config.LOGTAG,
|
Log.d(Config.LOGTAG,
|
||||||
"io exception during disconnect");
|
"io exception during disconnect");
|
||||||
} catch (InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
Log.d(Config.LOGTAG, "interrupted");
|
Log.d(Config.LOGTAG, "interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
} catch (IOException e) {
|
} catch (final IOException e) {
|
||||||
Log.d(Config.LOGTAG, "io exception during disconnect");
|
Log.d(Config.LOGTAG, "io exception during disconnect");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> findDiscoItemsByFeature(String feature) {
|
public List<String> findDiscoItemsByFeature(final String feature) {
|
||||||
final List<String> items = new ArrayList<>();
|
final List<String> items = new ArrayList<>();
|
||||||
for (Entry<String, List<String>> cursor : disco.entrySet()) {
|
for (final Entry<String, List<String>> cursor : disco.entrySet()) {
|
||||||
if (cursor.getValue().contains(feature)) {
|
if (cursor.getValue().contains(feature)) {
|
||||||
items.add(cursor.getKey());
|
items.add(cursor.getKey());
|
||||||
}
|
}
|
||||||
|
@ -997,8 +996,8 @@ public class XmppConnection implements Runnable {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String findDiscoItemByFeature(String feature) {
|
public String findDiscoItemByFeature(final String feature) {
|
||||||
List<String> items = findDiscoItemsByFeature(feature);
|
final List<String> items = findDiscoItemsByFeature(feature);
|
||||||
if (items.size() >= 1) {
|
if (items.size() >= 1) {
|
||||||
return items.get(0);
|
return items.get(0);
|
||||||
}
|
}
|
||||||
|
@ -1010,8 +1009,7 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMucServer() {
|
public String getMucServer() {
|
||||||
final List<String> items = new ArrayList<>();
|
for (final Entry<String, List<String>> cursor : disco.entrySet()) {
|
||||||
for (Entry<String, List<String>> cursor : disco.entrySet()) {
|
|
||||||
final List<String> value = cursor.getValue();
|
final List<String> value = cursor.getValue();
|
||||||
if (value.contains("http://jabber.org/protocol/muc") && !value.contains("jabber:iq:gateway") && !value.contains("siacs:no:muc")) {
|
if (value.contains("http://jabber.org/protocol/muc") && !value.contains("jabber:iq:gateway") && !value.contains("siacs:no:muc")) {
|
||||||
return cursor.getKey();
|
return cursor.getKey();
|
||||||
|
@ -1021,8 +1019,8 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTimeToNextAttempt() {
|
public int getTimeToNextAttempt() {
|
||||||
int interval = (int) (25 * Math.pow(1.5, attempt));
|
final int interval = (int) (25 * Math.pow(1.5, attempt));
|
||||||
int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000);
|
final int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000);
|
||||||
return interval - secondsSinceLast;
|
return interval - secondsSinceLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,7 +1033,7 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLastSessionEstablished() {
|
public long getLastSessionEstablished() {
|
||||||
long diff;
|
final long diff;
|
||||||
if (this.lastSessionStarted == 0) {
|
if (this.lastSessionStarted == 0) {
|
||||||
diff = SystemClock.elapsedRealtime() - this.lastConnect;
|
diff = SystemClock.elapsedRealtime() - this.lastConnect;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1067,7 +1065,7 @@ public class XmppConnection implements Runnable {
|
||||||
public class Features {
|
public class Features {
|
||||||
XmppConnection connection;
|
XmppConnection connection;
|
||||||
|
|
||||||
public Features(XmppConnection connection) {
|
public Features(final XmppConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1080,6 +1078,10 @@ public class XmppConnection implements Runnable {
|
||||||
return hasDiscoFeature(account.getServer(), "urn:xmpp:carbons:2");
|
return hasDiscoFeature(account.getServer(), "urn:xmpp:carbons:2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean blocking() {
|
||||||
|
return hasDiscoFeature(account.getServer(), Xmlns.BLOCKING);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean sm() {
|
public boolean sm() {
|
||||||
return streamId != null;
|
return streamId != null;
|
||||||
}
|
}
|
||||||
|
@ -1110,4 +1112,8 @@ public class XmppConnection implements Runnable {
|
||||||
.findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
|
.findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IqGenerator getIqGenerator() {
|
||||||
|
return mXmppConnectionService.getIqGenerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ public final class Jid {
|
||||||
return resourcepart;
|
return resourcepart;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Jid fromSessionID(SessionID id) throws InvalidJidException{
|
public static Jid fromSessionID(final SessionID id) throws InvalidJidException{
|
||||||
if (id.getUserID().isEmpty()) {
|
if (id.getUserID().isEmpty()) {
|
||||||
return Jid.fromString(id.getAccountID());
|
return Jid.fromString(id.getAccountID());
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,4 +190,8 @@ public final class Jid {
|
||||||
public boolean isBareJid() {
|
public boolean isBareJid() {
|
||||||
return this.resourcepart.isEmpty();
|
return this.resourcepart.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDomainJid() {
|
||||||
|
return !this.hasLocalpart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,27 @@ public class IqPacket extends AbstractStanza {
|
||||||
public static final int TYPE_RESULT = 1;
|
public static final int TYPE_RESULT = 1;
|
||||||
public static final int TYPE_GET = 2;
|
public static final int TYPE_GET = 2;
|
||||||
|
|
||||||
private IqPacket(String name) {
|
private IqPacket(final String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket(int type) {
|
public IqPacket(final int type) {
|
||||||
super("iq");
|
super("iq");
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_SET:
|
case TYPE_SET:
|
||||||
this.setAttribute("type", "set");
|
this.setAttribute("type", "set");
|
||||||
break;
|
break;
|
||||||
case TYPE_GET:
|
case TYPE_GET:
|
||||||
this.setAttribute("type", "get");
|
this.setAttribute("type", "get");
|
||||||
break;
|
break;
|
||||||
case TYPE_RESULT:
|
case TYPE_RESULT:
|
||||||
this.setAttribute("type", "result");
|
this.setAttribute("type", "result");
|
||||||
break;
|
break;
|
||||||
case TYPE_ERROR:
|
case TYPE_ERROR:
|
||||||
this.setAttribute("type", "error");
|
this.setAttribute("type", "error");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,29 +45,30 @@ public class IqPacket extends AbstractStanza {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element query(String xmlns) {
|
public Element query(final String xmlns) {
|
||||||
Element query = query();
|
final Element query = query();
|
||||||
query.setAttribute("xmlns", xmlns);
|
query.setAttribute("xmlns", xmlns);
|
||||||
return query();
|
return query();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getType() {
|
public int getType() {
|
||||||
String type = getAttribute("type");
|
final String type = getAttribute("type");
|
||||||
if ("error".equals(type)) {
|
switch (type) {
|
||||||
return TYPE_ERROR;
|
case "error":
|
||||||
} else if ("result".equals(type)) {
|
return TYPE_ERROR;
|
||||||
return TYPE_RESULT;
|
case "result":
|
||||||
} else if ("set".equals(type)) {
|
return TYPE_RESULT;
|
||||||
return TYPE_SET;
|
case "set":
|
||||||
} else if ("get".equals(type)) {
|
return TYPE_SET;
|
||||||
return TYPE_GET;
|
case "get":
|
||||||
} else {
|
return TYPE_GET;
|
||||||
return 1000;
|
default:
|
||||||
|
return 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket generateRespone(int type) {
|
public IqPacket generateRespone(final int type) {
|
||||||
IqPacket packet = new IqPacket(type);
|
final IqPacket packet = new IqPacket(type);
|
||||||
packet.setTo(this.getFrom());
|
packet.setTo(this.getFrom());
|
||||||
packet.setId(this.getId());
|
packet.setId(this.getId());
|
||||||
return packet;
|
return packet;
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/context_contact_details"
|
android:id="@+id/context_contact_details"
|
||||||
android:title="@string/view_contact_details"/>
|
android:title="@string/view_contact_details"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/context_contact_block_unblock"
|
||||||
|
android:title="@string/block_contact"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/context_delete_contact"
|
android:id="@+id/context_delete_contact"
|
||||||
android:title="@string/delete_contact"/>
|
android:title="@string/delete_contact"/>
|
||||||
|
|
|
@ -56,6 +56,18 @@
|
||||||
android:showAsAction="never"
|
android:showAsAction="never"
|
||||||
android:title="@string/enable_notifications"/>
|
android:title="@string/enable_notifications"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_block"
|
||||||
|
android:orderInCategory="72"
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/action_block_contact"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_unblock"
|
||||||
|
android:orderInCategory="73"
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/action_unblock_contact"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_accounts"
|
android:id="@+id/action_accounts"
|
||||||
android:orderInCategory="90"
|
android:orderInCategory="90"
|
||||||
|
|
|
@ -4,5 +4,9 @@
|
||||||
android:id="@+id/action_show_qr_code"
|
android:id="@+id/action_show_qr_code"
|
||||||
android:title="@string/show_qr_code"
|
android:title="@string/show_qr_code"
|
||||||
android:showAsAction="never" />
|
android:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_show_block_list"
|
||||||
|
android:title="@string/show_block_list"
|
||||||
|
android:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
|
@ -13,6 +13,10 @@
|
||||||
<string name="action_edit_contact">Edit name</string>
|
<string name="action_edit_contact">Edit name</string>
|
||||||
<string name="action_add_phone_book">Add to phone book</string>
|
<string name="action_add_phone_book">Add to phone book</string>
|
||||||
<string name="action_delete_contact">Delete from roster</string>
|
<string name="action_delete_contact">Delete from roster</string>
|
||||||
|
<string name="action_block_contact">Block contact</string>
|
||||||
|
<string name="action_unblock_contact">Unblock contact</string>
|
||||||
|
<string name="action_block_domain">Block domain</string>
|
||||||
|
<string name="action_unblock_domain">Unblock domain</string>
|
||||||
<string name="title_activity_manage_accounts">Manage Accounts</string>
|
<string name="title_activity_manage_accounts">Manage Accounts</string>
|
||||||
<string name="title_activity_settings">Settings</string>
|
<string name="title_activity_settings">Settings</string>
|
||||||
<string name="title_activity_conference_details">Conference Details</string>
|
<string name="title_activity_conference_details">Conference Details</string>
|
||||||
|
@ -21,6 +25,7 @@
|
||||||
<string name="title_activity_sharewith">Share with Conversation</string>
|
<string name="title_activity_sharewith">Share with Conversation</string>
|
||||||
<string name="title_activity_start_conversation">Start Conversation</string>
|
<string name="title_activity_start_conversation">Start Conversation</string>
|
||||||
<string name="title_activity_choose_contact">Choose contact</string>
|
<string name="title_activity_choose_contact">Choose contact</string>
|
||||||
|
<string name="title_activity_block_list">Block list</string>
|
||||||
<string name="just_now">just now</string>
|
<string name="just_now">just now</string>
|
||||||
<string name="minute_ago">1 min ago</string>
|
<string name="minute_ago">1 min ago</string>
|
||||||
<string name="minutes_ago">%d mins ago</string>
|
<string name="minutes_ago">%d mins ago</string>
|
||||||
|
@ -34,6 +39,11 @@
|
||||||
<string name="participant">Participant</string>
|
<string name="participant">Participant</string>
|
||||||
<string name="visitor">Visitor</string>
|
<string name="visitor">Visitor</string>
|
||||||
<string name="remove_contact_text">Would you like to remove %s from your roster? The conversation associated with this contact will not be removed.</string>
|
<string name="remove_contact_text">Would you like to remove %s from your roster? The conversation associated with this contact will not be removed.</string>
|
||||||
|
<string name="block_contact_text">Would you like to block %s from sending you messages?</string>
|
||||||
|
<string name="unblock_contact_text">Would you like to unblock %s and allow them to send you messages?</string>
|
||||||
|
<string name="block_domain_text">Block all contacts from %s?</string>
|
||||||
|
<string name="unblock_domain_text">Unblock all contacts from %s?</string>
|
||||||
|
<string name="contact_blocked">Contact blocked</string>
|
||||||
<string name="remove_bookmark_text">Would you like to remove %s as a bookmark? The conversation associated with this bookmark will not be removed.</string>
|
<string name="remove_bookmark_text">Would you like to remove %s as a bookmark? The conversation associated with this bookmark will not be removed.</string>
|
||||||
<string name="register_account">Register new account on server</string>
|
<string name="register_account">Register new account on server</string>
|
||||||
<string name="share_with">Share with</string>
|
<string name="share_with">Share with</string>
|
||||||
|
@ -45,6 +55,8 @@
|
||||||
<string name="add">Add</string>
|
<string name="add">Add</string>
|
||||||
<string name="edit">Edit</string>
|
<string name="edit">Edit</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
|
<string name="block">Block</string>
|
||||||
|
<string name="unblock">Unblock</string>
|
||||||
<string name="save">Save</string>
|
<string name="save">Save</string>
|
||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
<string name="crash_report_title">Conversations has crashed</string>
|
<string name="crash_report_title">Conversations has crashed</string>
|
||||||
|
@ -202,6 +214,8 @@
|
||||||
<string name="join_conference">Join Conference</string>
|
<string name="join_conference">Join Conference</string>
|
||||||
<string name="delete_contact">Delete Contact</string>
|
<string name="delete_contact">Delete Contact</string>
|
||||||
<string name="view_contact_details">View contact details</string>
|
<string name="view_contact_details">View contact details</string>
|
||||||
|
<string name="block_contact">Block contact</string>
|
||||||
|
<string name="unblock_contact">Unblock contact</string>
|
||||||
<string name="create">Create</string>
|
<string name="create">Create</string>
|
||||||
<string name="contact_already_exists">The contact already exists</string>
|
<string name="contact_already_exists">The contact already exists</string>
|
||||||
<string name="join">Join</string>
|
<string name="join">Join</string>
|
||||||
|
@ -318,6 +332,7 @@
|
||||||
<string name="image_transmission_failed">Image transmission failed</string>
|
<string name="image_transmission_failed">Image transmission failed</string>
|
||||||
<string name="scan_qr_code">Scan QR code</string>
|
<string name="scan_qr_code">Scan QR code</string>
|
||||||
<string name="show_qr_code">Show QR code</string>
|
<string name="show_qr_code">Show QR code</string>
|
||||||
|
<string name="show_block_list">Show block list</string>
|
||||||
<string name="account_details">Account details</string>
|
<string name="account_details">Account details</string>
|
||||||
<string name="verify_otr">Verify OTR</string>
|
<string name="verify_otr">Verify OTR</string>
|
||||||
<string name="remote_fingerprint">Remote Fingerprint</string>
|
<string name="remote_fingerprint">Remote Fingerprint</string>
|
||||||
|
|
Loading…
Reference in New Issue