diff options
Diffstat (limited to 'src/main/java/eu/siacs')
7 files changed, 75 insertions, 24 deletions
diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 54a272a23..4ad16559f 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -40,6 +40,8 @@ public final class Config { public static final String XMPP_IP = "185.26.156.37"; // set to null means disable public static final Integer[] XMPP_Ports = {61000, 65000}; // set to null means disable + public static final String BUG_REPORTS = "bugs@pix-art.de"; + public static final String DOMAIN_LOCK = "pix-art.de"; //only allow account creation for this domain public static final String MAGIC_CREATE_DOMAIN = "pix-art.de"; public static final boolean SINGLE_ACCOUNT = true; //set to true to allow only one account @@ -55,6 +57,7 @@ public final class Config { public static final boolean USE_ALWAYS_FOREGROUND = true; //if set to true the foreground service is always enabled public static final int PING_MAX_INTERVAL = 300; + public static final int IDLE_PING_INTERVAL = 600; //540 is minimum according to docs; public static final int PING_MIN_INTERVAL = 30; public static final int PING_TIMEOUT = 15; public static final int SOCKET_TIMEOUT = 15; diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 818ac1d65..4b6877119 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -19,7 +19,7 @@ public class Message extends AbstractEntity { public static final String TABLENAME = "messages"; - public static final String MERGE_SEPARATOR = " \u200B\n\n"; + public static final String MERGE_SEPARATOR = "\n\u0004\n"; public static final int STATUS_RECEIVED = 0; public static final int STATUS_UNSEND = 1; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ad45d8e9a..4a8d813e1 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.services; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.Service; @@ -26,7 +27,6 @@ import android.os.SystemClock; import android.preference.PreferenceManager; import android.provider.ContactsContract; import android.security.KeyChain; -import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; import android.util.LruCache; @@ -129,6 +129,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public static final String ACTION_DISABLE_FOREGROUND = "disable_foreground"; public static final String ACTION_TRY_AGAIN = "try_again"; public static final String ACTION_DISABLE_ACCOUNT = "disable_account"; + public static final String ACTION_IDLE_PING = "idle_ping"; private static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; public static final String ACTION_GCM_TOKEN_REFRESH = "gcm_token_refresh"; public static final String ACTION_GCM_MESSAGE_RECEIVED = "gcm_message_received"; @@ -548,8 +549,14 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa case ACTION_GCM_TOKEN_REFRESH: refreshAllGcmTokens(); break; + case ACTION_IDLE_PING: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + scheduleNextIdlePing(); + } + break; case ACTION_GCM_MESSAGE_RECEIVED: Log.d(Config.LOGTAG,"gcm push message arrived in service. extras="+intent.getExtras()); + break; } } this.wakeLock.acquire(); @@ -624,7 +631,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa if (pingNow) { for (Account account : pingCandidates) { account.getXmppConnection().sendPing(); - Log.d(Config.LOGTAG, account.getJid().toBareJid() + " send ping"); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + " send ping (action="+action+")"); this.scheduleWakeUpCall(Config.PING_TIMEOUT, account.getUuid().hashCode()); } } @@ -756,6 +763,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa toggleForegroundService(); updateUnreadCountBadge(); toggleScreenEventReceiver(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + scheduleNextIdlePing(); + } } @Override @@ -838,16 +848,25 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void scheduleWakeUpCall(int seconds, int requestCode) { final long timeToWake = SystemClock.elapsedRealtime() + (seconds < 0 ? 1 : seconds + 1) * 1000; - - Context context = getApplicationContext(); - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - - Intent intent = new Intent(context, EventReceiver.class); + AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(this, EventReceiver.class); intent.setAction("ping"); - PendingIntent alarmIntent = PendingIntent.getBroadcast(context, requestCode, intent, 0); + PendingIntent alarmIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0); alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, alarmIntent); } + @TargetApi(Build.VERSION_CODES.M) + private void scheduleNextIdlePing() { + Log.d(Config.LOGTAG,"schedule next idle ping"); + AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(this, EventReceiver.class); + intent.setAction(ACTION_IDLE_PING); + alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime()+(Config.IDLE_PING_INTERVAL * 1000), + PendingIntent.getBroadcast(this,0,intent,0) + ); + } + public XmppConnection createConnection(final Account account) { final SharedPreferences sharedPref = getPreferences(); account.setResource(sharedPref.getString("resource", getString(R.string.default_resource)) 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 54cf97933..a22a4bb7f 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -39,6 +39,7 @@ import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.concurrent.RejectedExecutionException; +import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -362,14 +363,31 @@ public class MessageAdapter extends ArrayAdapter<Message> { viewHolder.messageBody.setText(span); } int urlCount = 0; - Matcher matcher = Patterns.WEB_URL.matcher(body); + final Matcher matcher = Patterns.WEB_URL.matcher(body); + int beginWebURL = Integer.MAX_VALUE; + int endWebURL = 0; while (matcher.find()) { + MatchResult result = matcher.toMatchResult(); + beginWebURL = result.start(); + endWebURL = result.end(); urlCount++; } + final Matcher geoMatcher = GeoHelper.GEO_URI.matcher(body); + while (geoMatcher.find()) { + urlCount++; + } + final Matcher xmppMatcher = XMPP_PATTERN.matcher(body); + while (xmppMatcher.find()) { + MatchResult result = xmppMatcher.toMatchResult(); + if (beginWebURL < result.start() || endWebURL > result.end()) { + urlCount++; + } + } viewHolder.messageBody.setTextIsSelectable(urlCount <= 1); viewHolder.messageBody.setAutoLinkMask(0); Linkify.addLinks(viewHolder.messageBody, Linkify.WEB_URLS); Linkify.addLinks(viewHolder.messageBody, XMPP_PATTERN, "xmpp"); + Linkify.addLinks(viewHolder.messageBody, GeoHelper.GEO_URI, "geo"); } else { viewHolder.messageBody.setText(""); viewHolder.messageBody.setTextIsSelectable(false); diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 1ef5fb3f6..253584bf1 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -9,6 +9,7 @@ import org.bouncycastle.asn1.x500.style.IETFUtils; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; @@ -184,9 +185,7 @@ public final class CryptoHelper { //ignored } try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] fingerprint = md.digest(certificate.getEncoded()); - information.putString("sha1", prettifyFingerprintCert(bytesToHex(fingerprint))); + information.putString("sha1", getFingerprintCert(certificate.getEncoded())); } catch (Exception e) { } @@ -196,6 +195,12 @@ public final class CryptoHelper { } } + public static String getFingerprintCert(byte[] input) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] fingerprint = md.digest(input); + return prettifyFingerprintCert(bytesToHex(fingerprint)); + } + public static int encryptionTypeToText(int encryption) { switch (encryption) { case Message.ENCRYPTION_OTR: diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java index 12140bde3..e43117433 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java @@ -8,6 +8,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.Signature; import android.preference.PreferenceManager; import android.text.format.DateUtils; import android.util.Log; @@ -18,6 +19,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.List; import eu.siacs.conversations.Config; @@ -31,6 +34,7 @@ import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; public class ExceptionHelper { + private static SimpleDateFormat DATE_FORMATs = new SimpleDateFormat("yyyy-MM-dd"); public static void init(Context context) { if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof ExceptionHandler)) { Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler( @@ -43,7 +47,7 @@ public class ExceptionHelper { final SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences(activity); boolean crashreport = preferences.getBoolean("crashreport", true); - if (!crashreport) { + if (!crashreport || Config.BUG_REPORTS == null) { return false; } List<Account> accounts = service.getAccounts(); @@ -63,16 +67,18 @@ public class ExceptionHelper { BufferedReader stacktrace = new BufferedReader(inputStreamReader); final StringBuilder report = new StringBuilder(); PackageManager pm = activity.getPackageManager(); - PackageInfo packageInfo = null; + PackageInfo packageInfo; try { - packageInfo = pm.getPackageInfo(activity.getPackageName(), 0); + packageInfo = pm.getPackageInfo(activity.getPackageName(), PackageManager.GET_SIGNATURES); report.append("Version: " + packageInfo.versionName + '\n'); - report.append("Last Update: " - + DateUtils.formatDateTime(activity, - packageInfo.lastUpdateTime, - DateUtils.FORMAT_SHOW_TIME - | DateUtils.FORMAT_SHOW_DATE) + '\n'); - } catch (NameNotFoundException e) { + report.append("Last Update: " + DATE_FORMATs.format(new Date(packageInfo.lastUpdateTime)) + '\n'); + Signature[] signatures = packageInfo.signatures; + if (signatures != null && signatures.length >= 1) { + report.append("SHA-1: " + CryptoHelper.getFingerprintCert(packageInfo.signatures[0].toByteArray()) + "\n"); + } + report.append('\n'); + } catch (Exception e) { + e.printStackTrace(); return false; } String line; @@ -98,7 +104,7 @@ public class ExceptionHelper { Conversation conversation = null; try { conversation = service.findOrCreateConversation(finalAccount, - Jid.fromString("bugs@pix-art.de"), false); + Jid.fromString(Config.BUG_REPORTS), false); } catch (final InvalidJidException ignored) { } Message message = new Message(conversation, report diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index 2db20a447..171e7dba6 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -14,7 +14,7 @@ import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; public class GeoHelper { - private static Pattern GEO_URI = Pattern.compile("geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?", Pattern.CASE_INSENSITIVE); + public static Pattern GEO_URI = Pattern.compile("geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?", Pattern.CASE_INSENSITIVE); public static boolean isGeoUri(String body) { return body != null && GEO_URI.matcher(body).matches(); |