initial tor support
This commit is contained in:
parent
06cadab7cc
commit
f0b1761ec3
|
@ -2,6 +2,10 @@ package eu.siacs.conversations;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.chatstate.ChatState;
|
import eu.siacs.conversations.xmpp.chatstate.ChatState;
|
||||||
|
|
||||||
public final class Config {
|
public final class Config {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package eu.siacs.conversations.entities;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
import eu.siacs.conversations.crypto.PgpDecryptionService;
|
import eu.siacs.conversations.crypto.PgpDecryptionService;
|
||||||
|
@ -13,6 +15,7 @@ import org.json.JSONObject;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.interfaces.DSAPublicKey;
|
import java.security.interfaces.DSAPublicKey;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
@ -39,6 +42,8 @@ public class Account extends AbstractEntity {
|
||||||
public static final String KEYS = "keys";
|
public static final String KEYS = "keys";
|
||||||
public static final String AVATAR = "avatar";
|
public static final String AVATAR = "avatar";
|
||||||
public static final String DISPLAY_NAME = "display_name";
|
public static final String DISPLAY_NAME = "display_name";
|
||||||
|
public static final String HOSTNAME = "hostname";
|
||||||
|
public static final String PORT = "port";
|
||||||
|
|
||||||
public static final String PINNED_MECHANISM_KEY = "pinned_mechanism";
|
public static final String PINNED_MECHANISM_KEY = "pinned_mechanism";
|
||||||
|
|
||||||
|
@ -67,7 +72,20 @@ public class Account extends AbstractEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum State {
|
public ArrayList<Parcelable> getHostnamePortBundles() {
|
||||||
|
ArrayList<Parcelable> values = new ArrayList<>();
|
||||||
|
Bundle hostPort = new Bundle();
|
||||||
|
if (hostname != null && !hostname.isEmpty()) {
|
||||||
|
hostPort.putString("name", hostname);
|
||||||
|
} else {
|
||||||
|
hostPort.putString("name", getServer().toString());
|
||||||
|
}
|
||||||
|
hostPort.putInt("port", port);
|
||||||
|
values.add(hostPort);
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum State {
|
||||||
DISABLED,
|
DISABLED,
|
||||||
OFFLINE,
|
OFFLINE,
|
||||||
CONNECTING,
|
CONNECTING,
|
||||||
|
@ -147,6 +165,8 @@ public class Account extends AbstractEntity {
|
||||||
protected JSONObject keys = new JSONObject();
|
protected JSONObject keys = new JSONObject();
|
||||||
protected String avatar;
|
protected String avatar;
|
||||||
protected String displayName = null;
|
protected String displayName = null;
|
||||||
|
protected String hostname = null;
|
||||||
|
protected int port = 5222;
|
||||||
protected boolean online = false;
|
protected boolean online = false;
|
||||||
private OtrService mOtrService = null;
|
private OtrService mOtrService = null;
|
||||||
private AxolotlService axolotlService = null;
|
private AxolotlService axolotlService = null;
|
||||||
|
@ -164,12 +184,12 @@ public class Account extends AbstractEntity {
|
||||||
|
|
||||||
public Account(final Jid jid, final String password) {
|
public Account(final Jid jid, final String password) {
|
||||||
this(java.util.UUID.randomUUID().toString(), jid,
|
this(java.util.UUID.randomUUID().toString(), jid,
|
||||||
password, 0, null, "", null, null);
|
password, 0, null, "", null, null, null, 5222);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account(final String uuid, final Jid jid,
|
public Account(final String uuid, final Jid jid,
|
||||||
final String password, final int options, final String rosterVersion, final String keys,
|
final String password, final int options, final String rosterVersion, final String keys,
|
||||||
final String avatar, String displayName) {
|
final String avatar, String displayName, String hostname, int port) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
if (jid.isBareJid()) {
|
if (jid.isBareJid()) {
|
||||||
|
@ -185,6 +205,8 @@ public class Account extends AbstractEntity {
|
||||||
}
|
}
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
|
this.hostname = hostname;
|
||||||
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account fromCursor(final Cursor cursor) {
|
public static Account fromCursor(final Cursor cursor) {
|
||||||
|
@ -201,7 +223,9 @@ public class Account extends AbstractEntity {
|
||||||
cursor.getString(cursor.getColumnIndex(ROSTERVERSION)),
|
cursor.getString(cursor.getColumnIndex(ROSTERVERSION)),
|
||||||
cursor.getString(cursor.getColumnIndex(KEYS)),
|
cursor.getString(cursor.getColumnIndex(KEYS)),
|
||||||
cursor.getString(cursor.getColumnIndex(AVATAR)),
|
cursor.getString(cursor.getColumnIndex(AVATAR)),
|
||||||
cursor.getString(cursor.getColumnIndex(DISPLAY_NAME)));
|
cursor.getString(cursor.getColumnIndex(DISPLAY_NAME)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(HOSTNAME)),
|
||||||
|
cursor.getInt(cursor.getColumnIndex(PORT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOptionSet(final int option) {
|
public boolean isOptionSet(final int option) {
|
||||||
|
@ -236,6 +260,22 @@ public class Account extends AbstractEntity {
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHostname(String hostname) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHostname() {
|
||||||
|
return this.hostname == null ? "" : this.hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return this.port;
|
||||||
|
}
|
||||||
|
|
||||||
public State getStatus() {
|
public State getStatus() {
|
||||||
if (isOptionSet(OPTION_DISABLED)) {
|
if (isOptionSet(OPTION_DISABLED)) {
|
||||||
return State.DISABLED;
|
return State.DISABLED;
|
||||||
|
@ -314,6 +354,8 @@ public class Account extends AbstractEntity {
|
||||||
values.put(ROSTERVERSION, rosterVersion);
|
values.put(ROSTERVERSION, rosterVersion);
|
||||||
values.put(AVATAR, avatar);
|
values.put(AVATAR, avatar);
|
||||||
values.put(DISPLAY_NAME, displayName);
|
values.put(DISPLAY_NAME, displayName);
|
||||||
|
values.put(HOSTNAME, hostname);
|
||||||
|
values.put(PORT, port);
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
package eu.siacs.conversations.http;
|
package eu.siacs.conversations.http;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import org.apache.http.conn.ssl.StrictHostnameVerifier;
|
import org.apache.http.conn.ssl.StrictHostnameVerifier;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -87,4 +93,12 @@ public class HttpConnectionManager extends AbstractConnectionManager {
|
||||||
} catch (final KeyManagementException | NoSuchAlgorithmException ignored) {
|
} catch (final KeyManagementException | NoSuchAlgorithmException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Proxy getProxy() throws IOException {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
return new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 9050));
|
||||||
|
} else {
|
||||||
|
return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(InetAddress.getLocalHost(), 8118));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,10 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@ -39,10 +42,12 @@ public class HttpDownloadConnection implements Transferable {
|
||||||
private int mStatus = Transferable.STATUS_UNKNOWN;
|
private int mStatus = Transferable.STATUS_UNKNOWN;
|
||||||
private boolean acceptedAutomatically = false;
|
private boolean acceptedAutomatically = false;
|
||||||
private int mProgress = 0;
|
private int mProgress = 0;
|
||||||
|
private boolean mUseTor = false;
|
||||||
|
|
||||||
public HttpDownloadConnection(HttpConnectionManager manager) {
|
public HttpDownloadConnection(HttpConnectionManager manager) {
|
||||||
this.mHttpConnectionManager = manager;
|
this.mHttpConnectionManager = manager;
|
||||||
this.mXmppConnectionService = manager.getXmppConnectionService();
|
this.mXmppConnectionService = manager.getXmppConnectionService();
|
||||||
|
this.mUseTor = mXmppConnectionService.useTorToConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -191,8 +196,15 @@ public class HttpDownloadConnection implements Transferable {
|
||||||
try {
|
try {
|
||||||
Log.d(Config.LOGTAG, "retrieve file size. interactive:" + String.valueOf(interactive));
|
Log.d(Config.LOGTAG, "retrieve file size. interactive:" + String.valueOf(interactive));
|
||||||
changeStatus(STATUS_CHECKING);
|
changeStatus(STATUS_CHECKING);
|
||||||
HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
|
HttpURLConnection connection;
|
||||||
|
if (mUseTor) {
|
||||||
|
connection = (HttpURLConnection) mUrl.openConnection(mHttpConnectionManager.getProxy());
|
||||||
|
} else {
|
||||||
|
connection = (HttpURLConnection) mUrl.openConnection();
|
||||||
|
}
|
||||||
connection.setRequestMethod("HEAD");
|
connection.setRequestMethod("HEAD");
|
||||||
|
Log.d(Config.LOGTAG,"url: "+connection.getURL().toString());
|
||||||
|
Log.d(Config.LOGTAG,"connection: "+connection.toString());
|
||||||
connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getIdentityName());
|
connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getIdentityName());
|
||||||
if (connection instanceof HttpsURLConnection) {
|
if (connection instanceof HttpsURLConnection) {
|
||||||
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive);
|
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive);
|
||||||
|
@ -245,7 +257,12 @@ public class HttpDownloadConnection implements Transferable {
|
||||||
PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_"+message.getUuid());
|
PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_"+message.getUuid());
|
||||||
try {
|
try {
|
||||||
wakeLock.acquire();
|
wakeLock.acquire();
|
||||||
HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection();
|
HttpURLConnection connection;
|
||||||
|
if (mUseTor) {
|
||||||
|
connection = (HttpURLConnection) mUrl.openConnection(mHttpConnectionManager.getProxy());
|
||||||
|
} else {
|
||||||
|
connection = (HttpURLConnection) mUrl.openConnection();
|
||||||
|
}
|
||||||
if (connection instanceof HttpsURLConnection) {
|
if (connection instanceof HttpsURLConnection) {
|
||||||
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive);
|
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, interactive);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,10 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
@ -46,6 +49,7 @@ public class HttpUploadConnection implements Transferable {
|
||||||
private String mime;
|
private String mime;
|
||||||
private URL mGetUrl;
|
private URL mGetUrl;
|
||||||
private URL mPutUrl;
|
private URL mPutUrl;
|
||||||
|
private boolean mUseTor = false;
|
||||||
|
|
||||||
private byte[] key = null;
|
private byte[] key = null;
|
||||||
|
|
||||||
|
@ -56,6 +60,7 @@ public class HttpUploadConnection implements Transferable {
|
||||||
public HttpUploadConnection(HttpConnectionManager httpConnectionManager) {
|
public HttpUploadConnection(HttpConnectionManager httpConnectionManager) {
|
||||||
this.mHttpConnectionManager = httpConnectionManager;
|
this.mHttpConnectionManager = httpConnectionManager;
|
||||||
this.mXmppConnectionService = httpConnectionManager.getXmppConnectionService();
|
this.mXmppConnectionService = httpConnectionManager.getXmppConnectionService();
|
||||||
|
this.mUseTor = mXmppConnectionService.useTorToConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,7 +163,11 @@ public class HttpUploadConnection implements Transferable {
|
||||||
try {
|
try {
|
||||||
wakeLock.acquire();
|
wakeLock.acquire();
|
||||||
Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString());
|
Log.d(Config.LOGTAG, "uploading to " + mPutUrl.toString());
|
||||||
connection = (HttpURLConnection) mPutUrl.openConnection();
|
if (mUseTor) {
|
||||||
|
connection = (HttpURLConnection) mPutUrl.openConnection(mHttpConnectionManager.getProxy());
|
||||||
|
} else {
|
||||||
|
connection = (HttpURLConnection) mPutUrl.openConnection();
|
||||||
|
}
|
||||||
if (connection instanceof HttpsURLConnection) {
|
if (connection instanceof HttpsURLConnection) {
|
||||||
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, true);
|
mHttpConnectionManager.setupTrustManager((HttpsURLConnection) connection, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
private static DatabaseBackend instance = null;
|
private static DatabaseBackend instance = null;
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "history";
|
private static final String DATABASE_NAME = "history";
|
||||||
private static final int DATABASE_VERSION = 19;
|
private static final int DATABASE_VERSION = 20;
|
||||||
|
|
||||||
private static String CREATE_CONTATCS_STATEMENT = "create table "
|
private static String CREATE_CONTATCS_STATEMENT = "create table "
|
||||||
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
|
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
|
||||||
|
@ -59,41 +59,41 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE "
|
private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE "
|
||||||
+ SQLiteAxolotlStore.PREKEY_TABLENAME + "("
|
+ SQLiteAxolotlStore.PREKEY_TABLENAME + "("
|
||||||
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
||||||
+ SQLiteAxolotlStore.ID + " INTEGER, "
|
+ SQLiteAxolotlStore.ID + " INTEGER, "
|
||||||
+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
||||||
+ SQLiteAxolotlStore.ACCOUNT
|
+ SQLiteAxolotlStore.ACCOUNT
|
||||||
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
||||||
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
||||||
+ SQLiteAxolotlStore.ID
|
+ SQLiteAxolotlStore.ID
|
||||||
+ ") ON CONFLICT REPLACE"
|
+ ") ON CONFLICT REPLACE"
|
||||||
+");";
|
+ ");";
|
||||||
|
|
||||||
private static String CREATE_SIGNED_PREKEYS_STATEMENT = "CREATE TABLE "
|
private static String CREATE_SIGNED_PREKEYS_STATEMENT = "CREATE TABLE "
|
||||||
+ SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME + "("
|
+ SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME + "("
|
||||||
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
||||||
+ SQLiteAxolotlStore.ID + " INTEGER, "
|
+ SQLiteAxolotlStore.ID + " INTEGER, "
|
||||||
+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
||||||
+ SQLiteAxolotlStore.ACCOUNT
|
+ SQLiteAxolotlStore.ACCOUNT
|
||||||
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
||||||
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
||||||
+ SQLiteAxolotlStore.ID
|
+ SQLiteAxolotlStore.ID
|
||||||
+ ") ON CONFLICT REPLACE"+
|
+ ") ON CONFLICT REPLACE" +
|
||||||
");";
|
");";
|
||||||
|
|
||||||
private static String CREATE_SESSIONS_STATEMENT = "CREATE TABLE "
|
private static String CREATE_SESSIONS_STATEMENT = "CREATE TABLE "
|
||||||
+ SQLiteAxolotlStore.SESSION_TABLENAME + "("
|
+ SQLiteAxolotlStore.SESSION_TABLENAME + "("
|
||||||
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
|
||||||
+ SQLiteAxolotlStore.NAME + " TEXT, "
|
+ SQLiteAxolotlStore.NAME + " TEXT, "
|
||||||
+ SQLiteAxolotlStore.DEVICE_ID + " INTEGER, "
|
+ SQLiteAxolotlStore.DEVICE_ID + " INTEGER, "
|
||||||
+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
+ SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY("
|
||||||
+ SQLiteAxolotlStore.ACCOUNT
|
+ SQLiteAxolotlStore.ACCOUNT
|
||||||
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
||||||
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
||||||
+ SQLiteAxolotlStore.NAME + ", "
|
+ SQLiteAxolotlStore.NAME + ", "
|
||||||
+ SQLiteAxolotlStore.DEVICE_ID
|
+ SQLiteAxolotlStore.DEVICE_ID
|
||||||
+ ") ON CONFLICT REPLACE"
|
+ ") ON CONFLICT REPLACE"
|
||||||
+");";
|
+ ");";
|
||||||
|
|
||||||
private static String CREATE_IDENTITIES_STATEMENT = "CREATE TABLE "
|
private static String CREATE_IDENTITIES_STATEMENT = "CREATE TABLE "
|
||||||
+ SQLiteAxolotlStore.IDENTITIES_TABLENAME + "("
|
+ SQLiteAxolotlStore.IDENTITIES_TABLENAME + "("
|
||||||
|
@ -106,10 +106,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
+ SQLiteAxolotlStore.ACCOUNT
|
+ SQLiteAxolotlStore.ACCOUNT
|
||||||
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
+ ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, "
|
||||||
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
+ "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", "
|
||||||
+ SQLiteAxolotlStore.NAME + ", "
|
+ SQLiteAxolotlStore.NAME + ", "
|
||||||
+ SQLiteAxolotlStore.FINGERPRINT
|
+ SQLiteAxolotlStore.FINGERPRINT
|
||||||
+ ") ON CONFLICT IGNORE"
|
+ ") ON CONFLICT IGNORE"
|
||||||
+");";
|
+ ");";
|
||||||
|
|
||||||
private DatabaseBackend(Context context) {
|
private DatabaseBackend(Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
@ -124,7 +124,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
+ Account.DISPLAY_NAME + " TEXT, "
|
+ Account.DISPLAY_NAME + " TEXT, "
|
||||||
+ Account.ROSTERVERSION + " TEXT," + Account.OPTIONS
|
+ Account.ROSTERVERSION + " TEXT," + Account.OPTIONS
|
||||||
+ " NUMBER, " + Account.AVATAR + " TEXT, " + Account.KEYS
|
+ " NUMBER, " + Account.AVATAR + " TEXT, " + Account.KEYS
|
||||||
+ " TEXT)");
|
+ " TEXT, " + Account.HOSTNAME + " TEXT, " + Account.PORT + " NUMBER DEFAULT 5222)");
|
||||||
db.execSQL("create table " + Conversation.TABLENAME + " ("
|
db.execSQL("create table " + Conversation.TABLENAME + " ("
|
||||||
+ Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME
|
+ Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME
|
||||||
+ " TEXT, " + Conversation.CONTACT + " TEXT, "
|
+ " TEXT, " + Conversation.CONTACT + " TEXT, "
|
||||||
|
@ -202,23 +202,23 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
if (oldVersion < 11 && newVersion >= 11) {
|
if (oldVersion < 11 && newVersion >= 11) {
|
||||||
db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN "
|
db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN "
|
||||||
+ Contact.GROUPS + " TEXT");
|
+ Contact.GROUPS + " TEXT");
|
||||||
db.execSQL("delete from "+Contact.TABLENAME);
|
db.execSQL("delete from " + Contact.TABLENAME);
|
||||||
db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL");
|
db.execSQL("update " + Account.TABLENAME + " set " + Account.ROSTERVERSION + " = NULL");
|
||||||
}
|
}
|
||||||
if (oldVersion < 12 && newVersion >= 12) {
|
if (oldVersion < 12 && newVersion >= 12) {
|
||||||
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "
|
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "
|
||||||
+ Message.SERVER_MSG_ID + " TEXT");
|
+ Message.SERVER_MSG_ID + " TEXT");
|
||||||
}
|
}
|
||||||
if (oldVersion < 13 && newVersion >= 13) {
|
if (oldVersion < 13 && newVersion >= 13) {
|
||||||
db.execSQL("delete from "+Contact.TABLENAME);
|
db.execSQL("delete from " + Contact.TABLENAME);
|
||||||
db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL");
|
db.execSQL("update " + Account.TABLENAME + " set " + Account.ROSTERVERSION + " = NULL");
|
||||||
}
|
}
|
||||||
if (oldVersion < 14 && newVersion >= 14) {
|
if (oldVersion < 14 && newVersion >= 14) {
|
||||||
// migrate db to new, canonicalized JID domainpart representation
|
// migrate db to new, canonicalized JID domainpart representation
|
||||||
|
|
||||||
// Conversation table
|
// Conversation table
|
||||||
Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME, new String[0]);
|
Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME, new String[0]);
|
||||||
while(cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
String newJid;
|
String newJid;
|
||||||
try {
|
try {
|
||||||
newJid = Jid.fromString(
|
newJid = Jid.fromString(
|
||||||
|
@ -226,8 +226,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
).toString();
|
).toString();
|
||||||
} catch (InvalidJidException ignored) {
|
} catch (InvalidJidException ignored) {
|
||||||
Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID "
|
Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID "
|
||||||
+cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID))
|
+ cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID))
|
||||||
+": " + ignored +". Skipping...");
|
+ ": " + ignored + ". Skipping...");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,14 +236,14 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
cursor.getString(cursor.getColumnIndex(Conversation.UUID)),
|
cursor.getString(cursor.getColumnIndex(Conversation.UUID)),
|
||||||
};
|
};
|
||||||
db.execSQL("update " + Conversation.TABLENAME
|
db.execSQL("update " + Conversation.TABLENAME
|
||||||
+ " set " + Conversation.CONTACTJID + " = ? "
|
+ " set " + Conversation.CONTACTJID + " = ? "
|
||||||
+ " where " + Conversation.UUID + " = ?", updateArgs);
|
+ " where " + Conversation.UUID + " = ?", updateArgs);
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
|
||||||
// Contact table
|
// Contact table
|
||||||
cursor = db.rawQuery("select * from " + Contact.TABLENAME, new String[0]);
|
cursor = db.rawQuery("select * from " + Contact.TABLENAME, new String[0]);
|
||||||
while(cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
String newJid;
|
String newJid;
|
||||||
try {
|
try {
|
||||||
newJid = Jid.fromString(
|
newJid = Jid.fromString(
|
||||||
|
@ -251,8 +251,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
).toString();
|
).toString();
|
||||||
} catch (InvalidJidException ignored) {
|
} catch (InvalidJidException ignored) {
|
||||||
Log.e(Config.LOGTAG, "Failed to migrate Contact JID "
|
Log.e(Config.LOGTAG, "Failed to migrate Contact JID "
|
||||||
+cursor.getString(cursor.getColumnIndex(Contact.JID))
|
+ cursor.getString(cursor.getColumnIndex(Contact.JID))
|
||||||
+": " + ignored +". Skipping...");
|
+ ": " + ignored + ". Skipping...");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
// Account table
|
// Account table
|
||||||
cursor = db.rawQuery("select * from " + Account.TABLENAME, new String[0]);
|
cursor = db.rawQuery("select * from " + Account.TABLENAME, new String[0]);
|
||||||
while(cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
String newServer;
|
String newServer;
|
||||||
try {
|
try {
|
||||||
newServer = Jid.fromParts(
|
newServer = Jid.fromParts(
|
||||||
|
@ -280,8 +280,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
).getDomainpart();
|
).getDomainpart();
|
||||||
} catch (InvalidJidException ignored) {
|
} catch (InvalidJidException ignored) {
|
||||||
Log.e(Config.LOGTAG, "Failed to migrate Account SERVER "
|
Log.e(Config.LOGTAG, "Failed to migrate Account SERVER "
|
||||||
+cursor.getString(cursor.getColumnIndex(Account.SERVER))
|
+ cursor.getString(cursor.getColumnIndex(Account.SERVER))
|
||||||
+": " + ignored +". Skipping...");
|
+ ": " + ignored + ". Skipping...");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
if (oldVersion < 15 && newVersion >= 15) {
|
if (oldVersion < 15 && newVersion >= 15) {
|
||||||
recreateAxolotlDb(db);
|
recreateAxolotlDb(db);
|
||||||
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "
|
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "
|
||||||
+ Message.FINGERPRINT + " TEXT");
|
+ Message.FINGERPRINT + " TEXT");
|
||||||
|
@ -305,7 +305,11 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
+ Message.CARBON + " INTEGER");
|
+ Message.CARBON + " INTEGER");
|
||||||
}
|
}
|
||||||
if (oldVersion < 19 && newVersion >= 19) {
|
if (oldVersion < 19 && newVersion >= 19) {
|
||||||
db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN "+ Account.DISPLAY_NAME+ " TEXT");
|
db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.DISPLAY_NAME + " TEXT");
|
||||||
|
}
|
||||||
|
if (oldVersion < 20 && newVersion >= 20) {
|
||||||
|
db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.HOSTNAME + " TEXT");
|
||||||
|
db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.PORT + " NUMBER DEFAULT 5222");
|
||||||
}
|
}
|
||||||
/* Any migrations that alter the Account table need to happen BEFORE this migration, as it
|
/* Any migrations that alter the Account table need to happen BEFORE this migration, as it
|
||||||
* depends on account de-serialization.
|
* depends on account de-serialization.
|
||||||
|
@ -314,7 +318,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
List<Account> accounts = getAccounts(db);
|
List<Account> accounts = getAccounts(db);
|
||||||
for (Account account : accounts) {
|
for (Account account : accounts) {
|
||||||
String ownDeviceIdString = account.getKey(SQLiteAxolotlStore.JSONKEY_REGISTRATION_ID);
|
String ownDeviceIdString = account.getKey(SQLiteAxolotlStore.JSONKEY_REGISTRATION_ID);
|
||||||
if ( ownDeviceIdString == null ) {
|
if (ownDeviceIdString == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int ownDeviceId = Integer.valueOf(ownDeviceIdString);
|
int ownDeviceId = Integer.valueOf(ownDeviceIdString);
|
||||||
|
@ -324,12 +328,12 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
if (identityKeyPair != null) {
|
if (identityKeyPair != null) {
|
||||||
setIdentityKeyTrust(db, account, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.TRUSTED);
|
setIdentityKeyTrust(db, account, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.TRUSTED);
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not load own identity key pair");
|
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not load own identity key pair");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oldVersion < 18 && newVersion >= 18) {
|
if (oldVersion < 18 && newVersion >= 18) {
|
||||||
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "+ Message.READ+ " NUMBER DEFAULT 1");
|
db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.READ + " NUMBER DEFAULT 1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +378,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
public CopyOnWriteArrayList<Conversation> getConversations(int status) {
|
public CopyOnWriteArrayList<Conversation> getConversations(int status) {
|
||||||
CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<>();
|
CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<>();
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
String[] selectionArgs = { Integer.toString(status) };
|
String[] selectionArgs = {Integer.toString(status)};
|
||||||
Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME
|
Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME
|
||||||
+ " where " + Conversation.STATUS + " = ? order by "
|
+ " where " + Conversation.STATUS + " = ? order by "
|
||||||
+ Conversation.CREATED + " desc", selectionArgs);
|
+ Conversation.CREATED + " desc", selectionArgs);
|
||||||
|
@ -390,20 +394,20 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Message> getMessages(Conversation conversation, int limit,
|
public ArrayList<Message> getMessages(Conversation conversation, int limit,
|
||||||
long timestamp) {
|
long timestamp) {
|
||||||
ArrayList<Message> list = new ArrayList<>();
|
ArrayList<Message> list = new ArrayList<>();
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
if (timestamp == -1) {
|
if (timestamp == -1) {
|
||||||
String[] selectionArgs = { conversation.getUuid() };
|
String[] selectionArgs = {conversation.getUuid()};
|
||||||
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
+ "=?", selectionArgs, null, null, Message.TIME_SENT
|
+ "=?", selectionArgs, null, null, Message.TIME_SENT
|
||||||
+ " DESC", String.valueOf(limit));
|
+ " DESC", String.valueOf(limit));
|
||||||
} else {
|
} else {
|
||||||
String[] selectionArgs = { conversation.getUuid(),
|
String[] selectionArgs = {conversation.getUuid(),
|
||||||
Long.toString(timestamp) };
|
Long.toString(timestamp)};
|
||||||
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
+ "=? and " + Message.TIME_SENT + "<?", selectionArgs,
|
+ "=? and " + Message.TIME_SENT + "<?", selectionArgs,
|
||||||
null, null, Message.TIME_SENT + " DESC",
|
null, null, Message.TIME_SENT + " DESC",
|
||||||
String.valueOf(limit));
|
String.valueOf(limit));
|
||||||
}
|
}
|
||||||
|
@ -419,13 +423,13 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<Message> getMessagesIterable(final Conversation conversation){
|
public Iterable<Message> getMessagesIterable(final Conversation conversation) {
|
||||||
return new Iterable<Message>() {
|
return new Iterable<Message>() {
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Message> iterator() {
|
public Iterator<Message> iterator() {
|
||||||
class MessageIterator implements Iterator<Message>{
|
class MessageIterator implements Iterator<Message> {
|
||||||
SQLiteDatabase db = getReadableDatabase();
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
String[] selectionArgs = { conversation.getUuid() };
|
String[] selectionArgs = {conversation.getUuid()};
|
||||||
Cursor cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
Cursor cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
+ "=?", selectionArgs, null, null, Message.TIME_SENT
|
+ "=?", selectionArgs, null, null, Message.TIME_SENT
|
||||||
+ " ASC", null);
|
+ " ASC", null);
|
||||||
|
@ -458,10 +462,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public Conversation findConversation(final Account account, final Jid contactJid) {
|
public Conversation findConversation(final Account account, final Jid contactJid) {
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
String[] selectionArgs = { account.getUuid(),
|
String[] selectionArgs = {account.getUuid(),
|
||||||
contactJid.toBareJid().toString() + "/%",
|
contactJid.toBareJid().toString() + "/%",
|
||||||
contactJid.toBareJid().toString()
|
contactJid.toBareJid().toString()
|
||||||
};
|
};
|
||||||
Cursor cursor = db.query(Conversation.TABLENAME, null,
|
Cursor cursor = db.query(Conversation.TABLENAME, null,
|
||||||
Conversation.ACCOUNT + "=? AND (" + Conversation.CONTACTJID
|
Conversation.ACCOUNT + "=? AND (" + Conversation.CONTACTJID
|
||||||
+ " like ? OR " + Conversation.CONTACTJID + "=?)", selectionArgs, null, null, null);
|
+ " like ? OR " + Conversation.CONTACTJID + "=?)", selectionArgs, null, null, null);
|
||||||
|
@ -475,7 +479,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public void updateConversation(final Conversation conversation) {
|
public void updateConversation(final Conversation conversation) {
|
||||||
final SQLiteDatabase db = this.getWritableDatabase();
|
final SQLiteDatabase db = this.getWritableDatabase();
|
||||||
final String[] args = { conversation.getUuid() };
|
final String[] args = {conversation.getUuid()};
|
||||||
db.update(Conversation.TABLENAME, conversation.getContentValues(),
|
db.update(Conversation.TABLENAME, conversation.getContentValues(),
|
||||||
Conversation.UUID + "=?", args);
|
Conversation.UUID + "=?", args);
|
||||||
}
|
}
|
||||||
|
@ -498,14 +502,14 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public void updateAccount(Account account) {
|
public void updateAccount(Account account) {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
String[] args = { account.getUuid() };
|
String[] args = {account.getUuid()};
|
||||||
db.update(Account.TABLENAME, account.getContentValues(), Account.UUID
|
db.update(Account.TABLENAME, account.getContentValues(), Account.UUID
|
||||||
+ "=?", args);
|
+ "=?", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAccount(Account account) {
|
public void deleteAccount(Account account) {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
String[] args = { account.getUuid() };
|
String[] args = {account.getUuid()};
|
||||||
db.delete(Account.TABLENAME, Account.UUID + "=?", args);
|
db.delete(Account.TABLENAME, Account.UUID + "=?", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +538,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public void updateMessage(Message message) {
|
public void updateMessage(Message message) {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
String[] args = { message.getUuid() };
|
String[] args = {message.getUuid()};
|
||||||
db.update(Message.TABLENAME, message.getContentValues(), Message.UUID
|
db.update(Message.TABLENAME, message.getContentValues(), Message.UUID
|
||||||
+ "=?", args);
|
+ "=?", args);
|
||||||
}
|
}
|
||||||
|
@ -542,7 +546,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
public void readRoster(Roster roster) {
|
public void readRoster(Roster roster) {
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
String args[] = { roster.getAccount().getUuid() };
|
String args[] = {roster.getAccount().getUuid()};
|
||||||
cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", args, null, null, null);
|
cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", args, null, null, null);
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
roster.initContact(Contact.fromCursor(cursor));
|
roster.initContact(Contact.fromCursor(cursor));
|
||||||
|
@ -558,7 +562,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
db.insert(Contact.TABLENAME, null, contact.getContentValues());
|
db.insert(Contact.TABLENAME, null, contact.getContentValues());
|
||||||
} else {
|
} else {
|
||||||
String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?";
|
String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?";
|
||||||
String[] whereArgs = { account.getUuid(), contact.getJid().toString() };
|
String[] whereArgs = {account.getUuid(), contact.getJid().toString()};
|
||||||
db.delete(Contact.TABLENAME, where, whereArgs);
|
db.delete(Contact.TABLENAME, where, whereArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,19 +572,19 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public void deleteMessage(Message message) {
|
public void deleteMessage(Message message) {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
String[] args = { message.getUuid() };
|
String[] args = {message.getUuid()};
|
||||||
db.delete(Message.TABLENAME, Message.UUID + "=?", args);
|
db.delete(Message.TABLENAME, Message.UUID + "=?", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteMessagesInConversation(Conversation conversation) {
|
public void deleteMessagesInConversation(Conversation conversation) {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
String[] args = { conversation.getUuid() };
|
String[] args = {conversation.getUuid()};
|
||||||
db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args);
|
db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Conversation findConversationByUuid(String conversationUuid) {
|
public Conversation findConversationByUuid(String conversationUuid) {
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
String[] selectionArgs = { conversationUuid };
|
String[] selectionArgs = {conversationUuid};
|
||||||
Cursor cursor = db.query(Conversation.TABLENAME, null,
|
Cursor cursor = db.query(Conversation.TABLENAME, null,
|
||||||
Conversation.UUID + "=?", selectionArgs, null, null, null);
|
Conversation.UUID + "=?", selectionArgs, null, null, null);
|
||||||
if (cursor.getCount() == 0) {
|
if (cursor.getCount() == 0) {
|
||||||
|
@ -594,7 +598,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public Message findMessageByUuid(String messageUuid) {
|
public Message findMessageByUuid(String messageUuid) {
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
String[] selectionArgs = { messageUuid };
|
String[] selectionArgs = {messageUuid};
|
||||||
Cursor cursor = db.query(Message.TABLENAME, null, Message.UUID + "=?",
|
Cursor cursor = db.query(Message.TABLENAME, null, Message.UUID + "=?",
|
||||||
selectionArgs, null, null, null);
|
selectionArgs, null, null, null);
|
||||||
if (cursor.getCount() == 0) {
|
if (cursor.getCount() == 0) {
|
||||||
|
@ -608,7 +612,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public Account findAccountByUuid(String accountUuid) {
|
public Account findAccountByUuid(String accountUuid) {
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
String[] selectionArgs = { accountUuid };
|
String[] selectionArgs = {accountUuid};
|
||||||
Cursor cursor = db.query(Account.TABLENAME, null, Account.UUID + "=?",
|
Cursor cursor = db.query(Account.TABLENAME, null, Account.UUID + "=?",
|
||||||
selectionArgs, null, null, null);
|
selectionArgs, null, null, null);
|
||||||
if (cursor.getCount() == 0) {
|
if (cursor.getCount() == 0) {
|
||||||
|
@ -624,9 +628,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
ArrayList<Message> list = new ArrayList<>();
|
ArrayList<Message> list = new ArrayList<>();
|
||||||
SQLiteDatabase db = this.getReadableDatabase();
|
SQLiteDatabase db = this.getReadableDatabase();
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
String[] selectionArgs = { conversation.getUuid(), String.valueOf(Message.TYPE_IMAGE) };
|
String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.TYPE_IMAGE)};
|
||||||
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION
|
||||||
+ "=? AND "+Message.TYPE+"=?", selectionArgs, null, null,null);
|
+ "=? AND " + Message.TYPE + "=?", selectionArgs, null, null, null);
|
||||||
if (cursor.getCount() > 0) {
|
if (cursor.getCount() > 0) {
|
||||||
cursor.moveToLast();
|
cursor.moveToLast();
|
||||||
do {
|
do {
|
||||||
|
@ -659,10 +663,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
public SessionRecord loadSession(Account account, AxolotlAddress contact) {
|
public SessionRecord loadSession(Account account, AxolotlAddress contact) {
|
||||||
SessionRecord session = null;
|
SessionRecord session = null;
|
||||||
Cursor cursor = getCursorForSession(account, contact);
|
Cursor cursor = getCursorForSession(account, contact);
|
||||||
if(cursor.getCount() != 0) {
|
if (cursor.getCount() != 0) {
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
try {
|
try {
|
||||||
session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT));
|
session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
|
@ -689,7 +693,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
selectionArgs,
|
selectionArgs,
|
||||||
null, null, null);
|
null, null, null);
|
||||||
|
|
||||||
while(cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
devices.add(cursor.getInt(
|
devices.add(cursor.getInt(
|
||||||
cursor.getColumnIndex(SQLiteAxolotlStore.DEVICE_ID)));
|
cursor.getColumnIndex(SQLiteAxolotlStore.DEVICE_ID)));
|
||||||
}
|
}
|
||||||
|
@ -710,7 +714,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(SQLiteAxolotlStore.NAME, contact.getName());
|
values.put(SQLiteAxolotlStore.NAME, contact.getName());
|
||||||
values.put(SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId());
|
values.put(SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId());
|
||||||
values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(session.serialize(),Base64.DEFAULT));
|
values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(session.serialize(), Base64.DEFAULT));
|
||||||
values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
||||||
db.insert(SQLiteAxolotlStore.SESSION_TABLENAME, null, values);
|
db.insert(SQLiteAxolotlStore.SESSION_TABLENAME, null, values);
|
||||||
}
|
}
|
||||||
|
@ -757,11 +761,11 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
public PreKeyRecord loadPreKey(Account account, int preKeyId) {
|
public PreKeyRecord loadPreKey(Account account, int preKeyId) {
|
||||||
PreKeyRecord record = null;
|
PreKeyRecord record = null;
|
||||||
Cursor cursor = getCursorForPreKey(account, preKeyId);
|
Cursor cursor = getCursorForPreKey(account, preKeyId);
|
||||||
if(cursor.getCount() != 0) {
|
if (cursor.getCount() != 0) {
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
try {
|
try {
|
||||||
record = new PreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT));
|
record = new PreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT));
|
||||||
} catch (IOException e ) {
|
} catch (IOException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,7 +784,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(SQLiteAxolotlStore.ID, record.getId());
|
values.put(SQLiteAxolotlStore.ID, record.getId());
|
||||||
values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT));
|
values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(), Base64.DEFAULT));
|
||||||
values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
||||||
db.insert(SQLiteAxolotlStore.PREKEY_TABLENAME, null, values);
|
db.insert(SQLiteAxolotlStore.PREKEY_TABLENAME, null, values);
|
||||||
}
|
}
|
||||||
|
@ -810,11 +814,11 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
public SignedPreKeyRecord loadSignedPreKey(Account account, int signedPreKeyId) {
|
public SignedPreKeyRecord loadSignedPreKey(Account account, int signedPreKeyId) {
|
||||||
SignedPreKeyRecord record = null;
|
SignedPreKeyRecord record = null;
|
||||||
Cursor cursor = getCursorForSignedPreKey(account, signedPreKeyId);
|
Cursor cursor = getCursorForSignedPreKey(account, signedPreKeyId);
|
||||||
if(cursor.getCount() != 0) {
|
if (cursor.getCount() != 0) {
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
try {
|
try {
|
||||||
record = new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT));
|
record = new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT));
|
||||||
} catch (IOException e ) {
|
} catch (IOException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,7 +837,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
selectionArgs,
|
selectionArgs,
|
||||||
null, null, null);
|
null, null, null);
|
||||||
|
|
||||||
while(cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
try {
|
try {
|
||||||
prekeys.add(new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT)));
|
prekeys.add(new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT)));
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
|
@ -854,7 +858,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(SQLiteAxolotlStore.ID, record.getId());
|
values.put(SQLiteAxolotlStore.ID, record.getId());
|
||||||
values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT));
|
values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(), Base64.DEFAULT));
|
||||||
values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid());
|
||||||
db.insert(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, null, values);
|
db.insert(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, null, values);
|
||||||
}
|
}
|
||||||
|
@ -874,7 +878,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String name, boolean own) {
|
private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String name, boolean own) {
|
||||||
return getIdentityKeyCursor(db, account, name, own, null);
|
return getIdentityKeyCursor(db, account, name, own, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cursor getIdentityKeyCursor(Account account, String fingerprint) {
|
private Cursor getIdentityKeyCursor(Account account, String fingerprint) {
|
||||||
|
@ -892,16 +896,16 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
ArrayList<String> selectionArgs = new ArrayList<>(4);
|
ArrayList<String> selectionArgs = new ArrayList<>(4);
|
||||||
selectionArgs.add(account.getUuid());
|
selectionArgs.add(account.getUuid());
|
||||||
String selectionString = SQLiteAxolotlStore.ACCOUNT + " = ?";
|
String selectionString = SQLiteAxolotlStore.ACCOUNT + " = ?";
|
||||||
if (name != null){
|
if (name != null) {
|
||||||
selectionArgs.add(name);
|
selectionArgs.add(name);
|
||||||
selectionString += " AND " + SQLiteAxolotlStore.NAME + " = ?";
|
selectionString += " AND " + SQLiteAxolotlStore.NAME + " = ?";
|
||||||
}
|
}
|
||||||
if (fingerprint != null){
|
if (fingerprint != null) {
|
||||||
selectionArgs.add(fingerprint);
|
selectionArgs.add(fingerprint);
|
||||||
selectionString += " AND " + SQLiteAxolotlStore.FINGERPRINT + " = ?";
|
selectionString += " AND " + SQLiteAxolotlStore.FINGERPRINT + " = ?";
|
||||||
}
|
}
|
||||||
if (own != null){
|
if (own != null) {
|
||||||
selectionArgs.add(own?"1":"0");
|
selectionArgs.add(own ? "1" : "0");
|
||||||
selectionString += " AND " + SQLiteAxolotlStore.OWN + " = ?";
|
selectionString += " AND " + SQLiteAxolotlStore.OWN + " = ?";
|
||||||
}
|
}
|
||||||
Cursor cursor = db.query(SQLiteAxolotlStore.IDENTITIES_TABLENAME,
|
Cursor cursor = db.query(SQLiteAxolotlStore.IDENTITIES_TABLENAME,
|
||||||
|
@ -922,12 +926,12 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
String name = account.getJid().toBareJid().toString();
|
String name = account.getJid().toBareJid().toString();
|
||||||
IdentityKeyPair identityKeyPair = null;
|
IdentityKeyPair identityKeyPair = null;
|
||||||
Cursor cursor = getIdentityKeyCursor(db, account, name, true);
|
Cursor cursor = getIdentityKeyCursor(db, account, name, true);
|
||||||
if(cursor.getCount() != 0) {
|
if (cursor.getCount() != 0) {
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
try {
|
try {
|
||||||
identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT));
|
identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT));
|
||||||
} catch (InvalidKeyException e) {
|
} catch (InvalidKeyException e) {
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name);
|
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
@ -943,16 +947,16 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
Set<IdentityKey> identityKeys = new HashSet<>();
|
Set<IdentityKey> identityKeys = new HashSet<>();
|
||||||
Cursor cursor = getIdentityKeyCursor(account, name, false);
|
Cursor cursor = getIdentityKeyCursor(account, name, false);
|
||||||
|
|
||||||
while(cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
if ( trust != null &&
|
if (trust != null &&
|
||||||
cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED))
|
cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED))
|
||||||
!= trust.getCode()) {
|
!= trust.getCode()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT),0));
|
identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT), 0));
|
||||||
} catch (InvalidKeyException e) {
|
} catch (InvalidKeyException e) {
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account"+account.getJid().toBareJid()+", address: "+name);
|
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
@ -970,8 +974,8 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
};
|
};
|
||||||
return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME,
|
return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME,
|
||||||
SQLiteAxolotlStore.ACCOUNT + " = ?"
|
SQLiteAxolotlStore.ACCOUNT + " = ?"
|
||||||
+ " AND " + SQLiteAxolotlStore.NAME + " = ?"
|
+ " AND " + SQLiteAxolotlStore.NAME + " = ?"
|
||||||
+ " AND (" + SQLiteAxolotlStore.TRUSTED + " = ? OR "+SQLiteAxolotlStore.TRUSTED+ " = ?)",
|
+ " AND (" + SQLiteAxolotlStore.TRUSTED + " = ? OR " + SQLiteAxolotlStore.TRUSTED + " = ?)",
|
||||||
args
|
args
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1018,7 +1022,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
values.put(SQLiteAxolotlStore.TRUSTED, trust.getCode());
|
values.put(SQLiteAxolotlStore.TRUSTED, trust.getCode());
|
||||||
int rows = db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, values,
|
int rows = db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, values,
|
||||||
SQLiteAxolotlStore.ACCOUNT + " = ? AND "
|
SQLiteAxolotlStore.ACCOUNT + " = ? AND "
|
||||||
+ SQLiteAxolotlStore.FINGERPRINT + " = ? ",
|
+ SQLiteAxolotlStore.FINGERPRINT + " = ? ",
|
||||||
selectionArgs);
|
selectionArgs);
|
||||||
return rows == 1;
|
return rows == 1;
|
||||||
}
|
}
|
||||||
|
@ -1036,7 +1040,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recreateAxolotlDb(SQLiteDatabase db) {
|
public void recreateAxolotlDb(SQLiteDatabase db) {
|
||||||
Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+">>> (RE)CREATING AXOLOTL DATABASE <<<");
|
Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + ">>> (RE)CREATING AXOLOTL DATABASE <<<");
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.SESSION_TABLENAME);
|
db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.SESSION_TABLENAME);
|
||||||
db.execSQL(CREATE_SESSIONS_STATEMENT);
|
db.execSQL(CREATE_SESSIONS_STATEMENT);
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.PREKEY_TABLENAME);
|
db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.PREKEY_TABLENAME);
|
||||||
|
@ -1049,9 +1053,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public void wipeAxolotlDb(Account account) {
|
public void wipeAxolotlDb(Account account) {
|
||||||
String accountName = account.getUuid();
|
String accountName = account.getUuid();
|
||||||
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+">>> WIPING AXOLOTL DATABASE FOR ACCOUNT " + accountName + " <<<");
|
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ">>> WIPING AXOLOTL DATABASE FOR ACCOUNT " + accountName + " <<<");
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
String[] deleteArgs= {
|
String[] deleteArgs = {
|
||||||
accountName
|
accountName
|
||||||
};
|
};
|
||||||
db.delete(SQLiteAxolotlStore.SESSION_TABLENAME,
|
db.delete(SQLiteAxolotlStore.SESSION_TABLENAME,
|
||||||
|
|
|
@ -2106,8 +2106,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createContact(Contact contact) {
|
public void createContact(Contact contact) {
|
||||||
SharedPreferences sharedPref = getPreferences();
|
boolean autoGrant = getPreferences().getBoolean("grant_new_contacts", true);
|
||||||
boolean autoGrant = sharedPref.getBoolean("grant_new_contacts", true);
|
|
||||||
if (autoGrant) {
|
if (autoGrant) {
|
||||||
contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
|
contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
|
||||||
contact.setOption(Contact.Options.ASKING);
|
contact.setOption(Contact.Options.ASKING);
|
||||||
|
@ -2534,10 +2533,6 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
.getDefaultSharedPreferences(getApplicationContext());
|
.getDefaultSharedPreferences(getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean forceEncryption() {
|
|
||||||
return getPreferences().getBoolean("force_encryption", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean confirmMessages() {
|
public boolean confirmMessages() {
|
||||||
return getPreferences().getBoolean("confirm_messages", true);
|
return getPreferences().getBoolean("confirm_messages", true);
|
||||||
}
|
}
|
||||||
|
@ -2554,6 +2549,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
return getPreferences().getBoolean("indicate_received", false);
|
return getPreferences().getBoolean("indicate_received", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean useTorToConnect() {
|
||||||
|
return getPreferences().getBoolean("use_tor", false);
|
||||||
|
}
|
||||||
|
|
||||||
public int unreadCount() {
|
public int unreadCount() {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Conversation conversation : getConversations()) {
|
for (Conversation conversation : getConversations()) {
|
||||||
|
|
|
@ -82,10 +82,14 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
private ImageButton mRegenerateAxolotlKeyButton;
|
private ImageButton mRegenerateAxolotlKeyButton;
|
||||||
private LinearLayout keys;
|
private LinearLayout keys;
|
||||||
private LinearLayout keysCard;
|
private LinearLayout keysCard;
|
||||||
|
private LinearLayout mNamePort;
|
||||||
|
private EditText mHostname;
|
||||||
|
private EditText mPort;
|
||||||
private AlertDialog mCaptchaDialog = null;
|
private AlertDialog mCaptchaDialog = null;
|
||||||
|
|
||||||
private Jid jidToEdit;
|
private Jid jidToEdit;
|
||||||
private boolean mInitMode = false;
|
private boolean mInitMode = false;
|
||||||
|
private boolean mUseTor = false;
|
||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
private String messageFingerprint;
|
private String messageFingerprint;
|
||||||
|
|
||||||
|
@ -136,6 +140,8 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
}
|
}
|
||||||
final String password = mPassword.getText().toString();
|
final String password = mPassword.getText().toString();
|
||||||
final String passwordConfirm = mPasswordConfirm.getText().toString();
|
final String passwordConfirm = mPasswordConfirm.getText().toString();
|
||||||
|
final String hostname = mHostname.getText().toString();
|
||||||
|
final String port = mPort.getText().toString();
|
||||||
if (registerNewAccount) {
|
if (registerNewAccount) {
|
||||||
if (!password.equals(passwordConfirm)) {
|
if (!password.equals(passwordConfirm)) {
|
||||||
mPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
|
mPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
|
||||||
|
@ -149,6 +155,25 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
mPasswordConfirm.setError(null);
|
mPasswordConfirm.setError(null);
|
||||||
mAccount.setPassword(password);
|
mAccount.setPassword(password);
|
||||||
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
|
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
|
||||||
|
if (hostname.contains(" ")) {
|
||||||
|
mHostname.setError(getString(R.string.not_valid_hostname));
|
||||||
|
mHostname.requestFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mAccount.setHostname(hostname);
|
||||||
|
try {
|
||||||
|
int numericPort = Integer.parseInt(port);
|
||||||
|
if (numericPort < 0 || numericPort > 65535) {
|
||||||
|
mPort.setError(getString(R.string.not_a_valid_port));
|
||||||
|
mPort.requestFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mAccount.setPort(numericPort);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
mPort.setError(getString(R.string.not_a_valid_port));
|
||||||
|
mPort.requestFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
xmppConnectionService.updateAccount(mAccount);
|
xmppConnectionService.updateAccount(mAccount);
|
||||||
} else {
|
} else {
|
||||||
if (xmppConnectionService.findAccountByJid(jid) != null) {
|
if (xmppConnectionService.findAccountByJid(jid) != null) {
|
||||||
|
@ -319,7 +344,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
unmodified = this.mAccount.getJid().toBareJid().toString();
|
unmodified = this.mAccount.getJid().toBareJid().toString();
|
||||||
}
|
}
|
||||||
return !unmodified.equals(this.mAccountJid.getText().toString()) ||
|
return !unmodified.equals(this.mAccountJid.getText().toString()) ||
|
||||||
!this.mAccount.getPassword().equals(this.mPassword.getText().toString());
|
!this.mAccount.getPassword().equals(this.mPassword.getText().toString()) ||
|
||||||
|
!this.mAccount.getHostname().equals(this.mHostname.getText().toString()) ||
|
||||||
|
!String.valueOf(this.mAccount.getPort()).equals(this.mPort.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -368,6 +395,12 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
this.mRegenerateAxolotlKeyButton = (ImageButton) findViewById(R.id.action_regenerate_axolotl_key);
|
this.mRegenerateAxolotlKeyButton = (ImageButton) findViewById(R.id.action_regenerate_axolotl_key);
|
||||||
this.keysCard = (LinearLayout) findViewById(R.id.other_device_keys_card);
|
this.keysCard = (LinearLayout) findViewById(R.id.other_device_keys_card);
|
||||||
this.keys = (LinearLayout) findViewById(R.id.other_device_keys);
|
this.keys = (LinearLayout) findViewById(R.id.other_device_keys);
|
||||||
|
this.mNamePort = (LinearLayout) findViewById(R.id.name_port);
|
||||||
|
this.mHostname = (EditText) findViewById(R.id.hostname);
|
||||||
|
this.mHostname.addTextChangedListener(mTextWatcher);
|
||||||
|
this.mPort = (EditText) findViewById(R.id.port);
|
||||||
|
this.mPort.setText("5222");
|
||||||
|
this.mPort.addTextChangedListener(mTextWatcher);
|
||||||
this.mSaveButton = (Button) findViewById(R.id.save_button);
|
this.mSaveButton = (Button) findViewById(R.id.save_button);
|
||||||
this.mCancelButton = (Button) findViewById(R.id.cancel_button);
|
this.mCancelButton = (Button) findViewById(R.id.cancel_button);
|
||||||
this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener);
|
this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener);
|
||||||
|
@ -448,6 +481,8 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.mUseTor = getPreferences().getBoolean("use_tor", false);
|
||||||
|
this.mNamePort.setVisibility(mUseTor ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -529,6 +564,12 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate
|
||||||
this.mAccountJid.getEditableText().append(this.mAccount.getJid().toBareJid().toString());
|
this.mAccountJid.getEditableText().append(this.mAccount.getJid().toBareJid().toString());
|
||||||
}
|
}
|
||||||
this.mPassword.setText(this.mAccount.getPassword());
|
this.mPassword.setText(this.mAccount.getPassword());
|
||||||
|
this.mHostname.setText("");
|
||||||
|
this.mHostname.getEditableText().append(this.mAccount.getHostname());
|
||||||
|
this.mPort.setText("");
|
||||||
|
this.mPort.getEditableText().append(String.valueOf(this.mAccount.getPort()));
|
||||||
|
this.mNamePort.setVisibility(mUseTor ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!mInitMode) {
|
if (!mInitMode) {
|
||||||
this.mAvatar.setVisibility(View.VISIBLE);
|
this.mAvatar.setVisibility(View.VISIBLE);
|
||||||
|
|
|
@ -160,6 +160,8 @@ public class SettingsActivity extends XmppActivity implements
|
||||||
} else if (name.equals("dont_trust_system_cas")) {
|
} else if (name.equals("dont_trust_system_cas")) {
|
||||||
xmppConnectionService.updateMemorizingTrustmanager();
|
xmppConnectionService.updateMemorizingTrustmanager();
|
||||||
reconnectAccounts();
|
reconnectAccounts();
|
||||||
|
} else if (name.equals("use_tor")) {
|
||||||
|
reconnectAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.net.ConnectException;
|
||||||
import java.net.IDN;
|
import java.net.IDN;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -233,16 +234,23 @@ public class XmppConnection implements Runnable {
|
||||||
tagReader = new XmlReader(wakeLock);
|
tagReader = new XmlReader(wakeLock);
|
||||||
tagWriter = new TagWriter();
|
tagWriter = new TagWriter();
|
||||||
this.changeStatus(Account.State.CONNECTING);
|
this.changeStatus(Account.State.CONNECTING);
|
||||||
|
final boolean useTor = mXmppConnectionService.useTorToConnect();
|
||||||
|
final Proxy TOR_PROXY = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 9050));
|
||||||
if (DNSHelper.isIp(account.getServer().toString())) {
|
if (DNSHelper.isIp(account.getServer().toString())) {
|
||||||
socket = new Socket();
|
socket = useTor ? new Socket(TOR_PROXY) : new Socket();
|
||||||
try {
|
try {
|
||||||
socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000);
|
socket.connect(new InetSocketAddress(account.getServer().toString(), 5222), Config.SOCKET_TIMEOUT * 1000);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UnknownHostException();
|
throw new UnknownHostException();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService);
|
final ArrayList<Parcelable> values;
|
||||||
final ArrayList<Parcelable> values = result.getParcelableArrayList("values");
|
if (useTor) {
|
||||||
|
values = account.getHostnamePortBundles();
|
||||||
|
} else {
|
||||||
|
final Bundle result = DNSHelper.getSRVRecord(account.getServer(),mXmppConnectionService);
|
||||||
|
values = result.getParcelableArrayList("values");
|
||||||
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
boolean socketError = true;
|
boolean socketError = true;
|
||||||
while (socketError && values.size() > i) {
|
while (socketError && values.size() > i) {
|
||||||
|
@ -269,11 +277,11 @@ public class XmppConnection implements Runnable {
|
||||||
+ ": using values from dns "
|
+ ": using values from dns "
|
||||||
+ srvRecordServer + ":" + srvRecordPort);
|
+ srvRecordServer + ":" + srvRecordPort);
|
||||||
}
|
}
|
||||||
socket = new Socket();
|
socket = useTor ? new Socket(TOR_PROXY) : new Socket();
|
||||||
socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
|
socket.connect(addr, Config.SOCKET_TIMEOUT * 1000);
|
||||||
socketError = false;
|
socketError = false;
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
|
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage() +"("+e.getClass().getName()+")");
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@ import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
@ -59,7 +61,9 @@ public class JingleSocks5Transport extends JingleTransport {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
socket = new Socket();
|
final boolean useTor = connection.getConnectionManager().getXmppConnectionService().useTorToConnect();
|
||||||
|
final Proxy TOR_PROXY = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(InetAddress.getLocalHost(), 9050));
|
||||||
|
socket = useTor ? new Socket(TOR_PROXY) : new Socket();
|
||||||
SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort());
|
SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort());
|
||||||
socket.connect(address,Config.SOCKET_TIMEOUT * 1000);
|
socket.connect(address,Config.SOCKET_TIMEOUT * 1000);
|
||||||
inputStream = socket.getInputStream();
|
inputStream = socket.getInputStream();
|
||||||
|
|
|
@ -78,7 +78,59 @@
|
||||||
android:textColorHint="@color/black54"
|
android:textColorHint="@color/black54"
|
||||||
android:textSize="?attr/TextSizeBody" />
|
android:textSize="?attr/TextSizeBody" />
|
||||||
|
|
||||||
<CheckBox
|
<LinearLayout
|
||||||
|
android:id="@+id/name_port"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:weightSum="1">
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.8">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/account_settings_hostname"
|
||||||
|
android:textColor="@color/black87"
|
||||||
|
android:textSize="?attr/TextSizeBody"
|
||||||
|
android:id="@+id/textView"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/black87"
|
||||||
|
android:textColorHint="@color/black54"
|
||||||
|
android:textSize="?attr/TextSizeBody"
|
||||||
|
android:id="@+id/hostname"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
android:hint="@string/hostname_or_onion"/>
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0.2"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/account_settings_port"
|
||||||
|
android:textColor="@color/black87"
|
||||||
|
android:textSize="?attr/TextSizeBody"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:inputType="number"
|
||||||
|
android:maxLength="5"
|
||||||
|
android:textColor="@color/black87"
|
||||||
|
android:textColorHint="@color/black54"
|
||||||
|
android:textSize="?attr/TextSizeBody"
|
||||||
|
android:id="@+id/port"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
<CheckBox
|
||||||
android:id="@+id/account_register_new"
|
android:id="@+id/account_register_new"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -31,4 +31,9 @@
|
||||||
<item android:id="@+id/action_clear_devices"
|
<item android:id="@+id/action_clear_devices"
|
||||||
android:title="@string/clear_other_devices"
|
android:title="@string/clear_other_devices"
|
||||||
android:showAsAction="never"/>
|
android:showAsAction="never"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_settings"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/action_settings"/>
|
||||||
</menu>
|
</menu>
|
|
@ -540,4 +540,12 @@
|
||||||
<string name="error_fetching_omemo_key">Error fetching OMEMO key!</string>
|
<string name="error_fetching_omemo_key">Error fetching OMEMO key!</string>
|
||||||
<string name="verified_omemo_key_with_certificate">Verified OMEMO key with certificate!</string>
|
<string name="verified_omemo_key_with_certificate">Verified OMEMO key with certificate!</string>
|
||||||
<string name="device_does_not_support_certificates">Your device does not support the selection of client certificates!</string>
|
<string name="device_does_not_support_certificates">Your device does not support the selection of client certificates!</string>
|
||||||
|
<string name="pref_connection_options">Connection options</string>
|
||||||
|
<string name="pref_use_tor">Connect via Tor</string>
|
||||||
|
<string name="pref_use_tor_summary">Tunnel all connections through the TOR network. Requires Orbot</string>
|
||||||
|
<string name="account_settings_hostname">Hostname</string>
|
||||||
|
<string name="account_settings_port">Port</string>
|
||||||
|
<string name="hostname_or_onion">Server- or .onion-Address</string>
|
||||||
|
<string name="not_a_valid_port">This is not a valid port number</string>
|
||||||
|
<string name="not_valid_hostname">This is not a valid hostname</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -147,6 +147,13 @@
|
||||||
android:summary="@string/pref_remove_trusted_certificates_summary"
|
android:summary="@string/pref_remove_trusted_certificates_summary"
|
||||||
android:title="@string/pref_remove_trusted_certificates_title"/>
|
android:title="@string/pref_remove_trusted_certificates_title"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
<PreferenceCategory android:title="@string/pref_connection_options">
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="use_tor"
|
||||||
|
android:title="@string/pref_use_tor"
|
||||||
|
android:summary="@string/pref_use_tor_summary"/>
|
||||||
|
</PreferenceCategory>
|
||||||
<PreferenceCategory android:title="@string/pref_input_options">
|
<PreferenceCategory android:title="@string/pref_input_options">
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
|
Loading…
Reference in a new issue