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