aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/pixart/messenger/utils')
-rw-r--r--src/main/java/de/pixart/messenger/utils/BackupFileHeader.java84
-rw-r--r--src/main/java/de/pixart/messenger/utils/Compatibility.java18
-rw-r--r--src/main/java/de/pixart/messenger/utils/ConversationsFileObserver.java24
-rw-r--r--src/main/java/de/pixart/messenger/utils/CryptoHelper.java3
-rw-r--r--src/main/java/de/pixart/messenger/utils/ExceptionHelper.java2
-rw-r--r--src/main/java/de/pixart/messenger/utils/GeoHelper.java76
-rw-r--r--src/main/java/de/pixart/messenger/utils/Namespace.java1
-rw-r--r--src/main/java/de/pixart/messenger/utils/PermissionUtils.java34
-rw-r--r--src/main/java/de/pixart/messenger/utils/PhoneHelper.java7
-rw-r--r--src/main/java/de/pixart/messenger/utils/SerialSingleThreadExecutor.java1
-rw-r--r--src/main/java/de/pixart/messenger/utils/UIHelper.java9
-rw-r--r--src/main/java/de/pixart/messenger/utils/XmppUri.java2
12 files changed, 223 insertions, 38 deletions
diff --git a/src/main/java/de/pixart/messenger/utils/BackupFileHeader.java b/src/main/java/de/pixart/messenger/utils/BackupFileHeader.java
new file mode 100644
index 000000000..19ad9bff9
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/utils/BackupFileHeader.java
@@ -0,0 +1,84 @@
+package de.pixart.messenger.utils;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import rocks.xmpp.addr.Jid;
+
+public class BackupFileHeader {
+
+ private static final int VERSION = 1;
+
+ private String app;
+ private Jid jid;
+ private long timestamp;
+ private byte[] iv;
+ private byte[] salt;
+
+
+ @Override
+ public String toString() {
+ return "BackupFileHeader{" +
+ "app='" + app + '\'' +
+ ", jid=" + jid +
+ ", timestamp=" + timestamp +
+ ", iv=" + CryptoHelper.bytesToHex(iv) +
+ ", salt=" + CryptoHelper.bytesToHex(salt) +
+ '}';
+ }
+
+ public BackupFileHeader(String app, Jid jid, long timestamp, byte[] iv, byte[] salt) {
+ this.app = app;
+ this.jid = jid;
+ this.timestamp = timestamp;
+ this.iv = iv;
+ this.salt = salt;
+ }
+
+ public void write(DataOutputStream dataOutputStream) throws IOException {
+ dataOutputStream.writeInt(VERSION);
+ dataOutputStream.writeUTF(app);
+ dataOutputStream.writeUTF(jid.asBareJid().toEscapedString());
+ dataOutputStream.writeLong(timestamp);
+ dataOutputStream.write(iv);
+ dataOutputStream.write(salt);
+ }
+
+ public static BackupFileHeader read(DataInputStream inputStream) throws IOException {
+ final int version = inputStream.readInt();
+ if (version > VERSION) {
+ throw new IllegalArgumentException("Backup File version was " + version + " but app only supports up to version " + VERSION);
+ }
+ String app = inputStream.readUTF();
+ String jid = inputStream.readUTF();
+ long timestamp = inputStream.readLong();
+ byte[] iv = new byte[12];
+ inputStream.readFully(iv);
+ byte[] salt = new byte[16];
+ inputStream.readFully(salt);
+
+ return new BackupFileHeader(app, Jid.of(jid), timestamp, iv, salt);
+
+ }
+
+ public byte[] getSalt() {
+ return salt;
+ }
+
+ public byte[] getIv() {
+ return iv;
+ }
+
+ public Jid getJid() {
+ return jid;
+ }
+
+ public String getApp() {
+ return app;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/utils/Compatibility.java b/src/main/java/de/pixart/messenger/utils/Compatibility.java
index 38f9db378..c8922e18b 100644
--- a/src/main/java/de/pixart/messenger/utils/Compatibility.java
+++ b/src/main/java/de/pixart/messenger/utils/Compatibility.java
@@ -1,6 +1,7 @@
package de.pixart.messenger.utils;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -11,15 +12,19 @@ import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.support.annotation.BoolRes;
import android.support.v4.content.ContextCompat;
+import android.util.Log;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.ui.SettingsActivity;
import de.pixart.messenger.ui.SettingsFragment;
+import static de.pixart.messenger.services.EventReceiver.EXTRA_NEEDS_FOREGROUND_SERVICE;
+
public class Compatibility {
private static final List<String> UNUSED_SETTINGS_POST_TWENTYSIX = Arrays.asList(
SettingsActivity.SHOW_FOREGROUND_SERVICE,
@@ -102,4 +107,17 @@ public class Compatibility {
}
}
}
+
+ public static void startService(Context context, Intent intent) {
+ try {
+ if (Compatibility.runsAndTargetsTwentySix(context)) {
+ intent.putExtra(EXTRA_NEEDS_FOREGROUND_SERVICE, true);
+ ContextCompat.startForegroundService(context, intent);
+ } else {
+ context.startService(intent);
+ }
+ } catch (RuntimeException e) {
+ Log.d(Config.LOGTAG, context.getClass().getSimpleName() + " was unable to start service");
+ }
+ }
} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/utils/ConversationsFileObserver.java b/src/main/java/de/pixart/messenger/utils/ConversationsFileObserver.java
index 73d5589e4..5e2948b5b 100644
--- a/src/main/java/de/pixart/messenger/utils/ConversationsFileObserver.java
+++ b/src/main/java/de/pixart/messenger/utils/ConversationsFileObserver.java
@@ -8,6 +8,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
+import java.util.concurrent.atomic.AtomicBoolean;
import de.pixart.messenger.Config;
@@ -21,16 +22,26 @@ public abstract class ConversationsFileObserver {
private final String path;
private final List<SingleFileObserver> mObservers = new ArrayList<>();
+ private final AtomicBoolean shouldStop = new AtomicBoolean(true);
protected ConversationsFileObserver(String path) {
this.path = path;
}
- public synchronized void startWatching() {
+ public void startWatching() {
+ shouldStop.set(false);
+ startWatchingInternal();
+ }
+
+ private synchronized void startWatchingInternal() {
Stack<String> stack = new Stack<>();
stack.push(path);
while (!stack.empty()) {
+ if (shouldStop.get()) {
+ Log.d(Config.LOGTAG, "file observer received command to stop");
+ return;
+ }
String parent = stack.pop();
mObservers.add(new SingleFileObserver(parent, FileObserver.DELETE | FileObserver.MOVED_FROM));
final File path = new File(parent);
@@ -44,6 +55,10 @@ public abstract class ConversationsFileObserver {
continue;
}
for (File file : files) {
+ if (shouldStop.get()) {
+ Log.d(Config.LOGTAG, "file observer received command to stop");
+ return;
+ }
if (file.isDirectory() && file.getName().charAt(0) != '.') {
final String currentPath = file.getAbsolutePath();
if (depth(file) <= 8 && !stack.contains(currentPath) && !observing(currentPath)) {
@@ -74,7 +89,12 @@ public abstract class ConversationsFileObserver {
return false;
}
- public synchronized void stopWatching() {
+ public void stopWatching() {
+ shouldStop.set(true);
+ stopWatchingInternal();
+ }
+
+ private synchronized void stopWatchingInternal() {
for (FileObserver observer : mObservers) {
observer.stopWatching();
}
diff --git a/src/main/java/de/pixart/messenger/utils/CryptoHelper.java b/src/main/java/de/pixart/messenger/utils/CryptoHelper.java
index 2104349d8..5d1e7980c 100644
--- a/src/main/java/de/pixart/messenger/utils/CryptoHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/CryptoHelper.java
@@ -63,7 +63,8 @@ public final class CryptoHelper {
}
public static String pronounceable(SecureRandom random) {
- char[] output = new char[random.nextInt(4) * 2 + 5];
+ final int rand = random.nextInt(4);
+ char[] output = new char[rand * 2 + (5 - rand)];
boolean vowel = random.nextBoolean();
for (int i = 0; i < output.length; ++i) {
output[i] = vowel ? VOWELS[random.nextInt(VOWELS.length)] : CONSONANTS[random.nextInt(CONSONANTS.length)];
diff --git a/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java b/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java
index 18238ae60..428aa616e 100644
--- a/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java
@@ -17,7 +17,6 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.List;
import java.util.Locale;
import de.pixart.messenger.Config;
@@ -27,7 +26,6 @@ import de.pixart.messenger.entities.Conversation;
import de.pixart.messenger.entities.Message;
import de.pixart.messenger.services.XmppConnectionService;
import de.pixart.messenger.ui.XmppActivity;
-import rocks.xmpp.addr.Jid;
public class ExceptionHelper {
private static final String FILENAME = "stacktrace.txt";
diff --git a/src/main/java/de/pixart/messenger/utils/GeoHelper.java b/src/main/java/de/pixart/messenger/utils/GeoHelper.java
index 209fd75db..d978c89e0 100644
--- a/src/main/java/de/pixart/messenger/utils/GeoHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/GeoHelper.java
@@ -4,6 +4,8 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import org.osmdroid.util.GeoPoint;
+
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
@@ -11,8 +13,8 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.pixart.messenger.Config;
+import de.pixart.messenger.R;
import de.pixart.messenger.entities.Contact;
-import de.pixart.messenger.entities.Conversation;
import de.pixart.messenger.entities.Conversational;
import de.pixart.messenger.entities.Message;
import de.pixart.messenger.ui.ShowLocationActivity;
@@ -43,41 +45,43 @@ public class GeoHelper {
return "https://xmpp.pix-art.de/staticmap/staticmap.php?center=" + latitude + "," + longitude + "&size=500x500&markers=" + latitude + "," + longitude + "&zoom= " + Config.DEFAULT_ZOOM;
}
- public static ArrayList<Intent> createGeoIntentsFromMessage(Message message, Context context) {
- final ArrayList<Intent> intents = new ArrayList<>();
- Matcher matcher = GEO_URI.matcher(message.getBody());
+ private static GeoPoint parseGeoPoint(String body) throws IllegalArgumentException {
+ Matcher matcher = GEO_URI.matcher(body);
+ ;
if (!matcher.matches()) {
- return intents;
+ throw new IllegalArgumentException("Invalid geo uri");
}
double latitude;
double longitude;
try {
latitude = Double.parseDouble(matcher.group(1));
if (latitude > 90.0 || latitude < -90.0) {
- return intents;
+ throw new IllegalArgumentException("Invalid geo uri");
}
longitude = Double.parseDouble(matcher.group(2));
if (longitude > 180.0 || longitude < -180.0) {
- return intents;
+ throw new IllegalArgumentException("Invalid geo uri");
}
- } catch (NumberFormatException nfe) {
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid geo uri", e);
+ }
+ return new GeoPoint(latitude, longitude);
+ }
+
+ public static ArrayList<Intent> createGeoIntentsFromMessage(Context context, Message message) {
+ final ArrayList<Intent> intents = new ArrayList<>();
+ final GeoPoint geoPoint;
+ try {
+ geoPoint = parseGeoPoint(message.getBody());
+ } catch (IllegalArgumentException e) {
return intents;
}
final Conversational conversation = message.getConversation();
- String label;
- if (conversation instanceof Conversation && conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) {
- try {
- label = "(" + URLEncoder.encode(((Conversation) conversation).getName().toString(), "UTF-8") + ")";
- } catch (UnsupportedEncodingException e) {
- label = "";
- }
- } else {
- label = "";
- }
+ final String label = getLabel(context, message);
Intent locationPluginIntent = new Intent(context, ShowLocationActivity.class);
- locationPluginIntent.putExtra("latitude", latitude);
- locationPluginIntent.putExtra("longitude", longitude);
+ locationPluginIntent.putExtra("latitude", geoPoint.getLatitude());
+ locationPluginIntent.putExtra("longitude", geoPoint.getLongitude());
if (message.getStatus() != Message.STATUS_RECEIVED) {
locationPluginIntent.putExtra("jid", conversation.getAccount().getJid().toString());
locationPluginIntent.putExtra("name", conversation.getAccount().getJid().getLocal());
@@ -93,8 +97,38 @@ public class GeoHelper {
intents.add(locationPluginIntent);
Intent geoIntent = new Intent(Intent.ACTION_VIEW);
- geoIntent.setData(Uri.parse("geo:" + String.valueOf(latitude) + "," + String.valueOf(longitude) + "?q=" + String.valueOf(latitude) + "," + String.valueOf(longitude) + label));
+ geoIntent.setData(Uri.parse("geo:" + String.valueOf(geoPoint.getLatitude()) + "," + String.valueOf(geoPoint.getLongitude()) + "?q=" + String.valueOf(geoPoint.getLatitude()) + "," + String.valueOf(geoPoint.getLongitude()) + label));
intents.add(geoIntent);
return intents;
}
+
+ public static void view(Context context, Message message) {
+ final GeoPoint geoPoint = parseGeoPoint(message.getBody());
+ final String label = getLabel(context, message);
+ context.startActivity(geoIntent(geoPoint, label));
+ }
+
+ private static Intent geoIntent(GeoPoint geoPoint, String label) {
+ Intent geoIntent = new Intent(Intent.ACTION_VIEW);
+ geoIntent.setData(Uri.parse("geo:" + String.valueOf(geoPoint.getLatitude()) + "," + String.valueOf(geoPoint.getLongitude()) + "?q=" + String.valueOf(geoPoint.getLatitude()) + "," + String.valueOf(geoPoint.getLongitude()) + "(" + label + ")"));
+ return geoIntent;
+ }
+
+ public static boolean openInOsmAnd(Context context, Message message) {
+ final GeoPoint geoPoint = parseGeoPoint(message.getBody());
+ final String label = getLabel(context, message);
+ return geoIntent(geoPoint, label).resolveActivity(context.getPackageManager()) != null;
+ }
+
+ private static String getLabel(Context context, Message message) {
+ if (message.getStatus() == Message.STATUS_RECEIVED) {
+ try {
+ return URLEncoder.encode(UIHelper.getMessageDisplayName(message), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError(e);
+ }
+ } else {
+ return context.getString(R.string.me);
+ }
+ }
} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/utils/Namespace.java b/src/main/java/de/pixart/messenger/utils/Namespace.java
index 83d63cdaa..3a3e32f73 100644
--- a/src/main/java/de/pixart/messenger/utils/Namespace.java
+++ b/src/main/java/de/pixart/messenger/utils/Namespace.java
@@ -24,4 +24,5 @@ public final class Namespace {
public static final String BOOKMARKS_CONVERSION = "urn:xmpp:bookmarks-conversion:0";
public static final String BOOKMARKS = "storage:bookmarks";
public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0";
+ public static final String AVATAR_CONVERSION = "urn:xmpp:pep-vcard-conversion:0";
}
diff --git a/src/main/java/de/pixart/messenger/utils/PermissionUtils.java b/src/main/java/de/pixart/messenger/utils/PermissionUtils.java
new file mode 100644
index 000000000..b21ca8869
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/utils/PermissionUtils.java
@@ -0,0 +1,34 @@
+package de.pixart.messenger.utils;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+
+public class PermissionUtils {
+
+ public static boolean allGranted(int[] grantResults) {
+ for (int grantResult : grantResults) {
+ if (grantResult != PackageManager.PERMISSION_GRANTED) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean writeGranted(int[] grantResults, String[] permission) {
+ for (int i = 0; i < grantResults.length; ++i) {
+ if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission[i])) {
+ return grantResults[i] == PackageManager.PERMISSION_GRANTED;
+ }
+ }
+ return false;
+ }
+
+ public static String getFirstDenied(int[] grantResults, String[] permissions) {
+ for (int i = 0; i < grantResults.length; ++i) {
+ if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
+ return permissions[i];
+ }
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/utils/PhoneHelper.java b/src/main/java/de/pixart/messenger/utils/PhoneHelper.java
index 327ae1904..86a9bed1a 100644
--- a/src/main/java/de/pixart/messenger/utils/PhoneHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/PhoneHelper.java
@@ -3,20 +3,13 @@ package de.pixart.messenger.utils;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
-import android.content.CursorLoader;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
-import android.os.Bundle;
-import android.provider.ContactsContract;
import android.provider.ContactsContract.Profile;
import android.provider.Settings;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.RejectedExecutionException;
-
public class PhoneHelper {
@SuppressLint("HardwareIds")
diff --git a/src/main/java/de/pixart/messenger/utils/SerialSingleThreadExecutor.java b/src/main/java/de/pixart/messenger/utils/SerialSingleThreadExecutor.java
index 9846146a8..dc2f2bc09 100644
--- a/src/main/java/de/pixart/messenger/utils/SerialSingleThreadExecutor.java
+++ b/src/main/java/de/pixart/messenger/utils/SerialSingleThreadExecutor.java
@@ -1,6 +1,5 @@
package de.pixart.messenger.utils;
-import android.os.Looper;
import android.util.Log;
import java.util.ArrayDeque;
diff --git a/src/main/java/de/pixart/messenger/utils/UIHelper.java b/src/main/java/de/pixart/messenger/utils/UIHelper.java
index 03af31e23..ea1878557 100644
--- a/src/main/java/de/pixart/messenger/utils/UIHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/UIHelper.java
@@ -263,8 +263,6 @@ public class UIHelper {
case Transferable.STATUS_OFFER_CHECK_FILESIZE:
return new Pair<>(context.getString(R.string.x_file_offered_for_download,
getFileDescriptionString(context, message)), true);
- case Transferable.STATUS_DELETED:
- return new Pair<>(context.getString(R.string.file_deleted), true);
case Transferable.STATUS_FAILED:
return new Pair<>(context.getString(R.string.file_transmission_failed), true);
case Transferable.STATUS_UPLOADING:
@@ -278,6 +276,8 @@ public class UIHelper {
default:
return new Pair<>("", false);
}
+ } else if (message.isFileOrImage() && message.isFileDeleted()) {
+ return new Pair<>(context.getString(R.string.file_deleted), true);
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
return new Pair<>(context.getString(R.string.pgp_message), true);
} else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
@@ -286,7 +286,7 @@ public class UIHelper {
return new Pair<>(context.getString(R.string.not_encrypted_for_this_device), true);
} else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) {
return new Pair<>(context.getString(R.string.omemo_decryption_failed), true);
- } else if (message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) {
+ } else if (message.isFileOrImage()) {
return new Pair<>(getFileDescriptionString(context, message), true);
} else {
final String body = MessageUtils.filterLtrRtl(message.getBody());
@@ -307,6 +307,9 @@ public class UIHelper {
SpannableStringBuilder builder = new SpannableStringBuilder();
for (CharSequence l : CharSequenceUtils.split(styledBody, '\n')) {
if (l.length() > 0) {
+ if (l.toString().equals("```")) {
+ continue;
+ }
char first = l.charAt(0);
if ((first != '>' || !isPositionFollowedByQuoteableCharacter(l,0)) && first != '\u00bb') {
CharSequence line = CharSequenceUtils.trim(l);
diff --git a/src/main/java/de/pixart/messenger/utils/XmppUri.java b/src/main/java/de/pixart/messenger/utils/XmppUri.java
index 9c0b3e666..1ee90aa84 100644
--- a/src/main/java/de/pixart/messenger/utils/XmppUri.java
+++ b/src/main/java/de/pixart/messenger/utils/XmppUri.java
@@ -171,7 +171,7 @@ public class XmppUri {
private boolean hasAction(String query, String action) {
for(String pair : query == null ? new String[0] : query.split(";")) {
final String[] parts = pair.split("=",2);
- if (parts.length == 1 && parts[0].equals(action)) {
+ if (parts.length == 1 && parts[0].toLowerCase(Locale.US).startsWith(action)) {
return true;
}
}