From f338d897535ebc7737a6bc5edb169d9ae41627c1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 4 Jan 2015 00:14:40 +0100 Subject: no longer use ConcurrentHashMap in favor of synchronize on a final HashMap --- .../eu/siacs/conversations/entities/Roster.java | 46 +++++++++++++--------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Roster.java b/src/main/java/eu/siacs/conversations/entities/Roster.java index 1a81a419..ce058004 100644 --- a/src/main/java/eu/siacs/conversations/entities/Roster.java +++ b/src/main/java/eu/siacs/conversations/entities/Roster.java @@ -1,14 +1,14 @@ package eu.siacs.conversations.entities; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; import eu.siacs.conversations.xmpp.jid.Jid; public class Roster { final Account account; - final ConcurrentHashMap contacts = new ConcurrentHashMap<>(); + final HashMap contacts = new HashMap<>(); private String version = null; public Roster(Account account) { @@ -19,23 +19,27 @@ public class Roster { if (jid == null) { return null; } - final Contact contact = contacts.get(jid.toBareJid().toString()); - if (contact != null && contact.showInRoster()) { - return contact; - } else { - return null; + synchronized (this.contacts) { + Contact contact = contacts.get(jid.toBareJid().toString()); + if (contact != null && contact.showInRoster()) { + return contact; + } else { + return null; + } } } public Contact getContact(final Jid jid) { - final Jid bareJid = jid.toBareJid(); - if (contacts.containsKey(bareJid.toString())) { - return contacts.get(bareJid.toString()); - } else { - final Contact contact = new Contact(bareJid); - contact.setAccount(account); - contacts.put(bareJid.toString(), contact); - return contact; + synchronized (this.contacts) { + final Jid bareJid = jid.toBareJid(); + if (contacts.containsKey(bareJid.toString())) { + return contacts.get(bareJid.toString()); + } else { + Contact contact = new Contact(bareJid); + contact.setAccount(account); + contacts.put(bareJid.toString(), contact); + return contact; + } } } @@ -46,13 +50,13 @@ public class Roster { } public void markAllAsNotInRoster() { - for (final Contact contact : getContacts()) { + for (Contact contact : getContacts()) { contact.resetOption(Contact.Options.IN_ROSTER); } } public void clearSystemAccounts() { - for (final Contact contact : getContacts()) { + for (Contact contact : getContacts()) { contact.setPhotoUri(null); contact.setSystemName(null); contact.setSystemAccount(null); @@ -60,13 +64,17 @@ public class Roster { } public List getContacts() { - return new ArrayList<>(this.contacts.values()); + synchronized (this.contacts) { + return new ArrayList<>(this.contacts.values()); + } } public void initContact(final Contact contact) { contact.setAccount(account); contact.setOption(Contact.Options.IN_ROSTER); - contacts.put(contact.getJid().toBareJid().toString(), contact); + synchronized (this.contacts) { + contacts.put(contact.getJid().toBareJid().toString(), contact); + } } public void setVersion(String version) { -- cgit v1.2.3 From e32a927300a96fc59adcabb2ebc16318e67de226 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 4 Jan 2015 12:09:39 +0100 Subject: Use packet callbacks only for IqPackets. Removed unnecessary code --- .../services/XmppConnectionService.java | 4 +- .../siacs/conversations/xmpp/XmppConnection.java | 104 +++++++-------------- 2 files changed, 37 insertions(+), 71 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 6bdc55a1..04fc04d3 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -803,7 +803,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); final Element query = iqPacket.query("jabber:iq:private"); query.addChild("storage", "storage:bookmarks"); - final PacketReceived callback = new OnIqPacketReceived() { + final OnIqPacketReceived callback = new OnIqPacketReceived() { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { @@ -2090,7 +2090,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - public void sendIqPacket(final Account account, final IqPacket packet, final PacketReceived callback) { + public void sendIqPacket(final Account account, final IqPacket packet, final OnIqPacketReceived callback) { final XmppConnection connection = account.getXmppConnection(); if (connection != null) { connection.sendIqPacket(packet, callback); diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index f7f0c346..ff3210a4 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -104,7 +104,7 @@ public class XmppConnection implements Runnable { private long lastConnect = 0; private long lastSessionStarted = 0; private int attempt = 0; - private final Map packetCallbacks = new Hashtable<>(); + private final Map packetCallbacks = new Hashtable<>(); private OnPresencePacketReceived presenceListener = null; private OnJinglePacketReceived jingleListener = null; private OnIqPacketReceived unregisteredIqListener = null; @@ -444,50 +444,24 @@ public class XmppConnection implements Runnable { } } else { if (packetCallbacks.containsKey(packet.getId())) { - if (packetCallbacks.get(packet.getId()) instanceof OnIqPacketReceived) { - ((OnIqPacketReceived) packetCallbacks.get(packet.getId())) - .onIqPacketReceived(account, packet); - } - + packetCallbacks.get(packet.getId()).onIqPacketReceived(account, packet); packetCallbacks.remove(packet.getId()); } else if ((packet.getType() == IqPacket.TYPE_GET || packet .getType() == IqPacket.TYPE_SET) && this.unregisteredIqListener != null) { this.unregisteredIqListener.onIqPacketReceived(account, packet); - } + } } } - private void processMessage(final Tag currentTag) throws XmlPullParserException, - IOException { - final MessagePacket packet = (MessagePacket) processPacket(currentTag, - PACKET_MESSAGE); - final String id = packet.getAttribute("id"); - if ((id != null) && (packetCallbacks.containsKey(id))) { - if (packetCallbacks.get(id) instanceof OnMessagePacketReceived) { - ((OnMessagePacketReceived) packetCallbacks.get(id)) - .onMessagePacketReceived(account, packet); - } - packetCallbacks.remove(id); - } else if (this.messageListener != null) { - this.messageListener.onMessagePacketReceived(account, packet); - } + private void processMessage(final Tag currentTag) throws XmlPullParserException, IOException { + final MessagePacket packet = (MessagePacket) processPacket(currentTag,PACKET_MESSAGE); + this.messageListener.onMessagePacketReceived(account, packet); } - private void processPresence(final Tag currentTag) throws XmlPullParserException, - IOException { - PresencePacket packet = (PresencePacket) processPacket(currentTag, - PACKET_PRESENCE); - final String id = packet.getAttribute("id"); - if ((id != null) && (packetCallbacks.containsKey(id))) { - if (packetCallbacks.get(id) instanceof OnPresencePacketReceived) { - ((OnPresencePacketReceived) packetCallbacks.get(id)) - .onPresencePacketReceived(account, packet); - } - packetCallbacks.remove(id); - } else if (this.presenceListener != null) { - this.presenceListener.onPresencePacketReceived(account, packet); - } + private void processPresence(final Tag currentTag) throws XmlPullParserException, IOException { + PresencePacket packet = (PresencePacket) processPacket(currentTag, PACKET_PRESENCE); + this.presenceListener.onPresencePacketReceived(account, packet); } private void sendStartTLS() throws IOException { @@ -497,8 +471,7 @@ public class XmppConnection implements Runnable { } private SharedPreferences getPreferences() { - return PreferenceManager - .getDefaultSharedPreferences(applicationContext); + return PreferenceManager.getDefaultSharedPreferences(applicationContext); } private boolean enableLegacySSL() { @@ -676,7 +649,7 @@ public class XmppConnection implements Runnable { 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() { + this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { final Element bind = packet.findChild("bind"); @@ -719,12 +692,10 @@ public class XmppConnection implements Runnable { } }); if (this.streamFeatures.hasChild("session")) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() - + ": sending deprecated session"); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending deprecated session"); final IqPacket startSession = new IqPacket(IqPacket.TYPE_SET); - startSession.addChild("session", - "urn:ietf:params:xml:ns:xmpp-session"); - this.sendUnboundIqPacket(startSession, null); + startSession.addChild("session","urn:ietf:params:xml:ns:xmpp-session"); + this.sendUnmodifiedIqPacket(startSession, null); } } @@ -845,49 +816,44 @@ public class XmppConnection implements Runnable { return new BigInteger(50, mXmppConnectionService.getRNG()).toString(32); } - public void sendIqPacket(final IqPacket packet, final PacketReceived callback) { - if (packet.getId() == null) { - final String id = nextRandomId(); - packet.setAttribute("id", id); - } + public void sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { packet.setFrom(account.getJid()); - this.sendPacket(packet, callback); + this.sendUnmodifiedIqPacket(packet,callback); + } - public void sendUnboundIqPacket(final IqPacket packet, final PacketReceived callback) { + private void sendUnmodifiedIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { if (packet.getId() == null) { final String id = nextRandomId(); packet.setAttribute("id", id); } - this.sendPacket(packet, callback); + if (callback != null) { + if (packet.getId() == null) { + packet.setId(nextRandomId()); + } + packetCallbacks.put(packet.getId(), callback); + } + this.sendPacket(packet); } public void sendMessagePacket(final MessagePacket packet) { - this.sendPacket(packet, null); + this.sendPacket(packet); } public void sendPresencePacket(final PresencePacket packet) { - this.sendPacket(packet, null); + this.sendPacket(packet); } - private synchronized void sendPacket(final AbstractStanza packet, final PacketReceived callback) { - if (packet.getName().equals("iq") || packet.getName().equals("message") - || packet.getName().equals("presence")) { + private synchronized void sendPacket(final AbstractStanza packet) { + final String name = packet.getName(); + if (name.equals("iq") || name.equals("message") || name.equals("presence")) { ++stanzasSent; - } + } tagWriter.writeStanzaAsync(packet); - if (packet instanceof MessagePacket && packet.getId() != null - && this.streamId != null) { - Log.d(Config.LOGTAG, "request delivery report for stanza " - + stanzasSent); + if (packet instanceof MessagePacket && packet.getId() != null && this.streamId != null) { + Log.d(Config.LOGTAG, "request delivery report for stanza " + stanzasSent); this.messageReceipts.put(stanzasSent, packet.getId()); tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion)); - } - if (callback != null) { - if (packet.getId() == null) { - packet.setId(nextRandomId()); - } - packetCallbacks.put(packet.getId(), callback); } } @@ -1044,11 +1010,11 @@ public class XmppConnection implements Runnable { } public void sendActive() { - this.sendPacket(new ActivePacket(), null); + this.sendPacket(new ActivePacket()); } public void sendInactive() { - this.sendPacket(new InactivePacket(), null); + this.sendPacket(new InactivePacket()); } public class Features { -- cgit v1.2.3 From 5c190487bc04e5dcb9b12a49d2447d441860d990 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 4 Jan 2015 12:37:22 +0100 Subject: deal with prosodys muc namespace tagging of messages --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 44cda261..65a8f9e6 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -245,6 +245,10 @@ public class MessageParser extends AbstractParser implements return null; } } + if (message.hasChild("x","http://jabber.org/protocol/muc#user") + && "chat".equals(message.getAttribute("type"))) { + return null; + } Conversation conversation = mXmppConnectionService .findOrCreateConversation(account, fullJid.toBareJid(), false); String pgpBody = getPgpBody(message); @@ -482,7 +486,6 @@ public class MessageParser extends AbstractParser implements public void onMessagePacketReceived(Account account, MessagePacket packet) { Message message = null; this.parseNick(packet, account); - if ((packet.getType() == MessagePacket.TYPE_CHAT || packet.getType() == MessagePacket.TYPE_NORMAL)) { if ((packet.getBody() != null) && (packet.getBody().startsWith("?OTR"))) { @@ -490,9 +493,7 @@ public class MessageParser extends AbstractParser implements if (message != null) { message.markUnread(); } - } else if (packet.hasChild("body") - && !(packet.hasChild("x", - "http://jabber.org/protocol/muc#user"))) { + } else if (packet.hasChild("body")) { message = this.parseChat(packet, account); if (message != null) { message.markUnread(); -- cgit v1.2.3 From eb7e683403e9335165341ed65cf949cb60319ebc Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 30 Dec 2014 08:16:25 -0500 Subject: Make IqPacket type an enum --- .../siacs/conversations/generator/IqGenerator.java | 16 ++++---- .../eu/siacs/conversations/parser/IqParser.java | 14 +++---- .../services/MessageArchiveService.java | 2 +- .../services/XmppConnectionService.java | 32 +++++++-------- .../siacs/conversations/xmpp/XmppConnection.java | 46 +++++++++++----------- .../xmpp/jingle/JingleConnection.java | 10 ++--- .../xmpp/jingle/JingleConnectionManager.java | 4 +- .../xmpp/jingle/JingleInbandTransport.java | 14 +++---- .../siacs/conversations/xmpp/stanzas/IqPacket.java | 46 ++++++++-------------- 9 files changed, 85 insertions(+), 99 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index f94dc5d7..58933692 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -21,7 +21,7 @@ public class IqGenerator extends AbstractGenerator { } public IqPacket discoResponse(final IqPacket request) { - final IqPacket packet = new IqPacket(IqPacket.TYPE_RESULT); + final IqPacket packet = new IqPacket(IqPacket.TYPE.RESULT); packet.setId(request.getId()); packet.setTo(request.getFrom()); final Element query = packet.addChild("query", @@ -40,7 +40,7 @@ public class IqGenerator extends AbstractGenerator { } protected IqPacket publish(final String node, final Element item) { - final IqPacket packet = new IqPacket(IqPacket.TYPE_SET); + final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); final Element pubsub = packet.addChild("pubsub", "http://jabber.org/protocol/pubsub"); final Element publish = pubsub.addChild("publish"); @@ -50,7 +50,7 @@ public class IqGenerator extends AbstractGenerator { } protected IqPacket retrieve(String node, Element item) { - final IqPacket packet = new IqPacket(IqPacket.TYPE_GET); + final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); final Element pubsub = packet.addChild("pubsub", "http://jabber.org/protocol/pubsub"); final Element items = pubsub.addChild("items"); @@ -100,7 +100,7 @@ public class IqGenerator extends AbstractGenerator { } public IqPacket queryMessageArchiveManagement(final MessageArchiveService.Query mam) { - final IqPacket packet = new IqPacket(IqPacket.TYPE_SET); + final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); final Element query = packet.query("urn:xmpp:mam:0"); query.setAttribute("queryid",mam.getQueryId()); final Data data = new Data(); @@ -119,28 +119,28 @@ public class IqGenerator extends AbstractGenerator { return packet; } public IqPacket generateGetBlockList() { - final IqPacket iq = new IqPacket(IqPacket.TYPE_GET); + 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 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 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; } public IqPacket generateSetPassword(final Account account, final String newPassword) { - final IqPacket packet = new IqPacket(IqPacket.TYPE_SET); + final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); packet.setTo(account.getServer()); final Element query = packet.addChild("query", Xmlns.REGISTER); final Jid jid = account.getJid(); diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index e84545fc..70a6e3f7 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -83,7 +83,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { if (packet.hasChild("query", Xmlns.ROSTER) && fromServer(account, packet)) { final Element query = packet.findChild("query"); // If this is in response to a query for the whole roster: - if (packet.getType() == IqPacket.TYPE_RESULT) { + if (packet.getType() == IqPacket.TYPE.RESULT) { account.getRoster().markAllAsNotInRoster(); } this.rosterItems(account, query); @@ -97,7 +97,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { (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) { + if (packet.getType() == IqPacket.TYPE.RESULT) { account.clearBlocklist(); } if (items != null) { @@ -116,7 +116,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { // Update the UI mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED); } else if (packet.hasChild("unblock", Xmlns.BLOCKING) && - fromServer(account, packet) && packet.getType() == IqPacket.TYPE_SET) { + fromServer(account, packet) && packet.getType() == IqPacket.TYPE.SET) { Log.d(Config.LOGTAG, "Received unblock update from server"); final Collection items = packet.findChild("unblock", Xmlns.BLOCKING).getChildren(); if (items.size() == 0) { @@ -144,12 +144,12 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { .discoResponse(packet); account.getXmppConnection().sendIqPacket(response, null); } else if (packet.hasChild("ping", "urn:xmpp:ping")) { - final IqPacket response = packet.generateResponse(IqPacket.TYPE_RESULT); + final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT); mXmppConnectionService.sendIqPacket(account, response, null); } else { - if ((packet.getType() == IqPacket.TYPE_GET) - || (packet.getType() == IqPacket.TYPE_SET)) { - final IqPacket response = packet.generateResponse(IqPacket.TYPE_ERROR); + if ((packet.getType() == IqPacket.TYPE.GET) + || (packet.getType() == IqPacket.TYPE.SET)) { + final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR); final Element error = response.addChild("error"); error.setAttribute("type", "cancel"); error.addChild("feature-not-implemented", diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java index 82111243..5fb50f90 100644 --- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java +++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java @@ -111,7 +111,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { this.mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_ERROR) { + if (packet.getType() == IqPacket.TYPE.ERROR) { Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": error executing mam: " + packet.toString()); finalizeQuery(query); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 04fc04d3..fd0a4b9d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -787,7 +787,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void fetchRosterFromServer(final Account account) { - final IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); + final IqPacket iqPacket = new IqPacket(IqPacket.TYPE.GET); if (!"".equals(account.getRosterVersion())) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetching roster version " + account.getRosterVersion()); @@ -800,7 +800,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void fetchBookmarks(final Account account) { - final IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); + final IqPacket iqPacket = new IqPacket(IqPacket.TYPE.GET); final Element query = iqPacket.query("jabber:iq:private"); query.addChild("storage", "storage:bookmarks"); final OnIqPacketReceived callback = new OnIqPacketReceived() { @@ -835,7 +835,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void pushBookmarks(Account account) { - IqPacket iqPacket = new IqPacket(IqPacket.TYPE_SET); + IqPacket iqPacket = new IqPacket(IqPacket.TYPE.SET); Element query = iqPacket.query("jabber:iq:private"); Element storage = query.addChild("storage", "storage:bookmarks"); for (Bookmark bookmark : account.getBookmarks()) { @@ -1107,7 +1107,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa sendIqPacket(account, iq, new OnIqPacketReceived() { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { + if (packet.getType() == IqPacket.TYPE.RESULT) { account.setPassword(newPassword); databaseBackend.updateAccount(account); callback.onPasswordChangeSucceeded(); @@ -1500,13 +1500,13 @@ 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); + IqPacket request = new IqPacket(IqPacket.TYPE.GET); request.setTo(conversation.getJid().toBareJid()); request.query("http://jabber.org/protocol/muc#owner"); sendIqPacket(conversation.getAccount(),request,new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() != IqPacket.TYPE_ERROR) { + if (packet.getType() != IqPacket.TYPE.ERROR) { Data data = Data.parse(packet.query().findChild("x", "jabber:x:data")); for (Field field : data.getFields()) { if (options.containsKey(field.getName())) { @@ -1514,13 +1514,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } data.submit(); - IqPacket set = new IqPacket(IqPacket.TYPE_SET); + IqPacket set = new IqPacket(IqPacket.TYPE.SET); set.setTo(conversation.getJid().toBareJid()); set.query("http://jabber.org/protocol/muc#owner").addChild(data); sendIqPacket(account, set, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { + if (packet.getType() == IqPacket.TYPE.RESULT) { if (callback != null) { callback.onPushSucceeded(); } @@ -1662,7 +1662,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final boolean sendUpdates = contact .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST) && contact.getOption(Contact.Options.PREEMPTIVE_GRANT); - final IqPacket iq = new IqPacket(IqPacket.TYPE_SET); + final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.query(Xmlns.ROSTER).addChild(contact.asElement()); account.getXmppConnection().sendIqPacket(iq, null); if (sendUpdates) { @@ -1702,7 +1702,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket result) { - if (result.getType() == IqPacket.TYPE_RESULT) { + if (result.getType() == IqPacket.TYPE.RESULT) { final IqPacket packet = XmppConnectionService.this.mIqGenerator .publishAvatarMetadata(avatar); sendIqPacket(account, packet, new OnIqPacketReceived() { @@ -1710,7 +1710,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket result) { - if (result.getType() == IqPacket.TYPE_RESULT) { + if (result.getType() == IqPacket.TYPE.RESULT) { if (account.setAvatar(avatar.getFilename())) { databaseBackend.updateAccount(account); } @@ -1747,7 +1747,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onIqPacketReceived(Account account, IqPacket result) { final String ERROR = account.getJid().toBareJid() + ": fetching avatar for " + avatar.owner + " failed "; - if (result.getType() == IqPacket.TYPE_RESULT) { + if (result.getType() == IqPacket.TYPE.RESULT) { avatar.image = mIqParser.avatarData(result); if (avatar.image != null) { if (getFileBackend().save(avatar)) { @@ -1801,7 +1801,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { + if (packet.getType() == IqPacket.TYPE.RESULT) { Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub"); if (pubsub != null) { @@ -1835,7 +1835,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa contact.setOption(Contact.Options.DIRTY_DELETE); Account account = contact.getAccount(); if (account.getStatus() == Account.State.ONLINE) { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); + IqPacket iq = new IqPacket(IqPacket.TYPE.SET); Element item = iq.query(Xmlns.ROSTER).addChild("item"); item.setAttribute("jid", contact.getJid().toString()); item.setAttribute("subscription", "remove"); @@ -2202,7 +2202,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { + if (packet.getType() == IqPacket.TYPE.RESULT) { account.getBlocklist().add(jid); updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED); } @@ -2217,7 +2217,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa 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) { + if (packet.getType() == IqPacket.TYPE.RESULT) { account.getBlocklist().remove(jid); updateBlocklistUi(OnUpdateBlocklist.Status.UNBLOCKED); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index ff3210a4..d954c0d4 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -372,7 +372,7 @@ public class XmppConnection implements Runnable { private void sendInitialPing() { Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": sending intial ping"); - final 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() { @@ -446,11 +446,11 @@ public class XmppConnection implements Runnable { if (packetCallbacks.containsKey(packet.getId())) { packetCallbacks.get(packet.getId()).onIqPacketReceived(account, packet); packetCallbacks.remove(packet.getId()); - } else if ((packet.getType() == IqPacket.TYPE_GET || packet - .getType() == IqPacket.TYPE_SET) + } else if ((packet.getType() == IqPacket.TYPE.GET || packet + .getType() == IqPacket.TYPE.SET) && this.unregisteredIqListener != null) { this.unregisteredIqListener.onIqPacketReceived(account, packet); - } + } } } @@ -479,19 +479,19 @@ public class XmppConnection implements Runnable { } private void switchOverToTls(final Tag currentTag) throws XmlPullParserException, IOException { - tagReader.readTag(); - try { + tagReader.readTag(); + try { final SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null,new X509TrustManager[]{this.mXmppConnectionService.getMemorizingTrustManager()},mXmppConnectionService.getRNG()); final SSLSocketFactory factory = sc.getSocketFactory(); final HostnameVerifier verifier = this.mXmppConnectionService.getMemorizingTrustManager().wrapHostnameVerifier(new StrictHostnameVerifier()); - final InetAddress address = socket == null ? null : socket.getInetAddress(); + final InetAddress address = socket == null ? null : socket.getInetAddress(); if (factory == null || address == null || verifier == null) { throw new IOException("could not setup ssl"); } - final SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket,address.getHostAddress(), socket.getPort(),true); + final SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket,address.getHostAddress(), socket.getPort(),true); if (sslSocket == null) { throw new IOException("could not initialize ssl socket"); @@ -506,13 +506,13 @@ public class XmppConnection implements Runnable { supportedProtocols.remove("SSLv3"); supportProtocols = new String[supportedProtocols.size()]; supportedProtocols.toArray(supportProtocols); - } + } sslSocket.setEnabledProtocols(supportProtocols); - if (!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); + if (!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()); @@ -521,11 +521,11 @@ public class XmppConnection implements Runnable { enabledEncryption = true; processStream(tagReader.readTag()); sslSocket.close(); - } catch (final NoSuchAlgorithmException | KeyManagementException e1) { + } catch (final NoSuchAlgorithmException | KeyManagementException e1) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed"); disconnect(true); changeStatus(Account.State.SECURITY_ERROR); - } + } } private void processStreamFeatures(final Tag currentTag) @@ -598,7 +598,7 @@ public class XmppConnection implements Runnable { } private void sendRegistryRequest() { - final 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() { @@ -608,7 +608,7 @@ public class XmppConnection implements Runnable { final Element instructions = packet.query().findChild("instructions"); if (packet.query().hasChild("username") && (packet.query().hasChild("password"))) { - final IqPacket register = new IqPacket(IqPacket.TYPE_SET); + final IqPacket register = new IqPacket(IqPacket.TYPE.SET); final Element username = new Element("username") .setContent(account.getUsername()); final Element password = new Element("password") @@ -619,7 +619,7 @@ public class XmppConnection implements Runnable { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_RESULT) { + if (packet.getType() == IqPacket.TYPE.RESULT) { account.setOption(Account.OPTION_REGISTER, false); changeStatus(Account.State.REGISTRATION_SUCCESSFUL); @@ -646,7 +646,7 @@ public class XmppConnection implements Runnable { } private void sendBindRequest() { - final IqPacket iq = new IqPacket(IqPacket.TYPE_SET); + final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind") .addChild("resource").setContent(account.getResource()); this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() { @@ -705,7 +705,7 @@ public class XmppConnection implements Runnable { enableAdvancedStreamFeatures(); } } else { - final IqPacket iq = new IqPacket(IqPacket.TYPE_GET); + final IqPacket iq = new IqPacket(IqPacket.TYPE.GET); iq.setTo(server.toDomainJid()); iq.query("http://jabber.org/protocol/disco#info"); this.sendIqPacket(iq, new OnIqPacketReceived() { @@ -750,7 +750,7 @@ public class XmppConnection implements Runnable { } private void sendServiceDiscoveryItems(final Jid server) { - final IqPacket iq = new IqPacket(IqPacket.TYPE_GET); + final IqPacket iq = new IqPacket(IqPacket.TYPE.GET); iq.setTo(server.toDomainJid()); iq.query("http://jabber.org/protocol/disco#items"); this.sendIqPacket(iq, new OnIqPacketReceived() { @@ -771,7 +771,7 @@ public class XmppConnection implements Runnable { } private void sendEnableCarbons() { - final 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() { @@ -861,7 +861,7 @@ public class XmppConnection implements Runnable { if (streamFeatures.hasChild("sm")) { tagWriter.writeStanzaAsync(new RequestPacket(smVersion)); } else { - final 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); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index d578ca38..d6f901d8 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -75,7 +75,7 @@ public class JingleConnection implements Downloadable { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_ERROR) { + if (packet.getType() == IqPacket.TYPE.ERROR) { fail(); } } @@ -191,10 +191,10 @@ public class JingleConnection implements Downloadable { } IqPacket response; if (returnResult) { - response = packet.generateResponse(IqPacket.TYPE_RESULT); + response = packet.generateResponse(IqPacket.TYPE.RESULT); } else { - response = packet.generateResponse(IqPacket.TYPE_ERROR); + response = packet.generateResponse(IqPacket.TYPE.ERROR); } account.getXmppConnection().sendIqPacket(response, null); } @@ -552,7 +552,7 @@ public class JingleConnection implements Downloadable { Log.d(Config.LOGTAG, "candidate " + connection.getCandidate().getCid() + " was our proxy. going to activate"); - IqPacket activation = new IqPacket(IqPacket.TYPE_SET); + IqPacket activation = new IqPacket(IqPacket.TYPE.SET); activation.setTo(connection.getCandidate().getJid()); activation.query("http://jabber.org/protocol/bytestreams") .setAttribute("sid", this.getSessionId()); @@ -564,7 +564,7 @@ public class JingleConnection implements Downloadable { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_ERROR) { + if (packet.getType() == IqPacket.TYPE.ERROR) { onProxyActivated.failed(); } else { onProxyActivated.success(); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index b0a730b1..57c74ad9 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -46,7 +46,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { return; } } - IqPacket response = packet.generateResponse(IqPacket.TYPE_ERROR); + IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR); Element error = response.addChild("error"); error.setAttribute("type", "cancel"); error.addChild("item-not-found", @@ -84,7 +84,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { final String proxy = account.getXmppConnection() .findDiscoItemByFeature(xmlns); if (proxy != null) { - IqPacket iq = new IqPacket(IqPacket.TYPE_GET); + IqPacket iq = new IqPacket(IqPacket.TYPE.GET); iq.setAttribute("to", proxy); iq.query(xmlns); account.getXmppConnection().sendIqPacket(iq, diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java index e25f7e65..174f70fa 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java @@ -44,7 +44,7 @@ public class JingleInbandTransport extends JingleTransport { private OnIqPacketReceived onAckReceived = new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (connected && packet.getType() == IqPacket.TYPE_RESULT) { + if (connected && packet.getType() == IqPacket.TYPE.RESULT) { sendNextBlock(); } } @@ -60,7 +60,7 @@ public class JingleInbandTransport extends JingleTransport { } public void connect(final OnTransportConnected callback) { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); + IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.setTo(this.counterpart); Element open = iq.addChild("open", "http://jabber.org/protocol/ibb"); open.setAttribute("sid", this.sessionId); @@ -73,7 +73,7 @@ public class JingleInbandTransport extends JingleTransport { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE_ERROR) { + if (packet.getType() == IqPacket.TYPE.ERROR) { callback.failed(); } else { callback.established(); @@ -157,7 +157,7 @@ public class JingleInbandTransport extends JingleTransport { this.remainingSize -= count; this.digest.update(buffer); String base64 = Base64.encodeToString(buffer, Base64.NO_WRAP); - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); + IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.setTo(this.counterpart); Element data = iq.addChild("data", "http://jabber.org/protocol/ibb"); @@ -208,15 +208,15 @@ public class JingleInbandTransport extends JingleTransport { established = true; connected = true; this.account.getXmppConnection().sendIqPacket( - packet.generateResponse(IqPacket.TYPE_RESULT), null); + packet.generateResponse(IqPacket.TYPE.RESULT), null); } else { this.account.getXmppConnection().sendIqPacket( - packet.generateResponse(IqPacket.TYPE_ERROR), null); + packet.generateResponse(IqPacket.TYPE.ERROR), null); } } else if (connected && payload.getName().equals("data")) { this.receiveNextBlock(payload.getContent()); this.account.getXmppConnection().sendIqPacket( - packet.generateResponse(IqPacket.TYPE_RESULT), null); + packet.generateResponse(IqPacket.TYPE.RESULT), null); } else { // TODO some sort of exception } diff --git a/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java b/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java index 2481112b..7b36fc49 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java +++ b/src/main/java/eu/siacs/conversations/xmpp/stanzas/IqPacket.java @@ -4,32 +4,18 @@ import eu.siacs.conversations.xml.Element; public class IqPacket extends AbstractStanza { - public static final int TYPE_ERROR = -1; - public static final int TYPE_SET = 0; - public static final int TYPE_RESULT = 1; - public static final int TYPE_GET = 2; - - private IqPacket(final String name) { - super(name); + public static enum TYPE { + ERROR, + SET, + RESULT, + GET, + INVALID } - public IqPacket(final int type) { + public IqPacket(final TYPE 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; + if (type != TYPE.INVALID) { + this.setAttribute("type", type.toString().toLowerCase()); } } @@ -51,23 +37,23 @@ public class IqPacket extends AbstractStanza { return query(); } - public int getType() { + public TYPE getType() { final String type = getAttribute("type"); switch (type) { case "error": - return TYPE_ERROR; + return TYPE.ERROR; case "result": - return TYPE_RESULT; + return TYPE.RESULT; case "set": - return TYPE_SET; + return TYPE.SET; case "get": - return TYPE_GET; + return TYPE.GET; default: - return 1000; + return TYPE.INVALID; } } - public IqPacket generateResponse(final int type) { + public IqPacket generateResponse(final TYPE type) { final IqPacket packet = new IqPacket(type); packet.setTo(this.getFrom()); packet.setId(this.getId()); -- cgit v1.2.3 From 88704ce5cd68047008375c2eba6751e2e3cdd8c0 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 30 Dec 2014 08:50:51 -0500 Subject: Verify IQ responses Fixes #20 Move fromServer/toServer to AbstractStanza --- .../eu/siacs/conversations/parser/IqParser.java | 13 +++--------- .../services/XmppConnectionService.java | 3 +-- .../siacs/conversations/xmpp/XmppConnection.java | 24 +++++++++++++++++----- .../conversations/xmpp/stanzas/AbstractStanza.java | 17 ++++++++++++++- 4 files changed, 39 insertions(+), 18 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 70a6e3f7..3b501f33 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -71,16 +71,9 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return super.avatarData(items); } - public static boolean fromServer(final Account account, final IqPacket packet) { - return packet.getFrom() == null - || packet.getFrom().equals(account.getServer()) - || packet.getFrom().equals(account.getJid().toBareJid()) - || packet.getFrom().equals(account.getJid()); - } - @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.hasChild("query", Xmlns.ROSTER) && fromServer(account, packet)) { + if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { final Element query = packet.findChild("query"); // If this is in response to a query for the whole roster: if (packet.getType() == IqPacket.TYPE.RESULT) { @@ -88,7 +81,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } this.rosterItems(account, query); } else if ((packet.hasChild("block", Xmlns.BLOCKING) || packet.hasChild("blocklist", Xmlns.BLOCKING)) && - fromServer(account, packet)) { + packet.fromServer(account)) { // Block list or block push. Log.d(Config.LOGTAG, "Received blocklist update from server"); final Element blocklist = packet.findChild("blocklist", Xmlns.BLOCKING); @@ -116,7 +109,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { // Update the UI mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED); } else if (packet.hasChild("unblock", Xmlns.BLOCKING) && - fromServer(account, packet) && packet.getType() == IqPacket.TYPE.SET) { + packet.fromServer(account) && packet.getType() == IqPacket.TYPE.SET) { Log.d(Config.LOGTAG, "Received unblock update from server"); final Collection items = packet.findChild("unblock", Xmlns.BLOCKING).getChildren(); if (items.size() == 0) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index fd0a4b9d..beba97fe 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -84,7 +84,6 @@ 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; @@ -979,7 +978,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa query.setCallback(callback); } callback.informUser(R.string.fetching_history_from_server); - } + } } }).start(); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index d954c0d4..56d3e560 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -9,6 +9,7 @@ import android.os.PowerManager.WakeLock; import android.os.SystemClock; import android.preference.PreferenceManager; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import org.apache.http.conn.ssl.StrictHostnameVerifier; @@ -104,7 +105,7 @@ public class XmppConnection implements Runnable { private long lastConnect = 0; private long lastSessionStarted = 0; private int attempt = 0; - private final Map packetCallbacks = new Hashtable<>(); + private final Map> packetCallbacks = new Hashtable<>(); private OnPresencePacketReceived presenceListener = null; private OnJinglePacketReceived jingleListener = null; private OnIqPacketReceived unregisteredIqListener = null; @@ -444,8 +445,21 @@ public class XmppConnection implements Runnable { } } else { if (packetCallbacks.containsKey(packet.getId())) { - packetCallbacks.get(packet.getId()).onIqPacketReceived(account, packet); - packetCallbacks.remove(packet.getId()); + final Pair packetCallbackDuple = packetCallbacks.get(packet.getId()); + // Packets to the server should have responses from the server + if (packetCallbackDuple.first.toServer(account)) { + if (packet.fromServer(account)) { + packetCallbackDuple.second + .onIqPacketReceived(account, packet); + packetCallbacks.remove(packet.getId()); + } + } else { + if (packet.getFrom().equals(packetCallbackDuple.first.getTo())) { + packetCallbackDuple.second + .onIqPacketReceived(account, packet); + packetCallbacks.remove(packet.getId()); + } + } } else if ((packet.getType() == IqPacket.TYPE.GET || packet .getType() == IqPacket.TYPE.SET) && this.unregisteredIqListener != null) { @@ -693,7 +707,7 @@ public class XmppConnection implements Runnable { }); if (this.streamFeatures.hasChild("session")) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending deprecated session"); - final 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.sendUnmodifiedIqPacket(startSession, null); } @@ -831,7 +845,7 @@ public class XmppConnection implements Runnable { if (packet.getId() == null) { packet.setId(nextRandomId()); } - packetCallbacks.put(packet.getId(), callback); + packetCallbacks.put(packet.getId(), new Pair<>(packet, callback)); } this.sendPacket(packet); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java b/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java index 1a49b45e..55256ece 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java +++ b/src/main/java/eu/siacs/conversations/xmpp/stanzas/AbstractStanza.java @@ -1,11 +1,12 @@ package eu.siacs.conversations.xmpp.stanzas; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.Jid; public class AbstractStanza extends Element { - protected AbstractStanza(String name) { + protected AbstractStanza(final String name) { super(name); } @@ -36,4 +37,18 @@ public class AbstractStanza extends Element { public void setId(final String id) { setAttribute("id", id); } + + public boolean fromServer(final Account account) { + return getFrom() == null + || getFrom().equals(account.getServer()) + || getFrom().equals(account.getJid().toBareJid()) + || getFrom().equals(account.getJid()); + } + + public boolean toServer(final Account account) { + return getTo() == null + || getTo().equals(account.getServer()) + || getTo().equals(account.getJid().toBareJid()) + || getTo().equals(account.getJid()); + } } -- cgit v1.2.3 From 0d6d09b7e97709f0978a5527454ab6bbd9ad9443 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 4 Jan 2015 15:40:09 +0100 Subject: code cleanup + logging of spoofed iq packets --- .../siacs/conversations/xmpp/XmppConnection.java | 68 +++++++++++----------- 1 file changed, 33 insertions(+), 35 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 56d3e560..714b9a51 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -430,42 +430,40 @@ public class XmppConnection implements Runnable { return element; } - private void processIq(final Tag currentTag) throws XmlPullParserException, - IOException { - final IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ); + private void processIq(final Tag currentTag) throws XmlPullParserException, IOException { + final IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ); - if (packet.getId() == null) { - return; // an iq packet without id is definitely invalid - } + if (packet.getId() == null) { + return; // an iq packet without id is definitely invalid + } - if (packet instanceof JinglePacket) { - if (this.jingleListener != null) { - this.jingleListener.onJinglePacketReceived(account, - (JinglePacket) packet); - } - } else { - if (packetCallbacks.containsKey(packet.getId())) { - final Pair packetCallbackDuple = packetCallbacks.get(packet.getId()); - // Packets to the server should have responses from the server - if (packetCallbackDuple.first.toServer(account)) { - if (packet.fromServer(account)) { - packetCallbackDuple.second - .onIqPacketReceived(account, packet); - packetCallbacks.remove(packet.getId()); - } - } else { - if (packet.getFrom().equals(packetCallbackDuple.first.getTo())) { - packetCallbackDuple.second - .onIqPacketReceived(account, packet); - packetCallbacks.remove(packet.getId()); - } - } - } else if ((packet.getType() == IqPacket.TYPE.GET || packet - .getType() == IqPacket.TYPE.SET) - && this.unregisteredIqListener != null) { - this.unregisteredIqListener.onIqPacketReceived(account, packet); - } - } + if (packet instanceof JinglePacket) { + if (this.jingleListener != null) { + this.jingleListener.onJinglePacketReceived(account,(JinglePacket) packet); + } + } else { + if (packetCallbacks.containsKey(packet.getId())) { + final Pair packetCallbackDuple = packetCallbacks.get(packet.getId()); + // Packets to the server should have responses from the server + if (packetCallbackDuple.first.toServer(account)) { + if (packet.fromServer(account)) { + packetCallbackDuple.second.onIqPacketReceived(account, packet); + packetCallbacks.remove(packet.getId()); + } else { + Log.e(Config.LOGTAG,account.getJid().toBareJid().toString()+": ignoring spoofed iq packet"); + } + } else { + if (packet.getFrom().equals(packetCallbackDuple.first.getTo())) { + packetCallbackDuple.second.onIqPacketReceived(account, packet); + packetCallbacks.remove(packet.getId()); + } else { + Log.e(Config.LOGTAG,account.getJid().toBareJid().toString()+": ignoring spoofed iq packet"); + } + } + } else if (packet.getType() == IqPacket.TYPE.GET|| packet.getType() == IqPacket.TYPE.SET) { + this.unregisteredIqListener.onIqPacketReceived(account, packet); + } + } } private void processMessage(final Tag currentTag) throws XmlPullParserException, IOException { @@ -836,7 +834,7 @@ public class XmppConnection implements Runnable { } - private void sendUnmodifiedIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { + private synchronized void sendUnmodifiedIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { if (packet.getId() == null) { final String id = nextRandomId(); packet.setAttribute("id", id); -- cgit v1.2.3 From e6cd92a663ba2f8ae572c901b359ce0f42db5900 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 4 Jan 2015 17:53:06 +0100 Subject: added higher auto accept file sizes also changed labeling to MiB and KiB --- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 478586b9..ae3c1834 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -103,9 +103,9 @@ public class MessageAdapter extends ArrayAdapter { if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getDownloadable() != null) { ImageParams params = message.getImageParams(); if (params.size > (1.5 * 1024 * 1024)) { - filesize = params.size / (1024 * 1024)+ " MB"; + filesize = params.size / (1024 * 1024)+ " MiB"; } else if (params.size > 0) { - filesize = params.size / 1024 + " KB"; + filesize = params.size / 1024 + " KiB"; } if (message.getDownloadable() != null && message.getDownloadable().getStatus() == Downloadable.STATUS_FAILED) { error = true; -- cgit v1.2.3 From 3522243835fd29751109cb578897b4e403f06b7d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 4 Jan 2015 18:16:55 +0100 Subject: do not run mam queries in findOrCreateConversation() when isn't available --- .../siacs/conversations/services/XmppConnectionService.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index beba97fe..59cb3bb2 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1052,11 +1052,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } this.databaseBackend.createConversation(conversation); } - if (query == null) { - this.mMessageArchiveService.query(conversation); - } else { - if (query.getConversation() == null) { - this.mMessageArchiveService.query(conversation,query.getStart()); + if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().mam()) { + if (query == null) { + this.mMessageArchiveService.query(conversation); + } else { + if (query.getConversation() == null) { + this.mMessageArchiveService.query(conversation, query.getStart()); + } } } this.conversations.add(conversation); -- cgit v1.2.3 From 2723c9ccb938e073b4c8cd26e39553a31bcbfdbe Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 4 Jan 2015 23:04:23 +0100 Subject: made checks for valid image extensions case insensitive --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- src/main/java/eu/siacs/conversations/http/HttpConnection.java | 2 +- src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index b5a1897d..8cb48635 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -395,7 +395,7 @@ public class Message extends AbstractEntity { String[] pathParts = url.getPath().split("/"); String filename; if (pathParts.length > 0) { - filename = pathParts[pathParts.length - 1]; + filename = pathParts[pathParts.length - 1].toLowerCase(); } else { return false; } diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index 5348e395..b715c3f3 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -65,7 +65,7 @@ public class HttpConnection implements Downloadable { this.message.setDownloadable(this); try { mUrl = new URL(message.getBody()); - String path = mUrl.getPath(); + String path = mUrl.getPath().toLowerCase(); if (path != null && (path.endsWith(".pgp") || path.endsWith(".gpg"))) { this.message.setEncryption(Message.ENCRYPTION_PGP); } else if (message.getEncryption() != Message.ENCRYPTION_OTR) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index d6f901d8..ff94563c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -280,7 +280,7 @@ public class JingleConnection implements Downloadable { Element fileNameElement = fileOffer.findChild("name"); if (fileNameElement != null) { String[] filename = fileNameElement.getContent() - .toLowerCase(Locale.US).split("\\."); + .toLowerCase(Locale.US).toLowerCase().split("\\."); if (Arrays.asList(VALID_IMAGE_EXTENSIONS).contains( filename[filename.length - 1])) { message.setType(Message.TYPE_IMAGE); -- cgit v1.2.3 From f1ebece8669768910707d3cc696b98390bddbfc0 Mon Sep 17 00:00:00 2001 From: Olivier Mehani Date: Mon, 10 Nov 2014 23:40:16 +1100 Subject: Send notification to Pebble on new message This implements basic notifications to the Pebble through the app (using an intent). This simply hooks into NotificationService.notify(). This is pretty basic, but it works (I haven't tested to see how the intent is received when the Pebble app is not around, though). More fancy stuff could probably be added to avoid getting flooded, but the Pebble app already does a good job a filtering notification (e.g., screen on or quiet times). Signed-off-by: Olivier Mehani --- .../services/NotificationService.java | 30 ++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index a30cf2f1..594b356f 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -21,11 +21,15 @@ import android.util.Log; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.json.JSONArray; +import org.json.JSONObject; + import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; @@ -65,6 +69,24 @@ public class NotificationService { ); } + public void notifyPebble(Message message) { + final Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION"); + + final HashMap data = new HashMap(); + final Conversation conversation = message.getConversation(); + data.put("title", conversation.getName()); + data.put("body", message.getBody()); + final JSONObject jsonData = new JSONObject(data); + final String notificationData = new JSONArray().put(jsonData).toString(); + + i.putExtra("messageType", "PEBBLE_ALERT"); + i.putExtra("sender", "Conversations"); /* XXX: Shouldn't be hardcoded, e.g., AbstractGenerator.APP_NAME); */ + i.putExtra("notificationData", notificationData); + + mXmppConnectionService.sendBroadcast(i); + } + + public boolean notificationsEnabled() { return mXmppConnectionService.getPreferences().getBoolean("show_notification", true); } @@ -110,9 +132,13 @@ public class NotificationService { notifications.put(conversationUuid, mList); } final Account account = message.getConversation().getAccount(); - updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) + final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) && !account.inGracePeriod() - && !this.inMiniGracePeriod(account)); + && !this.inMiniGracePeriod(account); + updateNotification(doNotify); + if (doNotify) { + notifyPebble(message); + } } } -- cgit v1.2.3 From bdb335e6b08d35a23468ca1d5730330c520a6a90 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 5 Jan 2015 15:06:39 +0100 Subject: Show affiliation instead of role in MucDetails and offer 'advanced mode' to display role --- .../siacs/conversations/entities/MucOptions.java | 103 ++++++++++++++------- .../ui/ConferenceDetailsActivity.java | 93 ++++++++++--------- 2 files changed, 118 insertions(+), 78 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 97a63532..ce2c5b04 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -4,15 +4,55 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; + import android.annotation.SuppressLint; @SuppressLint("DefaultLocale") public class MucOptions { + + public enum Affiliation { + OWNER(R.string.owner), + ADMIN(R.string.admin), + MEMBER(R.string.member), + OUTCAST(R.string.outcast), + NONE(R.string.no_affiliation); + + private Affiliation(int resId) { + this.resId = resId; + } + + private int resId; + + public int getResId() { + return resId; + } + } + + ; + + public enum Role { + MODERATOR(R.string.moderator), + VISITOR(R.string.visitor), + PARTICIPANT(R.string.participant), + NONE(R.string.no_role); + + private Role(int resId) { + this.resId = resId; + } + + private int resId; + + public int getResId() { + return resId; + } + } + public static final int ERROR_NO_ERROR = 0; public static final int ERROR_NICK_IN_USE = 1; public static final int ERROR_UNKNOWN = 2; @@ -30,6 +70,7 @@ public class MucOptions { private interface OnEventListener { public void onSuccess(); + public void onFailure(); } @@ -42,18 +83,8 @@ public class MucOptions { } public class User { - public static final int ROLE_MODERATOR = 3; - public static final int ROLE_NONE = 0; - public static final int ROLE_PARTICIPANT = 2; - public static final int ROLE_VISITOR = 1; - public static final int AFFILIATION_ADMIN = 4; - public static final int AFFILIATION_OWNER = 3; - public static final int AFFILIATION_MEMBER = 2; - public static final int AFFILIATION_OUTCAST = 1; - public static final int AFFILIATION_NONE = 0; - - private int role; - private int affiliation; + private Role role; + private Affiliation affiliation; private String name; private Jid jid; private long pgpKeyId = 0; @@ -74,7 +105,7 @@ public class MucOptions { return this.jid; } - public int getRole() { + public Role getRole() { return this.role; } @@ -82,35 +113,41 @@ public class MucOptions { role = role.toLowerCase(); switch (role) { case "moderator": - this.role = ROLE_MODERATOR; + this.role = Role.MODERATOR; break; case "participant": - this.role = ROLE_PARTICIPANT; + this.role = Role.PARTICIPANT; break; case "visitor": - this.role = ROLE_VISITOR; + this.role = Role.VISITOR; break; default: - this.role = ROLE_NONE; + this.role = Role.NONE; break; } } - public int getAffiliation() { + public Affiliation getAffiliation() { return this.affiliation; } public void setAffiliation(String affiliation) { - if (affiliation.equalsIgnoreCase("admin")) { - this.affiliation = AFFILIATION_ADMIN; - } else if (affiliation.equalsIgnoreCase("owner")) { - this.affiliation = AFFILIATION_OWNER; - } else if (affiliation.equalsIgnoreCase("member")) { - this.affiliation = AFFILIATION_MEMBER; - } else if (affiliation.equalsIgnoreCase("outcast")) { - this.affiliation = AFFILIATION_OUTCAST; - } else { - this.affiliation = AFFILIATION_NONE; + affiliation = affiliation.toLowerCase(); + switch (affiliation) { + case "admin": + this.affiliation = Affiliation.ADMIN; + break; + case "owner": + this.affiliation = Affiliation.OWNER; + break; + case "member": + this.affiliation = Affiliation.MEMBER; + break; + case "outcast": + this.affiliation = Affiliation.OUTCAST; + break; + default: + this.affiliation = Affiliation.NONE; } } @@ -168,7 +205,7 @@ public class MucOptions { if (!from.isBareJid()) { final String name = from.getResourcepart(); final String type = packet.getAttribute("type"); - final Element x = packet.findChild("x","http://jabber.org/protocol/muc#user"); + final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); final List codes = getStatusCodes(x); if (type == null) { User user = new User(); @@ -204,7 +241,7 @@ public class MucOptions { msg = ""; } user.setPgpKeyId(pgp.fetchKeyId(account, msg, - signed.getContent())); + signed.getContent())); } } } @@ -261,10 +298,10 @@ public class MucOptions { private List getStatusCodes(Element x) { List codes = new ArrayList(); if (x != null) { - for(Element child : x.getChildren()) { + for (Element child : x.getChildren()) { if (child.getName().equals("status")) { String code = child.getAttribute("code"); - if (code!=null) { + if (code != null) { codes.add(code); } } @@ -389,7 +426,7 @@ public class MucOptions { public Jid createJoinJid(String nick) { try { - return Jid.fromString(this.conversation.getJid().toBareJid().toString() + "/"+nick); + return Jid.fromString(this.conversation.getJid().toBareJid().toString() + "/" + nick); } catch (final InvalidJidException e) { return null; } diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index eeb015f3..5a30d761 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -31,6 +31,7 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.User; import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; @@ -59,6 +60,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers private List users = new ArrayList<>(); private User mSelectedUser = null; + private boolean mAdvancedMode = false; + private UiCallback renameCallback = new UiCallback() { @Override public void success(Conversation object) { @@ -66,7 +69,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override public void run() { Toast.makeText(ConferenceDetailsActivity.this,getString(R.string.your_nick_has_been_changed),Toast.LENGTH_SHORT).show(); - populateView(); + updateView(); } }); @@ -94,7 +97,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override public void run() { - populateView(); + updateView(); } }); } @@ -105,7 +108,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override public void run() { - populateView(); + updateView(); } }); } @@ -171,23 +174,16 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers case R.id.action_delete_bookmark: deleteBookmark(); break; + case R.id.action_advanced_mode: + this.mAdvancedMode = !menuItem.isChecked(); + menuItem.setChecked(this.mAdvancedMode); + invalidateOptionsMenu(); + updateView(); + break; } return super.onOptionsItemSelected(menuItem); } - public String getReadableRole(int role) { - switch (role) { - case User.ROLE_MODERATOR: - return getString(R.string.moderator); - case User.ROLE_PARTICIPANT: - return getString(R.string.participant); - case User.ROLE_VISITOR: - return getString(R.string.visitor); - default: - return ""; - } - } - @Override protected String getShareableUri() { if (mConversation != null) { @@ -201,6 +197,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers public boolean onPrepareOptionsMenu(Menu menu) { MenuItem menuItemSaveBookmark = menu.findItem(R.id.action_save_as_bookmark); MenuItem menuItemDeleteBookmark = menu.findItem(R.id.action_delete_bookmark); + MenuItem menuItemAdvancedMode = menu.findItem(R.id.action_advanced_mode); + menuItemAdvancedMode.setChecked(mAdvancedMode); Account account = mConversation.getAccount(); if (account.hasBookmarkFor(mConversation.getJid().toBareJid())) { menuItemSaveBookmark.setVisible(false); @@ -290,16 +288,15 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers this.mConversation = xmppConnectionService .findConversationByUuid(uuid); if (this.mConversation != null) { - populateView(); + updateView(); } } } - private void populateView() { + private void updateView() { mAccountJid.setText(getString(R.string.using_account, mConversation .getAccount().getJid().toBareJid())); - mYourPhoto.setImageBitmap(avatarService().get( - mConversation.getAccount(), getPixel(48))); + mYourPhoto.setImageBitmap(avatarService().get(mConversation.getAccount(), getPixel(48))); setTitle(mConversation.getName()); mFullJid.setText(mConversation.getJid().toBareJid().toString()); mYourNick.setText(mConversation.getMucOptions().getActualNick()); @@ -307,18 +304,12 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers if (mConversation.getMucOptions().online()) { mMoreDetails.setVisibility(View.VISIBLE); User self = mConversation.getMucOptions().getSelf(); - switch (self.getAffiliation()) { - case User.AFFILIATION_ADMIN: - mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " (" - + getString(R.string.admin) + ")"); - break; - case User.AFFILIATION_OWNER: - mRoleAffiliaton.setText(getReadableRole(self.getRole()) + " (" - + getString(R.string.owner) + ")"); - break; - default: - mRoleAffiliaton.setText(getReadableRole(self.getRole())); - break; + final String status = getStatus(self); + if (status != null) { + mRoleAffiliaton.setVisibility(View.VISIBLE); + mRoleAffiliaton.setText(status); + } else { + mRoleAffiliaton.setVisibility(View.GONE); } } this.users.clear(); @@ -337,32 +328,31 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers }); registerForContextMenu(view); view.setTag(user); - TextView name = (TextView) view - .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) { - key.setVisibility(View.VISIBLE); - key.setOnClickListener(new OnClickListener() { + TextView tvDisplayName = (TextView) view.findViewById(R.id.contact_display_name); + TextView tvKey = (TextView) view.findViewById(R.id.key); + TextView tvStatus = (TextView) view.findViewById(R.id.contact_jid); + if (mAdvancedMode && user.getPgpKeyId() != 0) { + tvKey.setVisibility(View.VISIBLE); + tvKey.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewPgpKey(user); } }); - key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId())); + tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId())); } Bitmap bm; Contact contact = user.getContact(); if (contact != null) { bm = avatarService().get(contact, getPixel(48)); - name.setText(contact.getDisplayName()); - role.setText(user.getName() + " \u2022 " - + getReadableRole(user.getRole())); + tvDisplayName.setText(contact.getDisplayName()); + tvStatus.setText(user.getName() + " \u2022 " + getStatus(user)); } else { bm = avatarService().get(user.getName(), getPixel(48)); - name.setText(user.getName()); - role.setText(getReadableRole(user.getRole())); + tvDisplayName.setText(user.getName()); + tvStatus.setText(getStatus(user)); + } ImageView iv = (ImageView) view.findViewById(R.id.contact_photo); iv.setImageBitmap(bm); @@ -370,6 +360,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } } + private String getStatus(User user) { + if (mAdvancedMode) { + StringBuilder builder = new StringBuilder(); + builder.append(getString(user.getAffiliation().getResId())); + builder.append(" ("); + builder.append(getString(user.getRole().getResId())); + builder.append(')'); + return builder.toString(); + } else { + return getString(user.getAffiliation().getResId()); + } + } + @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void setListItemBackgroundOnView(View view) { -- cgit v1.2.3 From 2679824770b025e65a9a848c1112219bc8df1b37 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 5 Jan 2015 15:08:13 +0100 Subject: prevent QR code parser from crashing fixed #839 --- .../java/eu/siacs/conversations/utils/XmppUri.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/XmppUri.java b/src/main/java/eu/siacs/conversations/utils/XmppUri.java index aacb6362..0f1b18c3 100644 --- a/src/main/java/eu/siacs/conversations/utils/XmppUri.java +++ b/src/main/java/eu/siacs/conversations/utils/XmppUri.java @@ -18,7 +18,11 @@ public class XmppUri { try { parse(Uri.parse(uri)); } catch (IllegalArgumentException e) { - jid = null; + try { + jid = Jid.fromString(uri).toBareJid().toString(); + } catch (InvalidJidException e2) { + jid = null; + } } } @@ -42,6 +46,13 @@ public class XmppUri { try { jid = URLDecoder.decode(uri.getEncodedPath(), "UTF-8").split("/")[1]; } catch (final UnsupportedEncodingException ignored) { + jid = null; + } + } else { + try { + jid = Jid.fromString(uri.toString()).toBareJid().toString(); + } catch (final InvalidJidException ignored) { + jid = null; } } } @@ -62,7 +73,7 @@ public class XmppUri { public Jid getJid() { try { - return Jid.fromString(this.jid); + return this.jid == null ? null :Jid.fromString(this.jid); } catch (InvalidJidException e) { return null; } @@ -71,8 +82,4 @@ public class XmppUri { public String getFingerprint() { return this.fingerprint; } - - public boolean isMuc() { - return this.muc; - } } -- cgit v1.2.3 From 85f24c91061ecc6b9d038837cd304164f59135bb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 5 Jan 2015 16:17:05 +0100 Subject: avoid requesting blocklist after stream resumption --- .../eu/siacs/conversations/parser/IqParser.java | 1 + .../siacs/conversations/xmpp/XmppConnection.java | 50 ++++++++++------------ 2 files changed, 24 insertions(+), 27 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 3b501f33..6430c296 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -92,6 +92,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { // Otherwise, just update the existing blocklist. if (packet.getType() == IqPacket.TYPE.RESULT) { account.clearBlocklist(); + account.getXmppConnection().getFeatures().setBlockListRequested(true); } if (items != null) { final Collection jids = new ArrayList<>(items.size()); diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 714b9a51..30437575 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -95,12 +95,9 @@ public class XmppConnection implements Runnable { private int smVersion = 3; private final SparseArray messageReceipts = new SparseArray<>(); - private boolean enabledEncryption = false; - private boolean enabledCarbons = false; - private int stanzasReceived = 0; private int stanzasSent = 0; - private long lastPaketReceived = 0; + private long lastPacketReceived = 0; private long lastPingSent = 0; private long lastConnect = 0; private long lastSessionStarted = 0; @@ -147,13 +144,12 @@ public class XmppConnection implements Runnable { protected void connect() { Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting"); - enabledEncryption = false; + features.encryptionEnabled = false; lastConnect = SystemClock.elapsedRealtime(); lastPingSent = SystemClock.elapsedRealtime(); this.attempt++; try { - shouldAuthenticate = shouldBind = !account - .isOptionSet(Account.OPTION_REGISTER); + shouldAuthenticate = shouldBind = !account.isOptionSet(Account.OPTION_REGISTER); tagReader = new XmlReader(wakeLock); tagWriter = new TagWriter(); packetCallbacks.clear(); @@ -304,7 +300,7 @@ public class XmppConnection implements Runnable { final RequestPacket r = new RequestPacket(smVersion); tagWriter.writeStanzaAsync(r); } else if (nextTag.isStart("resumed")) { - lastPaketReceived = SystemClock.elapsedRealtime(); + lastPacketReceived = SystemClock.elapsedRealtime(); final Element resumed = tagReader.readElement(nextTag); final String h = resumed.getAttribute("h"); try { @@ -337,7 +333,7 @@ public class XmppConnection implements Runnable { tagWriter.writeStanzaAsync(ack); } else if (nextTag.isStart("a")) { final Element ack = tagReader.readElement(nextTag); - lastPaketReceived = SystemClock.elapsedRealtime(); + lastPacketReceived = SystemClock.elapsedRealtime(); final int serverSequence = Integer.parseInt(ack.getAttribute("h")); final String msgId = this.messageReceipts.get(serverSequence); if (msgId != null) { @@ -426,7 +422,7 @@ public class XmppConnection implements Runnable { } } ++stanzasReceived; - lastPaketReceived = SystemClock.elapsedRealtime(); + lastPacketReceived = SystemClock.elapsedRealtime(); return element; } @@ -530,7 +526,7 @@ public class XmppConnection implements Runnable { tagWriter.setOutputStream(sslSocket.getOutputStream()); sendStartStream(); Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": TLS connection established"); - enabledEncryption = true; + features.encryptionEnabled = true; processStream(tagReader.readTag()); sslSocket.close(); } catch (final NoSuchAlgorithmException | KeyManagementException e1) { @@ -543,18 +539,18 @@ public class XmppConnection implements Runnable { private void processStreamFeatures(final Tag currentTag) throws XmlPullParserException, IOException { this.streamFeatures = tagReader.readElement(currentTag); - if (this.streamFeatures.hasChild("starttls") && !enabledEncryption) { + if (this.streamFeatures.hasChild("starttls") && !features.encryptionEnabled) { sendStartTLS(); } else if (this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER) - && enabledEncryption) { + && features.encryptionEnabled) { sendRegistryRequest(); } else if (!this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) { changeStatus(Account.State.REGISTRATION_NOT_SUPPORTED); disconnect(true); } else if (this.streamFeatures.hasChild("mechanisms") - && shouldAuthenticate && enabledEncryption) { + && shouldAuthenticate && features.encryptionEnabled) { final List mechanisms = extractMechanisms(streamFeatures .findChild("mechanisms")); final Element auth = new Element("auth"); @@ -679,15 +675,15 @@ public class XmppConnection implements Runnable { tagWriter.writeStanzaAsync(enable); stanzasSent = 0; messageReceipts.clear(); - } else if (streamFeatures.hasChild("sm", - "urn:xmpp:sm:2")) { + } else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) { smVersion = 2; final EnablePacket enable = new EnablePacket(smVersion); tagWriter.writeStanzaAsync(enable); stanzasSent = 0; messageReceipts.clear(); } - enabledCarbons = false; + features.carbonsEnabled = false; + features.blockListRequested = false; disco.clear(); sendServiceDiscoveryInfo(account.getServer()); sendServiceDiscoveryItems(account.getServer()); @@ -750,12 +746,10 @@ public class XmppConnection implements Runnable { } private void enableAdvancedStreamFeatures() { - if (getFeatures().carbons()) { - if (!enabledCarbons) { - sendEnableCarbons(); - } + if (getFeatures().carbons() && !features.carbonsEnabled) { + sendEnableCarbons(); } - if (getFeatures().blocking()) { + if (getFeatures().blocking() && !features.blockListRequested) { Log.d(Config.LOGTAG, "Requesting block list"); this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser()); } @@ -792,7 +786,7 @@ public class XmppConnection implements Runnable { if (!packet.hasChild("error")) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": successfully enabled carbons"); - enabledCarbons = true; + features.carbonsEnabled = true; } else { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": error enableing carbons " + packet.toString()); @@ -1018,7 +1012,7 @@ public class XmppConnection implements Runnable { } public long getLastPacketReceived() { - return this.lastPaketReceived; + return this.lastPacketReceived; } public void sendActive() { @@ -1031,6 +1025,9 @@ public class XmppConnection implements Runnable { public class Features { XmppConnection connection; + private boolean carbonsEnabled = false; + private boolean encryptionEnabled = false; + private boolean blockListRequested = false; public Features(final XmppConnection connection) { this.connection = connection; @@ -1078,9 +1075,8 @@ public class XmppConnection implements Runnable { return connection.streamFeatures != null && connection.streamFeatures.hasChild("ver"); } - public boolean streamhost() { - return connection - .findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null; + public void setBlockListRequested(boolean value) { + this.blockListRequested = value; } } -- cgit v1.2.3 From 0c51245ff5840cf485ce893062adc1cf778cd808 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 5 Jan 2015 18:45:39 +0100 Subject: reworked ping scheduling strategy. very experimental --- .../services/XmppConnectionService.java | 93 ++++++++-------------- 1 file changed, 32 insertions(+), 61 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 59cb3bb2..1192d5b9 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -188,12 +188,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } syncDirtyContacts(account); - scheduleWakeupCall(Config.PING_MAX_INTERVAL, true); + scheduleWakeUpCall(Config.PING_MAX_INTERVAL,account.getUuid().hashCode()); } else if (account.getStatus() == Account.State.OFFLINE) { resetSendingToWaiting(account); if (!account.isOptionSet(Account.OPTION_DISABLED)) { int timeToReconnect = mRandom.nextInt(50) + 10; - scheduleWakeupCall(timeToReconnect, false); + scheduleWakeUpCall(timeToReconnect,account.getUuid().hashCode()); } } else if (account.getStatus() == Account.State.REGISTRATION_SUCCESSFUL) { databaseBackend.updateAccount(account); @@ -206,7 +206,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa + ": error connecting account. try again in " + next + "s for the " + (connection.getAttempt() + 1) + " time"); - scheduleWakeupCall((int) (next * 1.2), false); + scheduleWakeUpCall(next,account.getUuid().hashCode()); } } getNotificationService().updateErrorNotification(); @@ -241,8 +241,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private OpenPgpServiceConnection pgpServiceConnection; private PgpEngine mPgpEngine = null; - private Intent pingIntent; - private PendingIntent pendingPingIntent = null; private WakeLock wakeLock; private PowerManager pm; private final OnBindListener mOnBindListener = new OnBindListener() { @@ -388,16 +386,17 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public int onStartCommand(Intent intent, int flags, int startId) { - if (intent != null && intent.getAction() != null) { - if (intent.getAction().equals(ACTION_MERGE_PHONE_CONTACTS)) { + final String action = intent == null ? null : intent.getAction(); + if (action != null) { + if (action.equals(ACTION_MERGE_PHONE_CONTACTS)) { PhoneHelper.loadPhoneContacts(getApplicationContext(), new ArrayList(), this); return START_STICKY; - } else if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) { + } else if (action.equals(Intent.ACTION_SHUTDOWN)) { logoutAndSave(); return START_NOT_STICKY; - } else if (intent.getAction().equals(ACTION_CLEAR_NOTIFICATION)) { + } else if (action.equals(ACTION_CLEAR_NOTIFICATION)) { mNotificationService.clear(); - } else if (intent.getAction().equals(ACTION_DISABLE_FOREGROUND)) { + } else if (action.equals(ACTION_DISABLE_FOREGROUND)) { getPreferences().edit().putBoolean("keep_foreground_service",false).commit(); toggleForegroundService(); } @@ -419,37 +418,36 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } if (account.getStatus() == Account.State.ONLINE) { - long lastReceived = account.getXmppConnection() - .getLastPacketReceived(); - long lastSent = account.getXmppConnection() - .getLastPingSent(); - if (lastSent - lastReceived >= Config.PING_TIMEOUT * 1000) { - Log.d(Config.LOGTAG, account.getJid() - + ": ping timeout"); + long lastReceived = account.getXmppConnection().getLastPacketReceived(); + long lastSent = account.getXmppConnection().getLastPingSent(); + long pingInterval = "ui".equals(action) ? Config.PING_MIN_INTERVAL * 1000 : Config.PING_MAX_INTERVAL * 1000; + long secondsToNextPing = ((lastReceived + pingInterval) - SystemClock.elapsedRealtime()) / 1000; + if (lastSent > lastReceived && (lastSent + Config.PING_TIMEOUT * 1000) < SystemClock.elapsedRealtime()) { + Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": ping timeout"); this.reconnectAccount(account, true); - } else if (SystemClock.elapsedRealtime() - lastReceived >= Config.PING_MIN_INTERVAL * 1000) { + } else if (secondsToNextPing <= 0) { account.getXmppConnection().sendPing(); - this.scheduleWakeupCall(2, false); + Log.d(Config.LOGTAG, account.getJid().toBareJid()+" send ping"); + this.scheduleWakeUpCall(Config.PING_TIMEOUT,account.getUuid().hashCode()); + } else { + this.scheduleWakeUpCall((int) secondsToNextPing, account.getUuid().hashCode()); } } else if (account.getStatus() == Account.State.OFFLINE) { if (account.getXmppConnection() == null) { - account.setXmppConnection(this - .createConnection(account)); + account.setXmppConnection(this.createConnection(account)); } new Thread(account.getXmppConnection()).start(); } else if ((account.getStatus() == Account.State.CONNECTING) && ((SystemClock.elapsedRealtime() - account .getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) { - Log.d(Config.LOGTAG, account.getJid() - + ": time out during connect reconnecting"); + Log.d(Config.LOGTAG, account.getJid()+ ": time out during connect reconnecting"); reconnectAccount(account, true); } else { if (account.getXmppConnection().getTimeToNextAttempt() <= 0) { reconnectAccount(account, true); } } - // in any case. reschedule wakup call - this.scheduleWakeupCall(Config.PING_MAX_INTERVAL, true); + } if (mOnAccountUpdate != null) { mOnAccountUpdate.onAccountUpdate(); @@ -546,42 +544,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa stopSelf(); } - protected void scheduleWakeupCall(int seconds, boolean ping) { - long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000; - Context context = getApplicationContext(); - AlarmManager alarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); + protected void scheduleWakeUpCall(int seconds, int requestCode) { + final long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000; - if (ping) { - if (this.pingIntent == null) { - this.pingIntent = new Intent(context, EventReceiver.class); - this.pingIntent.setAction("ping"); - this.pingIntent.putExtra("time", timeToWake); - this.pendingPingIntent = PendingIntent.getBroadcast(context, 0, - this.pingIntent, 0); - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - timeToWake, pendingPingIntent); - } else { - long scheduledTime = this.pingIntent.getLongExtra("time", 0); - if (scheduledTime < SystemClock.elapsedRealtime() - || (scheduledTime > timeToWake)) { - this.pingIntent.putExtra("time", timeToWake); - alarmManager.cancel(this.pendingPingIntent); - this.pendingPingIntent = PendingIntent.getBroadcast( - context, 0, this.pingIntent, 0); - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - timeToWake, pendingPingIntent); - } - } - } else { - Intent intent = new Intent(context, EventReceiver.class); - intent.setAction("ping_check"); - PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, - intent, 0); - alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, - alarmIntent); - } + Context context = getApplicationContext(); + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(context, EventReceiver.class); + intent.setAction("ping"); + PendingIntent alarmIntent = PendingIntent.getBroadcast(context, requestCode, intent, 0); + alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, alarmIntent); } public XmppConnection createConnection(final Account account) { @@ -1862,8 +1834,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } Thread thread = new Thread(account.getXmppConnection()); thread.start(); - scheduleWakeupCall((int) (Config.CONNECT_TIMEOUT * 1.2), - false); + scheduleWakeUpCall(Config.CONNECT_TIMEOUT,account.getUuid().hashCode()); } else { account.getRoster().clearPresences(); account.setXmppConnection(null); -- cgit v1.2.3 From fdcbdfdc0500e9cad97d716def5112d2bec91e19 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 5 Jan 2015 18:46:42 +0100 Subject: added debug info + possible platform bug work arounds to message adapter --- .../java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index ae3c1834..5b5664c6 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -10,6 +10,7 @@ import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.util.DisplayMetrics; +import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; @@ -23,6 +24,7 @@ import android.widget.Toast; 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.Contact; @@ -430,6 +432,11 @@ public class MessageAdapter extends ArrayAdapter { } return view; } else if (type == NULL) { + if (viewHolder.message_box != null) { + Log.e(Config.LOGTAG, "detected type=NULL but with wrong cached view"); + view = activity.getLayoutInflater().inflate(R.layout.message_null, parent, false); + view.setTag(new ViewHolder()); + } if (position == getCount() - 1) { view.getLayoutParams().height = 1; } else { @@ -438,6 +445,9 @@ public class MessageAdapter extends ArrayAdapter { } view.setLayoutParams(view.getLayoutParams()); return view; + } else if (message.wasMergedIntoPrevious()) { + Log.e(Config.LOGTAG,"detected wasMergedIntoPrevious with wrong type"); + return view; } else if (viewHolder.messageBody == null || viewHolder.image == null) { return view; //avoiding weird platform bugs } else if (type == RECEIVED) { -- cgit v1.2.3 From 4b0043ba91026887d74bfc46f0bcb0b23a6c2230 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 Jan 2015 18:25:31 +0100 Subject: fixed potential NPEs in ShareWithActivity --- src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index 5e770376..a3904d21 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -134,11 +134,12 @@ public class ShareWithActivity extends XmppActivity { @Override public void onStart() { final String type = getIntent().getType(); - if (type != null && !type.startsWith("text/")) { - this.share.uri = (Uri) getIntent().getParcelableExtra(Intent.EXTRA_STREAM); + final Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); + if (type != null && uri != null && !type.startsWith("text/")) { + this.share.uri = uri; try { - this.share.image = type.startsWith("image/") - || URLConnection.guessContentTypeFromName(this.share.uri.toString()).startsWith("image/"); + String guess = URLConnection.guessContentTypeFromName(uri.toString()); + this.share.image = type.startsWith("image/") || (guess != null && guess.startsWith("image/")); } catch (final StringIndexOutOfBoundsException ignored) { this.share.image = false; } -- cgit v1.2.3 From 562699c7458a2acda942b8a6fe7e0bed4032309c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 Jan 2015 18:26:14 +0100 Subject: run invalidateOptionsMenu on uiThread --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 5cfc1116..e71f4cbb 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -1050,10 +1050,10 @@ public class ConversationActivity extends XmppActivity @Override public void OnUpdateBlocklist(Status status) { - invalidateOptionsMenu(); runOnUiThread(new Runnable() { @Override public void run() { + invalidateOptionsMenu(); ConversationActivity.this.mConversationFragment.updateMessages(); } }); -- cgit v1.2.3 From 353f4e38bb065dacd8c8c16872b205aa0ca02f92 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 Jan 2015 18:44:08 +0100 Subject: mark sent images as sent_received instead of sent fixed #842 --- src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index ff94563c..fe37596c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -707,8 +707,7 @@ public class JingleConnection implements Downloadable { private void receiveSuccess() { this.mJingleStatus = JINGLE_STATUS_FINISHED; - this.mXmppConnectionService.markMessage(this.message, - Message.STATUS_SEND); + this.mXmppConnectionService.markMessage(this.message,Message.STATUS_SEND_RECEIVED); this.disconnectSocks5Connections(); if (this.transport != null && this.transport instanceof JingleInbandTransport) { this.transport.disconnect(); -- cgit v1.2.3 From f02f510c187a581afd27093c97eb421fc56d3221 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 Jan 2015 19:46:52 +0100 Subject: fixed bug in new ping strategy --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 1192d5b9..cf3f72dc 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -421,16 +421,16 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa long lastReceived = account.getXmppConnection().getLastPacketReceived(); long lastSent = account.getXmppConnection().getLastPingSent(); long pingInterval = "ui".equals(action) ? Config.PING_MIN_INTERVAL * 1000 : Config.PING_MAX_INTERVAL * 1000; - long secondsToNextPing = ((lastReceived + pingInterval) - SystemClock.elapsedRealtime()) / 1000; + long msToNextPing = (Math.max(lastReceived,lastSent) + pingInterval) - SystemClock.elapsedRealtime(); if (lastSent > lastReceived && (lastSent + Config.PING_TIMEOUT * 1000) < SystemClock.elapsedRealtime()) { Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": ping timeout"); this.reconnectAccount(account, true); - } else if (secondsToNextPing <= 0) { + } else if (msToNextPing <= 0) { account.getXmppConnection().sendPing(); Log.d(Config.LOGTAG, account.getJid().toBareJid()+" send ping"); this.scheduleWakeUpCall(Config.PING_TIMEOUT,account.getUuid().hashCode()); } else { - this.scheduleWakeUpCall((int) secondsToNextPing, account.getUuid().hashCode()); + this.scheduleWakeUpCall((int) (msToNextPing / 1000), account.getUuid().hashCode()); } } else if (account.getStatus() == Account.State.OFFLINE) { if (account.getXmppConnection() == null) { -- cgit v1.2.3 From d502e57661ecc63e09692add8ae3e7c0daf93b70 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 7 Jan 2015 00:59:42 +0100 Subject: refactored UiHelper --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 2f1383b8..74f0d345 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -51,10 +51,18 @@ public class UIHelper { } private static boolean today(Date date) { + return sameDay(date,new Date(System.currentTimeMillis())); + } + + public static boolean sameDay(long timestamp1, long timestamp2) { + return sameDay(new Date(timestamp1),new Date(timestamp2)); + } + + private static boolean sameDay(Date a, Date b) { Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); - cal1.setTime(date); - cal2.setTimeInMillis(System.currentTimeMillis()); + cal1.setTime(a); + cal2.setTime(b); return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.DAY_OF_YEAR) == cal2 .get(Calendar.DAY_OF_YEAR); -- cgit v1.2.3 From a22c8c04d8c15925e6048dcc5de3d8e8eb9d7055 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 7 Jan 2015 01:01:15 +0100 Subject: use copyonwritearraylist in for phone helper --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index cf3f72dc..90e9f20b 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -389,7 +389,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final String action = intent == null ? null : intent.getAction(); if (action != null) { if (action.equals(ACTION_MERGE_PHONE_CONTACTS)) { - PhoneHelper.loadPhoneContacts(getApplicationContext(), new ArrayList(), this); + PhoneHelper.loadPhoneContacts(getApplicationContext(), new CopyOnWriteArrayList(), this); return START_STICKY; } else if (action.equals(Intent.ACTION_SHUTDOWN)) { logoutAndSave(); @@ -500,7 +500,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa this.databaseBackend.readRoster(account.getRoster()); } initConversations(); - PhoneHelper.loadPhoneContacts(getApplicationContext(),new ArrayList(), this); + PhoneHelper.loadPhoneContacts(getApplicationContext(),new CopyOnWriteArrayList(), this); getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver); this.fileObserver.startWatching(); -- cgit v1.2.3 From 81e9afdf192aa925f1dc18a1b5e1d666ab153342 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 7 Jan 2015 12:20:39 +0100 Subject: reset next encryption when archiving conversations --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 3 +++ src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 90e9f20b..5d314ecf 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1005,6 +1005,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } else { conversation.setMode(Conversation.MODE_SINGLE); } + conversation.setNextEncryption(-1); conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE)); this.databaseBackend.updateConversation(conversation); } else { @@ -1040,6 +1041,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void archiveConversation(Conversation conversation) { + conversation.setStatus(Conversation.STATUS_ARCHIVED); + conversation.setNextEncryption(-1); synchronized (this.conversations) { if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getAccount().getStatus() == Account.State.ONLINE) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index e71f4cbb..795dabf2 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -492,7 +492,6 @@ public class ConversationActivity extends XmppActivity } public void endConversation(Conversation conversation) { - conversation.setStatus(Conversation.STATUS_ARCHIVED); showConversationsOverview(); xmppConnectionService.archiveConversation(conversation); if (conversationList.size() > 0) { -- cgit v1.2.3 From ef525fb10e672b23219fdf180d310de9f6ce59d3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 7 Jan 2015 15:03:29 +0100 Subject: basic affiliation changes in muc --- .../siacs/conversations/entities/MucOptions.java | 48 ++++++++++---- .../siacs/conversations/generator/IqGenerator.java | 11 ++++ .../services/XmppConnectionService.java | 22 +++++++ .../ui/ConferenceDetailsActivity.java | 76 ++++++++++++++++++---- 4 files changed, 132 insertions(+), 25 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index ce2c5b04..6a12f407 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -17,40 +17,64 @@ import android.annotation.SuppressLint; public class MucOptions { public enum Affiliation { - OWNER(R.string.owner), - ADMIN(R.string.admin), - MEMBER(R.string.member), - OUTCAST(R.string.outcast), - NONE(R.string.no_affiliation); - - private Affiliation(int resId) { + OWNER("owner", 4, R.string.owner), + ADMIN("admin", 3, R.string.admin), + MEMBER("member", 2, R.string.member), + OUTCAST("outcast", 0, R.string.outcast), + NONE("none", 1, R.string.no_affiliation); + + private Affiliation(String string, int rank, int resId) { + this.string = string; this.resId = resId; + this.rank = rank; } + private String string; private int resId; + private int rank; public int getResId() { return resId; } + + @Override + public String toString() { + return this.string; + } + + public boolean outranks(Affiliation affiliation) { + return rank > affiliation.rank; + } + + public boolean ranks(Affiliation affiliation) { + return rank >= affiliation.rank; + } } ; public enum Role { - MODERATOR(R.string.moderator), - VISITOR(R.string.visitor), - PARTICIPANT(R.string.participant), - NONE(R.string.no_role); + MODERATOR("moderator", R.string.moderator), + VISITOR("visitor", R.string.visitor), + PARTICIPANT("participant", R.string.participant), + NONE("none", R.string.no_role); - private Role(int resId) { + private Role(String string, int resId) { + this.string = string; this.resId = resId; } + private String string; private int resId; public int getResId() { return resId; } + + @Override + public String toString() { + return this.string; + } } public static final int ERROR_NO_ERROR = 0; diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 58933692..988b9744 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -5,6 +5,7 @@ import java.util.Collections; import java.util.List; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.Xmlns; @@ -148,4 +149,14 @@ public class IqGenerator extends AbstractGenerator { query.addChild("password").setContent(newPassword); return packet; } + + public IqPacket changeAffiliation(Conversation conference, Jid jid, String affiliation) { + IqPacket packet = new IqPacket(IqPacket.TYPE.SET); + packet.setTo(conference.getJid().toBareJid()); + packet.setFrom(conference.getAccount().getJid()); + Element item = packet.query("http://jabber.org/protocol/muc#admin").addChild("item"); + item.setAttribute("jid", jid.toString()); + item.setAttribute("affiliation", affiliation); + return packet; + } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 5d314ecf..4ab2d42b 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1516,6 +1516,28 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } + public void changeAffiliationInConference(final Conversation conference, Jid user, MucOptions.Affiliation affiliation, final OnAffiliationChanged callback) { + final Jid jid = user.toBareJid(); + IqPacket request = this.mIqGenerator.changeAffiliation(conference, jid, affiliation.toString()); + Log.d(Config.LOGTAG,request.toString()); + sendIqPacket(conference.getAccount(),request,new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + Log.d(Config.LOGTAG,packet.toString()); + if (packet.getType() == IqPacket.TYPE.RESULT) { + callback.onAffiliationChangedSuccessful(jid); + } else { + callback.onAffiliationChangeFailed(jid,R.string.could_not_change_affiliation); + } + } + }); + } + + public interface OnAffiliationChanged { + public void onAffiliationChangedSuccessful(Jid jid); + public void onAffiliationChangeFailed(Jid jid, int resId); + } + public void disconnect(Account account, boolean force) { if ((account.getStatus() == Account.State.ONLINE) || (account.getStatus() == Account.State.DISABLED)) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 5a30d761..41190ef2 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -33,11 +33,13 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.User; +import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; +import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; -public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate { +public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged { public static final String ACTION_VIEW_MUC = "view_muc"; private Conversation mConversation; private OnClickListener inviteListener = new OnClickListener() { @@ -222,21 +224,44 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers if (tag instanceof User) { getMenuInflater().inflate(R.menu.muc_details_context,menu); final User user = (User) tag; + final User self = mConversation.getMucOptions().getSelf(); this.mSelectedUser = user; String name; - final Contact contact = user.getContact(); - if (contact != null) { - name = contact.getDisplayName(); - } else if (user.getJid() != null) { - name = user.getJid().toBareJid().toString(); - } else { - name = user.getName(); - } - menu.setHeaderTitle(name); - MenuItem startConversation = menu.findItem(R.id.start_conversation); - if (user.getJid() == null) { - startConversation.setVisible(false); + if (user.getJid() != null) { + final Contact contact = user.getContact(); + if (contact != null) { + name = contact.getDisplayName(); + } else if (user.getJid() != null) { + name = user.getJid().toBareJid().toString(); + } else { + name = user.getName(); + } + menu.setHeaderTitle(name); + MenuItem startConversation = menu.findItem(R.id.start_conversation); + MenuItem giveMembership = menu.findItem(R.id.give_membership); + MenuItem removeMembership = menu.findItem(R.id.remove_membership); + MenuItem giveAdminPrivileges = menu.findItem(R.id.give_admin_privileges); + MenuItem removeAdminPrivileges = menu.findItem(R.id.remove_admin_privileges); + MenuItem removeFromRoom = menu.findItem(R.id.remove_from_room); + startConversation.setVisible(true); + if (self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) && + self.getAffiliation().outranks(user.getAffiliation())) { + if (mAdvancedMode) { + if (user.getAffiliation() == MucOptions.Affiliation.NONE) { + giveMembership.setVisible(true); + } else { + removeMembership.setVisible(true); + } + } + if (user.getAffiliation() != MucOptions.Affiliation.ADMIN) { + giveAdminPrivileges.setVisible(true); + } else { + removeAdminPrivileges.setVisible(true); + } + removeFromRoom.setVisible(true); + } } + } super.onCreateContextMenu(menu,v,menuInfo); } @@ -247,6 +272,21 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers case R.id.start_conversation: startConversation(mSelectedUser); return true; + case R.id.give_admin_privileges: + xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.ADMIN,this); + return true; + case R.id.give_membership: + xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this); + return true; + case R.id.remove_membership: + xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.NONE,this); + return true; + case R.id.remove_admin_privileges: + xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this); + return true; + case R.id.remove_from_room: + xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this); + return true; default: return super.onContextItemSelected(item); } @@ -399,4 +439,14 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } } } + + @Override + public void onAffiliationChangedSuccessful(Jid jid) { + + } + + @Override + public void onAffiliationChangeFailed(Jid jid, int resId) { + + } } -- cgit v1.2.3 From 0ad8796b4402cf9f39c6aede7873429cfcd0d4ad Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 7 Jan 2015 16:45:44 +0100 Subject: fixed invites --- .../siacs/conversations/parser/MessageParser.java | 61 +++++++++------------- 1 file changed, 24 insertions(+), 37 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 65a8f9e6..af9d0401 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -348,6 +348,17 @@ public class MessageParser extends AbstractParser implements private void parseNonMessage(Element packet, Account account) { final Jid from = packet.getAttributeAsJid("from"); + Element invite = extractInvite(packet); + if (invite != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account,from, true); + if (!conversation.getMucOptions().online()) { + Element password = invite.findChild("password"); + conversation.getMucOptions().setPassword(password == null ? null : password.getContent()); + mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.joinMuc(conversation); + mXmppConnectionService.updateConversationUi(); + } + } if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event"); @@ -374,42 +385,18 @@ public class MessageParser extends AbstractParser implements updateLastseen(packet, account, false); mXmppConnectionService.markMessage(account, from.toBareJid(), id, Message.STATUS_SEND_RECEIVED); - } else if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) { - Element x = packet.findChild("x", - "http://jabber.org/protocol/muc#user"); - if (x.hasChild("invite")) { - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, - packet.getAttributeAsJid("from"), true); - if (!conversation.getMucOptions().online()) { - if (x.hasChild("password")) { - Element password = x.findChild("password"); - conversation.getMucOptions().setPassword( - password.getContent()); - mXmppConnectionService.databaseBackend - .updateConversation(conversation); - } - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } - } - } else if (packet.hasChild("x", "jabber:x:conference")) { - Element x = packet.findChild("x", "jabber:x:conference"); - Jid jid = x.getAttributeAsJid("jid"); - String password = x.getAttribute("password"); - if (jid != null) { - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, jid, true); - if (!conversation.getMucOptions().online()) { - if (password != null) { - conversation.getMucOptions().setPassword(password); - mXmppConnectionService.databaseBackend - .updateConversation(conversation); - } - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } - } + } + } + + private Element extractInvite(Element message) { + Element x = message.findChild("x","http://jabber.org/protocol/muc#user"); + if (x == null) { + x = message.findChild("x","jabber:x:conference"); + } + if (x != null && x.hasChild("invite")) { + return x; + } else { + return null; } } @@ -493,7 +480,7 @@ public class MessageParser extends AbstractParser implements if (message != null) { message.markUnread(); } - } else if (packet.hasChild("body")) { + } else if (packet.hasChild("body") && extractInvite(packet) == null) { message = this.parseChat(packet, account); if (message != null) { message.markUnread(); -- cgit v1.2.3 From 8d655f445a37acff288e39ec237395d303b7c3a2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 7 Jan 2015 18:34:24 +0100 Subject: more muc options * show invite button only with admin privileges or on public conferences * Offer to ban user in public conferences. Thanks to @betheg for the awesome ground work for this --- .../siacs/conversations/entities/MucOptions.java | 30 ++++++++++++++++++---- .../siacs/conversations/parser/MessageParser.java | 23 ++++++++++++----- .../services/XmppConnectionService.java | 30 +++++++++++++++++++--- .../ui/ConferenceDetailsActivity.java | 27 ++++++++++++++++++- .../conversations/ui/ConversationActivity.java | 11 ++------ 5 files changed, 96 insertions(+), 25 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 6a12f407..96860a16 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.xml.Element; @@ -12,6 +13,7 @@ import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; import android.annotation.SuppressLint; +import android.util.Log; @SuppressLint("DefaultLocale") public class MucOptions { @@ -51,8 +53,6 @@ public class MucOptions { } } - ; - public enum Role { MODERATOR("moderator", R.string.moderator), VISITOR("visitor", R.string.visitor), @@ -86,6 +86,7 @@ public class MucOptions { public static final int KICKED_FROM_ROOM = 9; + public static final String STATUS_CODE_ROOM_CONFIG_CHANGED = "104"; public static final String STATUS_CODE_SELF_PRESENCE = "110"; public static final String STATUS_CODE_BANNED = "301"; public static final String STATUS_CODE_CHANGED_NICK = "303"; @@ -107,8 +108,8 @@ public class MucOptions { } public class User { - private Role role; - private Affiliation affiliation; + private Role role = Role.NONE; + private Affiliation affiliation = Affiliation.NONE; private String name; private Jid jid; private long pgpKeyId = 0; @@ -190,6 +191,7 @@ public class MucOptions { private Account account; private List users = new CopyOnWriteArrayList<>(); + private List features = new ArrayList<>(); private Conversation conversation; private boolean isOnline = false; private int error = ERROR_UNKNOWN; @@ -205,6 +207,23 @@ public class MucOptions { this.conversation = conversation; } + public void updateFeatures(ArrayList features) { + this.features.clear(); + this.features.addAll(features); + } + + public boolean hasFeature(String feature) { + return this.features.contains(feature); + } + + public boolean canInvite() { + return !membersOnly() || self.getAffiliation().ranks(Affiliation.ADMIN); + } + + public boolean membersOnly() { + return hasFeature("muc_membersonly"); + } + public void deleteUser(String name) { for (int i = 0; i < users.size(); ++i) { if (users.get(i).getName().equals(name)) { @@ -225,6 +244,7 @@ public class MucOptions { } public void processPacket(PresencePacket packet, PgpEngine pgp) { + Log.d(Config.LOGTAG, packet.toString()); final Jid from = packet.getFrom(); if (!from.isBareJid()) { final String name = from.getResourcepart(); @@ -320,7 +340,7 @@ public class MucOptions { } private List getStatusCodes(Element x) { - List codes = new ArrayList(); + List codes = new ArrayList<>(); if (x != null) { for (Element child : x.getChildren()) { if (child.getName().equals("status")) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index af9d0401..bb9de061 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -1,15 +1,13 @@ package eu.siacs.conversations.parser; -import android.util.Log; - import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; -import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; @@ -142,14 +140,25 @@ public class MessageParser extends AbstractParser implements Conversation conversation = mXmppConnectionService .findOrCreateConversation(account, from.toBareJid(), true); if (packet.hasChild("subject")) { - conversation.getMucOptions().setSubject( - packet.findChild("subject").getContent()); + conversation.getMucOptions().setSubject(packet.findChild("subject").getContent()); mXmppConnectionService.updateConversationUi(); return null; } - if (from.isBareJid()) { + + final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); + if (from.isBareJid() && (x == null || !x.hasChild("status"))) { return null; + } else if (from.isBareJid() && x.hasChild("status")) { + for(Element child : x.getChildren()) { + if (child.getName().equals("status")) { + String code = child.getAttribute("code"); + if (code.contains(MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED)) { + mXmppConnectionService.fetchConferenceConfiguration(conversation); + } + } + } } + if (from.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { if (mXmppConnectionService.markMessage(conversation, packet.getId(), Message.STATUS_SEND)) { @@ -350,7 +359,7 @@ public class MessageParser extends AbstractParser implements final Jid from = packet.getAttributeAsJid("from"); Element invite = extractInvite(packet); if (invite != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account,from, true); + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, from, true); if (!conversation.getMucOptions().online()) { Element password = invite.findChild("password"); conversation.getMucOptions().setPassword(password == null ? null : password.getContent()); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 4ab2d42b..5c16ef3f 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1316,6 +1316,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa packet.addChild("x", "jabber:x:signed").setContent(sig); } sendPresencePacket(account, packet); + fetchConferenceConfiguration(conversation); if (!joinJid.equals(conversation.getJid())) { conversation.setContactJid(joinJid); databaseBackend.updateConversation(conversation); @@ -1475,6 +1476,29 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + public void fetchConferenceConfiguration(final Conversation conversation) { + IqPacket request = new IqPacket(IqPacket.TYPE.GET); + request.setTo(conversation.getJid().toBareJid()); + request.query("http://jabber.org/protocol/disco#info"); + sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() != IqPacket.TYPE.ERROR) { + ArrayList features = new ArrayList(); + for (Element child : packet.query().getChildren()) { + if (child != null && child.getName().equals("feature")) { + String var = child.getAttribute("var"); + if (var != null) { + features.add(var); + } + } + } + conversation.getMucOptions().updateFeatures(features); + } + } + }); + } + public void pushConferenceConfiguration(final Conversation conversation,final Bundle options, final OnConferenceOptionsPushed callback) { IqPacket request = new IqPacket(IqPacket.TYPE.GET); request.setTo(conversation.getJid().toBareJid()); @@ -1520,14 +1544,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final Jid jid = user.toBareJid(); IqPacket request = this.mIqGenerator.changeAffiliation(conference, jid, affiliation.toString()); Log.d(Config.LOGTAG,request.toString()); - sendIqPacket(conference.getAccount(),request,new OnIqPacketReceived() { + sendIqPacket(conference.getAccount(), request, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - Log.d(Config.LOGTAG,packet.toString()); + Log.d(Config.LOGTAG, packet.toString()); if (packet.getType() == IqPacket.TYPE.RESULT) { callback.onAffiliationChangedSuccessful(jid); } else { - callback.onAffiliationChangeFailed(jid,R.string.could_not_change_affiliation); + callback.onAffiliationChangeFailed(jid, R.string.could_not_change_affiliation); } } }); diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 41190ef2..5272c922 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -1,8 +1,10 @@ package eu.siacs.conversations.ui; import android.annotation.TargetApi; +import android.app.AlertDialog; import android.app.PendingIntent; import android.content.Context; +import android.content.DialogInterface; import android.content.IntentSender.SendIntentException; import android.graphics.Bitmap; import android.os.Build; @@ -285,13 +287,31 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.MEMBER,this); return true; case R.id.remove_from_room: - xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this); + removeFromRoom(mSelectedUser); return true; default: return super.onContextItemSelected(item); } } + private void removeFromRoom(final User user) { + if (mConversation.getMucOptions().membersOnly()) { + xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.NONE,this); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.ban_user_from_conference); + builder.setMessage(getString(R.string.removing_from_public_conference,user.getName())); + builder.setNegativeButton(R.string.cancel,null); + builder.setPositiveButton(R.string.ban_now,new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.OUTCAST,ConferenceDetailsActivity.this); + } + }); + builder.create().show(); + } + } + protected void startConversation(User user) { if (user.getJid() != null) { Conversation conversation = xmppConnectionService.findOrCreateConversation(this.mConversation.getAccount(),user.getJid().toBareJid(),false); @@ -397,6 +417,11 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers ImageView iv = (ImageView) view.findViewById(R.id.contact_photo); iv.setImageBitmap(bm); membersView.addView(view); + if (mConversation.getMucOptions().canInvite()) { + mInviteButton.setVisibility(View.VISIBLE); + } else { + mInviteButton.setVisibility(View.GONE); + } } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 795dabf2..ba5b3e59 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -9,7 +9,6 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentSender.SendIntentException; -import android.media.MediaActionSound; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; @@ -83,11 +82,6 @@ public class ConversationActivity extends XmppActivity private boolean mActivityPaused = false; - - public List getConversationList() { - return this.conversationList; - } - public Conversation getSelectedConversation() { return this.mSelectedConversation; } @@ -284,8 +278,7 @@ public class ConversationActivity extends XmppActivity final MenuItem menuBlock = menu.findItem(R.id.action_block); final MenuItem menuUnblock = menu.findItem(R.id.action_unblock); - if (isConversationsOverviewVisable() - && isConversationsOverviewHideable()) { + if (isConversationsOverviewVisable() && isConversationsOverviewHideable()) { menuArchive.setVisible(false); menuMucDetails.setVisible(false); menuContactDetails.setVisible(false); @@ -309,9 +302,9 @@ public class ConversationActivity extends XmppActivity menuAttach.setVisible(false); menuBlock.setVisible(false); menuUnblock.setVisible(false); + menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite()); } else { menuMucDetails.setVisible(false); - menuInviteContact.setTitle(R.string.conference_with); if (this.getSelectedConversation().isBlocked()) { menuBlock.setVisible(false); } else { -- cgit v1.2.3 From 061de5205e198eac51cf54af5fd9b2e4faebe4d2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 8 Jan 2015 00:23:26 +0100 Subject: some clean ups for affiliation change context menu --- .../eu/siacs/conversations/ui/ConferenceDetailsActivity.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 5272c922..2185c3af 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -245,6 +245,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers MenuItem giveAdminPrivileges = menu.findItem(R.id.give_admin_privileges); MenuItem removeAdminPrivileges = menu.findItem(R.id.remove_admin_privileges); MenuItem removeFromRoom = menu.findItem(R.id.remove_from_room); + MenuItem banFromConference = menu.findItem(R.id.ban_from_conference); startConversation.setVisible(true); if (self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) && self.getAffiliation().outranks(user.getAffiliation())) { @@ -254,13 +255,15 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } else { removeMembership.setVisible(true); } + banFromConference.setVisible(true); + } else { + removeFromRoom.setVisible(true); } if (user.getAffiliation() != MucOptions.Affiliation.ADMIN) { giveAdminPrivileges.setVisible(true); } else { removeAdminPrivileges.setVisible(true); } - removeFromRoom.setVisible(true); } } @@ -289,6 +292,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers case R.id.remove_from_room: removeFromRoom(mSelectedUser); return true; + case R.id.ban_from_conference: + xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this); + return true; default: return super.onContextItemSelected(item); } @@ -299,7 +305,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.NONE,this); } else { AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.ban_user_from_conference); + builder.setTitle(R.string.ban_from_conference); builder.setMessage(getString(R.string.removing_from_public_conference,user.getName())); builder.setNegativeButton(R.string.cancel,null); builder.setPositiveButton(R.string.ban_now,new DialogInterface.OnClickListener() { -- cgit v1.2.3 From f8aa1bfec4df8cc7e34eae537f68ab45ed62756c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 8 Jan 2015 01:23:53 +0100 Subject: kick after ban --- .../siacs/conversations/generator/IqGenerator.java | 10 ++++++++++ .../services/XmppConnectionService.java | 21 +++++++++++++++++++++ .../conversations/ui/ConferenceDetailsActivity.java | 15 ++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 988b9744..6dcccaab 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -159,4 +159,14 @@ public class IqGenerator extends AbstractGenerator { item.setAttribute("affiliation", affiliation); return packet; } + + public IqPacket changeRole(Conversation conference, String nick, String role) { + IqPacket packet = new IqPacket(IqPacket.TYPE.SET); + packet.setTo(conference.getJid().toBareJid()); + packet.setFrom(conference.getAccount().getJid()); + Element item = packet.query("http://jabber.org/protocol/muc#admin").addChild("item"); + item.setAttribute("nick", nick); + item.setAttribute("role", role); + return packet; + } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 5c16ef3f..495b9c26 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1562,6 +1562,27 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onAffiliationChangeFailed(Jid jid, int resId); } + public void changeRoleInConference(final Conversation conference, final String nick, MucOptions.Role role, final OnRoleChanged callback) { + IqPacket request = this.mIqGenerator.changeRole(conference, nick, role.toString()); + Log.d(Config.LOGTAG,request.toString()); + sendIqPacket(conference.getAccount(), request, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + Log.d(Config.LOGTAG, packet.toString()); + if (packet.getType() == IqPacket.TYPE.RESULT) { + callback.onRoleChangedSuccessful(nick); + } else { + callback.onRoleChangeFailed(nick, R.string.could_not_change_role); + } + } + }); + } + + public interface OnRoleChanged{ + public void onRoleChangedSuccessful(String nick); + public void onRoleChangeFailed(String nick, int resid); + } + public void disconnect(Account account, boolean force) { if ((account.getStatus() == Account.State.ONLINE) || (account.getStatus() == Account.State.DISABLED)) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 2185c3af..daaa59cf 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -41,7 +41,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; -public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged { +public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged { public static final String ACTION_VIEW_MUC = "view_muc"; private Conversation mConversation; private OnClickListener inviteListener = new OnClickListener() { @@ -294,6 +294,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers return true; case R.id.ban_from_conference: xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this); + xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,this); return true; default: return super.onContextItemSelected(item); @@ -303,6 +304,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers private void removeFromRoom(final User user) { if (mConversation.getMucOptions().membersOnly()) { xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.NONE,this); + xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this); } else { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.ban_from_conference); @@ -312,6 +314,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override public void onClick(DialogInterface dialog, int which) { xmppConnectionService.changeAffiliationInConference(mConversation,user.getJid(), MucOptions.Affiliation.OUTCAST,ConferenceDetailsActivity.this); + xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,ConferenceDetailsActivity.this); } }); builder.create().show(); @@ -480,4 +483,14 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers public void onAffiliationChangeFailed(Jid jid, int resId) { } + + @Override + public void onRoleChangedSuccessful(String nick) { + + } + + @Override + public void onRoleChangeFailed(String nick, int resid) { + + } } -- cgit v1.2.3 From 0fe193b027b2879d68fe7bb9b27c0a8cd35aa205 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 8 Jan 2015 14:45:44 +0100 Subject: code cleanup --- .../services/XmppConnectionService.java | 27 ++++++++++++---------- .../ui/ConferenceDetailsActivity.java | 2 -- 2 files changed, 15 insertions(+), 14 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 495b9c26..ad951f3e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -388,17 +388,20 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public int onStartCommand(Intent intent, int flags, int startId) { final String action = intent == null ? null : intent.getAction(); if (action != null) { - if (action.equals(ACTION_MERGE_PHONE_CONTACTS)) { - PhoneHelper.loadPhoneContacts(getApplicationContext(), new CopyOnWriteArrayList(), this); - return START_STICKY; - } else if (action.equals(Intent.ACTION_SHUTDOWN)) { - logoutAndSave(); - return START_NOT_STICKY; - } else if (action.equals(ACTION_CLEAR_NOTIFICATION)) { - mNotificationService.clear(); - } else if (action.equals(ACTION_DISABLE_FOREGROUND)) { - getPreferences().edit().putBoolean("keep_foreground_service",false).commit(); - toggleForegroundService(); + switch (action) { + case ACTION_MERGE_PHONE_CONTACTS: + PhoneHelper.loadPhoneContacts(getApplicationContext(), new CopyOnWriteArrayList(), this); + return START_STICKY; + case Intent.ACTION_SHUTDOWN: + logoutAndSave(); + return START_NOT_STICKY; + case ACTION_CLEAR_NOTIFICATION: + mNotificationService.clear(); + break; + case ACTION_DISABLE_FOREGROUND: + getPreferences().edit().putBoolean("keep_foreground_service",false).commit(); + toggleForegroundService(); + break; } } this.wakeLock.acquire(); @@ -1484,7 +1487,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() != IqPacket.TYPE.ERROR) { - ArrayList features = new ArrayList(); + ArrayList features = new ArrayList<>(); for (Element child : packet.query().getChildren()) { if (child != null && child.getName().equals("feature")) { String var = child.getAttribute("var"); diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index daaa59cf..a6df1085 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -233,8 +233,6 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers final Contact contact = user.getContact(); if (contact != null) { name = contact.getDisplayName(); - } else if (user.getJid() != null) { - name = user.getJid().toBareJid().toString(); } else { name = user.getName(); } -- cgit v1.2.3 From a9159568b9aca24563a3b8c732b257d246e33a1a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 8 Jan 2015 21:29:26 +0100 Subject: allow for very basic muc configuration --- .../siacs/conversations/entities/MucOptions.java | 6 +- .../services/XmppConnectionService.java | 3 +- .../ui/ConferenceDetailsActivity.java | 80 ++++++++++++++++++++-- 3 files changed, 79 insertions(+), 10 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 96860a16..d4b997fc 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -13,7 +13,6 @@ import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; import android.annotation.SuppressLint; -import android.util.Log; @SuppressLint("DefaultLocale") public class MucOptions { @@ -224,6 +223,10 @@ public class MucOptions { return hasFeature("muc_membersonly"); } + public boolean nonanonymous() { + return hasFeature("muc_nonanonymous"); + } + public void deleteUser(String name) { for (int i = 0; i < users.size(); ++i) { if (users.get(i).getName().equals(name)) { @@ -244,7 +247,6 @@ public class MucOptions { } public void processPacket(PresencePacket packet, PgpEngine pgp) { - Log.d(Config.LOGTAG, packet.toString()); final Jid from = packet.getFrom(); if (!from.isBareJid()) { final String name = from.getResourcepart(); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ad951f3e..e13a3e65 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1497,6 +1497,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } conversation.getMucOptions().updateFeatures(features); + updateConversationUi(); } } }); @@ -2229,7 +2230,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onMucRosterUpdate(); } - private interface OnConferenceOptionsPushed { + public interface OnConferenceOptionsPushed { public void onPushSucceeded(); public void onPushFailed(); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index a6df1085..ce367240 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -41,7 +41,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; -public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged { +public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConferenceOptionsPushed { public static final String ACTION_VIEW_MUC = "view_muc"; private Conversation mConversation; private OnClickListener inviteListener = new OnClickListener() { @@ -59,6 +59,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers private TextView mAccountJid; private LinearLayout membersView; private LinearLayout mMoreDetails; + private TextView mConferenceType; + private ImageButton mChangeConferenceSettingsButton; private Button mInviteButton; private String uuid = null; private List users = new ArrayList<>(); @@ -94,6 +96,36 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } }; + private OnClickListener mChangeConferenceSettings = new OnClickListener() { + @Override + public void onClick(View v) { + final MucOptions mucOptions = mConversation.getMucOptions(); + AlertDialog.Builder builder = new AlertDialog.Builder(ConferenceDetailsActivity.this); + builder.setTitle(R.string.conference_options); + String[] options = {getString(R.string.members_only), + getString(R.string.non_anonymous)}; + final boolean[] values = new boolean[options.length]; + values[0] = mucOptions.membersOnly(); + values[1] = mucOptions.nonanonymous(); + builder.setMultiChoiceItems(options,values,new DialogInterface.OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int which, boolean isChecked) { + values[which] = isChecked; + } + }); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.confirm,new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Bundle options = new Bundle(); + options.putString("muc#roomconfig_membersonly", values[0] ? "1" : "0"); + options.putString("muc#roomconfig_whois", values[1] ? "anyone" : "moderators"); + xmppConnectionService.pushConferenceConfiguration(mConversation,options,ConferenceDetailsActivity.this); + } + }); + builder.create().show(); + } + }; @Override public void onConversationUpdate() { @@ -129,8 +161,12 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers mAccountJid = (TextView) findViewById(R.id.details_account); mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details); mMoreDetails.setVisibility(View.GONE); + mChangeConferenceSettingsButton = (ImageButton) findViewById(R.id.change_conference_button); + mChangeConferenceSettingsButton.setOnClickListener(this.mChangeConferenceSettings); + mConferenceType = (TextView) findViewById(R.id.muc_conference_type); mInviteButton = (Button) findViewById(R.id.invite); mInviteButton.setOnClickListener(inviteListener); + mConferenceType = (TextView) findViewById(R.id.muc_conference_type); if (getActionBar() != null) { getActionBar().setHomeButtonEnabled(true); getActionBar().setDisplayHomeAsUpEnabled(true); @@ -361,16 +397,17 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } private void updateView() { + final MucOptions mucOptions = mConversation.getMucOptions(); + final User self = mucOptions.getSelf(); mAccountJid.setText(getString(R.string.using_account, mConversation .getAccount().getJid().toBareJid())); mYourPhoto.setImageBitmap(avatarService().get(mConversation.getAccount(), getPixel(48))); setTitle(mConversation.getName()); mFullJid.setText(mConversation.getJid().toBareJid().toString()); - mYourNick.setText(mConversation.getMucOptions().getActualNick()); + mYourNick.setText(mucOptions.getActualNick()); mRoleAffiliaton = (TextView) findViewById(R.id.muc_role); - if (mConversation.getMucOptions().online()) { + if (mucOptions.online()) { mMoreDetails.setVisibility(View.VISIBLE); - User self = mConversation.getMucOptions().getSelf(); final String status = getStatus(self); if (status != null) { mRoleAffiliaton.setVisibility(View.VISIBLE); @@ -378,9 +415,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } else { mRoleAffiliaton.setVisibility(View.GONE); } + if (mucOptions.membersOnly()) { + mConferenceType.setText(R.string.private_conference); + } else { + mConferenceType.setText(R.string.public_conference); + } + if (self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) { + mChangeConferenceSettingsButton.setVisibility(View.VISIBLE); + } else { + mChangeConferenceSettingsButton.setVisibility(View.GONE); + } } this.users.clear(); - this.users.addAll(mConversation.getMucOptions().getUsers()); + this.users.addAll(mucOptions.getUsers()); LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); membersView.removeAllViews(); for (final User user : mConversation.getMucOptions().getUsers()) { @@ -479,7 +526,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers @Override public void onAffiliationChangeFailed(Jid jid, int resId) { - + displayToast(getString(resId,jid.toBareJid().toString())); } @Override @@ -488,7 +535,26 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers } @Override - public void onRoleChangeFailed(String nick, int resid) { + public void onRoleChangeFailed(String nick, int resId) { + displayToast(getString(resId,nick)); + } + + @Override + public void onPushSucceeded() { + displayToast(getString(R.string.modified_conference_options)); + } + + @Override + public void onPushFailed() { + displayToast(getString(R.string.could_not_modify_conference_options)); + } + private void displayToast(final String msg) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(ConferenceDetailsActivity.this,msg,Toast.LENGTH_SHORT).show(); + } + }); } } -- cgit v1.2.3 From d9f88c4669b024530301fe9e48d70d42bd56190f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 9 Jan 2015 13:28:01 +0100 Subject: ensure that everyone is member before making a room private --- .../eu/siacs/conversations/generator/IqGenerator.java | 16 +++++++++++++--- .../conversations/services/XmppConnectionService.java | 13 +++++++++++-- .../conversations/ui/ConferenceDetailsActivity.java | 9 ++++++++- 3 files changed, 32 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 6dcccaab..d0965821 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.generator; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -151,12 +152,21 @@ public class IqGenerator extends AbstractGenerator { } public IqPacket changeAffiliation(Conversation conference, Jid jid, String affiliation) { + List jids = new ArrayList<>(); + jids.add(jid); + return changeAffiliation(conference,jids,affiliation); + } + + public IqPacket changeAffiliation(Conversation conference, List jids, String affiliation) { IqPacket packet = new IqPacket(IqPacket.TYPE.SET); packet.setTo(conference.getJid().toBareJid()); packet.setFrom(conference.getAccount().getJid()); - Element item = packet.query("http://jabber.org/protocol/muc#admin").addChild("item"); - item.setAttribute("jid", jid.toString()); - item.setAttribute("affiliation", affiliation); + Element query = packet.query("http://jabber.org/protocol/muc#admin"); + for(Jid jid : jids) { + Element item = query.addChild("item"); + item.setAttribute("jid", jid.toString()); + item.setAttribute("affiliation", affiliation); + } return packet; } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e13a3e65..28a353b6 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1547,11 +1547,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void changeAffiliationInConference(final Conversation conference, Jid user, MucOptions.Affiliation affiliation, final OnAffiliationChanged callback) { final Jid jid = user.toBareJid(); IqPacket request = this.mIqGenerator.changeAffiliation(conference, jid, affiliation.toString()); - Log.d(Config.LOGTAG,request.toString()); sendIqPacket(conference.getAccount(), request, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - Log.d(Config.LOGTAG, packet.toString()); if (packet.getType() == IqPacket.TYPE.RESULT) { callback.onAffiliationChangedSuccessful(jid); } else { @@ -1561,6 +1559,17 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } + public void changeAffiliationsInConference(final Conversation conference, MucOptions.Affiliation before, MucOptions.Affiliation after) { + List jids = new ArrayList<>(); + for(MucOptions.User user : conference.getMucOptions().getUsers()) { + if (user.getAffiliation() == before) { + jids.add(user.getJid()); + } + } + IqPacket request = this.mIqGenerator.changeAffiliation(conference, jids, after.toString()); + sendIqPacket(conference.getAccount(), request, null); + } + public interface OnAffiliationChanged { public void onAffiliationChangedSuccessful(Jid jid); public void onAffiliationChangeFailed(Jid jid, int resId); diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index ce367240..9e38790a 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -117,10 +117,17 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers builder.setPositiveButton(R.string.confirm,new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + if (!mucOptions.membersOnly() && values[0]) { + xmppConnectionService.changeAffiliationsInConference(mConversation, + MucOptions.Affiliation.NONE, + MucOptions.Affiliation.MEMBER); + } Bundle options = new Bundle(); options.putString("muc#roomconfig_membersonly", values[0] ? "1" : "0"); options.putString("muc#roomconfig_whois", values[1] ? "anyone" : "moderators"); - xmppConnectionService.pushConferenceConfiguration(mConversation,options,ConferenceDetailsActivity.this); + xmppConnectionService.pushConferenceConfiguration(mConversation, + options, + ConferenceDetailsActivity.this); } }); builder.create().show(); -- cgit v1.2.3 From 0a48f777acefa29443743f68f242136309169ba2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 9 Jan 2015 14:42:58 +0100 Subject: code cleanup for jingle proxy discovery --- .../java/eu/siacs/conversations/utils/Xmlns.java | 1 + .../conversations/xmpp/jingle/JingleCandidate.java | 3 +- .../xmpp/jingle/JingleConnection.java | 91 ++++++++++------------ .../xmpp/jingle/JingleConnectionManager.java | 76 ++++++++---------- 4 files changed, 72 insertions(+), 99 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java index 67de7c79..17fd2d26 100644 --- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java +++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java @@ -4,4 +4,5 @@ public final class Xmlns { public static final String BLOCKING = "urn:xmpp:blocking"; public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; + public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java index 281ea3ca..dcadb92f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java @@ -85,8 +85,7 @@ public class JingleCandidate { } public boolean equalValues(JingleCandidate other) { - return other.getHost().equals(this.getHost()) - && (other.getPort() == this.getPort()); + return other != null && other.getHost().equals(this.getHost()) && (other.getPort() == this.getPort()); } public boolean isOurs() { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index fe37596c..cea4346c 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -396,58 +396,48 @@ public class JingleConnection implements Downloadable { mJingleStatus = JINGLE_STATUS_ACCEPTED; this.mStatus = Downloadable.STATUS_DOWNLOADING; mXmppConnectionService.updateConversationUi(); - this.mJingleConnectionManager.getPrimaryCandidate(this.account, - new OnPrimaryCandidateFound() { - - @Override - public void onPrimaryCandidateFound(boolean success, - final JingleCandidate candidate) { - final JinglePacket packet = bootstrapPacket("session-accept"); - final Content content = new Content(contentCreator, - contentName); - content.setFileOffer(fileOffer); - content.setTransportId(transportId); - if ((success) && (!equalCandidateExists(candidate))) { - final JingleSocks5Transport socksConnection = new JingleSocks5Transport( - JingleConnection.this, candidate); - connections.put(candidate.getCid(), socksConnection); - socksConnection.connect(new OnTransportConnected() { - - @Override - public void failed() { - Log.d(Config.LOGTAG, - "connection to our own primary candidate failed"); - content.socks5transport().setChildren( - getCandidatesAsElements()); - packet.setContent(content); - sendJinglePacket(packet); - connectNextCandidate(); - } + this.mJingleConnectionManager.getPrimaryCandidate(this.account, new OnPrimaryCandidateFound() { + @Override + public void onPrimaryCandidateFound(boolean success, final JingleCandidate candidate) { + final JinglePacket packet = bootstrapPacket("session-accept"); + final Content content = new Content(contentCreator,contentName); + content.setFileOffer(fileOffer); + content.setTransportId(transportId); + if (success && candidate != null && !equalCandidateExists(candidate)) { + final JingleSocks5Transport socksConnection = new JingleSocks5Transport( + JingleConnection.this, + candidate); + connections.put(candidate.getCid(), socksConnection); + socksConnection.connect(new OnTransportConnected() { - @Override - public void established() { - Log.d(Config.LOGTAG, - "connected to primary candidate"); - mergeCandidate(candidate); - content.socks5transport().setChildren( - getCandidatesAsElements()); - packet.setContent(content); - sendJinglePacket(packet); - connectNextCandidate(); - } - }); - } else { - Log.d(Config.LOGTAG, - "did not find a primary candidate for ourself"); - content.socks5transport().setChildren( - getCandidatesAsElements()); + @Override + public void failed() { + Log.d(Config.LOGTAG,"connection to our own primary candidate failed"); + content.socks5transport().setChildren(getCandidatesAsElements()); packet.setContent(content); sendJinglePacket(packet); connectNextCandidate(); } - } - }); + @Override + public void established() { + Log.d(Config.LOGTAG, "connected to primary candidate"); + mergeCandidate(candidate); + content.socks5transport().setChildren(getCandidatesAsElements()); + packet.setContent(content); + sendJinglePacket(packet); + connectNextCandidate(); + } + }); + } else { + Log.d(Config.LOGTAG,"did not find a primary candidate for ourself"); + content.socks5transport().setChildren(getCandidatesAsElements()); + packet.setContent(content); + sendJinglePacket(packet); + connectNextCandidate(); + } + } + }); } private JinglePacket bootstrapPacket(String action) { @@ -479,16 +469,13 @@ public class JingleConnection implements Downloadable { Content content = packet.getJingleContent(); if (content.hasSocks5Transport()) { if (content.socks5transport().hasChild("activated")) { - if ((this.transport != null) - && (this.transport instanceof JingleSocks5Transport)) { + if ((this.transport != null) && (this.transport instanceof JingleSocks5Transport)) { onProxyActivated.success(); } else { - String cid = content.socks5transport() - .findChild("activated").getAttribute("cid"); + String cid = content.socks5transport().findChild("activated").getAttribute("cid"); Log.d(Config.LOGTAG, "received proxy activated (" + cid + ")prior to choosing our own transport"); - JingleSocks5Transport connection = this.connections - .get(cid); + JingleSocks5Transport connection = this.connections.get(cid); if (connection != null) { connection.setActivated(true); } else { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 57c74ad9..5dfa3ff4 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -12,6 +12,7 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.AbstractConnectionManager; 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; @@ -80,49 +81,37 @@ public class JingleConnectionManager extends AbstractConnectionManager { return; } if (!this.primaryCandidates.containsKey(account.getJid().toBareJid())) { - String xmlns = "http://jabber.org/protocol/bytestreams"; - final String proxy = account.getXmppConnection() - .findDiscoItemByFeature(xmlns); + final String proxy = account.getXmppConnection().findDiscoItemByFeature(Xmlns.BYTE_STREAMS); if (proxy != null) { IqPacket iq = new IqPacket(IqPacket.TYPE.GET); iq.setAttribute("to", proxy); - iq.query(xmlns); - account.getXmppConnection().sendIqPacket(iq, - new OnIqPacketReceived() { + iq.query(Xmlns.BYTE_STREAMS); + account.getXmppConnection().sendIqPacket(iq,new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, - IqPacket packet) { - Element streamhost = packet - .query() - .findChild("streamhost", - "http://jabber.org/protocol/bytestreams"); - if (streamhost != null) { - JingleCandidate candidate = new JingleCandidate( - nextRandomId(), true); - candidate.setHost(streamhost - .getAttribute("host")); - candidate.setPort(Integer - .parseInt(streamhost - .getAttribute("port"))); - candidate - .setType(JingleCandidate.TYPE_PROXY); - try { - candidate.setJid(Jid.fromString(proxy)); - } catch (final InvalidJidException e) { - candidate.setJid(null); - } - candidate.setPriority(655360 + 65535); - primaryCandidates.put(account.getJid().toBareJid(), - candidate); - listener.onPrimaryCandidateFound(true, - candidate); - } else { - listener.onPrimaryCandidateFound(false, - null); - } + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + Element streamhost = packet.query().findChild("streamhost",Xmlns.BYTE_STREAMS); + final String host = streamhost == null ? null : streamhost.getAttribute("host"); + final String port = streamhost == null ? null : streamhost.getAttribute("port"); + if (host != null && port != null) { + try { + JingleCandidate candidate = new JingleCandidate(nextRandomId(), true); + candidate.setHost(host); + candidate.setPort(Integer.parseInt(port)); + candidate.setType(JingleCandidate.TYPE_PROXY); + candidate.setJid(Jid.fromString(proxy)); + candidate.setPriority(655360 + 65535); + primaryCandidates.put(account.getJid().toBareJid(),candidate); + listener.onPrimaryCandidateFound(true,candidate); + } catch (final NumberFormatException | InvalidJidException e) { + listener.onPrimaryCandidateFound(false,null); + return; } - }); + } else { + listener.onPrimaryCandidateFound(false,null); + } + } + }); } else { listener.onPrimaryCandidateFound(false, null); } @@ -141,12 +130,10 @@ public class JingleConnectionManager extends AbstractConnectionManager { String sid = null; Element payload = null; if (packet.hasChild("open", "http://jabber.org/protocol/ibb")) { - payload = packet - .findChild("open", "http://jabber.org/protocol/ibb"); + payload = packet.findChild("open", "http://jabber.org/protocol/ibb"); sid = payload.getAttribute("sid"); } else if (packet.hasChild("data", "http://jabber.org/protocol/ibb")) { - payload = packet - .findChild("data", "http://jabber.org/protocol/ibb"); + payload = packet.findChild("data", "http://jabber.org/protocol/ibb"); sid = payload.getAttribute("sid"); } if (sid != null) { @@ -161,10 +148,9 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } } - Log.d(Config.LOGTAG, - "couldnt deliver payload: " + payload.toString()); + Log.d(Config.LOGTAG,"couldn't deliver payload: " + payload.toString()); } else { - Log.d(Config.LOGTAG, "no sid found in incomming ibb packet"); + Log.d(Config.LOGTAG, "no sid found in incoming ibb packet"); } } -- cgit v1.2.3 From 06eae476ee7e19029fe1ac28eae75fdcc1d4d1e6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 9 Jan 2015 19:23:26 +0100 Subject: Introduced expert options to control enter-is-send (default == off) --- .../java/eu/siacs/conversations/ui/ConversationActivity.java | 4 ++++ .../java/eu/siacs/conversations/ui/ConversationFragment.java | 9 +++++++-- src/main/java/eu/siacs/conversations/ui/EditMessage.java | 9 ++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index ba5b3e59..a461656e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -1058,4 +1058,8 @@ public class ConversationActivity extends XmppActivity public void blockConversation(final Blockable conversation) { xmppConnectionService.sendBlockRequest(conversation); } + + public boolean enterIsSend() { + return getPreferences().getBoolean("enter_is_send",false); + } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 93a4cc7e..5eb81e64 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -316,8 +316,13 @@ public class ConversationFragment extends Fragment { mEditMessage.setOnEnterPressedListener(new OnEnterPressed() { @Override - public void onEnterPressed() { - sendMessage(); + public boolean onEnterPressed() { + if (activity.enterIsSend()) { + sendMessage(); + return true; + } else { + return false; + } } }); diff --git a/src/main/java/eu/siacs/conversations/ui/EditMessage.java b/src/main/java/eu/siacs/conversations/ui/EditMessage.java index f8302050..5090bbf5 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditMessage.java +++ b/src/main/java/eu/siacs/conversations/ui/EditMessage.java @@ -21,9 +21,12 @@ public class EditMessage extends EditText { public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_ENTER) { if (mOnEnterPressed != null) { - mOnEnterPressed.onEnterPressed(); + if (mOnEnterPressed.onEnterPressed()) { + return true; + } else { + return super.onKeyDown(keyCode, event); + } } - return true; } return super.onKeyDown(keyCode, event); } @@ -33,7 +36,7 @@ public class EditMessage extends EditText { } public interface OnEnterPressed { - public void onEnterPressed(); + public boolean onEnterPressed(); } } -- cgit v1.2.3 From c89fdec0b158f7525ab6f95482088a5fb06278ea Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 9 Jan 2015 22:24:50 +0100 Subject: fixed regression in tablet ui --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index a461656e..c9792260 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -170,6 +170,7 @@ public class ConversationActivity extends XmppActivity ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation()); } hideConversationsOverview(); + openConversation(); } }); mContentView = findViewById(R.id.content_view_spl); @@ -254,6 +255,7 @@ public class ConversationActivity extends XmppActivity xmppConnectionService.getNotificationService().setOpenConversation(conversation); sendReadMarkerIfNecessary(conversation); } + listAdapter.notifyDataSetChanged(); } public void sendReadMarkerIfNecessary(final Conversation conversation) { -- cgit v1.2.3 From 158f5dd17cf4d34c5d696983fc21ae88c869ec94 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 10 Jan 2015 19:43:23 +0100 Subject: don't crash when selecting a conversation by uuid did not work --- .../conversations/ui/ConversationActivity.java | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index c9792260..926edef0 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -784,11 +784,9 @@ public class ConversationActivity extends XmppActivity } else if (conversationList.size() <= 0) { startActivity(new Intent(this, StartConversationActivity.class)); finish(); - } else if (getIntent() != null - && VIEW_CONVERSATION.equals(getIntent().getType())) { + } else if (getIntent() != null && VIEW_CONVERSATION.equals(getIntent().getType())) { handleViewConversationIntent(getIntent()); - } else if (mOpenConverstaion != null) { - selectConversationByUuid(mOpenConverstaion); + } else if (selectConversationByUuid(mOpenConverstaion)) { if (mPanelOpen) { showConversationsOverview(); } else { @@ -823,26 +821,32 @@ public class ConversationActivity extends XmppActivity String uuid = (String) intent.getExtras().get(CONVERSATION); String text = intent.getExtras().getString(TEXT, ""); String nick = intent.getExtras().getString(NICK,null); - selectConversationByUuid(uuid); - this.mConversationFragment.reInit(getSelectedConversation()); - if (nick!=null) { - this.mConversationFragment.highlightInConference(nick); - } else { - this.mConversationFragment.appendText(text); - } - hideConversationsOverview(); - openConversation(); - if (mContentView instanceof SlidingPaneLayout) { - updateActionBarTitle(true); //fixes bug where slp isn't properly closed yet + if (selectConversationByUuid(uuid)) { + this.mConversationFragment.reInit(getSelectedConversation()); + if (nick != null) { + this.mConversationFragment.highlightInConference(nick); + } else { + this.mConversationFragment.appendText(text); + } + hideConversationsOverview(); + openConversation(); + if (mContentView instanceof SlidingPaneLayout) { + updateActionBarTitle(true); //fixes bug where slp isn't properly closed yet + } } } - private void selectConversationByUuid(String uuid) { + private boolean selectConversationByUuid(String uuid) { + if (uuid == null) { + return false; + } for (Conversation aConversationList : conversationList) { if (aConversationList.getUuid().equals(uuid)) { setSelectedConversation(aConversationList); + return true; } } + return false; } @Override -- cgit v1.2.3 From 18eb18794988ab94979020060e9bee9fe7fd9b67 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 10 Jan 2015 23:10:32 +0100 Subject: make room persistant when changing subject or other muc options --- .../siacs/conversations/entities/MucOptions.java | 4 ++++ .../services/XmppConnectionService.java | 12 ++++++++++ .../ui/ConferenceDetailsActivity.java | 26 +++++++++------------- 3 files changed, 26 insertions(+), 16 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index d4b997fc..0eb41c55 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -227,6 +227,10 @@ public class MucOptions { return hasFeature("muc_nonanonymous"); } + public boolean persistent() { + return hasFeature("muc_persistent"); + } + public void deleteUser(String name) { for (int i = 0; i < users.size(); ++i) { if (users.get(i).getName().equals(name)) { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 28a353b6..521991ba 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1544,6 +1544,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } + public void pushSubjectToConference(final Conversation conference, final String subject) { + MessagePacket packet = this.getMessageGenerator().conferenceSubject(conference, subject); + this.sendMessagePacket(conference.getAccount(), packet); + final MucOptions mucOptions = conference.getMucOptions(); + final MucOptions.User self = mucOptions.getSelf(); + if (!mucOptions.persistent() && self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) { + Bundle options = new Bundle(); + options.putString("muc#roomconfig_persistentroom", "1"); + this.pushConferenceConfiguration(conference,options,null); + } + } + public void changeAffiliationInConference(final Conversation conference, Jid user, MucOptions.Affiliation affiliation, final OnAffiliationChanged callback) { final Jid jid = user.toBareJid(); IqPacket request = this.mIqGenerator.changeAffiliation(conference, jid, affiliation.toString()); diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 9e38790a..399d9fdf 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -39,7 +39,6 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.OnMucRosterUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; import eu.siacs.conversations.xmpp.jid.Jid; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConferenceOptionsPushed { public static final String ACTION_VIEW_MUC = "view_muc"; @@ -63,7 +62,6 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers private ImageButton mChangeConferenceSettingsButton; private Button mInviteButton; private String uuid = null; - private List users = new ArrayList<>(); private User mSelectedUser = null; private boolean mAdvancedMode = false; @@ -125,6 +123,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers Bundle options = new Bundle(); options.putString("muc#roomconfig_membersonly", values[0] ? "1" : "0"); options.putString("muc#roomconfig_whois", values[1] ? "anyone" : "moderators"); + options.putString("muc#roomconfig_persistentroom", "1"); xmppConnectionService.pushConferenceConfiguration(mConversation, options, ConferenceDetailsActivity.this); @@ -133,6 +132,13 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers builder.create().show(); } }; + private OnValueEdited onSubjectEdited = new OnValueEdited() { + + @Override + public void onValueEdited(String value) { + xmppConnectionService.pushSubjectToConference(mConversation,value); + } + }; @Override public void onConversationUpdate() { @@ -202,17 +208,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers break; case R.id.action_edit_subject: if (mConversation != null) { - quickEdit(mConversation.getName(), new OnValueEdited() { - - @Override - public void onValueEdited(String value) { - MessagePacket packet = xmppConnectionService - .getMessageGenerator().conferenceSubject( - mConversation, value); - xmppConnectionService.sendMessagePacket( - mConversation.getAccount(), packet); - } - }); + quickEdit(mConversation.getName(),this.onSubjectEdited); } break; case R.id.action_save_as_bookmark: @@ -277,7 +273,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers if (contact != null) { name = contact.getDisplayName(); } else { - name = user.getName(); + name = user.getJid().toBareJid().toString(); } menu.setHeaderTitle(name); MenuItem startConversation = menu.findItem(R.id.start_conversation); @@ -433,8 +429,6 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers mChangeConferenceSettingsButton.setVisibility(View.GONE); } } - this.users.clear(); - this.users.addAll(mucOptions.getUsers()); LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); membersView.removeAllViews(); for (final User user : mConversation.getMucOptions().getUsers()) { -- cgit v1.2.3 From b07b7519a6bf382be809b8d33b801080a1616c8f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 11 Jan 2015 15:19:36 +0100 Subject: keep proper image file extension --- .../siacs/conversations/entities/MucOptions.java | 1 - .../siacs/conversations/http/HttpConnection.java | 17 +++++++++--- .../conversations/persistance/FileBackend.java | 31 +++++++++++++--------- .../xmpp/jingle/JingleConnection.java | 16 +++++------ 4 files changed, 39 insertions(+), 26 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 0eb41c55..27821c65 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.xml.Element; diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index b715c3f3..8951de74 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -14,6 +14,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.util.Arrays; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -65,14 +66,22 @@ public class HttpConnection implements Downloadable { this.message.setDownloadable(this); try { mUrl = new URL(message.getBody()); - String path = mUrl.getPath().toLowerCase(); - if (path != null && (path.endsWith(".pgp") || path.endsWith(".gpg"))) { + String[] parts = mUrl.getPath().toLowerCase().split("\\."); + String lastPart = parts.length >= 1 ? parts[parts.length - 1] : null; + String secondToLast = parts.length >= 2 ? parts[parts.length -2] : null; + if ("pgp".equals(lastPart) || "gpg".equals(lastPart)) { this.message.setEncryption(Message.ENCRYPTION_PGP); } else if (message.getEncryption() != Message.ENCRYPTION_OTR) { this.message.setEncryption(Message.ENCRYPTION_NONE); } - this.file = mXmppConnectionService.getFileBackend().getFile( - message, false); + String extension; + if (Arrays.asList(VALID_CRYPTO_EXTENSIONS).contains(lastPart)) { + extension = secondToLast; + } else { + extension = lastPart; + } + message.setRelativeFilePath(message.getUuid()+"."+extension); + this.file = mXmppConnectionService.getFileBackend().getFile(message, false); String reference = mUrl.getRef(); if (reference != null && reference.length() == 96) { this.file.setKey(CryptoHelper.hexToBytes(reference)); diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index f7defcdf..62987aaa 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -57,28 +57,33 @@ public class FileBackend { public DownloadableFile getFile(Message message, boolean decrypted) { String path = message.getRelativeFilePath(); - if (!decrypted && (message.getEncryption() == Message.ENCRYPTION_PGP || message.getEncryption() == Message.ENCRYPTION_DECRYPTED)) { - String extension; - if (path != null && !path.isEmpty()) { - String[] parts = path.split("\\."); - extension = "."+parts[parts.length - 1]; - } else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_TEXT) { + String extension; + if (path != null && !path.isEmpty()) { + String[] parts = path.split("\\."); + extension = "."+parts[parts.length - 1]; + } else { + if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_TEXT) { extension = ".webp"; } else { extension = ""; } + path = message.getUuid()+extension; + } + final boolean encrypted = !decrypted + && (message.getEncryption() == Message.ENCRYPTION_PGP + || message.getEncryption() == Message.ENCRYPTION_DECRYPTED); + if (encrypted) { return new DownloadableFile(getConversationsFileDirectory()+message.getUuid()+extension+".pgp"); - } else if (path != null && !path.isEmpty()) { + } else { if (path.startsWith("/")) { return new DownloadableFile(path); } else { - return new DownloadableFile(getConversationsFileDirectory()+path); + if (message.getType() == Message.TYPE_FILE) { + return new DownloadableFile(getConversationsFileDirectory() + path); + } else { + return new DownloadableFile(getConversationsImageDirectory()+path); + } } - } else { - StringBuilder filename = new StringBuilder(); - filename.append(getConversationsImageDirectory()); - filename.append(message.getUuid()+".webp"); - return new DownloadableFile(filename.toString()); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index cea4346c..843cf1e6 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -101,11 +101,9 @@ public class JingleConnection implements Downloadable { file.delete(); } } - Log.d(Config.LOGTAG, - "sucessfully transmitted file:" + file.getAbsolutePath()); + Log.d(Config.LOGTAG,"sucessfully transmitted file:" + file.getAbsolutePath()); if (message.getEncryption() != Message.ENCRYPTION_PGP) { - Intent intent = new Intent( - Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(Uri.fromFile(file)); mXmppConnectionService.sendBroadcast(intent); } @@ -281,15 +279,17 @@ public class JingleConnection implements Downloadable { if (fileNameElement != null) { String[] filename = fileNameElement.getContent() .toLowerCase(Locale.US).toLowerCase().split("\\."); - if (Arrays.asList(VALID_IMAGE_EXTENSIONS).contains( - filename[filename.length - 1])) { + String extension = filename[filename.length - 1]; + if (Arrays.asList(VALID_IMAGE_EXTENSIONS).contains(extension)) { message.setType(Message.TYPE_IMAGE); + message.setRelativeFilePath(message.getUuid()+"."+extension); } else if (Arrays.asList(VALID_CRYPTO_EXTENSIONS).contains( filename[filename.length - 1])) { if (filename.length == 3) { - if (Arrays.asList(VALID_IMAGE_EXTENSIONS).contains( - filename[filename.length - 2])) { + extension = filename[filename.length - 2]; + if (Arrays.asList(VALID_IMAGE_EXTENSIONS).contains(extension)) { message.setType(Message.TYPE_IMAGE); + message.setRelativeFilePath(message.getUuid()+"."+extension); } else { message.setType(Message.TYPE_FILE); } -- cgit v1.2.3 From ef6e4c5dd5e601f6a3c9e4e755fb31537a8cd56e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 11 Jan 2015 22:18:18 +0100 Subject: do not check image file size over http if accepted file size is 0 --- src/main/java/eu/siacs/conversations/crypto/PgpEngine.java | 9 ++++++--- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index 83d9b7b2..ad5a4132 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -19,6 +19,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.ui.UiCallback; import android.app.PendingIntent; @@ -56,9 +57,11 @@ public class PgpEngine { if (message.getEncryption() == Message.ENCRYPTION_PGP) { message.setBody(os.toString()); message.setEncryption(Message.ENCRYPTION_DECRYPTED); - if (message.trusted() && message.bodyContainsDownloadable()) { - mXmppConnectionService.getHttpConnectionManager() - .createNewConnection(message); + final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager(); + if (message.trusted() + && message.bodyContainsDownloadable() + && manager.getAutoAcceptFileSize() > 0) { + manager.createNewConnection(message); } callback.success(message); } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index bb9de061..a15be622 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -8,6 +8,8 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; +import eu.siacs.conversations.http.HttpConnection; +import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; @@ -575,9 +577,9 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.databaseBackend.createMessage(message); } } - if (message.trusted() && message.bodyContainsDownloadable()) { - this.mXmppConnectionService.getHttpConnectionManager() - .createNewConnection(message); + final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); + if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { + manager.createNewConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); } -- cgit v1.2.3 From 3c5224251c1590f57e23ae339cb65cc8bdb54170 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Sun, 11 Jan 2015 10:22:29 -0500 Subject: Add XEP-0245 (/me command) support --- .../eu/siacs/conversations/entities/Message.java | 47 +++- .../conversations/ui/ConversationFragment.java | 10 +- .../ui/adapter/ConversationAdapter.java | 19 +- .../conversations/ui/adapter/MessageAdapter.java | 288 +++++++++++---------- 4 files changed, 205 insertions(+), 159 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 8cb48635..e8e579ab 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -36,17 +36,18 @@ public class Message extends AbstractEntity { public static final int TYPE_STATUS = 3; public static final int TYPE_PRIVATE = 4; - public static String CONVERSATION = "conversationUuid"; - public static String COUNTERPART = "counterpart"; - public static String TRUE_COUNTERPART = "trueCounterpart"; - public static String BODY = "body"; - public static String TIME_SENT = "timeSent"; - public static String ENCRYPTION = "encryption"; - public static String STATUS = "status"; - public static String TYPE = "type"; - public static String REMOTE_MSG_ID = "remoteMsgId"; - public static String SERVER_MSG_ID = "serverMsgId"; - public static String RELATIVE_FILE_PATH = "relativeFilePath"; + public static final String CONVERSATION = "conversationUuid"; + public static final String COUNTERPART = "counterpart"; + public static final String TRUE_COUNTERPART = "trueCounterpart"; + public static final String BODY = "body"; + public static final String TIME_SENT = "timeSent"; + public static final String ENCRYPTION = "encryption"; + public static final String STATUS = "status"; + public static final String TYPE = "type"; + public static final String REMOTE_MSG_ID = "remoteMsgId"; + public static final String SERVER_MSG_ID = "serverMsgId"; + public static final String RELATIVE_FILE_PATH = "relativeFilePath"; + public boolean markable = false; protected String conversationUuid; protected Jid counterpart; @@ -348,17 +349,35 @@ public class Message extends AbstractEntity { } public boolean mergeable(final Message message) { - return message != null && (message.getType() == Message.TYPE_TEXT && this.getDownloadable() == null && message.getDownloadable() == null && message.getEncryption() != Message.ENCRYPTION_PGP && this.getType() == message.getType() && this.getStatus() == message.getStatus() && this.getEncryption() == message.getEncryption() && this.getCounterpart() != null && this.getCounterpart().equals(message.getCounterpart()) && (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && !message.bodyContainsDownloadable() && !this.bodyContainsDownloadable()); + return message != null && + (message.getType() == Message.TYPE_TEXT && + this.getDownloadable() == null && + message.getDownloadable() == null && + message.getEncryption() != Message.ENCRYPTION_PGP && + this.getType() == message.getType() && + this.getStatus() == message.getStatus() && + this.getEncryption() == message.getEncryption() && + this.getCounterpart() != null && + this.getCounterpart().equals(message.getCounterpart()) && + (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && + !message.bodyContainsDownloadable() && + !this.bodyContainsDownloadable() && + !this.body.startsWith("/me ") + ); } public String getMergedBody() { - Message next = this.next(); + final Message next = this.next(); if (this.mergeable(next)) { - return body.trim() + '\n' + next.getMergedBody(); + return getBody() + '\n' + next.getMergedBody(); } return body.trim(); } + public boolean hasMeCommand() { + return getMergedBody().startsWith("/me "); + } + public int getMergedStatus() { return getStatus(); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 5eb81e64..bd6fda98 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -425,16 +425,16 @@ public class ConversationFragment extends Fragment { if ((m.getType() != Message.TYPE_IMAGE && m.getDownloadable() == null) || m.getImageParams().url == null) { copyUrl.setVisible(false); - } + } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null || !m.bodyContainsDownloadable()) { downloadImage.setVisible(false); - } + } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) - || (m.isFileOrImage() && m.getStatus() == Message.STATUS_WAITING))) { + || (m.isFileOrImage() && m.getStatus() == Message.STATUS_WAITING))) { cancelTransmission.setVisible(false); - } + } } } @@ -657,7 +657,7 @@ public class ConversationFragment extends Fragment { } } conversation.populateWithMessages(ConversationFragment.this.messageList); - for (Message message : this.messageList) { + for (final Message message : this.messageList) { if (message.getEncryption() == Message.ENCRYPTION_PGP && (message.getStatus() == Message.STATUS_RECEIVED || message .getStatus() >= Message.STATUS_SEND) diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 2465380f..9c606c3e 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -1,5 +1,15 @@ package eu.siacs.conversations.ui.adapter; +import android.content.Context; +import android.graphics.Color; +import android.graphics.Typeface; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + import java.util.List; import eu.siacs.conversations.R; @@ -10,15 +20,6 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.XmppActivity; import eu.siacs.conversations.utils.UIHelper; -import android.content.Context; -import android.graphics.Color; -import android.graphics.Typeface; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.TextView; public class ConversationAdapter extends ArrayAdapter { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 5b5664c6..9a69db11 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -52,14 +52,14 @@ public class MessageAdapter extends ArrayAdapter { private OnContactPictureLongClicked mOnContactPictureLongClickedListener; private OnLongClickListener openContextMenu = new OnLongClickListener() { - + @Override public boolean onLongClick(View v) { v.showContextMenu(); return true; } }; - + public MessageAdapter(ConversationActivity activity, List messages) { super(activity, 0, messages); this.activity = activity; @@ -73,7 +73,7 @@ public class MessageAdapter extends ArrayAdapter { public void setOnContactPictureLongClicked( OnContactPictureLongClicked listener) { this.mOnContactPictureLongClickedListener = listener; - } + } @Override public int getViewTypeCount() { @@ -101,7 +101,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.indicatorReceived.setVisibility(View.GONE); } boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI - && message.getMergedStatus() <= Message.STATUS_RECEIVED; + && message.getMergedStatus() <= Message.STATUS_RECEIVED; if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getDownloadable() != null) { ImageParams params = message.getImageParams(); if (params.size > (1.5 * 1024 * 1024)) { @@ -114,44 +114,39 @@ public class MessageAdapter extends ArrayAdapter { } } switch (message.getMergedStatus()) { - case Message.STATUS_WAITING: - info = getContext().getString(R.string.waiting); - break; - case Message.STATUS_UNSEND: - Downloadable d = message.getDownloadable(); - if (d!=null) { - info = getContext().getString(R.string.sending_file,d.getProgress()); - } else { - info = getContext().getString(R.string.sending); - } - break; - case Message.STATUS_OFFERED: - info = getContext().getString(R.string.offering); - break; - case Message.STATUS_SEND_RECEIVED: - if (activity.indicateReceived()) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - } - break; - case Message.STATUS_SEND_DISPLAYED: - if (activity.indicateReceived()) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - } - break; - case Message.STATUS_SEND_FAILED: - info = getContext().getString(R.string.send_failed); - error = true; - break; - default: - if (multiReceived) { - Contact contact = message.getContact(); - if (contact != null) { - info = contact.getDisplayName(); + case Message.STATUS_WAITING: + info = getContext().getString(R.string.waiting); + break; + case Message.STATUS_UNSEND: + Downloadable d = message.getDownloadable(); + if (d!=null) { + info = getContext().getString(R.string.sending_file,d.getProgress()); } else { - info = getDisplayedMucCounterpart(message.getCounterpart()); + info = getContext().getString(R.string.sending); } - } - break; + break; + case Message.STATUS_OFFERED: + info = getContext().getString(R.string.offering); + break; + case Message.STATUS_SEND_RECEIVED: + if (activity.indicateReceived()) { + viewHolder.indicatorReceived.setVisibility(View.VISIBLE); + } + break; + case Message.STATUS_SEND_DISPLAYED: + if (activity.indicateReceived()) { + viewHolder.indicatorReceived.setVisibility(View.VISIBLE); + } + break; + case Message.STATUS_SEND_FAILED: + info = getContext().getString(R.string.send_failed); + error = true; + break; + default: + if (multiReceived) { + info = getMessageDisplayName(message); + } + break; } if (error) { viewHolder.time.setTextColor(activity.getWarningTextColor()); @@ -212,26 +207,53 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); viewHolder.messageBody.setText(getContext().getString( - R.string.decryption_failed)); + R.string.decryption_failed)); viewHolder.messageBody.setTextColor(activity.getWarningTextColor()); viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); viewHolder.messageBody.setTextIsSelectable(false); } - private void displayTextMessage(ViewHolder viewHolder, Message message) { + private String getMessageDisplayName(final Message message) { + if (message.getStatus() == Message.STATUS_RECEIVED) { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + return getDisplayedMucCounterpart(message.getCounterpart()); + } else { + final Contact contact = message.getContact(); + return contact != null ? contact.getDisplayName() : ""; + } + } else { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + return getDisplayedMucCounterpart(message.getConversation().getJid()); + } else { + final Jid jid = message.getConversation().getAccount().getJid(); + return jid.hasLocalpart() ? jid.getLocalpart() : jid.toDomainJid().toString(); + } + } + } + + private void displayTextMessage(final ViewHolder viewHolder, final Message message) { if (viewHolder.download_button != null) { viewHolder.download_button.setVisibility(View.GONE); } viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); if (message.getBody() != null) { + final String nick = getMessageDisplayName(message); + final String formattedBody = message.getMergedBody().replaceAll("^/me ", nick + " "); if (message.getType() != Message.TYPE_PRIVATE) { - viewHolder.messageBody.setText(message.getMergedBody()); + if (message.hasMeCommand()) { + final Spannable span = new SpannableString(formattedBody); + span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + viewHolder.messageBody.setText(span); + } else { + viewHolder.messageBody.setText(message.getMergedBody()); + } } else { String privateMarker; if (message.getStatus() <= Message.STATUS_RECEIVED) { privateMarker = activity - .getString(R.string.private_message); + .getString(R.string.private_message); } else { final String to; if (message.getCounterpart() != null) { @@ -241,15 +263,19 @@ public class MessageAdapter extends ArrayAdapter { } privateMarker = activity.getString(R.string.private_message_to, to); } - SpannableString span = new SpannableString(privateMarker + " " - + message.getBody()); - span.setSpan( - new ForegroundColorSpan(activity - .getSecondaryTextColor()), 0, privateMarker - .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - span.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, + final Spannable span = new SpannableString(privateMarker + " " + + formattedBody); + span.setSpan(new ForegroundColorSpan(activity + .getSecondaryTextColor()), 0, privateMarker + .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarker.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + if (message.hasMeCommand()) { + span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarker.length() + 1, + privateMarker.length() + 1 + nick.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } viewHolder.messageBody.setText(span); } } else { @@ -281,7 +307,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(activity.getString(R.string.open_file,file.getMimeType())); + viewHolder.download_button.setText(activity.getString(R.string.open_file, file.getMimeType())); viewHolder.download_button.setOnClickListener(new OnClickListener() { @Override @@ -311,7 +337,7 @@ public class MessageAdapter extends ArrayAdapter { scalledH = (int) (params.height / ((double) params.width / target)); } viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams( - scalledW, scalledH)); + scalledW, scalledH)); activity.loadBitmap(message, viewHolder.image); viewHolder.image.setOnClickListener(new OnClickListener() { @@ -346,59 +372,59 @@ public class MessageAdapter extends ArrayAdapter { if (view == null) { viewHolder = new ViewHolder(); switch (type) { - case NULL: - view = activity.getLayoutInflater().inflate( - R.layout.message_null, parent, false); - break; - case SENT: - view = activity.getLayoutInflater().inflate( - R.layout.message_sent, parent, false); - viewHolder.message_box = (LinearLayout) view + case NULL: + view = activity.getLayoutInflater().inflate( + R.layout.message_null, parent, false); + break; + case SENT: + view = activity.getLayoutInflater().inflate( + R.layout.message_sent, parent, false); + viewHolder.message_box = (LinearLayout) view .findViewById(R.id.message_box); - viewHolder.contact_picture = (ImageView) view + viewHolder.contact_picture = (ImageView) view .findViewById(R.id.message_photo); - viewHolder.download_button = (Button) view + viewHolder.download_button = (Button) view .findViewById(R.id.download_button); - viewHolder.indicator = (ImageView) view + viewHolder.indicator = (ImageView) view .findViewById(R.id.security_indicator); - viewHolder.image = (ImageView) view + viewHolder.image = (ImageView) view .findViewById(R.id.message_image); - viewHolder.messageBody = (TextView) view + viewHolder.messageBody = (TextView) view .findViewById(R.id.message_body); - viewHolder.time = (TextView) view + viewHolder.time = (TextView) view .findViewById(R.id.message_time); - viewHolder.indicatorReceived = (ImageView) view + viewHolder.indicatorReceived = (ImageView) view .findViewById(R.id.indicator_received); - break; - case RECEIVED: - view = activity.getLayoutInflater().inflate( - R.layout.message_received, parent, false); - viewHolder.message_box = (LinearLayout) view + break; + case RECEIVED: + view = activity.getLayoutInflater().inflate( + R.layout.message_received, parent, false); + viewHolder.message_box = (LinearLayout) view .findViewById(R.id.message_box); - viewHolder.contact_picture = (ImageView) view + viewHolder.contact_picture = (ImageView) view .findViewById(R.id.message_photo); - viewHolder.download_button = (Button) view + viewHolder.download_button = (Button) view .findViewById(R.id.download_button); - viewHolder.indicator = (ImageView) view + viewHolder.indicator = (ImageView) view .findViewById(R.id.security_indicator); - viewHolder.image = (ImageView) view + viewHolder.image = (ImageView) view .findViewById(R.id.message_image); - viewHolder.messageBody = (TextView) view + viewHolder.messageBody = (TextView) view .findViewById(R.id.message_body); - viewHolder.time = (TextView) view + viewHolder.time = (TextView) view .findViewById(R.id.message_time); - viewHolder.indicatorReceived = (ImageView) view + viewHolder.indicatorReceived = (ImageView) view .findViewById(R.id.indicator_received); - break; - case STATUS: - view = activity.getLayoutInflater().inflate( - R.layout.message_status, parent, false); - viewHolder.contact_picture = (ImageView) view + break; + case STATUS: + view = activity.getLayoutInflater().inflate( + R.layout.message_status, parent, false); + viewHolder.contact_picture = (ImageView) view .findViewById(R.id.message_photo); - break; - default: - viewHolder = null; - break; + break; + default: + viewHolder = null; + break; } view.setTag(viewHolder); } else { @@ -412,22 +438,22 @@ public class MessageAdapter extends ArrayAdapter { if (conversation.getMode() == Conversation.MODE_SINGLE) { viewHolder.contact_picture.setImageBitmap(activity .avatarService().get(conversation.getContact(), - activity.getPixel(32))); + activity.getPixel(32))); viewHolder.contact_picture.setAlpha(0.5f); viewHolder.contact_picture - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - String name = conversation.getName(); - String read = getContext() - .getString( - R.string.contact_has_read_up_to_this_point, - name); - Toast.makeText(getContext(), read, - Toast.LENGTH_SHORT).show(); - } - }); + .setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + String name = conversation.getName(); + String read = getContext() + .getString( + R.string.contact_has_read_up_to_this_point, + name); + Toast.makeText(getContext(), read, + Toast.LENGTH_SHORT).show(); + } + }); } return view; @@ -456,38 +482,38 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(contact, activity.getPixel(48))); } else if (conversation.getMode() == Conversation.MODE_MULTI) { viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(getDisplayedMucCounterpart(message.getCounterpart()), - activity.getPixel(48))); + activity.getPixel(48))); } } else if (type == SENT) { viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48))); } viewHolder.contact_picture - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (MessageAdapter.this.mOnContactPictureClickedListener != null) { - MessageAdapter.this.mOnContactPictureClickedListener - .onContactPictureClicked(message); - } + .setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (MessageAdapter.this.mOnContactPictureClickedListener != null) { + MessageAdapter.this.mOnContactPictureClickedListener + .onContactPictureClicked(message); } - }); + + } + }); viewHolder.contact_picture - .setOnLongClickListener(new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) { - MessageAdapter.this.mOnContactPictureLongClickedListener - .onContactPictureLongClicked(message); - return true; - } else { - return false; - } + .setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) { + MessageAdapter.this.mOnContactPictureLongClickedListener + .onContactPictureLongClicked(message); + return true; + } else { + return false; } - }); + } + }); if (message.getDownloadable() != null && message.getDownloadable().getStatus() != Downloadable.STATUS_UPLOADING) { Downloadable d = message.getDownloadable(); @@ -536,13 +562,13 @@ public class MessageAdapter extends ArrayAdapter { activity.getString(R.string.install_openkeychain)); if (viewHolder != null) { viewHolder.message_box - .setOnClickListener(new OnClickListener() { + .setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - activity.showInstallPgpDialog(); - } - }); + @Override + public void onClick(View v) { + activity.showInstallPgpDialog(); + } + }); } } } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { -- cgit v1.2.3 From 77e4e1c2acfffcb64d0538c00b087462d15a4bbf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 12 Jan 2015 16:09:39 +0100 Subject: reworked message preview / message meta information (ie file offered, received * file) fixed #837 --- .../services/NotificationService.java | 41 ++----- .../ui/adapter/ConversationAdapter.java | 123 ++++++--------------- .../conversations/ui/adapter/MessageAdapter.java | 52 +++------ .../eu/siacs/conversations/utils/UIHelper.java | 110 ++++++++++++++++++ 4 files changed, 163 insertions(+), 163 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 594b356f..961428c5 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -40,6 +40,7 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.ManageAccountActivity; import eu.siacs.conversations.ui.TimePreference; +import eu.siacs.conversations.utils.UIHelper; public class NotificationService { @@ -210,7 +211,7 @@ public class NotificationService { conversation = messages.get(0).getConversation(); String name = conversation.getName(); style.addLine(Html.fromHtml("" + name + " " - + getReadableBody(messages.get(0)))); + + UIHelper.getMessagePreview(mXmppConnectionService,messages.get(0)).first)); names.append(name); names.append(", "); } @@ -268,7 +269,7 @@ public class NotificationService { bigPictureStyle.bigPicture(bitmap); if (tmp.size() > 0) { bigPictureStyle.setSummaryText(getMergedBodies(tmp)); - builder.setContentText(getReadableBody(tmp.get(0))); + builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService,tmp.get(0)).first); } else { builder.setContentText(mXmppConnectionService.getString(R.string.image_file)); } @@ -280,11 +281,10 @@ public class NotificationService { private void modifyForTextOnly(final Builder builder, final ArrayList messages, final boolean notify) { - builder.setStyle(new NotificationCompat.BigTextStyle() - .bigText(getMergedBodies(messages))); - builder.setContentText(getReadableBody(messages.get(0))); + builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); + builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService,messages.get(0)).first); if (notify) { - builder.setTicker(getReadableBody(messages.get(messages.size() - 1))); + builder.setTicker(UIHelper.getMessagePreview(mXmppConnectionService,messages.get(messages.size() - 1)).first); } } @@ -302,7 +302,7 @@ public class NotificationService { private String getMergedBodies(final ArrayList messages) { final StringBuilder text = new StringBuilder(); for (int i = 0; i < messages.size(); ++i) { - text.append(getReadableBody(messages.get(i))); + text.append(UIHelper.getMessagePreview(mXmppConnectionService,messages.get(i)).first); if (i != messages.size() - 1) { text.append("\n"); } @@ -310,33 +310,6 @@ public class NotificationService { return text.toString(); } - private String getReadableBody(final Message message) { - if (message.getDownloadable() != null - && (message.getDownloadable().getStatus() == Downloadable.STATUS_OFFER || message - .getDownloadable().getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE)) { - if (message.getType() == Message.TYPE_FILE) { - return mXmppConnectionService.getString(R.string.file_offered_for_download); - } else { - return mXmppConnectionService.getText( - R.string.image_offered_for_download).toString(); - } - } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - return mXmppConnectionService.getText( - R.string.encrypted_message_received).toString(); - } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { - return mXmppConnectionService.getText(R.string.decryption_failed) - .toString(); - } else if (message.getType() == Message.TYPE_FILE) { - DownloadableFile file = mXmppConnectionService.getFileBackend().getFile(message); - return mXmppConnectionService.getString(R.string.file,file.getMimeType()); - } else if (message.getType() == Message.TYPE_IMAGE) { - return mXmppConnectionService.getText(R.string.image_file) - .toString(); - } else { - return message.getBody().trim(); - } - } - private PendingIntent createContentIntent(final String conversationUuid) { final TaskStackBuilder stackBuilder = TaskStackBuilder .create(mXmppConnectionService); diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 9c606c3e..37cdf223 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.ui.adapter; import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -34,10 +35,8 @@ public class ConversationAdapter extends ArrayAdapter { @Override public View getView(int position, View view, ViewGroup parent) { if (view == null) { - LayoutInflater inflater = (LayoutInflater) activity - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = inflater.inflate(R.layout.conversation_list_row, - parent, false); + LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = inflater.inflate(R.layout.conversation_list_row,parent, false); } Conversation conversation = getItem(position); if (this.activity instanceof ConversationActivity) { @@ -53,20 +52,15 @@ public class ConversationAdapter extends ArrayAdapter { view.setBackgroundColor(Color.TRANSPARENT); } } - TextView convName = (TextView) view - .findViewById(R.id.conversation_name); - if (conversation.getMode() == Conversation.MODE_SINGLE - || activity.useSubjectToIdentifyConference()) { + TextView convName = (TextView) view.findViewById(R.id.conversation_name); + if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) { convName.setText(conversation.getName()); } else { convName.setText(conversation.getJid().toBareJid().toString()); } - TextView mLastMessage = (TextView) view - .findViewById(R.id.conversation_lastmsg); - TextView mTimestamp = (TextView) view - .findViewById(R.id.conversation_lastupdate); - ImageView imagePreview = (ImageView) view - .findViewById(R.id.conversation_lastimage); + TextView mLastMessage = (TextView) view.findViewById(R.id.conversation_lastmsg); + TextView mTimestamp = (TextView) view.findViewById(R.id.conversation_lastupdate); + ImageView imagePreview = (ImageView) view.findViewById(R.id.conversation_lastimage); Message message = conversation.getLatestMessage(); @@ -76,89 +70,36 @@ public class ConversationAdapter extends ArrayAdapter { convName.setTypeface(null, Typeface.NORMAL); } - if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE - || message.getDownloadable() != null) { - Downloadable d = message.getDownloadable(); - if (conversation.isRead()) { - mLastMessage.setTypeface(null, Typeface.ITALIC); - } else { - mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC); - } - if (d != null) { - mLastMessage.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - if (d.getStatus() == Downloadable.STATUS_CHECKING) { - mLastMessage.setText(R.string.checking_image); - } else if (d.getStatus() == Downloadable.STATUS_DOWNLOADING) { - if (message.getType() == Message.TYPE_FILE) { - mLastMessage.setText(getContext().getString(R.string.receiving_file,d.getMimeType(), d.getProgress())); - } else { - mLastMessage.setText(getContext().getString(R.string.receiving_image, d.getProgress())); - } - } else if (d.getStatus() == Downloadable.STATUS_OFFER) { - if (message.getType() == Message.TYPE_FILE) { - mLastMessage.setText(R.string.file_offered_for_download); - } else { - mLastMessage.setText(R.string.image_offered_for_download); - } - } else if (d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { - mLastMessage.setText(R.string.image_offered_for_download); - } else if (d.getStatus() == Downloadable.STATUS_DELETED) { - if (message.getType() == Message.TYPE_FILE) { - mLastMessage.setText(R.string.file_deleted); - } else { - mLastMessage.setText(R.string.image_file_deleted); - } - } else if (d.getStatus() == Downloadable.STATUS_FAILED) { - if (message.getType() == Message.TYPE_FILE) { - mLastMessage.setText(R.string.file_transmission_failed); - } else { - mLastMessage.setText(R.string.image_transmission_failed); - } - } else if (message.getImageParams().width > 0) { - mLastMessage.setVisibility(View.GONE); - imagePreview.setVisibility(View.VISIBLE); - activity.loadBitmap(message, imagePreview); + if (message.getImageParams().width > 0 + && (message.getDownloadable() == null + || message.getDownloadable().getStatus() == Downloadable.STATUS_DELETED)) { + mLastMessage.setVisibility(View.GONE); + imagePreview.setVisibility(View.VISIBLE); + activity.loadBitmap(message, imagePreview); + } else { + Pair preview = UIHelper.getMessagePreview(activity,message); + mLastMessage.setVisibility(View.VISIBLE); + imagePreview.setVisibility(View.GONE); + mLastMessage.setText(preview.first); + if (preview.second) { + if (conversation.isRead()) { + mLastMessage.setTypeface(null, Typeface.ITALIC); } else { - mLastMessage.setText(""); + mLastMessage.setTypeface(null,Typeface.BOLD_ITALIC); } - } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - imagePreview.setVisibility(View.GONE); - mLastMessage.setVisibility(View.VISIBLE); - mLastMessage.setText(R.string.encrypted_message_received); - } else if (message.getType() == Message.TYPE_FILE && message.getImageParams().width <= 0) { - DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); - mLastMessage.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - mLastMessage.setText(getContext().getString(R.string.file,file.getMimeType())); - } else { - mLastMessage.setVisibility(View.GONE); - imagePreview.setVisibility(View.VISIBLE); - activity.loadBitmap(message, imagePreview); - } - } else { - if ((message.getEncryption() != Message.ENCRYPTION_PGP) - && (message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED)) { - mLastMessage.setText(message.getBody()); - } else { - mLastMessage.setText(R.string.encrypted_message_received); - } - if (!conversation.isRead()) { - mLastMessage.setTypeface(null, Typeface.BOLD); } else { - mLastMessage.setTypeface(null, Typeface.NORMAL); + if (conversation.isRead()) { + mLastMessage.setTypeface(null,Typeface.NORMAL); + } else { + mLastMessage.setTypeface(null,Typeface.BOLD); + } } - mLastMessage.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); } - mTimestamp.setText(UIHelper.readableTimeDifference(getContext(), - conversation.getLatestMessage().getTimeSent())); - ImageView profilePicture = (ImageView) view - .findViewById(R.id.conversation_image); - profilePicture.setImageBitmap(activity.avatarService().get( - conversation, activity.getPixel(56))); + mTimestamp.setText(UIHelper.readableTimeDifference(activity,conversation.getLatestMessage().getTimeSent())); + ImageView profilePicture = (ImageView) view.findViewById(R.id.conversation_image); + profilePicture.setImageBitmap(activity.avatarService().get(conversation, activity.getPixel(56))); return view; } -} +} \ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 9a69db11..a1361fa1 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -144,7 +144,7 @@ public class MessageAdapter extends ArrayAdapter { break; default: if (multiReceived) { - info = getMessageDisplayName(message); + info = UIHelper.getMessageDisplayName(message); } break; } @@ -213,24 +213,6 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setTextIsSelectable(false); } - private String getMessageDisplayName(final Message message) { - if (message.getStatus() == Message.STATUS_RECEIVED) { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - return getDisplayedMucCounterpart(message.getCounterpart()); - } else { - final Contact contact = message.getContact(); - return contact != null ? contact.getDisplayName() : ""; - } - } else { - if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - return getDisplayedMucCounterpart(message.getConversation().getJid()); - } else { - final Jid jid = message.getConversation().getAccount().getJid(); - return jid.hasLocalpart() ? jid.getLocalpart() : jid.toDomainJid().toString(); - } - } - } - private void displayTextMessage(final ViewHolder viewHolder, final Message message) { if (viewHolder.download_button != null) { viewHolder.download_button.setVisibility(View.GONE); @@ -238,7 +220,7 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.VISIBLE); if (message.getBody() != null) { - final String nick = getMessageDisplayName(message); + final String nick = UIHelper.getMessageDisplayName(message); final String formattedBody = message.getMergedBody().replaceAll("^/me ", nick + " "); if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { @@ -303,16 +285,15 @@ public class MessageAdapter extends ArrayAdapter { } private void displayOpenableMessage(ViewHolder viewHolder,final Message message) { - final DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); viewHolder.image.setVisibility(View.GONE); viewHolder.messageBody.setVisibility(View.GONE); viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(activity.getString(R.string.open_file, file.getMimeType())); + viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity,message))); viewHolder.download_button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - openDownloadable(file); + openDownloadable(message); } }); viewHolder.download_button.setOnLongClickListener(openContextMenu); @@ -352,16 +333,6 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setOnLongClickListener(openContextMenu); } - private String getDisplayedMucCounterpart(final Jid counterpart) { - if (counterpart==null) { - return ""; - } else if (!counterpart.isBareJid()) { - return counterpart.getResourcepart(); - } else { - return counterpart.toString(); - } - } - @Override public View getView(int position, View view, ViewGroup parent) { final Message message = getItem(position); @@ -481,8 +452,9 @@ public class MessageAdapter extends ArrayAdapter { if (contact != null) { viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(contact, activity.getPixel(48))); } else if (conversation.getMode() == Conversation.MODE_MULTI) { - viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(getDisplayedMucCounterpart(message.getCounterpart()), - activity.getPixel(48))); + viewHolder.contact_picture.setImageBitmap(activity.avatarService().get( + UIHelper.getMessageDisplayName(message), + activity.getPixel(48))); } } else if (type == SENT) { viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(account, activity.getPixel(48))); @@ -519,7 +491,9 @@ public class MessageAdapter extends ArrayAdapter { Downloadable d = message.getDownloadable(); if (d.getStatus() == Downloadable.STATUS_DOWNLOADING) { if (message.getType() == Message.TYPE_FILE) { - displayInfoMessage(viewHolder,activity.getString(R.string.receiving_file,d.getMimeType(),d.getProgress())); + displayInfoMessage(viewHolder,activity.getString(R.string.receiving_x_file, + UIHelper.getFileDescriptionString(activity,message), + d.getProgress())); } else { displayInfoMessage(viewHolder,activity.getString(R.string.receiving_image,d.getProgress())); } @@ -533,7 +507,8 @@ public class MessageAdapter extends ArrayAdapter { } } else if (d.getStatus() == Downloadable.STATUS_OFFER) { if (message.getType() == Message.TYPE_FILE) { - displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_file,d.getMimeType())); + displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, + UIHelper.getFileDescriptionString(activity,message))); } else { displayDownloadableMessage(viewHolder, message,activity.getString(R.string.download_image)); } @@ -592,7 +567,8 @@ public class MessageAdapter extends ArrayAdapter { } } - public void openDownloadable(DownloadableFile file) { + public void openDownloadable(Message message) { + DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); if (!file.exists()) { Toast.makeText(activity,R.string.file_deleted,Toast.LENGTH_SHORT).show(); return; diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 74f0d345..23fc48bb 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,12 +1,20 @@ package eu.siacs.conversations.utils; +import java.net.URLConnection; import java.util.Calendar; import java.util.Date; import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Contact; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.xmpp.jid.Jid; + import android.content.Context; import android.text.format.DateFormat; import android.text.format.DateUtils; +import android.util.Pair; public class UIHelper { private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE @@ -102,4 +110,106 @@ public class UIHelper { 0xFF795548, 0xFF607d8b}; return colors[(int) ((name.hashCode() & 0xffffffffl) % colors.length)]; } + + public static Pair getMessagePreview(final Context context, final Message message) { + final Downloadable d = message.getDownloadable(); + if (d != null ) { + switch (d.getStatus()) { + case Downloadable.STATUS_CHECKING: + return new Pair<>(context.getString(R.string.checking_image),true); + case Downloadable.STATUS_DOWNLOADING: + if (message.getType() == Message.TYPE_FILE) { + return new Pair<>(context.getString(R.string.receiving_x_file, + getFileDescriptionString(context,message), + d.getProgress()),true); + } else { + return new Pair<>(context.getString(R.string.receiving_image, d.getProgress()),true); + } + case Downloadable.STATUS_OFFER: + case Downloadable.STATUS_OFFER_CHECK_FILESIZE: + if (message.getType() == Message.TYPE_FILE) { + return new Pair<>(context.getString(R.string.x_file_offered_for_download, + getFileDescriptionString(context,message)),true); + } else { + return new Pair<>(context.getString(R.string.image_offered_for_download),true); + } + case Downloadable.STATUS_DELETED: + if (message.getType() == Message.TYPE_FILE) { + return new Pair<>(context.getString(R.string.file_deleted),true); + } else { + return new Pair<>(context.getString(R.string.image_file_deleted),true); + } + case Downloadable.STATUS_FAILED: + if (message.getType() == Message.TYPE_FILE) { + return new Pair<>(context.getString(R.string.file_transmission_failed),true); + } else { + return new Pair<>(context.getString(R.string.image_transmission_failed),true); + } + default: + return new Pair<>("",false); + } + } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { + return new Pair<>(context.getString(R.string.encrypted_message_received),true); + } else if (message.getType() == Message.TYPE_FILE) { + if (message.getStatus() == Message.STATUS_RECEIVED) { + return new Pair<>(context.getString(R.string.received_x_file, + getFileDescriptionString(context, message)), true); + } else { + return new Pair<>(getFileDescriptionString(context,message),true); + } + } else { + if (message.getBody().startsWith("/me ")) { + return new Pair<>(message.getBody().replaceAll("^/me ",UIHelper.getMessageDisplayName(message) + " "),false); + } else { + return new Pair<>(message.getBody(), false); + } + } + } + + public static String getFileDescriptionString(final Context context, final Message message) { + final String path = message.getRelativeFilePath(); + if (path == null) { + return ""; + } + final String mime = URLConnection.guessContentTypeFromName(path); + if (mime == null) { + return ""; + } else if (mime.startsWith("audio/")) { + return context.getString(R.string.audio); + } else if(mime.startsWith("video/")) { + return context.getString(R.string.video); + } else if (mime.contains("pdf")) { + return context.getString(R.string.pdf_document) ; + } else { + return mime; + } + } + + public static String getMessageDisplayName(final Message message) { + if (message.getStatus() == Message.STATUS_RECEIVED) { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + return getDisplayedMucCounterpart(message.getCounterpart()); + } else { + final Contact contact = message.getContact(); + return contact != null ? contact.getDisplayName() : ""; + } + } else { + if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + return getDisplayedMucCounterpart(message.getConversation().getJid()); + } else { + final Jid jid = message.getConversation().getAccount().getJid(); + return jid.hasLocalpart() ? jid.getLocalpart() : jid.toDomainJid().toString(); + } + } + } + + private static String getDisplayedMucCounterpart(final Jid counterpart) { + if (counterpart==null) { + return ""; + } else if (!counterpart.isBareJid()) { + return counterpart.getResourcepart(); + } else { + return counterpart.toString(); + } + } } -- cgit v1.2.3 From 8d3323e384746acfad563d9389529b0802787261 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 12 Jan 2015 16:42:20 +0100 Subject: context menu for files and offered files. fixed #848 fixed #849 --- .../conversations/ui/ConversationFragment.java | 34 +++++++++++++--------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index bd6fda98..4d4ee483 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -33,6 +33,7 @@ import android.widget.Toast; import net.java.otr4j.session.SessionStatus; +import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; @@ -408,7 +409,7 @@ public class ConversationFragment extends Fragment { activity.getMenuInflater().inflate(R.menu.message_context, menu); menu.setHeaderTitle(R.string.message_options); MenuItem copyText = menu.findItem(R.id.copy_text); - MenuItem shareImage = menu.findItem(R.id.share_image); + MenuItem shareWith = menu.findItem(R.id.share_with); MenuItem sendAgain = menu.findItem(R.id.send_again); MenuItem copyUrl = menu.findItem(R.id.copy_url); MenuItem downloadImage = menu.findItem(R.id.download_image); @@ -416,8 +417,10 @@ public class ConversationFragment extends Fragment { if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null) { copyText.setVisible(false); } - if (m.getType() != Message.TYPE_IMAGE || m.getDownloadable() != null) { - shareImage.setVisible(false); + if (m.getType() == Message.TYPE_TEXT + || m.getType() == Message.TYPE_PRIVATE + || m.getDownloadable() != null) { + shareWith.setVisible(false); } if (m.getStatus() != Message.STATUS_SEND_FAILED) { sendAgain.setVisible(false); @@ -425,24 +428,25 @@ public class ConversationFragment extends Fragment { if ((m.getType() != Message.TYPE_IMAGE && m.getDownloadable() == null) || m.getImageParams().url == null) { copyUrl.setVisible(false); - } + } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null || !m.bodyContainsDownloadable()) { downloadImage.setVisible(false); - } + } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) - || (m.isFileOrImage() && m.getStatus() == Message.STATUS_WAITING))) { + || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING + || m.getStatus() == Message.STATUS_OFFERED)))) { cancelTransmission.setVisible(false); - } + } } } @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { - case R.id.share_image: - shareImage(selectedMessage); + case R.id.share_with: + shareWith(selectedMessage); return true; case R.id.copy_text: copyText(selectedMessage); @@ -464,16 +468,20 @@ public class ConversationFragment extends Fragment { } } - private void shareImage(Message message) { + private void shareWith(Message message) { Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_STREAM, activity.xmppConnectionService.getFileBackend() .getJingleFileUri(message)); shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - shareIntent.setType("image/webp"); - activity.startActivity(Intent.createChooser(shareIntent, - getText(R.string.share_with))); + String path = message.getRelativeFilePath(); + String mime = path == null ? null :URLConnection.guessContentTypeFromName(path); + if (mime == null) { + mime = "image/webp"; + } + shareIntent.setType(mime); + activity.startActivity(Intent.createChooser(shareIntent,getText(R.string.share_with))); } private void copyText(Message message) { -- cgit v1.2.3 From dd5101ff5c46034a7c5ddf04b16a5aa8f0dc5f48 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 12 Jan 2015 18:40:15 +0100 Subject: catch bug in guessContentType --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 23fc48bb..ed1db287 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -171,7 +171,12 @@ public class UIHelper { if (path == null) { return ""; } - final String mime = URLConnection.guessContentTypeFromName(path); + final String mime; + try { + mime = URLConnection.guessContentTypeFromName(path); + } catch (final StringIndexOutOfBoundsException ignored) { + return ""; + } if (mime == null) { return ""; } else if (mime.startsWith("audio/")) { -- cgit v1.2.3 From caf861d96f577ffc8d4baa42815e6d733afba2ae Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 13 Jan 2015 22:46:06 -0500 Subject: Ensure type safety in Pebble notifications Also use forward-compatible screen-on detection --- .../services/NotificationService.java | 45 ++++++++++++++-------- 1 file changed, 30 insertions(+), 15 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 961428c5..c9d39e1f 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.services; +import android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -8,6 +9,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Build; import android.os.PowerManager; import android.os.SystemClock; import android.support.v4.app.NotificationCompat; @@ -18,6 +20,9 @@ import android.text.Html; import android.util.DisplayMetrics; import android.util.Log; +import org.json.JSONArray; +import org.json.JSONObject; + import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Calendar; @@ -27,15 +32,10 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.json.JSONArray; -import org.json.JSONObject; - import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; -import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.ManageAccountActivity; @@ -70,14 +70,14 @@ public class NotificationService { ); } - public void notifyPebble(Message message) { + public void notifyPebble(final Message message) { final Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION"); - final HashMap data = new HashMap(); final Conversation conversation = message.getConversation(); - data.put("title", conversation.getName()); - data.put("body", message.getBody()); - final JSONObject jsonData = new JSONObject(data); + final JSONObject jsonData = new JSONObject(new HashMap(2) {{ + put("title", conversation.getName()); + put("body", message.getBody()); + }}); final String notificationData = new JSONArray().put(jsonData).toString(); i.putExtra("messageType", "PEBBLE_ALERT"); @@ -111,13 +111,28 @@ public class NotificationService { return mXmppConnectionService.getPreferences().getBoolean("always_notify_in_conference", false); } + @SuppressLint("NewApi") + @SuppressWarnings("deprecation") + private boolean isInteractive() { + final PowerManager pm = (PowerManager) mXmppConnectionService + .getSystemService(Context.POWER_SERVICE); + + final boolean isScreenOn; + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + isScreenOn = pm.isScreenOn(); + } else { + isScreenOn = pm.isInteractive(); + } + + return isScreenOn; + } + public void push(final Message message) { if (!notify(message)) { return; } - final PowerManager pm = (PowerManager) mXmppConnectionService - .getSystemService(Context.POWER_SERVICE); - final boolean isScreenOn = pm.isScreenOn(); + + final boolean isScreenOn = isInteractive(); if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) { @@ -134,8 +149,8 @@ public class NotificationService { } final Account account = message.getConversation().getAccount(); final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) - && !account.inGracePeriod() - && !this.inMiniGracePeriod(account); + && !account.inGracePeriod() + && !this.inMiniGracePeriod(account); updateNotification(doNotify); if (doNotify) { notifyPebble(message); -- cgit v1.2.3 From 548a585b2c4af9b4c2a98faabb8855fcb260daf2 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Wed, 14 Jan 2015 12:20:02 -0500 Subject: Harden the TLS connection cipher suites --- src/main/java/eu/siacs/conversations/Config.java | 26 +++++++ .../siacs/conversations/http/HttpConnection.java | 81 ++++++++++++---------- .../eu/siacs/conversations/utils/CryptoHelper.java | 21 ++++-- .../siacs/conversations/xmpp/XmppConnection.java | 7 ++ 4 files changed, 93 insertions(+), 42 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 6fe13d93..b269dedf 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -29,6 +29,32 @@ public final class Config { public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; public static final int MAM_MAX_MESSAGES = 500; + public static final String ENABLED_CIPHERS[] = { + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_AES_128_SHA", + "TLS_ECDHE_RSA_AES_256_SHA", + + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA384", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + + "TLS_DHE_RSA_WITH_CAMELLIA_256_SHA", + + // Fallback. + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_128_GCM_SHA384", + "TLS_RSA_WITH_AES_256_GCM_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_CBC_SHA384", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_RSA_WITH_AES_256_CBC_SHA384" + }; + private Config() { } diff --git a/src/main/java/eu/siacs/conversations/http/HttpConnection.java b/src/main/java/eu/siacs/conversations/http/HttpConnection.java index 8951de74..4bff5251 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpConnection.java @@ -20,6 +20,7 @@ import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; import eu.siacs.conversations.Config; @@ -90,7 +91,7 @@ public class HttpConnection implements Downloadable { if (this.message.getEncryption() == Message.ENCRYPTION_OTR && this.file.getKey() == null) { this.message.setEncryption(Message.ENCRYPTION_NONE); - } + } checkFileSize(false); } catch (MalformedURLException e) { this.cancel(); @@ -124,33 +125,39 @@ public class HttpConnection implements Downloadable { mXmppConnectionService.updateConversationUi(); } - private void setupTrustManager(HttpsURLConnection connection, - boolean interactive) { - X509TrustManager trustManager; - HostnameVerifier hostnameVerifier; + private void setupTrustManager(final HttpsURLConnection connection, + final boolean interactive) { + final X509TrustManager trustManager; + final HostnameVerifier hostnameVerifier; if (interactive) { trustManager = mXmppConnectionService.getMemorizingTrustManager(); hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager().wrapHostnameVerifier( - new StrictHostnameVerifier()); + .getMemorizingTrustManager().wrapHostnameVerifier( + new StrictHostnameVerifier()); } else { trustManager = mXmppConnectionService.getMemorizingTrustManager() - .getNonInteractive(); + .getNonInteractive(); hostnameVerifier = mXmppConnectionService - .getMemorizingTrustManager() - .wrapHostnameVerifierNonInteractive( - new StrictHostnameVerifier()); + .getMemorizingTrustManager() + .wrapHostnameVerifierNonInteractive( + new StrictHostnameVerifier()); } try { - SSLContext sc = SSLContext.getInstance("TLS"); + final SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new X509TrustManager[]{trustManager}, mXmppConnectionService.getRNG()); - connection.setSSLSocketFactory(sc.getSocketFactory()); + + final SSLSocketFactory sf = sc.getSocketFactory(); + final String[] cipherSuites = CryptoHelper.getSupportedCipherSuites( + sf.getSupportedCipherSuites()); + if (cipherSuites.length > 0) { + sc.getDefaultSSLParameters().setCipherSuites(cipherSuites); + + } + + connection.setSSLSocketFactory(sf); connection.setHostnameVerifier(hostnameVerifier); - } catch (KeyManagementException e) { - return; - } catch (NoSuchAlgorithmException e) { - return; + } catch (final KeyManagementException | NoSuchAlgorithmException ignored) { } } @@ -188,24 +195,24 @@ public class HttpConnection implements Downloadable { } private long retrieveFileSize() throws IOException, - SSLHandshakeException { - changeStatus(STATUS_CHECKING); - HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); - connection.setRequestMethod("HEAD"); - if (connection instanceof HttpsURLConnection) { - setupTrustManager((HttpsURLConnection) connection, interactive); - } - connection.connect(); - String contentLength = connection.getHeaderField("Content-Length"); - if (contentLength == null) { - throw new IOException(); - } - try { - return Long.parseLong(contentLength, 10); - } catch (NumberFormatException e) { - throw new IOException(); - } + SSLHandshakeException { + changeStatus(STATUS_CHECKING); + HttpURLConnection connection = (HttpURLConnection) mUrl + .openConnection(); + connection.setRequestMethod("HEAD"); + if (connection instanceof HttpsURLConnection) { + setupTrustManager((HttpsURLConnection) connection, interactive); + } + connection.connect(); + String contentLength = connection.getHeaderField("Content-Length"); + if (contentLength == null) { + throw new IOException(); + } + try { + return Long.parseLong(contentLength, 10); + } catch (NumberFormatException e) { + throw new IOException(); + } } } @@ -234,7 +241,7 @@ public class HttpConnection implements Downloadable { private void download() throws SSLHandshakeException, IOException { HttpURLConnection connection = (HttpURLConnection) mUrl - .openConnection(); + .openConnection(); if (connection instanceof HttpsURLConnection) { setupTrustManager((HttpsURLConnection) connection, interactive); } @@ -300,4 +307,4 @@ public class HttpConnection implements Downloadable { public String getMimeType() { return ""; } -} \ No newline at end of file +} diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 7a36e2ba..48b0cdf3 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -2,12 +2,17 @@ package eu.siacs.conversations.utils; import java.security.SecureRandom; import java.text.Normalizer; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; -public class CryptoHelper { +import eu.siacs.conversations.Config; + +public final class CryptoHelper { public static final String FILETRANSFER = "?FILETRANSFERv1:"; - final protected static char[] hexArray = "0123456789abcdef".toCharArray(); - final protected static char[] vowels = "aeiou".toCharArray(); - final protected static char[] consonants = "bcdfghjklmnpqrstvwxyz".toCharArray(); + private final static char[] hexArray = "0123456789abcdef".toCharArray(); + private final static char[] vowels = "aeiou".toCharArray(); + private final static char[] consonants = "bcdfghjklmnpqrstvwxyz".toCharArray(); final public static byte[] ONE = new byte[] { 0, 0, 0, 1 }; public static String bytesToHex(byte[] bytes) { @@ -45,7 +50,7 @@ public class CryptoHelper { return randomWord(3, random) + "." + randomWord(7, random); } - protected static String randomWord(int lenght, SecureRandom random) { + private static String randomWord(int lenght, SecureRandom random) { StringBuilder builder = new StringBuilder(lenght); for (int i = 0; i < lenght; ++i) { if (i % 2 == 0) { @@ -91,4 +96,10 @@ public class CryptoHelper { builder.insert(35, " "); return builder.toString(); } + + public static String[] getSupportedCipherSuites(final String[] platformSupportedCipherSuites) { + final Collection cipherSuites = new LinkedHashSet<>(Arrays.asList(Config.ENABLED_CIPHERS)); + cipherSuites.retainAll(Arrays.asList(platformSupportedCipherSuites)); + return cipherSuites.toArray(new String[cipherSuites.size()]); + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 30437575..6424b1d5 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -53,6 +53,7 @@ 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.CryptoHelper; import eu.siacs.conversations.utils.DNSHelper; import eu.siacs.conversations.utils.Xmlns; import eu.siacs.conversations.xml.Element; @@ -514,6 +515,12 @@ public class XmppConnection implements Runnable { supportedProtocols.remove("SSLv3"); supportProtocols = new String[supportedProtocols.size()]; supportedProtocols.toArray(supportProtocols); + + final String[] cipherSuites = CryptoHelper.getSupportedCipherSuites( + sslSocket.getSupportedCipherSuites()); + if (cipherSuites.length > 0) { + sslSocket.setEnabledCipherSuites(cipherSuites); + } } sslSocket.setEnabledProtocols(supportProtocols); -- cgit v1.2.3 From 0a96bec3c1d65c0d3da22511f3b92a21fd94ad0f Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Wed, 14 Jan 2015 15:28:27 -0500 Subject: Add option to swap enter/emoticon key --- .../conversations/ui/ConversationActivity.java | 45 ++++++++++++---------- .../conversations/ui/ConversationFragment.java | 20 +++++++--- .../eu/siacs/conversations/ui/XmppActivity.java | 6 +++ 3 files changed, 45 insertions(+), 26 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 926edef0..7fac95c5 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -15,6 +15,7 @@ import android.os.SystemClock; import android.provider.MediaStore; import android.support.v4.widget.SlidingPaneLayout; import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -32,6 +33,7 @@ import net.java.otr4j.session.SessionStatus; import java.util.ArrayList; 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; @@ -133,7 +135,7 @@ public class ConversationActivity extends XmppActivity } @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) {mOpenConverstaion = savedInstanceState.getString( STATE_OPEN_CONVERSATION, null); @@ -536,25 +538,25 @@ public class ConversationActivity extends XmppActivity } attachFilePopup.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_choose_file: - attachFile(ATTACHMENT_CHOICE_CHOOSE_FILE); - break; - case R.id.attach_record_voice: - attachFile(ATTACHMENT_CHOICE_RECORD_VOICE); - 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_choose_file: + attachFile(ATTACHMENT_CHOICE_CHOOSE_FILE); + break; + case R.id.attach_record_voice: + attachFile(ATTACHMENT_CHOICE_RECORD_VOICE); + break; } - }); + return false; + } + }); attachFilePopup.show(); } @@ -750,8 +752,9 @@ public class ConversationActivity extends XmppActivity @Override public void onResume() { super.onResume(); - int theme = findTheme(); - if (this.mTheme != theme) { + final int theme = findTheme(); + final boolean usingEnterKey = usingEnterKey(); + if (this.mTheme != theme || usingEnterKey != mUsingEnterKey) { recreate(); } this.mActivityPaused = false; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 4d4ee483..0a38daee 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -9,6 +9,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import android.os.Bundle; +import android.text.InputType; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Gravity; @@ -300,12 +301,21 @@ public class ConversationFragment extends Fragment { } } + private void setupIme() { + if (((ConversationActivity)getActivity()).usingEnterKey()) { + mEditMessage.setInputType(mEditMessage.getInputType() & (~InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE)); + } else { + mEditMessage.setInputType(mEditMessage.getInputType() | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE); + } + } + @Override public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_conversation, container, false); mEditMessage = (EditMessage) view.findViewById(R.id.textinput); + setupIme(); mEditMessage.setOnClickListener(new OnClickListener() { @Override @@ -421,24 +431,24 @@ public class ConversationFragment extends Fragment { || m.getType() == Message.TYPE_PRIVATE || m.getDownloadable() != null) { shareWith.setVisible(false); - } + } if (m.getStatus() != Message.STATUS_SEND_FAILED) { sendAgain.setVisible(false); } if ((m.getType() != Message.TYPE_IMAGE && m.getDownloadable() == null) || m.getImageParams().url == null) { copyUrl.setVisible(false); - } + } if (m.getType() != Message.TYPE_TEXT || m.getDownloadable() != null || !m.bodyContainsDownloadable()) { downloadImage.setVisible(false); - } + } if (!((m.getDownloadable() != null && !(m.getDownloadable() instanceof DownloadablePlaceholder)) || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING - || m.getStatus() == Message.STATUS_OFFERED)))) { + || m.getStatus() == Message.STATUS_OFFERED)))) { cancelTransmission.setVisible(false); - } + } } } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 69dd47e7..0deeacf0 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -96,6 +96,7 @@ public abstract class XmppActivity extends Activity { private DisplayMetrics metrics; protected int mTheme; + protected boolean mUsingEnterKey = false; protected interface OnValueEdited { public void onValueEdited(String value); @@ -303,9 +304,14 @@ public abstract class XmppActivity extends Activity { R.color.secondarybackground); this.mTheme = findTheme(); setTheme(this.mTheme); + this.mUsingEnterKey = usingEnterKey(); mUseSubject = getPreferences().getBoolean("use_subject", true); } + protected boolean usingEnterKey() { + return getPreferences().getBoolean("display_enter_key", false); + } + protected SharedPreferences getPreferences() { return PreferenceManager .getDefaultSharedPreferences(getApplicationContext()); -- cgit v1.2.3 From a6a9ed487786451f0eedfaa63fbbc5332d4adcf3 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 14 Jan 2015 22:48:14 +0100 Subject: handle muc nicks with white spaces. fixed #884 --- src/main/java/eu/siacs/conversations/services/AvatarService.java | 3 ++- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 3ac4462d..f28dc24e 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -212,7 +212,8 @@ public class AvatarService { } bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); - final String letter = name.isEmpty() ? "X" : name.substring(0,1); + final String trimmedName = name.trim(); + final String letter = trimmedName.isEmpty() ? "X" : trimmedName.substring(0,1); final int color = UIHelper.getColorForName(name); drawTile(canvas, letter, color, 0, 0, size, size); mXmppConnectionService.getBitmapCache().put(KEY, bitmap); diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index ed1db287..b00447a4 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -212,9 +212,9 @@ public class UIHelper { if (counterpart==null) { return ""; } else if (!counterpart.isBareJid()) { - return counterpart.getResourcepart(); + return counterpart.getResourcepart().trim(); } else { - return counterpart.toString(); + return counterpart.toString().trim(); } } } -- cgit v1.2.3 From 351e5d70652ccbb23bbd29ea75b1452f4fa8969e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 15 Jan 2015 15:45:11 +0100 Subject: fixed #888 --- src/main/java/eu/siacs/conversations/services/NotificationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index c9d39e1f..6f02fca9 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -436,7 +436,7 @@ public class NotificationService { mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_fix)); } mBuilder.setOngoing(true); - mBuilder.setLights(0xffffffff, 2000, 4000); + //mBuilder.setLights(0xffffffff, 2000, 4000); mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); TaskStackBuilder stackBuilder = TaskStackBuilder.create(mXmppConnectionService); stackBuilder.addParentStack(ConversationActivity.class); -- cgit v1.2.3 From 994c9495bad07fd7307ea85986a7766adb15cf84 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 15 Jan 2015 16:17:55 +0100 Subject: added dedicated button to disable foreground service in perma notification --- .../eu/siacs/conversations/services/NotificationService.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 6f02fca9..a32bb279 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -409,13 +409,20 @@ public class NotificationService { final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService); mBuilder.setSmallIcon(R.drawable.ic_stat_communication_import_export); mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.conversations_foreground_service)); - mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_disable)); - mBuilder.setContentIntent(createDisableForeground()); + mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_open_conversations)); + mBuilder.addAction(R.drawable.ic_action_cancel, + mXmppConnectionService.getString(R.string.disable_foreground_service), + createDisableForeground()); + mBuilder.setContentIntent(createOpenConversationsIntent()); mBuilder.setWhen(0); mBuilder.setPriority(NotificationCompat.PRIORITY_MIN); return mBuilder.build(); } + private PendingIntent createOpenConversationsIntent() { + return PendingIntent.getActivity(mXmppConnectionService, 0, new Intent(mXmppConnectionService,ConversationActivity.class),0); + } + public void updateErrorNotification() { final NotificationManager mNotificationManager = (NotificationManager) mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE); final List errors = new ArrayList<>(); -- cgit v1.2.3 From c0993a9acb7be045d75e1c1dcc4c0fafc879a31e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 15 Jan 2015 16:26:46 +0100 Subject: show toast when avatar has been published - fixed #874 --- .../ui/PublishProfilePictureActivity.java | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index 10ee0cd5..2ba0b090 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -11,6 +11,8 @@ import android.view.View.OnLongClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; + import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.utils.PhoneHelper; @@ -31,13 +33,18 @@ public class PublishProfilePictureActivity extends XmppActivity { private Uri avatarUri; private Uri defaultUri; + private OnLongClickListener backToDefaultListener = new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + avatarUri = defaultUri; + loadImageIntoPreview(defaultUri); + return true; + } + }; private Account account; - private boolean support = false; - private boolean mInitialAccountSetup; - private UiCallback avatarPublication = new UiCallback() { @Override @@ -50,6 +57,9 @@ public class PublishProfilePictureActivity extends XmppActivity { startActivity(new Intent(getApplicationContext(), StartConversationActivity.class)); } + Toast.makeText(PublishProfilePictureActivity.this, + R.string.avatar_has_been_published, + Toast.LENGTH_SHORT).show(); finish(); } }); @@ -75,16 +85,6 @@ public class PublishProfilePictureActivity extends XmppActivity { } }; - private OnLongClickListener backToDefaultListener = new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - avatarUri = defaultUri; - loadImageIntoPreview(defaultUri); - return true; - } - }; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); -- cgit v1.2.3 From dc8b467cf63af3466e13f58c8abc63875a44754e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 15 Jan 2015 16:32:24 +0100 Subject: sending read marker when resuming activity and conversation is open --- src/main/java/eu/siacs/conversations/ui/ConversationActivity.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 7fac95c5..4ba6c773 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -261,7 +261,7 @@ public class ConversationActivity extends XmppActivity } public void sendReadMarkerIfNecessary(final Conversation conversation) { - if (!mActivityPaused && !conversation.isRead()) { + if (!mActivityPaused && conversation != null && !conversation.isRead()) { xmppConnectionService.sendReadMarker(conversation); } } @@ -761,6 +761,9 @@ public class ConversationActivity extends XmppActivity if (this.xmppConnectionServiceBound) { this.xmppConnectionService.getNotificationService().setIsInForeground(true); } + if (!isConversationsOverviewVisable() || !isConversationsOverviewHideable()) { + sendReadMarkerIfNecessary(getSelectedConversation()); + } } @Override -- cgit v1.2.3 From edd58f19b46340f3c9e2182441c9f749754cfa5c Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Fri, 16 Jan 2015 00:36:11 -0500 Subject: Add download button on notification if applicable --- .../siacs/conversations/entities/Conversation.java | 12 ++-- .../services/NotificationService.java | 67 ++++++++++++++++------ .../conversations/ui/ConversationActivity.java | 20 +++++-- 3 files changed, 70 insertions(+), 29 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 470bd290..036acf63 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -108,9 +108,9 @@ public class Conversation extends AbstractEntity implements Blockable { } } - public void findMessagesWithFiles(OnMessageFound onMessageFound) { + public void findMessagesWithFiles(final OnMessageFound onMessageFound) { synchronized (this.messages) { - for (Message message : this.messages) { + for (final Message message : this.messages) { if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) && message.getEncryption() != Message.ENCRYPTION_PGP) { onMessageFound.onMessageFound(message); @@ -119,14 +119,14 @@ public class Conversation extends AbstractEntity implements Blockable { } } - public Message findMessageWithFileAndUuid(String uuid) { + public Message findMessageWithFileAndUuid(final String uuid) { synchronized (this.messages) { - for (Message message : this.messages) { - if (message.getType() == Message.TYPE_IMAGE + for (final Message message : this.messages) { + if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) && message.getEncryption() != Message.ENCRYPTION_PGP && message.getUuid().equals(uuid)) { return message; - } + } } } return null; diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index a32bb279..efdd2b60 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -44,7 +44,7 @@ import eu.siacs.conversations.utils.UIHelper; public class NotificationService { - private XmppConnectionService mXmppConnectionService; + private final XmppConnectionService mXmppConnectionService; private final LinkedHashMap> notifications = new LinkedHashMap<>(); @@ -56,7 +56,7 @@ public class NotificationService { private boolean mIsInForeground; private long mLastNotification; - public NotificationService(XmppConnectionService service) { + public NotificationService(final XmppConnectionService service) { this.mXmppConnectionService = service; } @@ -214,17 +214,17 @@ public class NotificationService { private Builder buildMultipleConversation() { final Builder mBuilder = new NotificationCompat.Builder( mXmppConnectionService); - NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); + final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); style.setBigContentTitle(notifications.size() + " " + mXmppConnectionService .getString(R.string.unread_conversations)); final StringBuilder names = new StringBuilder(); Conversation conversation = null; - for (ArrayList messages : notifications.values()) { + for (final ArrayList messages : notifications.values()) { if (messages.size() > 0) { conversation = messages.get(0).getConversation(); - String name = conversation.getName(); + final String name = conversation.getName(); style.addLine(Html.fromHtml("" + name + " " + UIHelper.getMessagePreview(mXmppConnectionService,messages.get(0)).first)); names.append(name); @@ -241,8 +241,7 @@ public class NotificationService { mBuilder.setContentText(names.toString()); mBuilder.setStyle(style); if (conversation != null) { - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); + mBuilder.setContentIntent(createContentIntent(conversation)); } return mBuilder; } @@ -256,14 +255,24 @@ public class NotificationService { mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() .get(conversation, getPixel(64))); mBuilder.setContentTitle(conversation.getName()); - final Message message; + Message message; if ((message = getImage(messages)) != null) { modifyForImage(mBuilder, message, messages, notify); } else { modifyForTextOnly(mBuilder, messages, notify); } - mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); + if ((message = getFirstDownloadableMessage(messages)) != null) { + mBuilder.addAction( + R.drawable.ic_action_download, + mXmppConnectionService.getResources().getString( + message.getType() == Message.TYPE_IMAGE ? + R.string.download_image : + R.string.download_file + ), + createDownloadIntent(message) + ); + } + mBuilder.setContentIntent(createContentIntent(conversation)); } return mBuilder; } @@ -303,7 +312,7 @@ public class NotificationService { } } - private Message getImage(final ArrayList messages) { + private Message getImage(final Iterable messages) { for (final Message message : messages) { if (message.getType() == Message.TYPE_IMAGE && message.getDownloadable() == null @@ -314,7 +323,17 @@ public class NotificationService { return null; } - private String getMergedBodies(final ArrayList messages) { + private Message getFirstDownloadableMessage(final Iterable messages) { + for (final Message message : messages) { + if ((message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) && + message.getDownloadable() != null) { + return message; + } + } + return null; + } + + private CharSequence getMergedBodies(final ArrayList messages) { final StringBuilder text = new StringBuilder(); for (int i = 0; i < messages.size(); ++i) { text.append(UIHelper.getMessagePreview(mXmppConnectionService,messages.get(i)).first); @@ -325,25 +344,39 @@ public class NotificationService { return text.toString(); } - private PendingIntent createContentIntent(final String conversationUuid) { + private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { final TaskStackBuilder stackBuilder = TaskStackBuilder .create(mXmppConnectionService); stackBuilder.addParentStack(ConversationActivity.class); final Intent viewConversationIntent = new Intent(mXmppConnectionService, ConversationActivity.class); - viewConversationIntent.setAction(Intent.ACTION_VIEW); + if (downloadMessageUuid != null) { + viewConversationIntent.setAction(ConversationActivity.ACTION_DOWNLOAD); + } else { + viewConversationIntent.setAction(Intent.ACTION_VIEW); + } if (conversationUuid != null) { - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, - conversationUuid); + viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversationUuid); viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); } + if (downloadMessageUuid != null) { + viewConversationIntent.putExtra(ConversationActivity.MESSAGE, downloadMessageUuid); + } stackBuilder.addNextIntent(viewConversationIntent); return stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); } + private PendingIntent createDownloadIntent(final Message message) { + return createContentIntent(message.getConversationUuid(), message.getUuid()); + } + + private PendingIntent createContentIntent(final Conversation conversation) { + return createContentIntent(conversation.getUuid(), null); + } + private PendingIntent createDeleteIntent() { final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); @@ -445,7 +478,7 @@ public class NotificationService { mBuilder.setOngoing(true); //mBuilder.setLights(0xffffffff, 2000, 4000); mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); - TaskStackBuilder stackBuilder = TaskStackBuilder.create(mXmppConnectionService); + final TaskStackBuilder stackBuilder = TaskStackBuilder.create(mXmppConnectionService); stackBuilder.addParentStack(ConversationActivity.class); final Intent manageAccountsIntent = new Intent(mXmppConnectionService,ManageAccountActivity.class); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 4ba6c773..1356e616 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -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.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -33,7 +32,6 @@ import net.java.otr4j.session.SessionStatus; import java.util.ArrayList; 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; @@ -50,8 +48,11 @@ import eu.siacs.conversations.xmpp.OnUpdateBlocklist; public class ConversationActivity extends XmppActivity implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist { + public static final String ACTION_DOWNLOAD = "eu.siacs.conversations.action.DOWNLOAD"; + public static final String VIEW_CONVERSATION = "viewConversation"; public static final String CONVERSATION = "conversationUuid"; + public static final String MESSAGE = "messageUuid"; public static final String TEXT = "text"; public static final String NICK = "nick"; @@ -823,10 +824,11 @@ public class ConversationActivity extends XmppActivity setIntent(new Intent()); } - private void handleViewConversationIntent(Intent intent) { - String uuid = (String) intent.getExtras().get(CONVERSATION); - String text = intent.getExtras().getString(TEXT, ""); - String nick = intent.getExtras().getString(NICK,null); + private void handleViewConversationIntent(final Intent intent) { + final String uuid = (String) intent.getExtras().get(CONVERSATION); + final String downloadUuid = (String) intent.getExtras().get(MESSAGE); + final String text = intent.getExtras().getString(TEXT, ""); + final String nick = intent.getExtras().getString(NICK, null); if (selectConversationByUuid(uuid)) { this.mConversationFragment.reInit(getSelectedConversation()); if (nick != null) { @@ -839,6 +841,12 @@ public class ConversationActivity extends XmppActivity if (mContentView instanceof SlidingPaneLayout) { updateActionBarTitle(true); //fixes bug where slp isn't properly closed yet } + if (downloadUuid != null) { + final Message message = mSelectedConversation.findMessageWithFileAndUuid(downloadUuid); + if (message != null) { + mConversationFragment.messageListAdapter.startDownloadable(message); + } + } } } -- cgit v1.2.3 From dfc1cea882b33c7bf27bca5a349377b6ed966a75 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Sat, 17 Jan 2015 09:10:33 -0500 Subject: Correct the download file string on notifications Fixes #896 --- .../services/NotificationService.java | 7 ++----- .../eu/siacs/conversations/utils/UIHelper.java | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index efdd2b60..8c3aff16 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -264,11 +264,8 @@ public class NotificationService { if ((message = getFirstDownloadableMessage(messages)) != null) { mBuilder.addAction( R.drawable.ic_action_download, - mXmppConnectionService.getResources().getString( - message.getType() == Message.TYPE_IMAGE ? - R.string.download_image : - R.string.download_file - ), + mXmppConnectionService.getResources().getString(R.string.download_x_file, + UIHelper.getFileDescriptionString(mXmppConnectionService, message)), createDownloadIntent(message) ); } diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index b00447a4..f468d9ae 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -18,9 +18,9 @@ import android.util.Pair; public class UIHelper { private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; + | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME - | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE; + | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE; public static String readableTimeDifference(Context context, long time) { return readableTimeDifference(context, time, false); @@ -72,8 +72,8 @@ public class UIHelper { cal1.setTime(a); cal2.setTime(b); return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) - && cal1.get(Calendar.DAY_OF_YEAR) == cal2 - .get(Calendar.DAY_OF_YEAR); + && cal1.get(Calendar.DAY_OF_YEAR) == cal2 + .get(Calendar.DAY_OF_YEAR); } public static String lastseen(Context context, long time) { @@ -106,8 +106,8 @@ public class UIHelper { return 0xFF202020; } int colors[] = {0xFFe91e63, 0xFF9c27b0, 0xFF673ab7, 0xFF3f51b5, - 0xFF5677fc, 0xFF03a9f4, 0xFF00bcd4, 0xFF009688, 0xFFff5722, - 0xFF795548, 0xFF607d8b}; + 0xFF5677fc, 0xFF03a9f4, 0xFF00bcd4, 0xFF009688, 0xFFff5722, + 0xFF795548, 0xFF607d8b}; return colors[(int) ((name.hashCode() & 0xffffffffl) % colors.length)]; } @@ -120,8 +120,8 @@ public class UIHelper { case Downloadable.STATUS_DOWNLOADING: if (message.getType() == Message.TYPE_FILE) { return new Pair<>(context.getString(R.string.receiving_x_file, - getFileDescriptionString(context,message), - d.getProgress()),true); + getFileDescriptionString(context,message), + d.getProgress()),true); } else { return new Pair<>(context.getString(R.string.receiving_image, d.getProgress()),true); } @@ -129,7 +129,7 @@ public class UIHelper { case Downloadable.STATUS_OFFER_CHECK_FILESIZE: if (message.getType() == Message.TYPE_FILE) { return new Pair<>(context.getString(R.string.x_file_offered_for_download, - getFileDescriptionString(context,message)),true); + getFileDescriptionString(context,message)),true); } else { return new Pair<>(context.getString(R.string.image_offered_for_download),true); } @@ -153,7 +153,7 @@ public class UIHelper { } else if (message.getType() == Message.TYPE_FILE) { if (message.getStatus() == Message.STATUS_RECEIVED) { return new Pair<>(context.getString(R.string.received_x_file, - getFileDescriptionString(context, message)), true); + getFileDescriptionString(context, message)), true); } else { return new Pair<>(getFileDescriptionString(context,message),true); } @@ -183,6 +183,8 @@ public class UIHelper { return context.getString(R.string.audio); } else if(mime.startsWith("video/")) { return context.getString(R.string.video); + } else if (mime.startsWith("image/")) { + return context.getString(R.string.image); } else if (mime.contains("pdf")) { return context.getString(R.string.pdf_document) ; } else { -- cgit v1.2.3 From 83c806a774a09d54a0ef84ec5400c348256ff03b Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Sat, 17 Jan 2015 20:53:25 -0500 Subject: Fix string substitutions with unknown filetypes --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index f468d9ae..86bc3f38 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -175,10 +175,10 @@ public class UIHelper { try { mime = URLConnection.guessContentTypeFromName(path); } catch (final StringIndexOutOfBoundsException ignored) { - return ""; + return context.getString(R.string.file); } if (mime == null) { - return ""; + return context.getString(R.string.file); } else if (mime.startsWith("audio/")) { return context.getString(R.string.audio); } else if(mime.startsWith("video/")) { -- cgit v1.2.3 From 99989cd1d52bda9016d21df8f1d876c569498135 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Sat, 17 Jan 2015 23:41:57 -0500 Subject: Add some Android 21 notification features --- .../java/eu/siacs/conversations/services/NotificationService.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 8c3aff16..4355dba0 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -203,6 +203,10 @@ public class NotificationService { mBuilder.setSound(Uri.parse(ringtone)); } } + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setCategory(Notification.CATEGORY_MESSAGE); + mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.primary)); + } mBuilder.setSmallIcon(R.drawable.ic_notification); mBuilder.setDeleteIntent(createDeleteIntent()); mBuilder.setLights(0xffffffff, 2000, 4000); -- cgit v1.2.3 From ae16439bd6f0fb87848ee56795af75d3cce6a693 Mon Sep 17 00:00:00 2001 From: Christian S Date: Sun, 18 Jan 2015 11:12:38 +0100 Subject: Added new file type names for file transfers - apk - vcard --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index f468d9ae..f749a851 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -187,6 +187,10 @@ public class UIHelper { return context.getString(R.string.image); } else if (mime.contains("pdf")) { return context.getString(R.string.pdf_document) ; + } else if (mime.contains("application/vnd.android.package-archive")) { + return context.getString(R.string.apk) ; + } else if (mime.contains("vcard")) { + return context.getString(R.string.vcard) ; } else { return mime; } -- cgit v1.2.3 From d58fadd05f303c594c05fca8307e0ac38425b817 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 18 Jan 2015 13:00:57 +0100 Subject: use same helper methods for images and files --- .../conversations/ui/adapter/MessageAdapter.java | 41 +++++----------------- .../eu/siacs/conversations/utils/UIHelper.java | 29 +++++---------- 2 files changed, 16 insertions(+), 54 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index a1361fa1..1d8b2e44 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -487,39 +487,14 @@ public class MessageAdapter extends ArrayAdapter { } }); - if (message.getDownloadable() != null && message.getDownloadable().getStatus() != Downloadable.STATUS_UPLOADING) { - Downloadable d = message.getDownloadable(); - if (d.getStatus() == Downloadable.STATUS_DOWNLOADING) { - if (message.getType() == Message.TYPE_FILE) { - displayInfoMessage(viewHolder,activity.getString(R.string.receiving_x_file, - UIHelper.getFileDescriptionString(activity,message), - d.getProgress())); - } else { - displayInfoMessage(viewHolder,activity.getString(R.string.receiving_image,d.getProgress())); - } - } else if (d.getStatus() == Downloadable.STATUS_CHECKING) { - displayInfoMessage(viewHolder,activity.getString(R.string.checking_image)); - } else if (d.getStatus() == Downloadable.STATUS_DELETED) { - if (message.getType() == Message.TYPE_FILE) { - displayInfoMessage(viewHolder, activity.getString(R.string.file_deleted)); - } else { - displayInfoMessage(viewHolder, activity.getString(R.string.image_file_deleted)); - } - } else if (d.getStatus() == Downloadable.STATUS_OFFER) { - if (message.getType() == Message.TYPE_FILE) { - displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, - UIHelper.getFileDescriptionString(activity,message))); - } else { - displayDownloadableMessage(viewHolder, message,activity.getString(R.string.download_image)); - } - } else if (d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { - displayDownloadableMessage(viewHolder, message,activity.getString(R.string.check_image_filesize)); - } else if (d.getStatus() == Downloadable.STATUS_FAILED) { - if (message.getType() == Message.TYPE_FILE) { - displayInfoMessage(viewHolder, activity.getString(R.string.file_transmission_failed)); - } else { - displayInfoMessage(viewHolder, activity.getString(R.string.image_transmission_failed)); - } + final Downloadable downloadable = message.getDownloadable(); + if (downloadable != null && downloadable.getStatus() != Downloadable.STATUS_UPLOADING) { + if (downloadable.getStatus() == Downloadable.STATUS_OFFER) { + displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message))); + } else if (downloadable.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) { + displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_image_filesize)); + } else { + displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first); } } else if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { displayImageMessage(viewHolder, message); diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index b2ca8e4a..d1a4b4a9 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -118,33 +118,17 @@ public class UIHelper { case Downloadable.STATUS_CHECKING: return new Pair<>(context.getString(R.string.checking_image),true); case Downloadable.STATUS_DOWNLOADING: - if (message.getType() == Message.TYPE_FILE) { - return new Pair<>(context.getString(R.string.receiving_x_file, + return new Pair<>(context.getString(R.string.receiving_x_file, getFileDescriptionString(context,message), d.getProgress()),true); - } else { - return new Pair<>(context.getString(R.string.receiving_image, d.getProgress()),true); - } case Downloadable.STATUS_OFFER: case Downloadable.STATUS_OFFER_CHECK_FILESIZE: - if (message.getType() == Message.TYPE_FILE) { - return new Pair<>(context.getString(R.string.x_file_offered_for_download, + return new Pair<>(context.getString(R.string.x_file_offered_for_download, getFileDescriptionString(context,message)),true); - } else { - return new Pair<>(context.getString(R.string.image_offered_for_download),true); - } case Downloadable.STATUS_DELETED: - if (message.getType() == Message.TYPE_FILE) { - return new Pair<>(context.getString(R.string.file_deleted),true); - } else { - return new Pair<>(context.getString(R.string.image_file_deleted),true); - } + return new Pair<>(context.getString(R.string.file_deleted),true); case Downloadable.STATUS_FAILED: - if (message.getType() == Message.TYPE_FILE) { - return new Pair<>(context.getString(R.string.file_transmission_failed),true); - } else { - return new Pair<>(context.getString(R.string.image_transmission_failed),true); - } + return new Pair<>(context.getString(R.string.file_transmission_failed),true); default: return new Pair<>("",false); } @@ -167,13 +151,16 @@ public class UIHelper { } public static String getFileDescriptionString(final Context context, final Message message) { + if (message.getType() == Message.TYPE_IMAGE) { + return context.getString(R.string.image); + } final String path = message.getRelativeFilePath(); if (path == null) { return ""; } final String mime; try { - mime = URLConnection.guessContentTypeFromName(path); + mime = URLConnection.guessContentTypeFromName(path.replace("#","")); } catch (final StringIndexOutOfBoundsException ignored) { return context.getString(R.string.file); } -- cgit v1.2.3 From 6756386eee42e0bd7995c82be75a2179f8f61099 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 18 Jan 2015 13:44:18 +0100 Subject: explain read marker --- .../conversations/ui/adapter/MessageAdapter.java | 26 +++++----------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 1d8b2e44..1d4e2493 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -35,7 +35,6 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message.ImageParams; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.utils.UIHelper; -import eu.siacs.conversations.xmpp.jid.Jid; public class MessageAdapter extends ArrayAdapter { @@ -388,10 +387,9 @@ public class MessageAdapter extends ArrayAdapter { .findViewById(R.id.indicator_received); break; case STATUS: - view = activity.getLayoutInflater().inflate( - R.layout.message_status, parent, false); - viewHolder.contact_picture = (ImageView) view - .findViewById(R.id.message_photo); + view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false); + viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo); + viewHolder.status_message = (TextView) view.findViewById(R.id.status_message); break; default: viewHolder = null; @@ -411,20 +409,8 @@ public class MessageAdapter extends ArrayAdapter { .avatarService().get(conversation.getContact(), activity.getPixel(32))); viewHolder.contact_picture.setAlpha(0.5f); - viewHolder.contact_picture - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - String name = conversation.getName(); - String read = getContext() - .getString( - R.string.contact_has_read_up_to_this_point, - name); - Toast.makeText(getContext(), read, - Toast.LENGTH_SHORT).show(); - } - }); + viewHolder.status_message.setText( + activity.getString(R.string.contact_has_read_up_to_this_point, conversation.getName())); } return view; @@ -577,6 +563,6 @@ public class MessageAdapter extends ArrayAdapter { protected TextView time; protected TextView messageBody; protected ImageView contact_picture; - + protected TextView status_message; } } -- cgit v1.2.3 From 149a6716b8a5d4afe61e8a9c257a0d551a6d0e3d Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 18 Jan 2015 20:26:22 +0100 Subject: proper desc for offering and sending images in conversations overview --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index d1a4b4a9..32227ff8 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -129,6 +129,14 @@ public class UIHelper { return new Pair<>(context.getString(R.string.file_deleted),true); case Downloadable.STATUS_FAILED: return new Pair<>(context.getString(R.string.file_transmission_failed),true); + case Downloadable.STATUS_UPLOADING: + if (message.getStatus() == Message.STATUS_OFFERED) { + return new Pair<>(context.getString(R.string.offering_x_file, + getFileDescriptionString(context, message)), true); + } else { + return new Pair<>(context.getString(R.string.sending_x_file, + getFileDescriptionString(context, message)), true); + } default: return new Pair<>("",false); } -- cgit v1.2.3 From fc2e458053fa42ef792773a4a6b1a86ef4d6be01 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 18 Jan 2015 20:27:16 +0100 Subject: fixed bug when sharing files from google drive --- .../eu/siacs/conversations/ui/ShareWithActivity.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index a3904d21..6be238dc 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -135,14 +135,9 @@ public class ShareWithActivity extends XmppActivity { public void onStart() { final String type = getIntent().getType(); final Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); - if (type != null && uri != null && !type.startsWith("text/")) { + if (type != null && uri != null && !type.equalsIgnoreCase("text/plain")) { this.share.uri = uri; - try { - String guess = URLConnection.guessContentTypeFromName(uri.toString()); - this.share.image = type.startsWith("image/") || (guess != null && guess.startsWith("image/")); - } catch (final StringIndexOutOfBoundsException ignored) { - this.share.image = false; - } + this.share.image = type.startsWith("image/") || isImage(uri); } else { this.share.text = getIntent().getStringExtra(Intent.EXTRA_TEXT); } @@ -152,6 +147,15 @@ public class ShareWithActivity extends XmppActivity { super.onStart(); } + protected boolean isImage(Uri uri) { + try { + String guess = URLConnection.guessContentTypeFromName(uri.toString()); + return (guess != null && guess.startsWith("image/")); + } catch (final StringIndexOutOfBoundsException ignored) { + return false; + } + } + @Override void onBackendConnected() { if (xmppConnectionServiceBound && share != null -- cgit v1.2.3 From 7af588c8b3965c99a672727c7232cbdb7aa08330 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 19 Jan 2015 11:17:27 +0100 Subject: account for rounding errors when rescheduling wake up --- .../services/XmppConnectionService.java | 303 +++++++++++---------- 1 file changed, 153 insertions(+), 150 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 521991ba..abe93183 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -100,9 +100,8 @@ import eu.siacs.conversations.xmpp.stanzas.PresencePacket; public class XmppConnectionService extends Service implements OnPhoneContactsLoadedListener { 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 static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; private ContentObserver contactObserver = new ContentObserver(null) { @Override public void onChange(boolean selfChange) { @@ -114,6 +113,56 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } }; private final IBinder mBinder = new XmppConnectionBinder(); + private final List conversations = new CopyOnWriteArrayList<>(); + private final FileObserver fileObserver = new FileObserver( + FileBackend.getConversationsImageDirectory()) { + + @Override + public void onEvent(int event, String path) { + if (event == FileObserver.DELETE) { + markFileDeleted(path.split("\\.")[0]); + } + } + }; + private final OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() { + + @Override + public void onJinglePacketReceived(Account account, JinglePacket packet) { + mJingleConnectionManager.deliverPacket(account, packet); + } + }; + private final OnBindListener mOnBindListener = new OnBindListener() { + + @Override + public void onBind(final Account account) { + account.getRoster().clearPresences(); + account.pendingConferenceJoins.clear(); + account.pendingConferenceLeaves.clear(); + fetchRosterFromServer(account); + fetchBookmarks(account); + sendPresencePacket(account, mPresenceGenerator.sendPresence(account)); + connectMultiModeConversations(account); + updateConversationUi(); + } + }; + private final OnMessageAcknowledged mOnMessageAcknowledgedListener = new OnMessageAcknowledged() { + + @Override + public void onMessageAcknowledged(Account account, String uuid) { + for (final Conversation conversation : getConversations()) { + if (conversation.getAccount() == account) { + Message message = conversation.findUnsentMessageWithUuid(uuid); + if (message != null) { + markMessage(message, Message.STATUS_SEND); + if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { + databaseBackend.updateConversation(conversation); + } + } + } + } + } + }; + private final IqGenerator mIqGenerator = new IqGenerator(this); public DatabaseBackend databaseBackend; public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() { @@ -142,7 +191,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private MessageGenerator mMessageGenerator = new MessageGenerator(this); private PresenceGenerator mPresenceGenerator = new PresenceGenerator(this); private List accounts; - private final List conversations = new CopyOnWriteArrayList<>(); private JingleConnectionManager mJingleConnectionManager = new JingleConnectionManager( this); private HttpConnectionManager mHttpConnectionManager = new HttpConnectionManager( @@ -212,7 +260,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa getNotificationService().updateErrorNotification(); } }; - private int accountChangedListenerCount = 0; private OnRosterUpdate mOnRosterUpdate = null; private OnUpdateBlocklist mOnUpdateBlocklist = null; @@ -221,62 +268,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private OnMucRosterUpdate mOnMucRosterUpdate = null; private int mucRosterChangedListenerCount = 0; private SecureRandom mRandom; - private final FileObserver fileObserver = new FileObserver( - FileBackend.getConversationsImageDirectory()) { - - @Override - public void onEvent(int event, String path) { - if (event == FileObserver.DELETE) { - markFileDeleted(path.split("\\.")[0]); - } - } - }; - private final OnJinglePacketReceived jingleListener = new OnJinglePacketReceived() { - - @Override - public void onJinglePacketReceived(Account account, JinglePacket packet) { - mJingleConnectionManager.deliverPacket(account, packet); - } - }; - private OpenPgpServiceConnection pgpServiceConnection; private PgpEngine mPgpEngine = null; private WakeLock wakeLock; private PowerManager pm; - private final OnBindListener mOnBindListener = new OnBindListener() { - - @Override - public void onBind(final Account account) { - account.getRoster().clearPresences(); - account.pendingConferenceJoins.clear(); - account.pendingConferenceLeaves.clear(); - fetchRosterFromServer(account); - fetchBookmarks(account); - sendPresencePacket(account,mPresenceGenerator.sendPresence(account)); - connectMultiModeConversations(account); - updateConversationUi(); - } - }; - - private final OnMessageAcknowledged mOnMessageAcknowledgedListener = new OnMessageAcknowledged() { - - @Override - public void onMessageAcknowledged(Account account, String uuid) { - for (final Conversation conversation : getConversations()) { - if (conversation.getAccount() == account) { - Message message = conversation.findUnsentMessageWithUuid(uuid); - if (message != null) { - markMessage(message, Message.STATUS_SEND); - if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { - databaseBackend.updateConversation(conversation); - } - } - } - } - } - }; private LruCache mBitmapCache; - private final IqGenerator mIqGenerator = new IqGenerator(this); private Thread mPhoneContactMergerThread; public PgpEngine getPgpEngine() { @@ -548,7 +544,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } protected void scheduleWakeUpCall(int seconds, int requestCode) { - final long timeToWake = SystemClock.elapsedRealtime() + seconds * 1000; + final long timeToWake = SystemClock.elapsedRealtime() + (seconds + 1) * 1000; Context context = getApplicationContext(); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); @@ -958,11 +954,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }).start(); } - public interface OnMoreMessagesLoaded { - public void onMoreMessagesLoaded(int count,Conversation conversation); - public void informUser(int r); - } - public List getAccounts() { return this.accounts; } @@ -977,23 +968,23 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public Conversation find(final Iterable haystack, final Account account, final Jid jid) { - if (jid == null ) { + if (jid == null) { return null; } for (final Conversation conversation : haystack) { if ((account == null || conversation.getAccount() == account) && (conversation.getJid().toBareJid().equals(jid.toBareJid()))) { return conversation; - } + } } return null; } - public Conversation findOrCreateConversation(final Account account, final Jid jid,final boolean muc) { - return this.findOrCreateConversation(account,jid,muc,null); + public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc) { + return this.findOrCreateConversation(account, jid, muc, null); } - public Conversation findOrCreateConversation(final Account account, final Jid jid,final boolean muc, final MessageArchiveService.Query query) { + public Conversation findOrCreateConversation(final Account account, final Jid jid, final boolean muc, final MessageArchiveService.Query query) { synchronized (this.conversations) { Conversation conversation = find(account, jid); if (conversation != null) { @@ -1097,11 +1088,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } - public interface OnAccountPasswordChanged { - public void onPasswordChangeSucceeded(); - public void onPasswordChangeFailed(); - } - public void deleteAccount(final Account account) { synchronized (this.conversations) { for (final Conversation conversation : conversations) { @@ -1290,7 +1276,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa && (conversation.getAccount() == account)) { conversation.resetMucOptions(); joinMuc(conversation); - } + } } } @@ -1308,11 +1294,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa PresencePacket packet = new PresencePacket(); packet.setFrom(conversation.getAccount().getJid()); packet.setTo(joinJid); - Element x = packet.addChild("x","http://jabber.org/protocol/muc"); + Element x = packet.addChild("x", "http://jabber.org/protocol/muc"); if (conversation.getMucOptions().getPassword() != null) { x.addChild("password").setContent(conversation.getMucOptions().getPassword()); } - x.addChild("history").setAttribute("since",PresenceGenerator.getTimestamp(conversation.getLastMessageTransmitted())); + x.addChild("history").setAttribute("since", PresenceGenerator.getTimestamp(conversation.getLastMessageTransmitted())); String sig = account.getPgpSignature(); if (sig != null) { packet.addChild("status").setContent("online"); @@ -1417,7 +1403,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return server; } } - for(Account other : getAccounts()) { + for (Account other : getAccounts()) { if (other != account && other.getXmppConnection() != null) { server = other.getXmppConnection().getMucServer(); if (server != null) { @@ -1435,12 +1421,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa String server = findConferenceServer(account); if (server == null) { if (callback != null) { - callback.error(R.string.no_conference_server_found,null); + callback.error(R.string.no_conference_server_found, null); } return; } - String name = new BigInteger(75,getRNG()).toString(32); - Jid jid = Jid.fromParts(name,server,null); + String name = new BigInteger(75, getRNG()).toString(32); + Jid jid = Jid.fromParts(name, server, null); final Conversation conversation = findOrCreateConversation(account, jid, true); joinMuc(conversation); Bundle options = new Bundle(); @@ -1451,8 +1437,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa pushConferenceConfiguration(conversation, options, new OnConferenceOptionsPushed() { @Override public void onPushSucceeded() { - for(Jid invite : jids) { - invite(conversation,invite); + for (Jid invite : jids) { + invite(conversation, invite); } if (callback != null) { callback.success(conversation); @@ -1474,7 +1460,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } else { if (callback != null) { - callback.error(R.string.not_connected_try_again,null); + callback.error(R.string.not_connected_try_again, null); } } } @@ -1503,11 +1489,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } - public void pushConferenceConfiguration(final Conversation conversation,final Bundle options, final OnConferenceOptionsPushed callback) { + public void pushConferenceConfiguration(final Conversation conversation, final Bundle options, final OnConferenceOptionsPushed callback) { IqPacket request = new IqPacket(IqPacket.TYPE.GET); request.setTo(conversation.getJid().toBareJid()); request.query("http://jabber.org/protocol/muc#owner"); - sendIqPacket(conversation.getAccount(),request,new OnIqPacketReceived() { + sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() != IqPacket.TYPE.ERROR) { @@ -1552,7 +1538,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (!mucOptions.persistent() && self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) { Bundle options = new Bundle(); options.putString("muc#roomconfig_persistentroom", "1"); - this.pushConferenceConfiguration(conference,options,null); + this.pushConferenceConfiguration(conference, options, null); } } @@ -1573,7 +1559,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void changeAffiliationsInConference(final Conversation conference, MucOptions.Affiliation before, MucOptions.Affiliation after) { List jids = new ArrayList<>(); - for(MucOptions.User user : conference.getMucOptions().getUsers()) { + for (MucOptions.User user : conference.getMucOptions().getUsers()) { if (user.getAffiliation() == before) { jids.add(user.getJid()); } @@ -1582,14 +1568,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa sendIqPacket(conference.getAccount(), request, null); } - public interface OnAffiliationChanged { - public void onAffiliationChangedSuccessful(Jid jid); - public void onAffiliationChangeFailed(Jid jid, int resId); - } - public void changeRoleInConference(final Conversation conference, final String nick, MucOptions.Role role, final OnRoleChanged callback) { IqPacket request = this.mIqGenerator.changeRole(conference, nick, role.toString()); - Log.d(Config.LOGTAG,request.toString()); + Log.d(Config.LOGTAG, request.toString()); sendIqPacket(conference.getAccount(), request, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { @@ -1603,11 +1584,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } - public interface OnRoleChanged{ - public void onRoleChangedSuccessful(String nick); - public void onRoleChangeFailed(String nick, int resid); - } - public void disconnect(Account account, boolean force) { if ((account.getStatus() == Account.State.ONLINE) || (account.getStatus() == Account.State.DISABLED)) { @@ -1628,7 +1604,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } account.getXmppConnection().disconnect(force); - } + } } @Override @@ -1667,8 +1643,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.getJid() + "/" - + otrSession.getSessionID().getUserID()); + + conversation.getJid() + "/" + + otrSession.getSessionID().getUserID()); conversation.findUnsentMessagesWithOtrEncryption(new Conversation.OnMessageFound() { @Override @@ -1710,7 +1686,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa try { packet.setBody(otrSession .transformSending(CryptoHelper.FILETRANSFER - + CryptoHelper.bytesToHex(symmetricKey))); + + CryptoHelper.bytesToHex(symmetricKey))); sendMessagePacket(account, packet); conversation.setSymmetricKey(symmetricKey); return true; @@ -1728,8 +1704,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (account.getStatus() == Account.State.ONLINE) { final boolean ask = contact.getOption(Contact.Options.ASKING); final boolean sendUpdates = contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST) - && contact.getOption(Contact.Options.PREEMPTIVE_GRANT); + .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST) + && contact.getOption(Contact.Options.PREEMPTIVE_GRANT); final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); iq.query(Xmlns.ROSTER).addChild(contact.asElement()); account.getXmppConnection().sendIqPacket(iq, null); @@ -1745,12 +1721,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void publishAvatar(final Account account, - final Uri image, - final UiCallback callback) { + final Uri image, + final UiCallback callback) { final Bitmap.CompressFormat format = Config.AVATAR_FORMAT; final int size = Config.AVATAR_SIZE; final Avatar avatar = getFileBackend() - .getPepAvatar(image, size, format); + .getPepAvatar(image, size, format); if (avatar != null) { avatar.height = size; avatar.width = size; @@ -1772,12 +1748,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void onIqPacketReceived(Account account, IqPacket result) { if (result.getType() == IqPacket.TYPE.RESULT) { final IqPacket packet = XmppConnectionService.this.mIqGenerator - .publishAvatarMetadata(avatar); + .publishAvatarMetadata(avatar); sendIqPacket(account, packet, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, - IqPacket result) { + IqPacket result) { if (result.getType() == IqPacket.TYPE.RESULT) { if (account.setAvatar(avatar.getFilename())) { databaseBackend.updateAccount(account); @@ -1807,14 +1783,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void fetchAvatar(Account account, final Avatar avatar, - final UiCallback callback) { + final UiCallback callback) { IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar); sendIqPacket(account, packet, new OnIqPacketReceived() { @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) { @@ -1828,7 +1804,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(); @@ -1863,7 +1839,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public void checkForAvatar(Account account, - final UiCallback callback) { + final UiCallback callback) { IqPacket packet = this.mIqGenerator.retrieveAvatarMetaData(null); this.sendIqPacket(account, packet, new OnIqPacketReceived() { @@ -1929,7 +1905,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } Thread thread = new Thread(account.getXmppConnection()); thread.start(); - scheduleWakeUpCall(Config.CONNECT_TIMEOUT,account.getUuid().hashCode()); + scheduleWakeUpCall(Config.CONNECT_TIMEOUT, account.getUuid().hashCode()); } else { account.getRoster().clearPresences(); account.setXmppConnection(null); @@ -1958,7 +1934,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } public boolean markMessage(final Account account, final Jid recipient, final String uuid, - final int status) { + final int status) { if (uuid == null) { return false; } else { @@ -1966,20 +1942,20 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (conversation.getJid().equals(recipient) && conversation.getAccount().equals(account)) { return markMessage(conversation, uuid, status); - } + } } return false; } } public boolean markMessage(Conversation conversation, String uuid, - int status) { + int status) { if (uuid == null) { return false; } else { Message message = conversation.findSentMessageWithUuid(uuid); - if (message!=null) { - markMessage(message,status); + if (message != null) { + markMessage(message, status); return true; } else { return false; @@ -1990,9 +1966,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void markMessage(Message message, int status) { if (status == Message.STATUS_SEND_FAILED && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message - .getStatus() == Message.STATUS_SEND_DISPLAYED)) { + .getStatus() == Message.STATUS_SEND_DISPLAYED)) { return; - } + } message.setStatus(status); databaseBackend.updateMessage(message); updateConversationUi(); @@ -2000,7 +1976,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public SharedPreferences getPreferences() { return PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); + .getDefaultSharedPreferences(getApplicationContext()); } public boolean forceEncryption() { @@ -2076,11 +2052,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa final Message markable = conversation.getLatestMarkableMessage(); this.markRead(conversation); if (confirmMessages() && markable != null && markable.getRemoteMsgId() != null) { - Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid()+ ": sending read marker to " + markable.getCounterpart().toString()); + Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": sending read marker to " + markable.getCounterpart().toString()); Account account = conversation.getAccount(); final Jid to = markable.getCounterpart(); MessagePacket packet = mMessageGenerator.confirm(account, to, markable.getRemoteMsgId()); - this.sendMessagePacket(conversation.getAccount(),packet); + this.sendMessagePacket(conversation.getAccount(), packet); } updateConversationUi(); } @@ -2176,7 +2152,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa return this.mIqGenerator; } - public IqParser getIqParser() { return this.mIqParser; } + public IqParser getIqParser() { + return this.mIqParser; + } public JingleConnectionManager getJingleConnectionManager() { return this.mJingleConnectionManager; @@ -2235,33 +2213,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }).start(); } - public interface OnConversationUpdate { - public void onConversationUpdate(); - } - - public interface OnAccountUpdate { - public void onAccountUpdate(); - } - - public interface OnRosterUpdate { - public void onRosterUpdate(); - } - - public interface OnMucRosterUpdate { - public void onMucRosterUpdate(); - } - - public interface OnConferenceOptionsPushed { - public void onPushSucceeded(); - public void onPushFailed(); - } - - public class XmppConnectionBinder extends Binder { - public XmppConnectionService getService() { - return XmppConnectionService.this; - } - } - public void sendBlockRequest(final Blockable blockable) { if (blockable != null && blockable.getBlockedJid() != null) { final Jid jid = blockable.getBlockedJid(); @@ -2292,4 +2243,56 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa }); } } + + public interface OnMoreMessagesLoaded { + public void onMoreMessagesLoaded(int count, Conversation conversation); + + public void informUser(int r); + } + + public interface OnAccountPasswordChanged { + public void onPasswordChangeSucceeded(); + + public void onPasswordChangeFailed(); + } + + public interface OnAffiliationChanged { + public void onAffiliationChangedSuccessful(Jid jid); + + public void onAffiliationChangeFailed(Jid jid, int resId); + } + + public interface OnRoleChanged { + public void onRoleChangedSuccessful(String nick); + + public void onRoleChangeFailed(String nick, int resid); + } + + public interface OnConversationUpdate { + public void onConversationUpdate(); + } + + public interface OnAccountUpdate { + public void onAccountUpdate(); + } + + public interface OnRosterUpdate { + public void onRosterUpdate(); + } + + public interface OnMucRosterUpdate { + public void onMucRosterUpdate(); + } + + public interface OnConferenceOptionsPushed { + public void onPushSucceeded(); + + public void onPushFailed(); + } + + public class XmppConnectionBinder extends Binder { + public XmppConnectionService getService() { + return XmppConnectionService.this; + } + } } -- cgit v1.2.3 From 100ba6e7e775c4253a0ed3b58ff26aa7431e5ba2 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 19 Jan 2015 11:23:05 +0100 Subject: check for deleted files when loading more messages from history --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index abe93183..dc292d5b 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -940,6 +940,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa List messages = databaseBackend.getMessages(conversation, 50,timestamp); if (messages.size() > 0) { conversation.addAll(0, messages); + checkDeletedFiles(conversation); callback.onMoreMessagesLoaded(messages.size(), conversation); } else if (conversation.hasMessagesLeftOnServer() && account.isOnlineAndConnected() @@ -949,7 +950,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa query.setCallback(callback); } callback.informUser(R.string.fetching_history_from_server); - } + } } }).start(); } @@ -1028,6 +1029,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } } + checkDeletedFiles(conversation); this.conversations.add(conversation); updateConversationUi(); return conversation; -- cgit v1.2.3 From e5dffcfb0751ceb7acc5a3f1840fde34fa1d5703 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 19 Jan 2015 11:32:27 +0100 Subject: added changelog for 1.0 --- src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 870ee757..501cba91 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -23,7 +23,7 @@ public abstract class AbstractGenerator { "http://jabber.org/protocol/disco#info", "urn:xmpp:avatar:metadata+notify", "urn:xmpp:ping"}; - public final String IDENTITY_NAME = "Conversations 0.10"; + public final String IDENTITY_NAME = "Conversations 1.0-beta"; public final String IDENTITY_TYPE = "phone"; private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); -- cgit v1.2.3 From 4cbf8120f57670086c5f706d836e92e62c876446 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 19 Jan 2015 12:14:30 +0100 Subject: fixed legacy translation of image received --- .../java/eu/siacs/conversations/services/NotificationService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 4355dba0..4f502102 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -296,7 +296,9 @@ public class NotificationService { bigPictureStyle.setSummaryText(getMergedBodies(tmp)); builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService,tmp.get(0)).first); } else { - builder.setContentText(mXmppConnectionService.getString(R.string.image_file)); + builder.setContentText(mXmppConnectionService.getString( + R.string.received_x_file, + UIHelper.getFileDescriptionString(mXmppConnectionService,message))); } builder.setStyle(bigPictureStyle); } catch (final FileNotFoundException e) { -- cgit v1.2.3 From 1e607d7b1b0accf03d0e170fe67d418dac7c2114 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 19 Jan 2015 12:15:27 +0100 Subject: don't trim bodies --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index e8e579ab..c25b300b 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -371,7 +371,7 @@ public class Message extends AbstractEntity { if (this.mergeable(next)) { return getBody() + '\n' + next.getMergedBody(); } - return body.trim(); + return getBody(); } public boolean hasMeCommand() { -- cgit v1.2.3 From 503237087ffc5585876dfdb96ef167960bef0f15 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Sat, 17 Jan 2015 13:40:15 -0500 Subject: Remove legacy SSL support --- .../siacs/conversations/xmpp/XmppConnection.java | 26 +++++++++------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 6424b1d5..c16ac32b 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -507,23 +507,19 @@ public class XmppConnection implements Runnable { } final String[] supportProtocols; - if (enableLegacySSL()) { - supportProtocols = sslSocket.getSupportedProtocols(); - } else { - final Collection supportedProtocols = new LinkedList<>( - Arrays.asList(sslSocket.getSupportedProtocols())); - supportedProtocols.remove("SSLv3"); - supportProtocols = new String[supportedProtocols.size()]; - supportedProtocols.toArray(supportProtocols); - - final String[] cipherSuites = CryptoHelper.getSupportedCipherSuites( - sslSocket.getSupportedCipherSuites()); - if (cipherSuites.length > 0) { - sslSocket.setEnabledCipherSuites(cipherSuites); - } - } + final Collection supportedProtocols = new LinkedList<>( + Arrays.asList(sslSocket.getSupportedProtocols())); + supportedProtocols.remove("SSLv3"); + supportProtocols = supportedProtocols.toArray(new String[supportedProtocols.size()]); + sslSocket.setEnabledProtocols(supportProtocols); + final String[] cipherSuites = CryptoHelper.getSupportedCipherSuites( + sslSocket.getSupportedCipherSuites()); + if (cipherSuites.length > 0) { + sslSocket.setEnabledCipherSuites(cipherSuites); + } + if (!verifier.verify(account.getServer().getDomainpart(),sslSocket.getSession())) { Log.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed"); disconnect(true); -- cgit v1.2.3 From fa7d748c3f8ec08ec161e6fac48c88279c655b39 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 20 Jan 2015 18:01:39 +0100 Subject: otr4j: update to 0.22 --- src/main/java/eu/siacs/conversations/crypto/OtrEngine.java | 6 ++++++ .../java/eu/siacs/conversations/generator/MessageGenerator.java | 2 +- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java index 7f7b350c..d5c45465 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java @@ -33,6 +33,7 @@ import net.java.otr4j.crypto.OtrCryptoEngineImpl; import net.java.otr4j.crypto.OtrCryptoException; import net.java.otr4j.session.InstanceTag; import net.java.otr4j.session.SessionID; +import net.java.otr4j.session.FragmenterInstructions; public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost { @@ -269,4 +270,9 @@ public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost { } } + @Override + public FragmenterInstructions getFragmenterInstructions(SessionID sessionID) { + return null; + } + } diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 8e99888b..2ee636b5 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -68,7 +68,7 @@ public class MessageGenerator extends AbstractGenerator { packet.addChild("private", "urn:xmpp:carbons:2"); packet.addChild("no-copy", "urn:xmpp:hints"); try { - packet.setBody(otrSession.transformSending(message.getBody())); + packet.setBody(otrSession.transformSending(message.getBody())[0]); return packet; } catch (OtrException e) { return null; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index dc292d5b..8b225228 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1688,7 +1688,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa try { packet.setBody(otrSession .transformSending(CryptoHelper.FILETRANSFER - + CryptoHelper.bytesToHex(symmetricKey))); + + CryptoHelper.bytesToHex(symmetricKey))[0]); sendMessagePacket(account, packet); conversation.setSymmetricKey(symmetricKey); return true; -- cgit v1.2.3 From 04f46805823878924335d40268d69544af6f47bf Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 20 Jan 2015 22:53:45 +0100 Subject: fixed up button on v21 devices --- src/main/java/eu/siacs/conversations/ui/XmppActivity.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 0deeacf0..9a4f9c7f 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -2,6 +2,7 @@ package eu.siacs.conversations.ui; import android.annotation.SuppressLint; import android.annotation.TargetApi; +import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; @@ -300,12 +301,15 @@ public abstract class XmppActivity extends Activity { mColorOrange = getResources().getColor(R.color.orange); mColorGreen = getResources().getColor(R.color.green); mPrimaryColor = getResources().getColor(R.color.primary); - mSecondaryBackgroundColor = getResources().getColor( - R.color.secondarybackground); + mSecondaryBackgroundColor = getResources().getColor(R.color.secondarybackground); this.mTheme = findTheme(); setTheme(this.mTheme); this.mUsingEnterKey = usingEnterKey(); mUseSubject = getPreferences().getBoolean("use_subject", true); + final ActionBar ab = getActionBar(); + if (ab!=null) { + ab.setDisplayHomeAsUpEnabled(true); + } } protected boolean usingEnterKey() { -- cgit v1.2.3 From 6dc53c2b3505adbe8e0c7b7991c0df4716b9b834 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 20 Jan 2015 22:54:26 +0100 Subject: fixed missing image preview --- .../java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 37cdf223..38c321d0 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -72,7 +72,7 @@ public class ConversationAdapter extends ArrayAdapter { if (message.getImageParams().width > 0 && (message.getDownloadable() == null - || message.getDownloadable().getStatus() == Downloadable.STATUS_DELETED)) { + || message.getDownloadable().getStatus() != Downloadable.STATUS_DELETED)) { mLastMessage.setVisibility(View.GONE); imagePreview.setVisibility(View.VISIBLE); activity.loadBitmap(message, imagePreview); -- cgit v1.2.3 From 7839438f513c101f831ec47b3d0224df07835e51 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 20 Jan 2015 22:54:58 +0100 Subject: changed message duplicate finder --- .../java/eu/siacs/conversations/entities/Message.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index c25b300b..55a1d2ce 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -311,12 +311,17 @@ public class Message extends AbstractEntity { public boolean equals(Message message) { if (this.serverMsgId != null && message.getServerMsgId() != null) { return this.serverMsgId.equals(message.getServerMsgId()); + } else if (this.body == null || this.counterpart == null) { + return false; + } else if (message.getRemoteMsgId() != null) { + return (message.getRemoteMsgId().equals(this.remoteMsgId) || message.getRemoteMsgId().equals(this.uuid)) + && this.counterpart.equals(message.getCounterpart()) + && this.body.equals(message.getBody()); } 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()); + return this.remoteMsgId == null + && this.counterpart.equals(message.getCounterpart()) + && this.body.equals(message.getBody()) + && Math.abs(this.getTimeSent() - message.getTimeSent()) < Config.PING_TIMEOUT * 500; } } -- cgit v1.2.3 From e42e0f88e131e904d248583156dd09aebb8c24c6 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 20 Jan 2015 18:24:48 -0500 Subject: Add color / category to foreground notification --- .../conversations/services/NotificationService.java | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 4f502102..894af421 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -118,7 +118,7 @@ public class NotificationService { .getSystemService(Context.POWER_SERVICE); final boolean isScreenOn; - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { isScreenOn = pm.isScreenOn(); } else { isScreenOn = pm.isInteractive(); @@ -134,10 +134,10 @@ public class NotificationService { final boolean isScreenOn = isInteractive(); - if (this.mIsInForeground && isScreenOn - && this.mOpenConversation == message.getConversation()) { + if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) { return; - } + } + synchronized (notifications) { final String conversationUuid = message.getConversationUuid(); if (notifications.containsKey(conversationUuid)) { @@ -156,7 +156,6 @@ public class NotificationService { notifyPebble(message); } } - } public void clear() { @@ -173,6 +172,10 @@ public class NotificationService { } } + private void setNotificationColor(final Builder mBuilder) { + mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.primary)); + } + private void updateNotification(final boolean notify) { final NotificationManager notificationManager = (NotificationManager) mXmppConnectionService .getSystemService(Context.NOTIFICATION_SERVICE); @@ -205,8 +208,8 @@ public class NotificationService { } if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mBuilder.setCategory(Notification.CATEGORY_MESSAGE); - mBuilder.setColor(mXmppConnectionService.getResources().getColor(R.color.primary)); } + setNotificationColor(mBuilder); mBuilder.setSmallIcon(R.drawable.ic_notification); mBuilder.setDeleteIntent(createDeleteIntent()); mBuilder.setLights(0xffffffff, 2000, 4000); @@ -331,7 +334,7 @@ public class NotificationService { if ((message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) && message.getDownloadable() != null) { return message; - } + } } return null; } @@ -452,6 +455,10 @@ public class NotificationService { mBuilder.setContentIntent(createOpenConversationsIntent()); mBuilder.setWhen(0); mBuilder.setPriority(NotificationCompat.PRIORITY_MIN); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setCategory(Notification.CATEGORY_SERVICE); + } + setNotificationColor(mBuilder); return mBuilder.build(); } -- cgit v1.2.3 From 764ef3c8cdebe0bd189a7d7c1031bb25dafa5f15 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Thu, 15 Jan 2015 19:08:12 -0500 Subject: Add block/unblock to contact details menu See #889 --- .../siacs/conversations/ui/ContactDetailsActivity.java | 17 +++++++++++++++-- .../eu/siacs/conversations/ui/ConversationActivity.java | 4 ---- .../eu/siacs/conversations/ui/ConversationFragment.java | 3 --- 3 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 657ae75b..7a500c0b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -201,7 +201,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd @Override public boolean onOptionsItemSelected(final MenuItem menuItem) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); + final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setNegativeButton(getString(R.string.cancel), null); switch (menuItem.getItemId()) { case android.R.id.home: @@ -237,13 +237,25 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd startActivity(intent); } break; + case R.id.action_block: + BlockContactDialog.show(this, xmppConnectionService, contact); + break; + case R.id.action_unblock: + BlockContactDialog.show(this, xmppConnectionService, contact); + break; } return super.onOptionsItemSelected(menuItem); } @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.contact_details, menu); + if (this.contact.isBlocked()) { + menu.findItem(R.id.action_block).setVisible(false); + } else { + menu.findItem(R.id.action_unblock).setVisible(false); + } + return true; } @@ -424,6 +436,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd @Override public void run() { + invalidateOptionsMenu(); populateView(); } }); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 1356e616..ad9c13aa 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -1075,10 +1075,6 @@ public class ConversationActivity extends XmppActivity xmppConnectionService.sendUnblockRequest(conversation); } - public void blockConversation(final Blockable conversation) { - xmppConnectionService.sendBlockRequest(conversation); - } - public boolean enterIsSend() { return getPreferences().getBoolean("enter_is_send",false); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 0a38daee..e767fbea 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -974,7 +974,4 @@ public class ConversationFragment extends Fragment { this.mEditMessage.append(text); } - public void clearInputField() { - this.mEditMessage.setText(""); - } } -- cgit v1.2.3 From be9af442efeafcbfbb369cc904490703b590a69e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 21 Jan 2015 15:31:40 +0100 Subject: always allow access to contact details. provide add button in contact details --- .../conversations/ui/ContactDetailsActivity.java | 111 ++++++++++++++------- .../conversations/ui/ConversationActivity.java | 22 +--- .../conversations/ui/ConversationFragment.java | 9 +- .../eu/siacs/conversations/ui/XmppActivity.java | 12 ++- 4 files changed, 82 insertions(+), 72 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 7a500c0b..fda0c617 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -18,6 +18,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; +import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -40,6 +41,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; +import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -51,9 +53,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd @Override public void onClick(DialogInterface dialog, int which) { - ContactDetailsActivity.this.xmppConnectionService - .deleteContactOnServer(contact); - ContactDetailsActivity.this.finish(); + xmppConnectionService.deleteContactOnServer(contact); } }; private OnCheckedChangeListener mOnSendCheckedChange = new OnCheckedChangeListener() { @@ -102,6 +102,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd private TextView lastseen; private CheckBox send; private CheckBox receive; + private Button addContactButton; private QuickContactBadge badge; private LinearLayout keys; private LinearLayout tags; @@ -142,6 +143,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd @Override public void run() { + invalidateOptionsMenu(); populateView(); } }); @@ -153,6 +155,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd @Override public void run() { + invalidateOptionsMenu(); populateView(); } }); @@ -188,6 +191,13 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd send = (CheckBox) findViewById(R.id.details_send_presence); receive = (CheckBox) findViewById(R.id.details_receive_presence); badge = (QuickContactBadge) findViewById(R.id.details_contact_badge); + addContactButton = (Button) findViewById(R.id.add_contact_button); + addContactButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + showAddToRosterDialog(contact); + } + }); keys = (LinearLayout) findViewById(R.id.details_contact_keys); tags = (LinearLayout) findViewById(R.id.tags); if (getActionBar() != null) { @@ -250,58 +260,83 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd @Override public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.contact_details, menu); - if (this.contact.isBlocked()) { - menu.findItem(R.id.action_block).setVisible(false); + MenuItem block = menu.findItem(R.id.action_block); + MenuItem unblock = menu.findItem(R.id.action_unblock); + MenuItem edit = menu.findItem(R.id.action_edit_contact); + MenuItem delete = menu.findItem(R.id.action_delete_contact); + final XmppConnection connection = contact.getAccount().getXmppConnection(); + if (connection != null && connection.getFeatures().blocking()) { + if (this.contact.isBlocked()) { + menu.findItem(R.id.action_block).setVisible(false); + } else { + menu.findItem(R.id.action_unblock).setVisible(false); + } } else { menu.findItem(R.id.action_unblock).setVisible(false); + menu.findItem(R.id.action_block).setVisible(false); + } + if (!contact.showInRoster()) { + edit.setVisible(false); + delete.setVisible(false); } - return true; } private void populateView() { - send.setOnCheckedChangeListener(null); - receive.setOnCheckedChangeListener(null); setTitle(contact.getDisplayName()); - if (contact.getOption(Contact.Options.FROM)) { - send.setText(R.string.send_presence_updates); - send.setChecked(true); - } else if (contact - .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { - send.setChecked(false); - send.setText(R.string.send_presence_updates); - } else { - send.setText(R.string.preemptively_grant); - if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { + if (contact.showInRoster()) { + send.setVisibility(View.VISIBLE); + receive.setVisibility(View.VISIBLE); + addContactButton.setVisibility(View.GONE); + send.setOnCheckedChangeListener(null); + receive.setOnCheckedChangeListener(null); + + if (contact.getOption(Contact.Options.FROM)) { + send.setText(R.string.send_presence_updates); send.setChecked(true); - } else { + } else if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { send.setChecked(false); + send.setText(R.string.send_presence_updates); + } else { + send.setText(R.string.preemptively_grant); + if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { + send.setChecked(true); + } else { + send.setChecked(false); + } } - } - if (contact.getOption(Contact.Options.TO)) { - receive.setText(R.string.receive_presence_updates); - receive.setChecked(true); - } else { - receive.setText(R.string.ask_for_presence_updates); - if (contact.getOption(Contact.Options.ASKING)) { + if (contact.getOption(Contact.Options.TO)) { + receive.setText(R.string.receive_presence_updates); receive.setChecked(true); } else { - receive.setChecked(false); + receive.setText(R.string.ask_for_presence_updates); + if (contact.getOption(Contact.Options.ASKING)) { + receive.setChecked(true); + } else { + receive.setChecked(false); + } } - } - if (contact.getAccount().getStatus() == Account.State.ONLINE) { - receive.setEnabled(true); - send.setEnabled(true); + if (contact.getAccount().isOnlineAndConnected()) { + receive.setEnabled(true); + send.setEnabled(true); + } else { + receive.setEnabled(false); + send.setEnabled(false); + } + + send.setOnCheckedChangeListener(this.mOnSendCheckedChange); + receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange); } else { - receive.setEnabled(false); - send.setEnabled(false); + addContactButton.setVisibility(View.VISIBLE); + send.setVisibility(View.GONE); + receive.setVisibility(View.GONE); } - send.setOnCheckedChangeListener(this.mOnSendCheckedChange); - receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange); - - lastseen.setText(UIHelper.lastseen(getApplicationContext(), - contact.lastseen.time)); + if (contact.isBlocked() && !this.showDynamicTags) { + lastseen.setText(R.string.contact_blocked); + } else { + lastseen.setText(UIHelper.lastseen(getApplicationContext(), contact.lastseen.time)); + } if (contact.getPresences().size() > 1) { contactJidTv.setText(contact.getJid() + " (" diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index ad9c13aa..7aa48c0c 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -280,8 +280,6 @@ public class ConversationActivity extends XmppActivity 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()) { menuArchive.setVisible(false); @@ -293,8 +291,6 @@ public class ConversationActivity extends XmppActivity menuClearHistory.setVisible(false); menuMute.setVisible(false); menuUnmute.setVisible(false); - menuBlock.setVisible(false); - menuUnblock.setVisible(false); } else { menuAdd.setVisible(!isConversationsOverviewHideable()); if (this.getSelectedConversation() != null) { @@ -305,21 +301,10 @@ public class ConversationActivity extends XmppActivity if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) { menuContactDetails.setVisible(false); menuAttach.setVisible(false); - menuBlock.setVisible(false); - menuUnblock.setVisible(false); menuInviteContact.setVisible(getSelectedConversation().getMucOptions().canInvite()); } else { menuMucDetails.setVisible(false); - if (this.getSelectedConversation().isBlocked()) { - menuBlock.setVisible(false); - } else { - menuUnblock.setVisible(false); - } final Account account = this.getSelectedConversation().getAccount(); - if (!(account.isOnlineAndConnected() && account.getXmppConnection().getFeatures().blocking())) { - menuBlock.setVisible(false); - menuUnblock.setVisible(false); - } } if (this.getSelectedConversation().isMuted()) { menuMute.setVisible(false); @@ -445,12 +430,7 @@ public class ConversationActivity extends XmppActivity this.endConversation(getSelectedConversation()); break; case R.id.action_contact_details: - Contact contact = this.getSelectedConversation().getContact(); - if (contact.showInRoster()) { - switchToContactDetails(contact); - } else { - showAddToRosterDialog(getSelectedConversation()); - } + switchToContactDetails(getSelectedConversation().getContact()); break; case R.id.action_muc_details: Intent intent = new Intent(this, diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index e767fbea..c1e02400 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -362,14 +362,7 @@ public class ConversationFragment extends Fragment { } } } else { - Contact contact = message.getConversation() - .getContact(); - if (contact.showInRoster()) { - activity.switchToContactDetails(contact); - } else { - activity.showAddToRosterDialog(message - .getConversation()); - } + activity.switchToContactDetails(message.getContact()); } } else { Account account = message.getConversation().getAccount(); diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 9a4f9c7f..7fd1094c 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -438,9 +438,12 @@ public abstract class XmppActivity extends Activity { } protected void showAddToRosterDialog(final Conversation conversation) { - final Jid jid = conversation.getJid(); + showAddToRosterDialog(conversation.getContact()); + } + + protected void showAddToRosterDialog(final Contact contact) { AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(jid.toString()); + builder.setTitle(contact.getJid().toString()); builder.setMessage(getString(R.string.not_in_roster)); builder.setNegativeButton(getString(R.string.cancel), null); builder.setPositiveButton(getString(R.string.add_contact), @@ -448,11 +451,10 @@ public abstract class XmppActivity extends Activity { @Override public void onClick(DialogInterface dialog, int which) { - final Jid jid = conversation.getJid(); - Account account = conversation.getAccount(); + final Jid jid = contact.getJid(); + Account account = contact.getAccount(); Contact contact = account.getRoster().getContact(jid); xmppConnectionService.createContact(contact); - switchToContactDetails(contact); } }); builder.create().show(); -- cgit v1.2.3 From 00c74503abf508b92d8704ed503ab5480e7cf5a1 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 21 Jan 2015 16:18:38 +0100 Subject: deal with user entering full jids in join conference dialog --- .../java/eu/siacs/conversations/services/XmppConnectionService.java | 4 +++- .../java/eu/siacs/conversations/ui/StartConversationActivity.java | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 8b225228..d4f40fec 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -997,8 +997,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa conversation.setAccount(account); if (muc) { conversation.setMode(Conversation.MODE_MULTI); + conversation.setContactJid(jid); } else { conversation.setMode(Conversation.MODE_SINGLE); + conversation.setContactJid(jid.toBareJid()); } conversation.setNextEncryption(-1); conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE)); @@ -1015,7 +1017,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa conversation = new Conversation(conversationName, account, jid, Conversation.MODE_MULTI); } else { - conversation = new Conversation(conversationName, account, jid, + conversation = new Conversation(conversationName, account, jid.toBareJid(), Conversation.MODE_SINGLE); } this.databaseBackend.createConversation(conversation); diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index 209c0a7b..2154754b 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -448,8 +448,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU if (account.hasBookmarkFor(conferenceJid)) { jid.setError(getString(R.string.bookmark_already_exists)); } else { - final Bookmark bookmark = new Bookmark(account, - conferenceJid); + final Bookmark bookmark = new Bookmark(account,conferenceJid.toBareJid()); bookmark.setAutojoin(true); account.getBookmarks().add(bookmark); xmppConnectionService -- cgit v1.2.3 From 2dc69eea682997229b632f9009facd21b85b47f5 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 21 Jan 2015 16:18:57 +0100 Subject: fixed bug in find conference in database method --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 5fa61491..3ae3356d 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -220,10 +220,13 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Conversation findConversation(final Account account, final Jid contactJid) { SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { account.getUuid(), contactJid.toBareJid().toString() + "%" }; + String[] selectionArgs = { account.getUuid(), + contactJid.toBareJid().toString() + "/%", + contactJid.toBareJid().toString() + }; Cursor cursor = db.query(Conversation.TABLENAME, null, - Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID - + " like ?", selectionArgs, null, null, null); + Conversation.ACCOUNT + "=? AND (" + Conversation.CONTACTJID + + " like ? OR "+Conversation.CONTACTJID+"=?)", selectionArgs, null, null, null); if (cursor.getCount() == 0) return null; cursor.moveToFirst(); -- cgit v1.2.3 From 4e50098e319b9ccd65801acf1774bc6212b75621 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 21 Jan 2015 17:24:02 +0100 Subject: show checkbox to hide offline contacts --- .../ui/StartConversationActivity.java | 25 ++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index 2154754b..ff46ffd8 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -59,6 +59,7 @@ 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.entities.Presences; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.ListItemAdapter; @@ -114,6 +115,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU return true; } }; + private boolean mHideOfflineContacts = false; private TabListener mTabListener = new TabListener() { @Override @@ -159,7 +161,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } }; private MenuItem mMenuSearchView; - private String mInitialJid; private ListItemAdapter.OnTagClickedListener mOnTagClickedListener = new ListItemAdapter.OnTagClickedListener() { @Override public void onTagClicked(String tag) { @@ -171,6 +172,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } } }; + private String mInitialJid; @Override public void onRosterUpdate() { @@ -245,6 +247,8 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } }); + this.mHideOfflineContacts = getPreferences().getBoolean("hide_offline", false); + } protected void openConversationForContact(int position) { @@ -496,10 +500,10 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU public boolean onCreateOptionsMenu(Menu menu) { this.mOptionsMenu = menu; getMenuInflater().inflate(R.menu.start_conversation, menu); - MenuItem menuCreateContact = menu - .findItem(R.id.action_create_contact); - MenuItem menuCreateConference = menu - .findItem(R.id.action_join_conference); + MenuItem menuCreateContact = menu.findItem(R.id.action_create_contact); + MenuItem menuCreateConference = menu.findItem(R.id.action_join_conference); + MenuItem menuHideOffline = menu.findItem(R.id.action_hide_offline); + menuHideOffline.setChecked(this.mHideOfflineContacts); mMenuSearchView = menu.findItem(R.id.action_search); mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener); View mSearchView = mMenuSearchView.getActionView(); @@ -531,6 +535,13 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU case R.id.action_scan_qr_code: new IntentIntegrator(this).initiateScan(); return true; + case R.id.action_hide_offline: + mHideOfflineContacts = !item.isChecked(); + getPreferences().edit().putBoolean("hide_offline", mHideOfflineContacts).commit(); + if (mSearchEditText != null) { + filter(mSearchEditText.getText().toString()); + } + invalidateOptionsMenu(); } return super.onOptionsItemSelected(item); } @@ -667,7 +678,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU for (Account account : xmppConnectionService.getAccounts()) { if (account.getStatus() != Account.State.DISABLED) { for (Contact contact : account.getRoster().getContacts()) { - if (contact.showInRoster() && contact.match(needle)) { + if (contact.showInRoster() && contact.match(needle) + && (!this.mHideOfflineContacts + || contact.getPresences().getMostAvailableStatus() < Presences.OFFLINE)) { this.contacts.add(contact); } } -- cgit v1.2.3 From cbebd14dbddcd4d09a929b9efa707d82661cea98 Mon Sep 17 00:00:00 2001 From: Anders Sandblad Date: Fri, 23 Jan 2015 22:28:10 +0100 Subject: Changed online color to green instead of primary --- src/main/java/eu/siacs/conversations/ui/XmppActivity.java | 4 ++++ src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 7fd1094c..6399bcef 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -687,6 +687,10 @@ public abstract class XmppActivity extends Activity { return this.mPrimaryColor; } + public int getOnlineColor() { + return this.mColorGreen; + } + public int getSecondaryBackgroundColor() { return this.mSecondaryBackgroundColor; } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java index 139f3657..29730914 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -39,7 +39,7 @@ public class AccountAdapter extends ArrayAdapter { statusView.setText(getContext().getString(account.getStatus().getReadableId())); switch (account.getStatus()) { case ONLINE: - statusView.setTextColor(activity.getPrimaryColor()); + statusView.setTextColor(activity.getOnlineColor()); break; case DISABLED: case CONNECTING: -- cgit v1.2.3 From b9af38464e971e21a78f5c99d20d37fea73cc67e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 24 Jan 2015 00:22:51 +0100 Subject: fixed mam to work with muc --- .../siacs/conversations/generator/IqGenerator.java | 4 +++- .../siacs/conversations/parser/MessageParser.java | 2 +- .../services/MessageArchiveService.java | 21 +++++++++++++-------- .../services/XmppConnectionService.java | 5 ++++- 4 files changed, 21 insertions(+), 11 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index d0965821..290e0d60 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -107,7 +107,9 @@ public class IqGenerator extends AbstractGenerator { query.setAttribute("queryid",mam.getQueryId()); final Data data = new Data(); data.setFormType("urn:xmpp:mam:0"); - if (mam.getWith()!=null) { + if (mam.muc()) { + packet.setTo(mam.getWith()); + } else if (mam.getWith()!=null) { data.put("with", mam.getWith().toString()); } data.put("start",getTimestamp(mam.getStart())); diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index a15be622..4d102c3a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -8,7 +8,6 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; -import eu.siacs.conversations.http.HttpConnection; import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.XmppConnectionService; @@ -142,6 +141,7 @@ public class MessageParser extends AbstractParser implements Conversation conversation = mXmppConnectionService .findOrCreateConversation(account, from.toBareJid(), true); if (packet.hasChild("subject")) { + conversation.setHasMessagesLeftOnServer(true); conversation.getMucOptions().setSubject(packet.findChild("subject").getContent()); mXmppConnectionService.updateConversationUi(); return null; diff --git a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java index 5fb50f90..f97077c4 100644 --- a/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java +++ b/src/main/java/eu/siacs/conversations/services/MessageArchiveService.java @@ -225,7 +225,6 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { private int messageCount = 0; private long start; private long end; - private Jid with = null; private String queryId; private String reference = null; private Account account; @@ -237,7 +236,6 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { public Query(Conversation conversation, long start, long end) { this(conversation.getAccount(), start, end); this.conversation = conversation; - this.with = conversation.getJid().toBareJid(); } public Query(Conversation conversation, long start, long end, PagingOrder order) { @@ -256,7 +254,6 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { Query query = new Query(this.account,this.start,this.end); query.reference = reference; query.conversation = conversation; - query.with = with; query.totalCount = totalCount; query.callback = callback; return query; @@ -287,7 +284,11 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { } public Jid getWith() { - return with; + return conversation == null ? null : conversation.getJid().toBareJid(); + } + + public boolean muc() { + return conversation != null && conversation.getMode() == Conversation.MODE_MULTI; } public long getStart() { @@ -338,11 +339,15 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded { @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("with="); - if (this.with==null) { - builder.append("*"); + if (this.muc()) { + builder.append("to="+this.getWith().toString()); } else { - builder.append(with.toString()); + builder.append("with="); + if (this.getWith() == null) { + builder.append("*"); + } else { + builder.append(getWith().toString()); + } } builder.append(", start="); builder.append(AbstractGenerator.getTimestamp(this.start)); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index d4f40fec..ca80fa84 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1022,7 +1022,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } this.databaseBackend.createConversation(conversation); } - if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().mam()) { + if (account.getXmppConnection() != null + && account.getXmppConnection().getFeatures().mam() + && !muc) { if (query == null) { this.mMessageArchiveService.query(conversation); } else { @@ -1314,6 +1316,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa conversation.setContactJid(joinJid); databaseBackend.updateConversation(conversation); } + conversation.setHasMessagesLeftOnServer(false); } else { account.pendingConferenceJoins.add(conversation); } -- cgit v1.2.3 From 8041d23cb16c9c032bd9e0a8008be543520d6353 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Jan 2015 16:19:58 +0100 Subject: MessageParser: fix the regex for otr query messages. --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 4d102c3a..bfe081cd 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -75,7 +75,7 @@ public class MessageParser extends AbstractParser implements } updateLastseen(packet, account, true); String body = packet.getBody(); - if (body.matches("^\\?OTRv\\d*\\?")) { + if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) { conversation.endOtrIfNeeded(); } if (!conversation.hasValidOtrSession()) { -- cgit v1.2.3 From 78006478858fe074ecea4224063c0e6fc156ce4e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Jan 2015 13:07:31 +0100 Subject: otr: switch to the otr-state the partner alternate. should also fixed #877 --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 ++ src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 1 + 2 files changed, 3 insertions(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index bfe081cd..0f56f734 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -102,8 +102,10 @@ public class MessageParser extends AbstractParser implements body = otrSession.transformReceiving(body); SessionStatus after = otrSession.getSessionStatus(); if ((before != after) && (after == SessionStatus.ENCRYPTED)) { + conversation.setNextEncryption(Message.ENCRYPTION_OTR); mXmppConnectionService.onOtrSessionEstablished(conversation); } else if ((before != after) && (after == SessionStatus.FINISHED)) { + conversation.setNextEncryption(Message.ENCRYPTION_NONE); conversation.resetOtrSession(); mXmppConnectionService.updateConversationUi(); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index c1e02400..49b6d0fb 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -298,6 +298,7 @@ public class ConversationFragment extends Fragment { default: break; } + getActivity().invalidateOptionsMenu(); } } -- cgit v1.2.3 From 82a74fabc978d554384351aae13996059c827550 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 25 Jan 2015 16:32:59 +0100 Subject: set jingle file transfer to offer after iq offer has returned --- .../xmpp/jingle/JingleConnection.java | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 843cf1e6..2d949e21 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -36,8 +36,6 @@ public class JingleConnection implements Downloadable { protected static final int JINGLE_STATUS_INITIATED = 0; protected static final int JINGLE_STATUS_ACCEPTED = 1; - protected static final int JINGLE_STATUS_TERMINATED = 2; - protected static final int JINGLE_STATUS_CANCELED = 3; protected static final int JINGLE_STATUS_FINISHED = 4; protected static final int JINGLE_STATUS_TRANSMITTING = 5; protected static final int JINGLE_STATUS_FAILED = 99; @@ -360,7 +358,6 @@ public class JingleConnection implements Downloadable { } private void sendInitRequest() { - this.mXmppConnectionService.markMessage(this.message, Message.STATUS_OFFERED); JinglePacket packet = this.bootstrapPacket("session-initiate"); Content content = new Content(this.contentCreator, this.contentName); if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { @@ -379,8 +376,19 @@ public class JingleConnection implements Downloadable { content.setTransportId(this.transportId); content.socks5transport().setChildren(getCandidatesAsElements()); packet.setContent(content); - this.sendJinglePacket(packet); - this.mJingleStatus = JINGLE_STATUS_INITIATED; + this.sendJinglePacket(packet,new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + if (packet.getType() != IqPacket.TYPE.ERROR) { + mJingleStatus = JINGLE_STATUS_INITIATED; + mXmppConnectionService.markMessage(message, Message.STATUS_OFFERED); + } else { + fail(); + } + } + }); + } } @@ -451,10 +459,13 @@ public class JingleConnection implements Downloadable { } private void sendJinglePacket(JinglePacket packet) { - // Log.d(Config.LOGTAG,packet.toString()); account.getXmppConnection().sendIqPacket(packet, responseListener); } + private void sendJinglePacket(JinglePacket packet, OnIqPacketReceived callback) { + account.getXmppConnection().sendIqPacket(packet,callback); + } + private boolean receiveAccept(JinglePacket packet) { Content content = packet.getJingleContent(); mergeCandidates(JingleCandidate.parse(content.socks5transport() -- cgit v1.2.3 From 29331e49b9fa97949e14f2a326b26c69a4ca3022 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Jan 2015 16:29:26 +0100 Subject: fix mergable() for /me command. --- src/main/java/eu/siacs/conversations/entities/Message.java | 6 ++++-- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 3 ++- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 5 +++-- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 55a1d2ce..8112f5de 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -47,6 +47,7 @@ public class Message extends AbstractEntity { public static final String REMOTE_MSG_ID = "remoteMsgId"; public static final String SERVER_MSG_ID = "serverMsgId"; public static final String RELATIVE_FILE_PATH = "relativeFilePath"; + public static final String ME_COMMAND = "/me "; public boolean markable = false; protected String conversationUuid; @@ -367,7 +368,8 @@ public class Message extends AbstractEntity { (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && !message.bodyContainsDownloadable() && !this.bodyContainsDownloadable() && - !this.body.startsWith("/me ") + !message.getBody().startsWith(ME_COMMAND) && + !this.getBody().startsWith(ME_COMMAND) ); } @@ -380,7 +382,7 @@ public class Message extends AbstractEntity { } public boolean hasMeCommand() { - return getMergedBody().startsWith("/me "); + return getMergedBody().startsWith(ME_COMMAND); } public int getMergedStatus() { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 1d4e2493..442c6ecf 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -220,7 +220,8 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setVisibility(View.VISIBLE); if (message.getBody() != null) { final String nick = UIHelper.getMessageDisplayName(message); - final String formattedBody = message.getMergedBody().replaceAll("^/me ", nick + " "); + final String formattedBody = message.getMergedBody().replaceAll("^" + Message.ME_COMMAND, + nick + " "); if (message.getType() != Message.TYPE_PRIVATE) { if (message.hasMeCommand()) { final Spannable span = new SpannableString(formattedBody); diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 32227ff8..ffb9390f 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -150,8 +150,9 @@ public class UIHelper { return new Pair<>(getFileDescriptionString(context,message),true); } } else { - if (message.getBody().startsWith("/me ")) { - return new Pair<>(message.getBody().replaceAll("^/me ",UIHelper.getMessageDisplayName(message) + " "),false); + if (message.getBody().startsWith(Message.ME_COMMAND)) { + return new Pair<>(message.getBody().replaceAll("^" + Message.ME_COMMAND, + UIHelper.getMessageDisplayName(message) + " "), false); } else { return new Pair<>(message.getBody(), false); } -- cgit v1.2.3 From f0d428a56d83e529825241510479aaed2ff9150b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 25 Jan 2015 20:52:53 +0100 Subject: made connect time out more failsave --- .../siacs/conversations/services/XmppConnectionService.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ca80fa84..a171de3d 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -436,11 +436,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa account.setXmppConnection(this.createConnection(account)); } new Thread(account.getXmppConnection()).start(); - } else if ((account.getStatus() == Account.State.CONNECTING) - && ((SystemClock.elapsedRealtime() - account - .getXmppConnection().getLastConnect()) / 1000 >= Config.CONNECT_TIMEOUT)) { - Log.d(Config.LOGTAG, account.getJid()+ ": time out during connect reconnecting"); - reconnectAccount(account, true); + } else if (account.getStatus() == Account.State.CONNECTING) { + long timeout = Config.CONNECT_TIMEOUT - ((SystemClock.elapsedRealtime() - account.getXmppConnection().getLastConnect()) / 1000); + if (timeout < 0) { + Log.d(Config.LOGTAG, account.getJid() + ": time out during connect reconnecting"); + reconnectAccount(account, true); + } else { + scheduleWakeUpCall((int) timeout,account.getUuid().hashCode()); + } } else { if (account.getXmppConnection().getTimeToNextAttempt() <= 0) { reconnectAccount(account, true); -- cgit v1.2.3 From 94086bb9b7dfca4df7579758f6a3172e6c0b17dc Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 26 Jan 2015 00:26:16 +0100 Subject: don't put ejabberds status code muc messages into an actual conversation --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 0f56f734..d4652940 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -161,6 +161,7 @@ public class MessageParser extends AbstractParser implements } } } + return null; } if (from.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { -- cgit v1.2.3 From 91e85d2faf18088dc7dc01653bda108f0c04d729 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 26 Jan 2015 00:48:56 +0100 Subject: adapt caps on whether or not message confirmation is on --- .../conversations/generator/AbstractGenerator.java | 22 ++++++++++++++++------ .../conversations/generator/PresenceGenerator.java | 2 +- .../services/XmppConnectionService.java | 6 +++++- .../siacs/conversations/ui/SettingsActivity.java | 8 ++++++++ .../eu/siacs/conversations/ui/XmppActivity.java | 4 +--- 5 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 501cba91..0b915dca 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -5,24 +5,30 @@ import android.util.Base64; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.List; import java.util.Locale; import java.util.TimeZone; import eu.siacs.conversations.services.XmppConnectionService; public abstract class AbstractGenerator { - public final String[] FEATURES = {"urn:xmpp:jingle:1", + public final String[] FEATURES = { + "urn:xmpp:jingle:1", "urn:xmpp:jingle:apps:file-transfer:3", "urn:xmpp:jingle:transports:s5b:1", - "urn:xmpp:jingle:transports:ibb:1", "urn:xmpp:receipts", - "urn:xmpp:chat-markers:0", "http://jabber.org/protocol/muc", - "jabber:x:conference", "http://jabber.org/protocol/caps", + "urn:xmpp:jingle:transports:ibb:1", + "http://jabber.org/protocol/muc", + "jabber:x:conference", + "http://jabber.org/protocol/caps", "http://jabber.org/protocol/disco#info", "urn:xmpp:avatar:metadata+notify", "urn:xmpp:ping"}; + public final String[] MESSAGE_CONFIRMATION_FEATURES = { + "urn:xmpp:chat-markers:0", + "urn:xmpp:receipts" + }; public final String IDENTITY_NAME = "Conversations 1.0-beta"; public final String IDENTITY_TYPE = "phone"; @@ -43,7 +49,11 @@ public abstract class AbstractGenerator { } catch (NoSuchAlgorithmException e) { return null; } - List features = Arrays.asList(FEATURES); + ArrayList features = new ArrayList<>(); + features.addAll(Arrays.asList(FEATURES)); + if (mXmppConnectionService.confirmMessages()) { + features.addAll(Arrays.asList(MESSAGE_CONFIRMATION_FEATURES)); + } Collections.sort(features); for (String feature : features) { s.append(feature + "<"); diff --git a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java index e3642f6b..1e896724 100644 --- a/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java @@ -49,7 +49,7 @@ public class PresenceGenerator extends AbstractGenerator { Element cap = packet.addChild("c", "http://jabber.org/protocol/caps"); cap.setAttribute("hash", "sha-1"); - cap.setAttribute("node", "http://conversions.siacs.eu"); + cap.setAttribute("node", "http://conversions.im"); cap.setAttribute("ver", capHash); } return packet; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index a171de3d..e34f9bd7 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -140,7 +140,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa account.pendingConferenceLeaves.clear(); fetchRosterFromServer(account); fetchBookmarks(account); - sendPresencePacket(account, mPresenceGenerator.sendPresence(account)); + sendPresence(account); connectMultiModeConversations(account); updateConversationUi(); } @@ -2150,6 +2150,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } + public void sendPresence(final Account account) { + sendPresencePacket(account, mPresenceGenerator.sendPresence(account)); + } + public MessageGenerator getMessageGenerator() { return this.mMessageGenerator; } diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index c6e7ab33..5bf3cdab 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -71,6 +71,14 @@ public class SettingsActivity extends XmppActivity implements } } else if (name.equals("keep_foreground_service")) { xmppConnectionService.toggleForegroundService(); + } else if (name.equals("confirm_messages")) { + if (xmppConnectionServiceBound) { + for (Account account : xmppConnectionService.getAccounts()) { + if (!account.isOptionSet(Account.OPTION_DISABLED)) { + xmppConnectionService.sendPresence(account); + } + } + } } } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 6399bcef..bf247787 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -402,9 +402,7 @@ public abstract class XmppActivity extends Activity { public void success(Account account) { xmppConnectionService.databaseBackend .updateAccount(account); - xmppConnectionService.sendPresencePacket(account, - xmppConnectionService.getPresenceGenerator() - .sendPresence(account)); + xmppConnectionService.sendPresence(account); if (conversation != null) { conversation .setNextEncryption(Message.ENCRYPTION_PGP); -- cgit v1.2.3 From 2a14a0d9b824c5e435928f0cf2d423444591b51c Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 26 Jan 2015 00:50:06 +0100 Subject: changed version code and version name to 1.0-beta2 --- src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 0b915dca..7689a183 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -29,7 +29,7 @@ public abstract class AbstractGenerator { "urn:xmpp:chat-markers:0", "urn:xmpp:receipts" }; - public final String IDENTITY_NAME = "Conversations 1.0-beta"; + public final String IDENTITY_NAME = "Conversations 1.0-beta2"; public final String IDENTITY_TYPE = "phone"; private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); -- cgit v1.2.3 From f8b662e7f8cc11f50063ed7d1b48f91dddb246e5 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 26 Jan 2015 01:25:47 +0100 Subject: muc tics for consistency --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d4652940..49efb004 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -166,7 +166,7 @@ public class MessageParser extends AbstractParser implements if (from.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { if (mXmppConnectionService.markMessage(conversation, - packet.getId(), Message.STATUS_SEND)) { + packet.getId(), Message.STATUS_SEND_RECEIVED)) { return null; } else if (packet.getId() == null) { Message message = conversation.findSentMessageWithBody(packet.getBody()); -- cgit v1.2.3 From 8cbf610bb2bf9e30ac45a92323697e53738176ed Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 27 Jan 2015 08:49:03 -0500 Subject: Show errors before mute snackbar See #939 --- .../siacs/conversations/ui/ConversationFragment.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 49b6d0fb..80ac9da1 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -612,15 +612,6 @@ public class ConversationFragment extends Fragment { } } }); - } else if (this.conversation.isMuted()) { - showSnackbar(R.string.notifications_disabled, R.string.enable, - new OnClickListener() { - - @Override - public void onClick(final View v) { - activity.unmuteConversation(conversation); - } - }); } else if (!contact.showInRoster() && contact .getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) { @@ -667,7 +658,16 @@ public class ConversationFragment extends Fragment { default: break; } - } + } else if (this.conversation.isMuted()) { + showSnackbar(R.string.notifications_disabled, R.string.enable, + new OnClickListener() { + + @Override + public void onClick(final View v) { + activity.unmuteConversation(conversation); + } + }); + } conversation.populateWithMessages(ConversationFragment.this.messageList); for (final Message message : this.messageList) { if (message.getEncryption() == Message.ENCRYPTION_PGP -- cgit v1.2.3 From 3c64839dafcbaaed9ee0f7ef01afe6516f49020b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 28 Jan 2015 00:28:00 +0100 Subject: fixed broken caps --- .../conversations/generator/AbstractGenerator.java | 24 ++++++++++++++-------- .../siacs/conversations/generator/IqGenerator.java | 7 ++----- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 7689a183..04e114da 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -8,13 +8,14 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.Locale; import java.util.TimeZone; import eu.siacs.conversations.services.XmppConnectionService; public abstract class AbstractGenerator { - public final String[] FEATURES = { + private final String[] FEATURES = { "urn:xmpp:jingle:1", "urn:xmpp:jingle:apps:file-transfer:3", "urn:xmpp:jingle:transports:s5b:1", @@ -25,7 +26,7 @@ public abstract class AbstractGenerator { "http://jabber.org/protocol/disco#info", "urn:xmpp:avatar:metadata+notify", "urn:xmpp:ping"}; - public final String[] MESSAGE_CONFIRMATION_FEATURES = { + private final String[] MESSAGE_CONFIRMATION_FEATURES = { "urn:xmpp:chat-markers:0", "urn:xmpp:receipts" }; @@ -49,13 +50,8 @@ public abstract class AbstractGenerator { } catch (NoSuchAlgorithmException e) { return null; } - ArrayList features = new ArrayList<>(); - features.addAll(Arrays.asList(FEATURES)); - if (mXmppConnectionService.confirmMessages()) { - features.addAll(Arrays.asList(MESSAGE_CONFIRMATION_FEATURES)); - } - Collections.sort(features); - for (String feature : features) { + + for (String feature : getFeatures()) { s.append(feature + "<"); } byte[] sha1 = md.digest(s.toString().getBytes()); @@ -66,4 +62,14 @@ public abstract class AbstractGenerator { DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); return DATE_FORMAT.format(time); } + + public List getFeatures() { + ArrayList features = new ArrayList<>(); + features.addAll(Arrays.asList(FEATURES)); + if (mXmppConnectionService.confirmMessages()) { + features.addAll(Arrays.asList(MESSAGE_CONFIRMATION_FEATURES)); + } + Collections.sort(features); + return features; + } } diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 290e0d60..161e6f89 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -1,8 +1,7 @@ package eu.siacs.conversations.generator; + import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import eu.siacs.conversations.entities.Account; @@ -33,9 +32,7 @@ public class IqGenerator extends AbstractGenerator { identity.setAttribute("category", "client"); identity.setAttribute("type", this.IDENTITY_TYPE); identity.setAttribute("name", IDENTITY_NAME); - final List features = Arrays.asList(FEATURES); - Collections.sort(features); - for (final String feature : features) { + for (final String feature : getFeatures()) { query.addChild("feature").setAttribute("var", feature); } return packet; -- cgit v1.2.3 From 0eeead495f62b3e04d33c0ad3648c28f56d10e63 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 29 Jan 2015 13:20:18 +0100 Subject: properly clear notifications. fixed #921 --- .../java/eu/siacs/conversations/ui/ConversationActivity.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 7aa48c0c..79cc6d12 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -262,8 +262,12 @@ public class ConversationActivity extends XmppActivity } public void sendReadMarkerIfNecessary(final Conversation conversation) { - if (!mActivityPaused && conversation != null && !conversation.isRead()) { - xmppConnectionService.sendReadMarker(conversation); + if (!mActivityPaused && conversation != null) { + if (!conversation.isRead()) { + xmppConnectionService.sendReadMarker(conversation); + } else { + xmppConnectionService.markRead(conversation); + } } } @@ -742,9 +746,11 @@ public class ConversationActivity extends XmppActivity if (this.xmppConnectionServiceBound) { this.xmppConnectionService.getNotificationService().setIsInForeground(true); } + if (!isConversationsOverviewVisable() || !isConversationsOverviewHideable()) { sendReadMarkerIfNecessary(getSelectedConversation()); } + } @Override -- cgit v1.2.3 From 48604a66201e0c0f403ba1576e35833c7407a7d0 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Wed, 21 Jan 2015 23:00:35 -0500 Subject: Use Material Design Icons on API 21+ --- .../services/NotificationService.java | 23 ++++++++++++++++------ .../conversations/ui/ConversationActivity.java | 9 +++++++-- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 894af421..2ea0904f 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -270,7 +270,8 @@ public class NotificationService { } if ((message = getFirstDownloadableMessage(messages)) != null) { mBuilder.addAction( - R.drawable.ic_action_download, + Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? + R.drawable.ic_file_download_white_24dp : R.drawable.ic_action_download, mXmppConnectionService.getResources().getString(R.string.download_x_file, UIHelper.getFileDescriptionString(mXmppConnectionService, message)), createDownloadIntent(message) @@ -446,18 +447,24 @@ public class NotificationService { public Notification createForegroundNotification() { final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService); - mBuilder.setSmallIcon(R.drawable.ic_stat_communication_import_export); + mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.conversations_foreground_service)); mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_open_conversations)); - mBuilder.addAction(R.drawable.ic_action_cancel, - mXmppConnectionService.getString(R.string.disable_foreground_service), - createDisableForeground()); mBuilder.setContentIntent(createOpenConversationsIntent()); mBuilder.setWhen(0); mBuilder.setPriority(NotificationCompat.PRIORITY_MIN); + final int cancelIcon; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mBuilder.setCategory(Notification.CATEGORY_SERVICE); + mBuilder.setSmallIcon(R.drawable.ic_import_export_white_48dp); + cancelIcon = R.drawable.ic_cancel_white_24dp; + } else { + mBuilder.setSmallIcon(R.drawable.ic_stat_communication_import_export); + cancelIcon = R.drawable.ic_action_cancel; } + mBuilder.addAction(cancelIcon, + mXmppConnectionService.getString(R.string.disable_foreground_service), + createDisableForeground()); setNotificationColor(mBuilder); return mBuilder.build(); } @@ -487,7 +494,11 @@ public class NotificationService { } mBuilder.setOngoing(true); //mBuilder.setLights(0xffffffff, 2000, 4000); - mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + mBuilder.setSmallIcon(R.drawable.ic_warning_white_36dp); + } else { + mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); + } final TaskStackBuilder stackBuilder = TaskStackBuilder.create(mXmppConnectionService); stackBuilder.addParentStack(ConversationActivity.class); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 7aa48c0c..299fb848 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -10,6 +10,7 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.provider.MediaStore; @@ -296,8 +297,12 @@ public class ConversationActivity extends XmppActivity if (this.getSelectedConversation() != null) { if (this.getSelectedConversation().getLatestMessage() .getEncryption() != Message.ENCRYPTION_NONE) { - menuSecure.setIcon(R.drawable.ic_action_secure); - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + menuSecure.setIcon(R.drawable.ic_lock_outline_white_48dp); + } else { + menuSecure.setIcon(R.drawable.ic_action_secure); + } + } if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) { menuContactDetails.setVisible(false); menuAttach.setVisible(false); -- cgit v1.2.3 From 3a52f318248134a49dda7d6704ba43bc91784318 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 29 Jan 2015 23:35:31 +0100 Subject: don't count when attempt failed completly --- src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index c16ac32b..19e271b2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -229,6 +229,7 @@ public class XmppConnection implements Runnable { } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) { Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage()); this.changeStatus(Account.State.OFFLINE); + this.attempt--; //don't count attempt when reconnecting instantly anyway } finally { if (wakeLock.isHeld()) { try { -- cgit v1.2.3 From 3216813e4939941611e0226d2f56b9180fad173b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 29 Jan 2015 23:56:04 +0100 Subject: made version codes ready for release candidate in beta channel --- src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 04e114da..526e5b19 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -30,7 +30,7 @@ public abstract class AbstractGenerator { "urn:xmpp:chat-markers:0", "urn:xmpp:receipts" }; - public final String IDENTITY_NAME = "Conversations 1.0-beta2"; + public final String IDENTITY_NAME = "Conversations 1.0"; public final String IDENTITY_TYPE = "phone"; private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); -- cgit v1.2.3 From d0e764c1a50bfe13be7c5ca5e9c9a52c108abdaa Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 1 Feb 2015 12:32:19 +0100 Subject: fixed text preview for images --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index ffb9390f..235ef84c 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -142,7 +142,7 @@ public class UIHelper { } } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { return new Pair<>(context.getString(R.string.encrypted_message_received),true); - } else if (message.getType() == Message.TYPE_FILE) { + } else if (message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) { if (message.getStatus() == Message.STATUS_RECEIVED) { return new Pair<>(context.getString(R.string.received_x_file, getFileDescriptionString(context, message)), true); -- cgit v1.2.3 From 6674a3d7572ad57c16033d5129c57a4ff0a56c35 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 2 Feb 2015 13:55:56 +0100 Subject: added more ciphers for old openssl versions --- src/main/java/eu/siacs/conversations/Config.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index b269dedf..7a50c47f 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -52,7 +52,9 @@ public final class Config { "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_RSA_WITH_AES_256_CBC_SHA384" + "TLS_RSA_WITH_AES_256_CBC_SHA384", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", }; private Config() { -- cgit v1.2.3 From bd3fccd2dcb082cdc3f0d684ea66626f3d588f0b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 2 Feb 2015 14:22:49 +0100 Subject: don't disable any ciphers --- src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 48b0cdf3..fc21acbc 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -98,8 +98,9 @@ public final class CryptoHelper { } public static String[] getSupportedCipherSuites(final String[] platformSupportedCipherSuites) { - final Collection cipherSuites = new LinkedHashSet<>(Arrays.asList(Config.ENABLED_CIPHERS)); - cipherSuites.retainAll(Arrays.asList(platformSupportedCipherSuites)); - return cipherSuites.toArray(new String[cipherSuites.size()]); + //final Collection cipherSuites = new LinkedHashSet<>(Arrays.asList(Config.ENABLED_CIPHERS)); + //cipherSuites.retainAll(Arrays.asList(platformSupportedCipherSuites)); + //return cipherSuites.toArray(new String[cipherSuites.size()]); + return platformSupportedCipherSuites; } } -- cgit v1.2.3