aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/eu/siacs/conversations/Config.java3
-rw-r--r--src/main/java/eu/siacs/conversations/entities/Message.java2
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java35
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java20
-rw-r--r--src/main/java/eu/siacs/conversations/utils/CryptoHelper.java11
-rw-r--r--src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java26
-rw-r--r--src/main/java/eu/siacs/conversations/utils/GeoHelper.java2
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();