aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs')
-rw-r--r--src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java68
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java41
2 files changed, 98 insertions, 11 deletions
diff --git a/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java b/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java
index ac4e8c47e..9d77efab8 100644
--- a/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java
+++ b/src/main/java/eu/siacs/conversations/entities/ServiceDiscoveryResult.java
@@ -1,6 +1,7 @@
package eu.siacs.conversations.entities;
import android.content.ContentValues;
+import android.database.Cursor;
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import java.lang.Comparable;
@@ -17,6 +18,10 @@ import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class ServiceDiscoveryResult {
+ public static final String TABLENAME = "discovery_results";
+ public static final String HASH = "hash";
+ public static final String VER = "ver";
+ public static final String RESULT = "result";
protected static String blankNull(String s) {
return s == null ? "" : s;
@@ -36,10 +41,21 @@ public class ServiceDiscoveryResult {
}
public Identity(final Element el) {
- this.category = el.getAttribute("category");
- this.type = el.getAttribute("type");
- this.lang = el.getAttribute("xml:lang");
- this.name = el.getAttribute("name");
+ this(
+ el.getAttribute("category"),
+ el.getAttribute("type"),
+ el.getAttribute("xml:lang"),
+ el.getAttribute("name")
+ );
+ }
+
+ public Identity(final JSONObject o) {
+ this(
+ o.optString("category", null),
+ o.optString("type", null),
+ o.optString("lang", null),
+ o.optString("name", null)
+ );
}
public String getCategory() {
@@ -88,17 +104,15 @@ public class ServiceDiscoveryResult {
}
}
+ protected final String hash;
+ protected final byte[] ver;
protected final List<Identity> identities;
protected final List<String> features;
- public ServiceDiscoveryResult(final List<Identity> identities, final List<String> features) {
- this.identities = identities;
- this.features = features;
- }
-
public ServiceDiscoveryResult(final IqPacket packet) {
this.identities = new ArrayList<>();
this.features = new ArrayList<>();
+ this.hash = "sha-1"; // We only support sha-1 for now
final List<Element> elements = packet.query().getChildren();
@@ -114,6 +128,33 @@ public class ServiceDiscoveryResult {
}
}
}
+
+ this.ver = this.mkCapHash();
+ }
+
+ public ServiceDiscoveryResult(String hash, byte[] ver, JSONObject o) throws JSONException {
+ this.identities = new ArrayList<>();
+ this.features = new ArrayList<>();
+ this.hash = hash;
+ this.ver = ver;
+
+ JSONArray identities = o.optJSONArray("identities");
+ for(int i = 0; i < identities.length(); i++) {
+ this.identities.add(new Identity(identities.getJSONObject(i)));
+ }
+
+ JSONArray features = o.optJSONArray("features");
+ for(int i = 0; i < features.length(); i++) {
+ this.features.add(features.getString(i));
+ }
+ }
+
+ public ServiceDiscoveryResult(Cursor cursor) throws JSONException {
+ this(
+ cursor.getString(cursor.getColumnIndex(HASH)),
+ Base64.decode(cursor.getString(cursor.getColumnIndex(VER)), Base64.DEFAULT),
+ new JSONObject(cursor.getString(cursor.getColumnIndex(RESULT)))
+ );
}
public List<Identity> getIdentities() {
@@ -135,7 +176,7 @@ public class ServiceDiscoveryResult {
return false;
}
- public byte[] getCapHash() {
+ protected byte[] mkCapHash() {
StringBuilder s = new StringBuilder();
List<Identity> identities = this.getIdentities();
@@ -191,4 +232,11 @@ public class ServiceDiscoveryResult {
}
}
+ public ContentValues getContentValues() {
+ final ContentValues values = new ContentValues();
+ values.put(HASH, this.hash);
+ values.put(VER, new String(Base64.encode(this.ver, Base64.DEFAULT)).trim());
+ values.put(RESULT, this.toJSON().toString());
+ return values;
+ }
}
diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
index 77c16f25b..2f28a30ff 100644
--- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java
@@ -31,6 +31,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
+import org.json.JSONException;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@@ -41,6 +42,7 @@ import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.Roster;
+import eu.siacs.conversations.entities.ServiceDiscoveryResult;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
@@ -49,7 +51,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
private static DatabaseBackend instance = null;
private static final String DATABASE_NAME = "history";
- private static final int DATABASE_VERSION = 22;
+ private static final int DATABASE_VERSION = 23;
private static String CREATE_CONTATCS_STATEMENT = "create table "
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
@@ -63,6 +65,14 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", "
+ Contact.JID + ") ON CONFLICT REPLACE);";
+ private static String CREATE_DISCOVERY_RESULTS_STATEMENT = "create table "
+ + ServiceDiscoveryResult.TABLENAME + "("
+ + ServiceDiscoveryResult.HASH + " TEXT, "
+ + ServiceDiscoveryResult.VER + " TEXT, "
+ + ServiceDiscoveryResult.RESULT + " TEXT, "
+ + "UNIQUE(" + ServiceDiscoveryResult.HASH + ", "
+ + ServiceDiscoveryResult.VER + ") ON CONFLICT REPLACE);";
+
private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE "
+ SQLiteAxolotlStore.PREKEY_TABLENAME + "("
+ SQLiteAxolotlStore.ACCOUNT + " TEXT, "
@@ -158,6 +168,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ ") ON DELETE CASCADE);");
db.execSQL(CREATE_CONTATCS_STATEMENT);
+ db.execSQL(CREATE_DISCOVERY_RESULTS_STATEMENT);
db.execSQL(CREATE_SESSIONS_STATEMENT);
db.execSQL(CREATE_PREKEYS_STATEMENT);
db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT);
@@ -355,6 +366,10 @@ public class DatabaseBackend extends SQLiteOpenHelper {
if (oldVersion < 22 && newVersion >= 22) {
db.execSQL("ALTER TABLE " + SQLiteAxolotlStore.IDENTITIES_TABLENAME + " ADD COLUMN " + SQLiteAxolotlStore.CERTIFICATE);
}
+
+ if (oldVersion < 23 && newVersion >= 23) {
+ db.execSQL(CREATE_DISCOVERY_RESULTS_STATEMENT);
+ }
}
public static synchronized DatabaseBackend getInstance(Context context) {
@@ -379,6 +394,30 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.insert(Account.TABLENAME, null, account.getContentValues());
}
+ public void insertDiscoveryResult(ServiceDiscoveryResult result) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.insert(ServiceDiscoveryResult.TABLENAME, null, result.getContentValues());
+ }
+
+ public ServiceDiscoveryResult findDiscoveryResult(final String hash, final String ver) {
+ SQLiteDatabase db = this.getReadableDatabase();
+ String[] selectionArgs = {hash, ver};
+ Cursor cursor = db.query(ServiceDiscoveryResult.TABLENAME, null,
+ ServiceDiscoveryResult.HASH + "=? AND " + ServiceDiscoveryResult.VER + "=?",
+ selectionArgs, null, null, null);
+ if (cursor.getCount() == 0)
+ return null;
+ cursor.moveToFirst();
+
+ ServiceDiscoveryResult result = null;
+ try {
+ result = new ServiceDiscoveryResult(cursor);
+ } catch (JSONException e) { /* result is still null */ }
+
+ cursor.close();
+ return result;
+ }
+
public CopyOnWriteArrayList<Conversation> getConversations(int status) {
CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();