diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/utils')
7 files changed, 211 insertions, 231 deletions
diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 306d50c2..1568eb8c 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -7,20 +7,13 @@ import android.net.LinkProperties; import android.net.Network; import android.net.RouteInfo; import android.os.Build; -import android.os.Bundle; -import android.os.Parcelable; -import android.util.Log; import java.io.IOException; import java.net.InetAddress; -import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Random; -import java.util.TreeMap; -import java.util.Map; +import java.util.TreeSet; import java.util.regex.Pattern; import de.measite.minidns.Client; @@ -28,47 +21,58 @@ import de.measite.minidns.DNSMessage; import de.measite.minidns.Record; import de.measite.minidns.Record.CLASS; import de.measite.minidns.Record.TYPE; -import de.measite.minidns.record.A; -import de.measite.minidns.record.AAAA; import de.measite.minidns.record.Data; import de.measite.minidns.record.SRV; import de.measite.minidns.util.NameUtil; +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.dto.SrvRecord; import eu.siacs.conversations.Config; import eu.siacs.conversations.xmpp.jid.Jid; public class DNSHelper { - - public static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); - public static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); - public static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); - public static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z"); - public static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z"); + private static final String CLIENT_SRV_PREFIX = "_xmpp-client._tcp."; + private static final String SECURE_CLIENT_SRV_PREFIX = "_xmpps-client._tcp."; + private static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + private static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + private static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + private static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z"); + private static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z"); protected static Client client = new Client(); - public static Bundle getSRVRecord(final Jid jid, Context context) throws IOException { - final String host = jid.getDomainpart(); - final List<InetAddress> servers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers(context) : getDnsServersPreLollipop(); - Bundle b = new Bundle(); - for(InetAddress server : servers) { - b = queryDNS(host, server); - if (b.containsKey("values")) { - return b; - } - } - if (!b.containsKey("values")) { - Log.d(Config.LOGTAG,"all dns queries failed. provide fallback A record"); - ArrayList<Parcelable> values = new ArrayList<>(); - values.add(createNamePortBundle(host, 5222, false)); - b.putParcelableArrayList("values",values); - } - return b; - } + static { + client.setTimeout(Config.PING_TIMEOUT * 1000); + } + + /** + * Queries the SRV record for the server JID. + * This method uses all available Domain Name Servers. + * @param jid the server JID + * @return TreeSet with SrvRecords. If no SRV record is found for JID an empty TreeSet is returned. + */ + public static final TreeSet<SrvRecord> querySrvRecord(Jid jid) { + String host = jid.getDomainpart(); + TreeSet<SrvRecord> result = new TreeSet<>(); + + final List<InetAddress> dnsServers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers() : getDnsServersPreLollipop(); + + if (dnsServers != null) { + for (InetAddress dnsServer : dnsServers) { + result = querySrvRecord(host, dnsServer); + if (!result.isEmpty()) { + break; + } + } + } + + return result; + } @TargetApi(21) - private static List<InetAddress> getDnsServers(Context context) { + private static List<InetAddress> getDnsServers() { List<InetAddress> servers = new ArrayList<>(); - ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + ConnectivityManager connectivityManager = (ConnectivityManager) ConversationsPlusApplication.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE); Network[] networks = connectivityManager == null ? null : connectivityManager.getAllNetworks(); if (networks == null) { return getDnsServersPreLollipop(); @@ -84,7 +88,7 @@ public class DNSHelper { } } if (servers.size() > 0) { - Log.d(Config.LOGTAG, "used lollipop variant to discover dns servers in " + networks.length + " networks"); + Logging.d("dns", "used lollipop variant to discover dns servers in " + networks.length + " networks"); } return servers.size() > 0 ? servers : getDnsServersPreLollipop(); } @@ -112,155 +116,38 @@ public class DNSHelper { return servers; } - private static class TlsSrv { - private final SRV srv; - private final boolean tls; - - public TlsSrv(SRV srv, boolean tls) { - this.srv = srv; - this.tls = tls; - } - } - - private static void fillSrvMaps(final String qname, final InetAddress dnsServer, final Map<Integer, List<TlsSrv>> priorities, final Map<String, List<String>> ips4, final Map<String, List<String>> ips6, final boolean tls) throws IOException { - final DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServer.getHostAddress()); - for (Record[] rrset : new Record[][] { message.getAnswers(), message.getAdditionalResourceRecords() }) { - for (Record rr : rrset) { - Data d = rr.getPayload(); - if (d instanceof SRV && NameUtil.idnEquals(qname, rr.getName())) { - SRV srv = (SRV) d; - if (!priorities.containsKey(srv.getPriority())) { - priorities.put(srv.getPriority(),new ArrayList<TlsSrv>()); - } - priorities.get(srv.getPriority()).add(new TlsSrv(srv, tls)); - } - if (d instanceof A) { - A a = (A) d; - if (!ips4.containsKey(rr.getName())) { - ips4.put(rr.getName(), new ArrayList<String>()); - } - ips4.get(rr.getName()).add(a.toString()); - } - if (d instanceof AAAA) { - AAAA aaaa = (AAAA) d; - if (!ips6.containsKey(rr.getName())) { - ips6.put(rr.getName(), new ArrayList<String>()); - } - ips6.get(rr.getName()).add("[" + aaaa.toString() + "]"); - } - } - } - } - - public static Bundle queryDNS(String host, InetAddress dnsServer) { - Bundle bundle = new Bundle(); - try { - client.setTimeout(Config.PING_TIMEOUT * 1000); - final String qname = "_xmpp-client._tcp." + host; - final String tlsQname = "_xmpps-client._tcp." + host; - Log.d(Config.LOGTAG, "using dns server: " + dnsServer.getHostAddress() + " to look up " + host); - - final Map<Integer, List<TlsSrv>> priorities = new TreeMap<>(); - final Map<String, List<String>> ips4 = new TreeMap<>(); - final Map<String, List<String>> ips6 = new TreeMap<>(); - - fillSrvMaps(qname, dnsServer, priorities, ips4, ips6, false); - fillSrvMaps(tlsQname, dnsServer, priorities, ips4, ips6, true); - - final List<TlsSrv> result = new ArrayList<>(); - for (final List<TlsSrv> s : priorities.values()) { - result.addAll(s); - } - - final ArrayList<Bundle> values = new ArrayList<>(); - if (result.size() == 0) { - DNSMessage response; - try { - response = client.query(host, TYPE.A, CLASS.IN, dnsServer.getHostAddress()); - for (int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload(), false)); - } - } catch (SocketTimeoutException e) { - Log.d(Config.LOGTAG,"ignoring timeout exception when querying A record on "+dnsServer.getHostAddress()); - } - try { - response = client.query(host, TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); - for (int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload(), false)); - } - } catch (SocketTimeoutException e) { - Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress()); - } - values.add(createNamePortBundle(host, 5222, false)); - bundle.putParcelableArrayList("values", values); - return bundle; - } - for (final TlsSrv tlsSrv : result) { - final SRV srv = tlsSrv.srv; - if (ips6.containsKey(srv.getName())) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6, tlsSrv.tls)); - } else { - try { - DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); - for (int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(srv.getName(), srv.getPort(), response.getAnswers()[i].getPayload(), tlsSrv.tls)); - } - } catch (SocketTimeoutException e) { - Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress()); - } - } - if (ips4.containsKey(srv.getName())) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4, tlsSrv.tls)); - } else { - DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); - for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload(), tlsSrv.tls)); - } - } - values.add(createNamePortBundle(srv.getName(), srv.getPort(), tlsSrv.tls)); - } - bundle.putParcelableArrayList("values", values); - } catch (SocketTimeoutException e) { - bundle.putString("error", "timeout"); - } catch (Exception e) { - bundle.putString("error", "unhandled"); - } - return bundle; - } - - private static Bundle createNamePortBundle(String name, int port, final boolean tls) { - Bundle namePort = new Bundle(); - namePort.putString("name", name); - namePort.putBoolean("tls", tls); - namePort.putInt("port", port); - return namePort; - } - - private static Bundle createNamePortBundle(String name, int port, Map<String, List<String>> ips, final boolean tls) { - Bundle namePort = new Bundle(); - namePort.putString("name", name); - namePort.putBoolean("tls", tls); - namePort.putInt("port", port); - if (ips!=null) { - List<String> ip = ips.get(name); - Collections.shuffle(ip, new Random()); - namePort.putString("ip", ip.get(0)); - } - return namePort; - } - - private static Bundle createNamePortBundle(String name, int port, Data data, final boolean tls) { - Bundle namePort = new Bundle(); - namePort.putString("name", name); - namePort.putBoolean("tls", tls); - namePort.putInt("port", port); - if (data instanceof A) { - namePort.putString("ip", data.toString()); - } else if (data instanceof AAAA) { - namePort.putString("ip","["+data.toString()+"]"); - } - return namePort; - } + /** + * Queries the SRV record for an host from the given Domain Name Server. + * @param host the host to query for + * @param dnsServerAddress the DNS to query on + * @return TreeSet with SrvRecords. + */ + private static final TreeSet<SrvRecord> querySrvRecord(String host, InetAddress dnsServerAddress) { + TreeSet<SrvRecord> result = new TreeSet<>(); + querySrvRecord(host, dnsServerAddress, false, result); + querySrvRecord(host, dnsServerAddress, true, result); + return result; + } + + private static final void querySrvRecord(String host, InetAddress dnsServerAddress, boolean tlsSrvRecord, TreeSet<SrvRecord> result) { + String qname = (tlsSrvRecord ? SECURE_CLIENT_SRV_PREFIX : CLIENT_SRV_PREFIX) + host; + String dnsServerHostAddress = dnsServerAddress.getHostAddress(); + Logging.d("dns", "using dns server: " + dnsServerHostAddress + " to look up " + qname); + try { + DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServerHostAddress); + Record[] rrset = message.getAnswers(); + for (Record rr : rrset) { + Data d = rr.getPayload(); + if (d instanceof SRV && NameUtil.idnEquals(qname, rr.getName())) { + SRV srv = (SRV) d; + SrvRecord srvRecord = new SrvRecord(srv.getPriority(), srv.getName(), srv.getPort(), tlsSrvRecord); + result.add(srvRecord); + } + } + } catch (IOException e) { + Logging.d("dns", "Error while retrieving SRV record '" + qname + "' for '" + host + "' from DNS '" + dnsServerHostAddress + "': " + e.getMessage()); + } + } public static boolean isIp(final String server) { return server != null && ( diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java index 8799b4a5..9c8db210 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java @@ -4,13 +4,10 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; -import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.preference.PreferenceManager; import android.text.format.DateUtils; -import android.util.Log; import java.io.BufferedReader; import java.io.FileInputStream; @@ -18,6 +15,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.List; +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.ConversationsPlusPreferences; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; @@ -36,11 +35,9 @@ public class ExceptionHelper { } } - public static boolean checkForCrash(ConversationActivity activity, final XmppConnectionService service) { + public static boolean checkForCrash(final ConversationActivity activity, final XmppConnectionService service) { try { - final SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(activity); - boolean neverSend = preferences.getBoolean("never_send", false); + boolean neverSend = ConversationsPlusPreferences.neverSend(); if (neverSend) { return false; } @@ -89,13 +86,13 @@ public class ExceptionHelper { @Override public void onClick(DialogInterface dialog, int which) { - Log.d(Config.LOGTAG, "using account=" + Logging.d(Config.LOGTAG, "using account=" + finalAccount.getJid().toBareJid() + " to send in stack trace"); Conversation conversation = null; try { conversation = service.findOrCreateConversation(finalAccount, - Jid.fromString("bugs@siacs.eu"), false); + Jid.fromString(activity.getString(R.string.cplus_bugreport_jabberid)), false); } catch (final InvalidJidException ignored) { } Message message = new Message(conversation, report @@ -108,8 +105,7 @@ public class ExceptionHelper { @Override public void onClick(DialogInterface dialog, int which) { - preferences.edit().putBoolean("never_send", true) - .apply(); + ConversationsPlusPreferences.applyNeverSend(true); } }); builder.create().show(); diff --git a/src/main/java/eu/siacs/conversations/utils/ExifHelper.java b/src/main/java/eu/siacs/conversations/utils/ExifHelper.java index ceda7293..5e465e94 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExifHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/ExifHelper.java @@ -16,11 +16,11 @@ package eu.siacs.conversations.utils; -import android.util.Log; - import java.io.IOException; import java.io.InputStream; +import de.thedevstack.android.logcat.Logging; + public class ExifHelper { private static final String TAG = "CameraExif"; @@ -56,7 +56,7 @@ public class ExifHelper { } length = pack(buf, 0, 2, false); if (length < 2) { - Log.e(TAG, "Invalid length"); + Logging.e(TAG, "Invalid length"); return 0; } length -= 2; @@ -91,7 +91,7 @@ public class ExifHelper { // Identify the byte order. int tag = pack(jpeg, offset, 4, false); if (tag != 0x49492A00 && tag != 0x4D4D002A) { - Log.e(TAG, "Invalid byte order"); + Logging.e(TAG, "Invalid byte order"); return 0; } boolean littleEndian = (tag == 0x49492A00); @@ -99,7 +99,7 @@ public class ExifHelper { // Get the offset and check if it is reasonable. int count = pack(jpeg, offset + 4, 4, littleEndian) + 2; if (count < 10 || count > length) { - Log.e(TAG, "Invalid offset"); + Logging.e(TAG, "Invalid offset"); return 0; } offset += count; @@ -123,7 +123,7 @@ public class ExifHelper { case 8: return 270; } - Log.i(TAG, "Unsupported orientation"); + Logging.i(TAG, "Unsupported orientation"); return 0; } offset += 12; @@ -131,7 +131,7 @@ public class ExifHelper { } } - Log.i(TAG, "Orientation not found"); + Logging.i(TAG, "Orientation not found"); return 0; } diff --git a/src/main/java/eu/siacs/conversations/utils/FileUtils.java b/src/main/java/eu/siacs/conversations/utils/FileUtils.java index 6e75d41c..1f2a71ca 100644 --- a/src/main/java/eu/siacs/conversations/utils/FileUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/FileUtils.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.utils; import android.annotation.SuppressLint; +import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; @@ -9,28 +10,31 @@ import android.os.Build; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; +import android.provider.OpenableColumns; import java.io.File; +import java.util.List; -public class FileUtils { +import de.thedevstack.conversationsplus.ConversationsPlusApplication; + +public final class FileUtils { /** * Get a file path from a Uri. This will get the the path for Storage Access * Framework Documents, as well as the _data field for the MediaStore and * other file-based ContentProviders. * - * @param context The context. * @param uri The Uri to query. * @author paulburke */ @SuppressLint("NewApi") - public static String getPath(final Context context, final Uri uri) { + public static String getPath(final Uri uri) { if (uri == null) { return null; } final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - + final Context context = ConversationsPlusApplication.getAppContext(); // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider @@ -78,7 +82,7 @@ public class FileUtils { } } // MediaStore (and general) - else if ("content".equalsIgnoreCase(uri.getScheme())) { + else if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { String path = getDataColumn(context, uri, null, null); if (path != null) { File file = new File(path); @@ -89,7 +93,7 @@ public class FileUtils { return path; } // File - else if ("file".equalsIgnoreCase(uri.getScheme())) { + else if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { return uri.getPath(); } @@ -106,7 +110,7 @@ public class FileUtils { * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ - public static String getDataColumn(Context context, Uri uri, String selection, + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; @@ -155,4 +159,71 @@ public class FileUtils { public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } + + /** + * @param filename The filename to extract extension from + * @return last extension or empty string + */ + public static String getLastExtension(final String filename) { + if (filename == null || filename.isEmpty()) { + return ""; + } + final int lastDotPosition = filename.lastIndexOf('.'); + final String lastPart = lastDotPosition != -1 ? + filename.substring(lastDotPosition + 1) : ""; + return lastPart; + } + + /** + * @param filename The filename to extract extension from + * @return second to last extension or empty string + */ + public static String getSecondToLastExtension(final String filename) { + if (filename == null || filename.isEmpty()) { + return ""; + } + final int lastDotPosition = filename.lastIndexOf('.'); + final int secondToLastDotPosition = filename.lastIndexOf('.', lastDotPosition - 1); + final String secondToLastPart = secondToLastDotPosition != -1 ? + filename.substring(secondToLastDotPosition + 1, lastDotPosition) : ""; + return secondToLastPart; + } + + /** + * Retrieve file size from given uri + * @param context actual Context + * @param uri uri to file + * @return file size or -1 in case of error + */ + private static long getFileSize(Context context, Uri uri) { + Cursor cursor = context.getContentResolver().query(uri, null, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + return cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE)); + } else { + return -1; + } + } + + /** + * Check for given list of uris if corresponding file sizes are all smaller than given maximum + * @param context actual Context + * @param uris list of uris + * @param max maximum file size + * @return true if all file sizes are smaller than max, false otherwise + */ + public static boolean allFilesUnderSize(Context context, List<Uri> uris, long max) { + if (max <= 0) { + return true; //exception to be compatible with HTTP Upload < v0.2 + } + for(Uri uri : uris) { + if (getFileSize(context, uri) > max) { + return false; + } + } + return true; + } + + private FileUtils() { + // Utility class - do not instantiate + } } diff --git a/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java b/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java index 8fe67234..5faa1fa7 100644 --- a/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java +++ b/src/main/java/eu/siacs/conversations/utils/PRNGFixes.java @@ -2,7 +2,6 @@ package eu.siacs.conversations.utils; import android.os.Build; import android.os.Process; -import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -19,6 +18,8 @@ import java.security.SecureRandom; import java.security.SecureRandomSpi; import java.security.Security; +import de.thedevstack.android.logcat.Logging; + /** * Fixes for the output of the default PRNG having low entropy. * @@ -209,7 +210,7 @@ public final class PRNGFixes { } catch (IOException e) { // On a small fraction of devices /dev/urandom is not writable. // Log and ignore. - Log.w(PRNGFixes.class.getSimpleName(), + Logging.w(PRNGFixes.class.getSimpleName(), "Failed to mix seed into " + URANDOM_FILE); } finally { mSeeded = true; diff --git a/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java b/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java index 768e9f17..04cfa2eb 100644 --- a/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java +++ b/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java @@ -43,10 +43,6 @@ public class SocksSocketFactory { return socket; } - public static Socket createSocketOverTor(String destination, int port) throws IOException { - return createSocket(new InetSocketAddress(InetAddress.getLocalHost(), 9050), destination, port); - } - static class SocksConnectionException extends IOException { } diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index add3d80c..a97b16a4 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -5,27 +5,25 @@ import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.Pair; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Locale; +import de.thedevstack.conversationsplus.ConversationsPlusColors; + import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.xmpp.jid.Jid; public class UIHelper { - private static String BLACK_HEART_SUIT = "\u2665"; - private static String HEAVY_BLACK_HEART_SUIT = "\u2764"; - private static String WHITE_HEART_SUIT = "\u2661"; - - public static final ArrayList<String> HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); - private static final ArrayList<String> LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( "where are you", //en "where are you now", //en @@ -182,9 +180,8 @@ public class UIHelper { return new Pair<>(getFileDescriptionString(context,message),true); } } else { - if (message.getBody().startsWith(Message.ME_COMMAND)) { - return new Pair<>(message.getBody().replaceAll("^" + Message.ME_COMMAND, - UIHelper.getMessageDisplayName(message) + " "), false); + if (message.hasMeCommand()) { + return new Pair<>(message.getBodyReplacedMeCommand(UIHelper.getMessageDisplayName(message)), false); } else if (GeoHelper.isGeoUri(message.getBody())) { if (message.getStatus() == Message.STATUS_RECEIVED) { return new Pair<>(context.getString(R.string.received_location), true); @@ -195,7 +192,7 @@ public class UIHelper { return new Pair<>(context.getString(R.string.x_file_offered_for_download, getFileDescriptionString(context,message)),true); } else{ - return new Pair<>(message.getBody().trim(), false); + return new Pair<>(message.getBody(), false); } } } @@ -220,7 +217,7 @@ public class UIHelper { } else if (mime.contains("vcard")) { return context.getString(R.string.vcard) ; } else { - return mime; + return message.getRelativeFilePath(); } } @@ -247,13 +244,29 @@ public class UIHelper { } } + public static int getStatusColor(Presence.Status status) { + switch (status) { + case ONLINE: + return ConversationsPlusColors.online(); + case CHAT: + return ConversationsPlusColors.chat(); + case AWAY: + return ConversationsPlusColors.away(); + case XA: + return ConversationsPlusColors.xa(); + case DND: + return ConversationsPlusColors.dnd(); + } + return ConversationsPlusColors.offline(); + } + private static String getDisplayedMucCounterpart(final Jid counterpart) { if (counterpart==null) { return ""; } else if (!counterpart.isBareJid()) { - return counterpart.getResourcepart().trim(); + return counterpart.getResourcepart(); } else { - return counterpart.toString().trim(); + return counterpart.toString(); } } @@ -263,8 +276,24 @@ public class UIHelper { || message.getType() != Message.TYPE_TEXT) { return false; } - String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + String body = message.getBody() == null ? null : message.getBody().toLowerCase(Locale.getDefault()); body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } + + public static String getHumanReadableFileSize(long filesize) { + if (0 > filesize) { + return "?"; + } + double size = Double.valueOf(filesize); + String[] sizes = {" bytes", " Kb", " Mb", " Gb", " Tb"}; + int i = 0; + while (1023 < size) { + size /= 1024d; + ++i; + } + BigDecimal readableSize = new BigDecimal(size); + readableSize = readableSize.setScale(2, BigDecimal.ROUND_HALF_UP); + return readableSize.doubleValue() + sizes[i]; + } } |