aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2016-07-28 22:58:37 +0200
committerDaniel Gultsch <daniel@gultsch.de>2016-07-28 22:58:37 +0200
commit0e96e0a796661aae1af133f24d010a4957f68af2 (patch)
tree07555ef3033750ee2f45ebb933898ef7eeeb7841
parentc06aceaae9b77d8a1e161b97499f5b62bea55851 (diff)
show identity type for device selection
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Contact.java6
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Message.java6
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Presences.java29
-rw-r--r--src/main/java/eu/siacs/conversations/parser/AbstractParser.java2
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/FileBackend.java7
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java2
-rw-r--r--src/main/java/eu/siacs/conversations/ui/XmppActivity.java101
-rw-r--r--src/main/java/eu/siacs/conversations/utils/CryptoHelper.java3
-rw-r--r--src/main/java/eu/siacs/conversations/utils/UIHelper.java18
-rw-r--r--src/main/res/values/strings.xml7
10 files changed, 135 insertions, 46 deletions
diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java
index f061413b..676c91d0 100644
--- a/src/main/java/eu/siacs/conversations/entities/Contact.java
+++ b/src/main/java/eu/siacs/conversations/entities/Contact.java
@@ -526,11 +526,11 @@ public class Contact implements ListItem, Blockable {
return this.mLastseen;
}
- public void setLastPresence(String presence) {
- this.mLastPresence = presence;
+ public void setLastResource(String resource) {
+ this.mLastPresence = resource;
}
- public String getLastPresence() {
+ public String getLastResource() {
return this.mLastPresence;
}
diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java
index 9ab1da96..1b38d349 100644
--- a/src/main/java/eu/siacs/conversations/entities/Message.java
+++ b/src/main/java/eu/siacs/conversations/entities/Message.java
@@ -5,10 +5,10 @@ import android.database.Cursor;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.Arrays;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
+import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.GeoHelper;
import eu.siacs.conversations.utils.MimeUtils;
import eu.siacs.conversations.utils.UIHelper;
@@ -396,7 +396,7 @@ public class Message extends AbstractEntity {
&& this.counterpart.equals(message.getCounterpart())
&& (body.equals(otherBody)
||(message.getEncryption() == Message.ENCRYPTION_PGP
- && message.getRemoteMsgId().matches("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"))) ;
+ && CryptoHelper.UUID_PATTERN.matcher(message.getRemoteMsgId()).matches()));
} else {
return this.remoteMsgId == null
&& this.counterpart.equals(message.getCounterpart())
@@ -550,7 +550,7 @@ public class Message extends AbstractEntity {
try {
counterpart = Jid.fromParts(conversation.getJid().getLocalpart(),
conversation.getJid().getDomainpart(),
- presences.asStringArray()[0]);
+ presences.toResourceArray()[0]);
return true;
} catch (InvalidJidException e) {
counterpart = null;
diff --git a/src/main/java/eu/siacs/conversations/entities/Presences.java b/src/main/java/eu/siacs/conversations/entities/Presences.java
index 6391f5bb..f9dfee36 100644
--- a/src/main/java/eu/siacs/conversations/entities/Presences.java
+++ b/src/main/java/eu/siacs/conversations/entities/Presences.java
@@ -1,7 +1,10 @@
package eu.siacs.conversations.entities;
+import android.util.Pair;
+
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
@@ -54,7 +57,7 @@ public class Presences {
}
}
- public String[] asStringArray() {
+ public String[] toResourceArray() {
synchronized (this.presences) {
final String[] presencesArray = new String[presences.size()];
presences.keySet().toArray(presencesArray);
@@ -104,4 +107,28 @@ public class Presences {
}
return true;
}
+
+ public Pair<Map<String, String>,Map<String,String>> toTypeAndNameMap() {
+ Map<String,String> typeMap = new HashMap<>();
+ Map<String,String> nameMap = new HashMap<>();
+ synchronized (this.presences) {
+ for(Map.Entry<String,Presence> presenceEntry : this.presences.entrySet()) {
+ String resource = presenceEntry.getKey();
+ Presence presence = presenceEntry.getValue();
+ ServiceDiscoveryResult serviceDiscoveryResult = presence == null ? null : presence.getServiceDiscoveryResult();
+ if (serviceDiscoveryResult != null && serviceDiscoveryResult.getIdentities().size() > 0) {
+ ServiceDiscoveryResult.Identity identity = serviceDiscoveryResult.getIdentities().get(0);
+ String type = identity.getType();
+ String name = identity.getName();
+ if (type != null) {
+ typeMap.put(resource,type);
+ }
+ if (name != null) {
+ nameMap.put(resource, name);
+ }
+ }
+ }
+ }
+ return new Pair(typeMap,nameMap);
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java
index 4699d286..b548b3c8 100644
--- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java
@@ -62,7 +62,7 @@ public abstract class AbstractParser {
protected void updateLastseen(final Account account, final Jid from) {
final Contact contact = account.getRoster().getContact(from);
- contact.setLastPresence(from.isBareJid() ? "" : from.getResourcepart());
+ contact.setLastResource(from.isBareJid() ? "" : from.getResourcepart());
}
protected String avatarData(Element items) {
diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
index cd46d1b8..947e19a6 100644
--- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
@@ -401,7 +401,12 @@ public class FileBackend {
private Bitmap getFullsizeImagePreview(File file, int size) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = calcSampleSize(file, size);
- return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
+ try {
+ return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
+ } catch (OutOfMemoryError e) {
+ options.inSampleSize *= 2;
+ return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
+ }
}
private Bitmap getVideoPreview(File file, int size) {
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 44840ba2..01aa5a60 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -196,7 +196,7 @@ public class XmppConnectionService extends Service {
if (contact.getPresences().size() >= 1) {
if (conversation.hasValidOtrSession()) {
String otrResource = conversation.getOtrSession().getSessionID().getUserID();
- if (!(Arrays.asList(contact.getPresences().asStringArray()).contains(otrResource))) {
+ if (!(Arrays.asList(contact.getPresences().toResourceArray()).contains(otrResource))) {
conversation.endOtrIfNeeded();
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
index df16fd64..e8047ce2 100644
--- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
@@ -44,6 +44,7 @@ import android.preference.PreferenceManager;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
@@ -66,9 +67,13 @@ import net.java.otr4j.session.SessionID;
import java.io.FileNotFoundException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.atomic.AtomicInteger;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@@ -78,13 +83,16 @@ 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.entities.Presence;
import eu.siacs.conversations.entities.Presences;
+import eu.siacs.conversations.entities.ServiceDiscoveryResult;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;
import eu.siacs.conversations.ui.widget.Switch;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.ExceptionHelper;
+import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
@@ -940,7 +948,7 @@ public abstract class XmppActivity extends Activity {
} else if (!contact.showInRoster()) {
showAddToRosterDialog(conversation);
} else {
- Presences presences = contact.getPresences();
+ final Presences presences = contact.getPresences();
if (presences.size() == 0) {
if (!contact.getOption(Contact.Options.TO)
&& !contact.getOption(Contact.Options.ASKING)
@@ -954,7 +962,7 @@ public abstract class XmppActivity extends Activity {
listener.onPresenceSelected();
}
} else if (presences.size() == 1) {
- String presence = presences.asStringArray()[0];
+ String presence = presences.toResourceArray()[0];
try {
conversation.setNextCounterpart(Jid.fromParts(contact.getJid().getLocalpart(),contact.getJid().getDomainpart(),presence));
} catch (InvalidJidException e) {
@@ -962,49 +970,72 @@ public abstract class XmppActivity extends Activity {
}
listener.onPresenceSelected();
} else {
- final StringBuilder presence = new StringBuilder();
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(getString(R.string.choose_presence));
- final String[] presencesArray = presences.asStringArray();
- int preselectedPresence = 0;
- for (int i = 0; i < presencesArray.length; ++i) {
- if (presencesArray[i].equals(contact.getLastPresence())) {
- preselectedPresence = i;
- break;
+ showPresenceSelectionDialog(presences,conversation,listener);
+ }
+ }
+ }
+
+ private void showPresenceSelectionDialog(Presences presences, final Conversation conversation, final OnPresenceSelected listener) {
+ final Contact contact = conversation.getContact();
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getString(R.string.choose_presence));
+ final String[] resourceArray = presences.toResourceArray();
+ Pair<Map<String, String>, Map<String, String>> typeAndName = presences.toTypeAndNameMap();
+ final Map<String,String> resourceTypeMap = typeAndName.first;
+ final Map<String,String> resourceNameMap = typeAndName.second;
+ final String[] readableIdentities = new String[resourceArray.length];
+ final AtomicInteger selectedResource = new AtomicInteger(0);
+ for (int i = 0; i < resourceArray.length; ++i) {
+ String resource = resourceArray[i];
+ if (resource.equals(contact.getLastResource())) {
+ selectedResource.set(i);
+ }
+ String type = resourceTypeMap.get(resource);
+ String name = resourceNameMap.get(resource);
+ if (type != null) {
+ if (Collections.frequency(resourceTypeMap.values(),type) == 1) {
+ readableIdentities[i] = UIHelper.tranlasteType(this,type);
+ } else if (name != null) {
+ if (Collections.frequency(resourceNameMap.values(), name) == 1
+ || CryptoHelper.UUID_PATTERN.matcher(resource).matches()) {
+ readableIdentities[i] = UIHelper.tranlasteType(this,type) + " (" + name+")";
+ } else {
+ readableIdentities[i] = UIHelper.tranlasteType(this,type) + " (" + name +" / " + resource+")";
}
+ } else {
+ readableIdentities[i] = UIHelper.tranlasteType(this,type) + " (" + resource+")";
}
- presence.append(presencesArray[preselectedPresence]);
- builder.setSingleChoiceItems(presencesArray,
- preselectedPresence,
- new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog,
- int which) {
- presence.delete(0, presence.length());
- presence.append(presencesArray[which]);
- }
- });
- builder.setNegativeButton(R.string.cancel, null);
- builder.setPositiveButton(R.string.ok, new OnClickListener() {
+ } else {
+ readableIdentities[i] = resource;
+ }
+ }
+ builder.setSingleChoiceItems(readableIdentities,
+ selectedResource.get(),
+ new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- try {
- conversation.setNextCounterpart(Jid.fromParts(contact.getJid().getLocalpart(),contact.getJid().getDomainpart(),presence.toString()));
- } catch (InvalidJidException e) {
- conversation.setNextCounterpart(null);
- }
- listener.onPresenceSelected();
+ selectedResource.set(which);
}
});
- builder.create().show();
+ builder.setNegativeButton(R.string.cancel, null);
+ builder.setPositiveButton(R.string.ok, new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ try {
+ Jid next = Jid.fromParts(contact.getJid().getLocalpart(),contact.getJid().getDomainpart(),resourceArray[selectedResource.get()]);
+ conversation.setNextCounterpart(next);
+ } catch (InvalidJidException e) {
+ conversation.setNextCounterpart(null);
+ }
+ listener.onPresenceSelected();
}
- }
+ });
+ builder.create().show();
}
- protected void onActivityResult(int requestCode, int resultCode,
- final Intent data) {
+ protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_INVITE_TO_CONVERSATION && resultCode == RESULT_OK) {
mPendingConferenceInvite = ConferenceInvite.parse(data);
diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java
index 253584bf..429c349a 100644
--- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java
@@ -21,6 +21,7 @@ import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
+import java.util.regex.Pattern;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@@ -31,6 +32,8 @@ import eu.siacs.conversations.xmpp.jid.Jid;
public final class CryptoHelper {
public static final String FILETRANSFER = "?FILETRANSFERv1:";
private final static char[] hexArray = "0123456789abcdef".toCharArray();
+
+ public static final Pattern UUID_PATTERN = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}");
final public static byte[] ONE = new byte[] { 0, 0, 0, 1 };
public static String bytesToHex(byte[] bytes) {
diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java
index acc7f28c..63dae04f 100644
--- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java
@@ -18,6 +18,7 @@ import eu.siacs.conversations.entities.ListItem;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.Presence;
import eu.siacs.conversations.entities.Transferable;
+import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.xmpp.jid.Jid;
public class UIHelper {
@@ -286,4 +287,21 @@ public class UIHelper {
return new ListItem.Tag(context.getString(R.string.presence_online), 0xff259b24);
}
}
+
+ public static String tranlasteType(Context context, String type) {
+ switch (type.toLowerCase()) {
+ case "pc":
+ return context.getString(R.string.type_pc);
+ case "phone":
+ return context.getString(R.string.type_phone);
+ case "tablet":
+ return context.getString(R.string.type_tablet);
+ case "web":
+ return context.getString(R.string.type_web);
+ case "console":
+ return context.getString(R.string.type_console);
+ default:
+ return type;
+ }
+ }
}
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 9b404295..96d7d3cc 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -79,7 +79,7 @@
<string name="clear_histor_msg">Do you want to delete all messages within this Conversation?\n\n<b>Warning:</b> This will not influence messages stored on other devices or servers.</string>
<string name="delete_messages">Delete messages</string>
<string name="also_end_conversation">End this conversation afterwards</string>
- <string name="choose_presence">Choose presence to contact</string>
+ <string name="choose_presence">Choose device</string>
<string name="send_unencrypted_message">Send unencrypted message</string>
<string name="send_message_to_x">Send message to %s</string>
<string name="send_otr_message">Send OTR encrypted message</string>
@@ -669,4 +669,9 @@
<string name="pref_use_green_background_summary">Use green background for received messages</string>
<string name="unable_to_connect_to_keychain">Unable to connect to OpenKeychain</string>
<string name="this_device_is_no_longer_in_use">This device is no longer in use</string>
+ <string name="type_pc">Computer</string>
+ <string name="type_phone">Mobile phone</string>
+ <string name="type_tablet">Tablet</string>
+ <string name="type_web">Web browser</string>
+ <string name="type_console">Console</string>
</resources>