mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 07:09:56 +01:00
Compare commits
8 Commits
library-de
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ae601e395 | ||
|
|
c5c1fdb61c | ||
|
|
cc9ebe9eda | ||
|
|
05b9dd699e | ||
|
|
09a9a00af6 | ||
|
|
67797d0378 | ||
|
|
4b11f3c0b3 | ||
|
|
cc47c8522a |
@@ -13,8 +13,8 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 10506
|
versionCode 10507
|
||||||
versionName "1.5.6"
|
versionName "1.5.7"
|
||||||
consumerProguardFiles 'proguard-rules.txt'
|
consumerProguardFiles 'proguard-rules.txt'
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private InetAddress getIpv6AddressForInterface(InetAddress ipv4) {
|
private InetAddress getIpv6AddressForInterface(InetAddress ipv4) {
|
||||||
try {
|
try {
|
||||||
|
// We may get an NPE from getByInetAddress() on Android 11
|
||||||
NetworkInterface iface = NetworkInterface.getByInetAddress(ipv4);
|
NetworkInterface iface = NetworkInterface.getByInetAddress(ipv4);
|
||||||
if (iface == null) return null;
|
if (iface == null) return null;
|
||||||
for (InetAddress addr : list(iface.getInetAddresses())) {
|
for (InetAddress addr : list(iface.getInetAddresses())) {
|
||||||
@@ -208,7 +209,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
|
|||||||
}
|
}
|
||||||
// No suitable address
|
// No suitable address
|
||||||
return null;
|
return null;
|
||||||
} catch (SocketException e) {
|
} catch (SocketException | NullPointerException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,11 +64,16 @@ public class AndroidUtils {
|
|||||||
}
|
}
|
||||||
// Return the address from settings if it's valid and not fake
|
// Return the address from settings if it's valid and not fake
|
||||||
if (SDK_INT < 33) {
|
if (SDK_INT < 33) {
|
||||||
|
try {
|
||||||
address = Settings.Secure.getString(ctx.getContentResolver(),
|
address = Settings.Secure.getString(ctx.getContentResolver(),
|
||||||
"bluetooth_address");
|
"bluetooth_address");
|
||||||
if (isValidBluetoothAddress(address)) {
|
if (isValidBluetoothAddress(address)) {
|
||||||
return new Pair<>(address, "settings");
|
return new Pair<>(address, "settings");
|
||||||
}
|
}
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// Some custom ROMs throw this exception on SDK_INT < 33.
|
||||||
|
// Fall through
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Try to get the address via reflection
|
// Try to get the address via reflection
|
||||||
address = getBluetoothAddressByReflection(adapter);
|
address = getBluetoothAddressByReflection(adapter);
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ dependencyVerification {
|
|||||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||||
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
||||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||||
'org.jacoco:org.jacoco.agent:0.8.8:org.jacoco.agent-0.8.8.jar:072ecbd496896623899a696fff12c01c1615f737616d2792e6d0e10cdf8a610d',
|
'org.jacoco:org.jacoco.agent:0.8.7:org.jacoco.agent-0.8.7.jar:9cbcc986e0fbe821a78ff1f8f7d5216f200e5eb124e7f6837d1dc4a77b28b143',
|
||||||
'org.jacoco:org.jacoco.ant:0.8.8:org.jacoco.ant-0.8.8.jar:02e33bd2c48dc0be67c2fea84d43beececfd400da6797c58153253d4c30aca15',
|
'org.jacoco:org.jacoco.ant:0.8.7:org.jacoco.ant-0.8.7.jar:97ca96a382c3f23a44d8eb4c4e6c3742a30cb8005774a76ced0fc4806ce49605',
|
||||||
'org.jacoco:org.jacoco.core:0.8.8:org.jacoco.core-0.8.8.jar:474c782f809d88924713dfdbf0acb79d330f904be576484803463d0465611643',
|
'org.jacoco:org.jacoco.core:0.8.7:org.jacoco.core-0.8.7.jar:ad7739b5fb5969aa1a8aead3d74ed54dc82ed012f1f10f336bd1b96e71c1a13c',
|
||||||
'org.jacoco:org.jacoco.report:0.8.8:org.jacoco.report-0.8.8.jar:2c129110f3e3fcaa1f8179578ea3894586199cb0826be5c7790278084c9622a9',
|
'org.jacoco:org.jacoco.report:0.8.7:org.jacoco.report-0.8.7.jar:cc89258623700a6c932592153cb528785876b6da183d5431f97efbba6f020e5b',
|
||||||
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0:kotlin-stdlib-common-1.8.0.jar:78ef93b59e603cc0fe51def9bd4c037b07cbace3b3b7806d1a490a42bc1f4cb2',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0:kotlin-stdlib-common-1.8.0.jar:78ef93b59e603cc0fe51def9bd4c037b07cbace3b3b7806d1a490a42bc1f4cb2',
|
||||||
@@ -58,10 +58,10 @@ dependencyVerification {
|
|||||||
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
|
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
|
||||||
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
|
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
|
||||||
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
|
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
|
||||||
'org.ow2.asm:asm-analysis:9.2:asm-analysis-9.2.jar:878fbe521731c072d14d2d65b983b1beae6ad06fda0007b6a8bae81f73f433c4',
|
'org.ow2.asm:asm-analysis:9.1:asm-analysis-9.1.jar:81a88041b1b8beda5a8a99646098046c48709538270c49def68abff25ac3be34',
|
||||||
'org.ow2.asm:asm-commons:9.2:asm-commons-9.2.jar:be4ce53138a238bb522cd781cf91f3ba5ce2f6ca93ec62d46a162a127225e0a6',
|
'org.ow2.asm:asm-commons:9.1:asm-commons-9.1.jar:afcb26dc1fc12c0c4a99ada670908dd82e18dfc488caf5ee92546996b470c00c',
|
||||||
'org.ow2.asm:asm-tree:9.2:asm-tree-9.2.jar:aabf9bd23091a4ebfc109c1f3ee7cf3e4b89f6ba2d3f51c5243f16b3cffae011',
|
'org.ow2.asm:asm-tree:9.1:asm-tree-9.1.jar:fd00afa49e9595d7646205b09cecb4a776a8ff0ba06f2d59b8f7bf9c704b4a73',
|
||||||
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
|
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
|
||||||
'org.ow2.asm:asm:9.2:asm-9.2.jar:b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5',
|
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ dependencies {
|
|||||||
api "org.briarproject:onionwrapper-core:$onionwrapper_version"
|
api "org.briarproject:onionwrapper-core:$onionwrapper_version"
|
||||||
|
|
||||||
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
|
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
|
||||||
// 2.2.222 includes a precompiled Java 21 class that breaks the jetifier, so it will require
|
//noinspection GradleDependency
|
||||||
// a Gradle/AGP upgrade
|
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6
|
||||||
implementation 'com.h2database:h2:2.2.220'
|
|
||||||
implementation 'org.bitlet:weupnp:0.1.4'
|
implementation 'org.bitlet:weupnp:0.1.4'
|
||||||
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
||||||
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class H2Database extends JdbcDatabase {
|
|||||||
|
|
||||||
private static final String HASH_TYPE = "BINARY(32)";
|
private static final String HASH_TYPE = "BINARY(32)";
|
||||||
private static final String SECRET_TYPE = "BINARY(32)";
|
private static final String SECRET_TYPE = "BINARY(32)";
|
||||||
private static final String BINARY_TYPE = "BINARY VARYING";
|
private static final String BINARY_TYPE = "BINARY";
|
||||||
private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT";
|
private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT";
|
||||||
private static final String STRING_TYPE = "VARCHAR";
|
private static final String STRING_TYPE = "VARCHAR";
|
||||||
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
|
||||||
@@ -57,7 +57,8 @@ class H2Database extends JdbcDatabase {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
File dir = config.getDatabaseDirectory();
|
File dir = config.getDatabaseDirectory();
|
||||||
String path = new File(dir, "db").getAbsolutePath();
|
String path = new File(dir, "db").getAbsolutePath();
|
||||||
url = "jdbc:h2:split:" + path + ";CIPHER=AES;WRITE_DELAY=0";
|
url = "jdbc:h2:split:" + path + ";CIPHER=AES;MULTI_THREADED=1"
|
||||||
|
+ ";WRITE_DELAY=0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
"CREATE TABLE settings"
|
"CREATE TABLE settings"
|
||||||
+ " (namespace _STRING NOT NULL,"
|
+ " (namespace _STRING NOT NULL,"
|
||||||
+ " settingKey _STRING NOT NULL,"
|
+ " settingKey _STRING NOT NULL,"
|
||||||
+ " settingValue _STRING NOT NULL,"
|
+ " value _STRING NOT NULL,"
|
||||||
+ " PRIMARY KEY (namespace, settingKey))";
|
+ " PRIMARY KEY (namespace, settingKey))";
|
||||||
|
|
||||||
private static final String CREATE_LOCAL_AUTHORS =
|
private static final String CREATE_LOCAL_AUTHORS =
|
||||||
@@ -143,7 +143,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " handshakePublicKey _BINARY," // Null if key is unknown
|
+ " handshakePublicKey _BINARY," // Null if key is unknown
|
||||||
+ " localAuthorId _HASH NOT NULL,"
|
+ " localAuthorId _HASH NOT NULL,"
|
||||||
+ " verified BOOLEAN NOT NULL,"
|
+ " verified BOOLEAN NOT NULL,"
|
||||||
+ " syncVersions _BINARY DEFAULT X'00' NOT NULL,"
|
+ " syncVersions _BINARY DEFAULT '00' NOT NULL,"
|
||||||
+ " PRIMARY KEY (contactId),"
|
+ " PRIMARY KEY (contactId),"
|
||||||
+ " FOREIGN KEY (localAuthorId)"
|
+ " FOREIGN KEY (localAuthorId)"
|
||||||
+ " REFERENCES localAuthors (authorId)"
|
+ " REFERENCES localAuthors (authorId)"
|
||||||
@@ -161,7 +161,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
"CREATE TABLE groupMetadata"
|
"CREATE TABLE groupMetadata"
|
||||||
+ " (groupId _HASH NOT NULL,"
|
+ " (groupId _HASH NOT NULL,"
|
||||||
+ " metaKey _STRING NOT NULL,"
|
+ " metaKey _STRING NOT NULL,"
|
||||||
+ " metaValue _BINARY NOT NULL,"
|
+ " value _BINARY NOT NULL,"
|
||||||
+ " PRIMARY KEY (groupId, metaKey),"
|
+ " PRIMARY KEY (groupId, metaKey),"
|
||||||
+ " FOREIGN KEY (groupId)"
|
+ " FOREIGN KEY (groupId)"
|
||||||
+ " REFERENCES groups (groupId)"
|
+ " REFERENCES groups (groupId)"
|
||||||
@@ -206,7 +206,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " groupId _HASH NOT NULL," // Denormalised
|
+ " groupId _HASH NOT NULL," // Denormalised
|
||||||
+ " state INT NOT NULL," // Denormalised
|
+ " state INT NOT NULL," // Denormalised
|
||||||
+ " metaKey _STRING NOT NULL,"
|
+ " metaKey _STRING NOT NULL,"
|
||||||
+ " metaValue _BINARY NOT NULL,"
|
+ " value _BINARY NOT NULL,"
|
||||||
+ " PRIMARY KEY (messageId, metaKey),"
|
+ " PRIMARY KEY (messageId, metaKey),"
|
||||||
+ " FOREIGN KEY (messageId)"
|
+ " FOREIGN KEY (messageId)"
|
||||||
+ " REFERENCES messages (messageId)"
|
+ " REFERENCES messages (messageId)"
|
||||||
@@ -1926,7 +1926,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
Set<MessageId> intersection = null;
|
Set<MessageId> intersection = null;
|
||||||
String sql = "SELECT messageId FROM messageMetadata"
|
String sql = "SELECT messageId FROM messageMetadata"
|
||||||
+ " WHERE groupId = ? AND state = ?"
|
+ " WHERE groupId = ? AND state = ?"
|
||||||
+ " AND metaKey = ? AND metaValue = ?";
|
+ " AND metaKey = ? AND value = ?";
|
||||||
for (Entry<String, byte[]> e : query.entrySet()) {
|
for (Entry<String, byte[]> e : query.entrySet()) {
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, g.getBytes());
|
ps.setBytes(1, g.getBytes());
|
||||||
@@ -1982,7 +1982,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT messageId, metaKey, metaValue"
|
String sql = "SELECT messageId, metaKey, value"
|
||||||
+ " FROM messageMetadata"
|
+ " FROM messageMetadata"
|
||||||
+ " WHERE groupId = ? AND state = ?";
|
+ " WHERE groupId = ? AND state = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
@@ -2027,7 +2027,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT metaKey, metaValue FROM groupMetadata"
|
String sql = "SELECT metaKey, value FROM groupMetadata"
|
||||||
+ " WHERE groupId = ?";
|
+ " WHERE groupId = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, g.getBytes());
|
ps.setBytes(1, g.getBytes());
|
||||||
@@ -2050,7 +2050,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT metaKey, metaValue FROM messageMetadata"
|
String sql = "SELECT metaKey, value FROM messageMetadata"
|
||||||
+ " WHERE state = ? AND messageId = ?";
|
+ " WHERE state = ? AND messageId = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setInt(1, DELIVERED.getValue());
|
ps.setInt(1, DELIVERED.getValue());
|
||||||
@@ -2074,7 +2074,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT metaKey, metaValue FROM messageMetadata"
|
String sql = "SELECT metaKey, value FROM messageMetadata"
|
||||||
+ " WHERE (state = ? OR state = ?)"
|
+ " WHERE (state = ? OR state = ?)"
|
||||||
+ " AND messageId = ?";
|
+ " AND messageId = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
@@ -2678,7 +2678,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT settingKey, settingValue FROM settings"
|
String sql = "SELECT settingKey, value FROM settings"
|
||||||
+ " WHERE namespace = ?";
|
+ " WHERE namespace = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setString(1, namespace);
|
ps.setString(1, namespace);
|
||||||
@@ -2914,8 +2914,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
g.getBytes(), meta, "groupMetadata", "groupId");
|
g.getBytes(), meta, "groupMetadata", "groupId");
|
||||||
if (added.isEmpty()) return;
|
if (added.isEmpty()) return;
|
||||||
// Insert any keys that don't already exist
|
// Insert any keys that don't already exist
|
||||||
String sql = "INSERT INTO groupMetadata"
|
String sql = "INSERT INTO groupMetadata (groupId, metaKey, value)"
|
||||||
+ " (groupId, metaKey, metaValue)"
|
|
||||||
+ " VALUES (?, ?, ?)";
|
+ " VALUES (?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, g.getBytes());
|
ps.setBytes(1, g.getBytes());
|
||||||
@@ -2958,7 +2957,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
// Insert any keys that don't already exist
|
// Insert any keys that don't already exist
|
||||||
sql = "INSERT INTO messageMetadata"
|
sql = "INSERT INTO messageMetadata"
|
||||||
+ " (messageId, groupId, state, metaKey, metaValue)"
|
+ " (messageId, groupId, state, metaKey, value)"
|
||||||
+ " VALUES (?, ?, ?, ?, ?)";
|
+ " VALUES (?, ?, ?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, m.getBytes());
|
ps.setBytes(1, m.getBytes());
|
||||||
@@ -3017,7 +3016,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
if (notRemoved.isEmpty()) return Collections.emptyMap();
|
if (notRemoved.isEmpty()) return Collections.emptyMap();
|
||||||
// Update any keys that already exist
|
// Update any keys that already exist
|
||||||
String sql = "UPDATE " + tableName + " SET metaValue = ?"
|
String sql = "UPDATE " + tableName + " SET value = ?"
|
||||||
+ " WHERE " + columnName + " = ? AND metaKey = ?";
|
+ " WHERE " + columnName + " = ? AND metaKey = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(2, id);
|
ps.setBytes(2, id);
|
||||||
@@ -3054,7 +3053,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
// Update any settings that already exist
|
// Update any settings that already exist
|
||||||
String sql = "UPDATE settings SET settingValue = ?"
|
String sql = "UPDATE settings SET value = ?"
|
||||||
+ " WHERE namespace = ? AND settingKey = ?";
|
+ " WHERE namespace = ? AND settingKey = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
for (Entry<String, String> e : s.entrySet()) {
|
for (Entry<String, String> e : s.entrySet()) {
|
||||||
@@ -3070,7 +3069,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows > 1) throw new DbStateException();
|
if (rows > 1) throw new DbStateException();
|
||||||
}
|
}
|
||||||
// Insert any settings that don't already exist
|
// Insert any settings that don't already exist
|
||||||
sql = "INSERT INTO settings (namespace, settingKey, settingValue)"
|
sql = "INSERT INTO settings (namespace, settingKey, value)"
|
||||||
+ " VALUES (?, ?, ?)";
|
+ " VALUES (?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
int updateIndex = 0, inserted = 0;
|
int updateIndex = 0, inserted = 0;
|
||||||
|
|||||||
@@ -23,18 +23,21 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
|
|
||||||
private static final String DROP_TABLE = "DROP TABLE foo IF EXISTS";
|
private static final String DROP_TABLE = "DROP TABLE foo IF EXISTS";
|
||||||
private static final String CREATE_TABLE = "CREATE TABLE foo"
|
private static final String CREATE_TABLE = "CREATE TABLE foo"
|
||||||
+ " (_key INT NOT NULL,"
|
+ " (key INT NOT NULL,"
|
||||||
+ " counter INT NOT NULL)";
|
+ " counter INT NOT NULL)";
|
||||||
private static final String INSERT_ROW =
|
private static final String INSERT_ROW =
|
||||||
"INSERT INTO foo (_key, counter) VALUES (1, 123)";
|
"INSERT INTO foo (key, counter) VALUES (1, 123)";
|
||||||
private static final String GET_COUNTER =
|
private static final String GET_COUNTER =
|
||||||
"SELECT counter FROM foo WHERE _key = 1";
|
"SELECT counter FROM foo WHERE key = 1";
|
||||||
private static final String SET_COUNTER =
|
private static final String SET_COUNTER =
|
||||||
"UPDATE foo SET counter = ? WHERE _key = 1";
|
"UPDATE foo SET counter = ? WHERE key = 1";
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
private final File testDir = TestUtils.getTestDirectory();
|
||||||
private final File db = new File(testDir, "db");
|
private final File db = new File(testDir, "db");
|
||||||
private final String url = "jdbc:h2:split:" + db.getAbsolutePath();
|
private final String withMvcc = "jdbc:h2:split:" + db.getAbsolutePath()
|
||||||
|
+ ";MV_STORE=TRUE;MVCC=TRUE";
|
||||||
|
private final String withoutMvcc = "jdbc:h2:split:" + db.getAbsolutePath()
|
||||||
|
+ ";MV_STORE=FALSE;MVCC=FALSE;LOCK_MODE=1";
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@@ -49,14 +52,14 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDoesNotReadUncommittedWritesWithMvcc() throws Exception {
|
public void testDoesNotReadUncommittedWritesWithMvcc() throws Exception {
|
||||||
Connection connection = openConnection();
|
Connection connection = openConnection(true);
|
||||||
try {
|
try {
|
||||||
createTableAndInsertRow(connection);
|
createTableAndInsertRow(connection);
|
||||||
} finally {
|
} finally {
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
// Start the first transaction
|
// Start the first transaction
|
||||||
Connection txn1 = openConnection();
|
Connection txn1 = openConnection(true);
|
||||||
try {
|
try {
|
||||||
txn1.setAutoCommit(false);
|
txn1.setAutoCommit(false);
|
||||||
// The first transaction should read the initial value
|
// The first transaction should read the initial value
|
||||||
@@ -64,7 +67,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
// The first transaction updates the value but doesn't commit it
|
// The first transaction updates the value but doesn't commit it
|
||||||
assertEquals(1, setCounter(txn1, 234));
|
assertEquals(1, setCounter(txn1, 234));
|
||||||
// Start the second transaction
|
// Start the second transaction
|
||||||
Connection txn2 = openConnection();
|
Connection txn2 = openConnection(true);
|
||||||
try {
|
try {
|
||||||
txn2.setAutoCommit(false);
|
txn2.setAutoCommit(false);
|
||||||
// The second transaction should still read the initial value
|
// The second transaction should still read the initial value
|
||||||
@@ -83,14 +86,14 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLastWriterWinsWithMvcc() throws Exception {
|
public void testLastWriterWinsWithMvcc() throws Exception {
|
||||||
Connection connection = openConnection();
|
Connection connection = openConnection(true);
|
||||||
try {
|
try {
|
||||||
createTableAndInsertRow(connection);
|
createTableAndInsertRow(connection);
|
||||||
} finally {
|
} finally {
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
// Start the first transaction
|
// Start the first transaction
|
||||||
Connection txn1 = openConnection();
|
Connection txn1 = openConnection(true);
|
||||||
try {
|
try {
|
||||||
txn1.setAutoCommit(false);
|
txn1.setAutoCommit(false);
|
||||||
// The first transaction should read the initial value
|
// The first transaction should read the initial value
|
||||||
@@ -98,7 +101,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
// The first transaction updates the value but doesn't commit it
|
// The first transaction updates the value but doesn't commit it
|
||||||
assertEquals(1, setCounter(txn1, 234));
|
assertEquals(1, setCounter(txn1, 234));
|
||||||
// Start the second transaction
|
// Start the second transaction
|
||||||
Connection txn2 = openConnection();
|
Connection txn2 = openConnection(true);
|
||||||
try {
|
try {
|
||||||
txn2.setAutoCommit(false);
|
txn2.setAutoCommit(false);
|
||||||
// The second transaction should still read the initial value
|
// The second transaction should still read the initial value
|
||||||
@@ -116,7 +119,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
txn1.close();
|
txn1.close();
|
||||||
}
|
}
|
||||||
// The second transaction was the last writer, so it should win
|
// The second transaction was the last writer, so it should win
|
||||||
connection = openConnection();
|
connection = openConnection(true);
|
||||||
try {
|
try {
|
||||||
assertEquals(345, getCounter(connection));
|
assertEquals(345, getCounter(connection));
|
||||||
} finally {
|
} finally {
|
||||||
@@ -126,20 +129,20 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLockTimeoutOnRowWithMvcc() throws Exception {
|
public void testLockTimeoutOnRowWithMvcc() throws Exception {
|
||||||
Connection connection = openConnection();
|
Connection connection = openConnection(true);
|
||||||
try {
|
try {
|
||||||
createTableAndInsertRow(connection);
|
createTableAndInsertRow(connection);
|
||||||
} finally {
|
} finally {
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
// Start the first transaction
|
// Start the first transaction
|
||||||
Connection txn1 = openConnection();
|
Connection txn1 = openConnection(true);
|
||||||
try {
|
try {
|
||||||
txn1.setAutoCommit(false);
|
txn1.setAutoCommit(false);
|
||||||
// The first transaction should read the initial value
|
// The first transaction should read the initial value
|
||||||
assertEquals(123, getCounter(txn1));
|
assertEquals(123, getCounter(txn1));
|
||||||
// Start the second transaction
|
// Start the second transaction
|
||||||
Connection txn2 = openConnection();
|
Connection txn2 = openConnection(true);
|
||||||
try {
|
try {
|
||||||
txn2.setAutoCommit(false);
|
txn2.setAutoCommit(false);
|
||||||
// The second transaction should read the initial value
|
// The second transaction should read the initial value
|
||||||
@@ -164,8 +167,84 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Connection openConnection() throws SQLException {
|
@Test
|
||||||
return DriverManager.getConnection(url);
|
public void testReadLockTimeoutOnTableWithoutMvcc() throws Exception {
|
||||||
|
Connection connection = openConnection(false);
|
||||||
|
try {
|
||||||
|
createTableAndInsertRow(connection);
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
// Start the first transaction
|
||||||
|
Connection txn1 = openConnection(false);
|
||||||
|
try {
|
||||||
|
txn1.setAutoCommit(false);
|
||||||
|
// The first transaction should read the initial value
|
||||||
|
assertEquals(123, getCounter(txn1));
|
||||||
|
// Start the second transaction
|
||||||
|
Connection txn2 = openConnection(false);
|
||||||
|
try {
|
||||||
|
txn2.setAutoCommit(false);
|
||||||
|
// The second transaction should read the initial value
|
||||||
|
assertEquals(123, getCounter(txn2));
|
||||||
|
// The first transaction tries to update the value
|
||||||
|
try {
|
||||||
|
setCounter(txn1, 345);
|
||||||
|
fail();
|
||||||
|
} catch (SQLException expected) {
|
||||||
|
// Expected: the table is locked by the second transaction
|
||||||
|
}
|
||||||
|
// Abort the transactions
|
||||||
|
txn1.rollback();
|
||||||
|
txn2.rollback();
|
||||||
|
} finally {
|
||||||
|
txn2.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
txn1.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWriteLockTimeoutOnTableWithoutMvcc() throws Exception {
|
||||||
|
Connection connection = openConnection(false);
|
||||||
|
try {
|
||||||
|
createTableAndInsertRow(connection);
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
// Start the first transaction
|
||||||
|
Connection txn1 = openConnection(false);
|
||||||
|
try {
|
||||||
|
txn1.setAutoCommit(false);
|
||||||
|
// The first transaction should read the initial value
|
||||||
|
assertEquals(123, getCounter(txn1));
|
||||||
|
// The first transaction updates the value but doesn't commit yet
|
||||||
|
assertEquals(1, setCounter(txn1, 345));
|
||||||
|
// Start the second transaction
|
||||||
|
Connection txn2 = openConnection(false);
|
||||||
|
try {
|
||||||
|
txn2.setAutoCommit(false);
|
||||||
|
// The second transaction tries to read the value
|
||||||
|
try {
|
||||||
|
getCounter(txn2);
|
||||||
|
fail();
|
||||||
|
} catch (SQLException expected) {
|
||||||
|
// Expected: the table is locked by the first transaction
|
||||||
|
}
|
||||||
|
// Abort the transactions
|
||||||
|
txn1.rollback();
|
||||||
|
txn2.rollback();
|
||||||
|
} finally {
|
||||||
|
txn2.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
txn1.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Connection openConnection(boolean mvcc) throws SQLException {
|
||||||
|
return DriverManager.getConnection(mvcc ? withMvcc : withoutMvcc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTableAndInsertRow(Connection c) throws SQLException {
|
private void createTableAndInsertRow(Connection c) throws SQLException {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ dependencyVerification {
|
|||||||
'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
|
'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
|
||||||
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
|
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
|
||||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||||
'com.h2database:h2:2.2.220:h2-2.2.220.jar:978ab863018d3f965e38880571c36293ea8b10a8086194159c4d5d20b50f0a57',
|
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
|
||||||
'com.squareup.okhttp3:mockwebserver:4.10.0:mockwebserver-4.10.0.jar:af29da234e63159d6e0dea43bf8288eea97d71cdf1651a5ee2d6c0d0d4adbf8f',
|
'com.squareup.okhttp3:mockwebserver:4.10.0:mockwebserver-4.10.0.jar:af29da234e63159d6e0dea43bf8288eea97d71cdf1651a5ee2d6c0d0d4adbf8f',
|
||||||
'com.squareup.okhttp3:okhttp:4.10.0:okhttp-4.10.0.jar:7580f14fa1691206e37081ad3f92063b1603b328da0bb316f2fef02e0562e7ec',
|
'com.squareup.okhttp3:okhttp:4.10.0:okhttp-4.10.0.jar:7580f14fa1691206e37081ad3f92063b1603b328da0bb316f2fef02e0562e7ec',
|
||||||
'com.squareup.okio:okio-jvm:3.0.0:okio-jvm-3.0.0.jar:be64a0cc1f28ea9cd5c970dd7e7557af72c808d738c495b397bf897c9921e907',
|
'com.squareup.okio:okio-jvm:3.0.0:okio-jvm-3.0.0.jar:be64a0cc1f28ea9cd5c970dd7e7557af72c808d738c495b397bf897c9921e907',
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode 10506
|
versionCode 10507
|
||||||
versionName "1.5.6"
|
versionName "1.5.7"
|
||||||
applicationId "org.briarproject.briar.android"
|
applicationId "org.briarproject.briar.android"
|
||||||
buildConfigField "String", "TorVersion", "\"$tor_version\""
|
buildConfigField "String", "TorVersion", "\"$tor_version\""
|
||||||
|
|
||||||
@@ -78,7 +78,6 @@ android {
|
|||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
coreLibraryDesugaringEnabled true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
testOptions {
|
testOptions {
|
||||||
@@ -98,10 +97,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for https://github.com/gradle/gradle/issues/20330 to make gradle-witness work
|
|
||||||
// with Android Gradle Plugin 7.4
|
|
||||||
project.evaluationDependsOn(project.getRootProject().findProject("bramble-android").getPath())
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// In theory this dependency shouldn't be needed, but without it Android Studio's linter will
|
// In theory this dependency shouldn't be needed, but without it Android Studio's linter will
|
||||||
// complain about unresolved symbols for bramble-api test classes in briar-android tests,
|
// complain about unresolved symbols for bramble-api test classes in briar-android tests,
|
||||||
@@ -148,8 +143,6 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.3'
|
|
||||||
|
|
||||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.briar.android.contact.add.remote;
|
package org.briarproject.briar.android.contact.add.remote;
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -20,6 +21,7 @@ import org.briarproject.briar.android.view.InfoView;
|
|||||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -29,8 +31,12 @@ import androidx.core.app.ShareCompat.IntentBuilder;
|
|||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import static android.content.Context.CLIPBOARD_SERVICE;
|
import static android.content.Context.CLIPBOARD_SERVICE;
|
||||||
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
|
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
||||||
|
|
||||||
@@ -39,6 +45,7 @@ import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
|||||||
public class LinkExchangeFragment extends BaseFragment {
|
public class LinkExchangeFragment extends BaseFragment {
|
||||||
|
|
||||||
private static final String TAG = LinkExchangeFragment.class.getName();
|
private static final String TAG = LinkExchangeFragment.class.getName();
|
||||||
|
private static final Logger LOG = getLogger(TAG);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
@@ -116,11 +123,18 @@ public class LinkExchangeFragment extends BaseFragment {
|
|||||||
copyButton.setEnabled(true);
|
copyButton.setEnabled(true);
|
||||||
|
|
||||||
Button shareButton = v.findViewById(R.id.shareButton);
|
Button shareButton = v.findViewById(R.id.shareButton);
|
||||||
shareButton.setOnClickListener(view ->
|
shareButton.setOnClickListener(view -> {
|
||||||
|
try {
|
||||||
IntentBuilder.from(requireActivity())
|
IntentBuilder.from(requireActivity())
|
||||||
.setText(link)
|
.setText(link)
|
||||||
.setType("text/plain")
|
.setType("text/plain")
|
||||||
.startChooser());
|
.startChooser();
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
Toast.makeText(requireContext(),
|
||||||
|
R.string.error_start_activity, LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
shareButton.setEnabled(true);
|
shareButton.setEnabled(true);
|
||||||
|
|
||||||
InfoView infoText = v.findViewById(R.id.infoView);
|
InfoView infoText = v.findViewById(R.id.infoView);
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ Vänlige installera Briar på en nyare enhet.</string>
|
|||||||
<string name="error_start_activity">Otillgänglig på ditt system</string>
|
<string name="error_start_activity">Otillgänglig på ditt system</string>
|
||||||
<string name="status_heading">Status</string>
|
<string name="status_heading">Status</string>
|
||||||
<string name="error">Fel</string>
|
<string name="error">Fel</string>
|
||||||
|
<string name="info">Information</string>
|
||||||
<!--Contacts and Private Conversations-->
|
<!--Contacts and Private Conversations-->
|
||||||
<string name="no_contacts">Inga kontakter</string>
|
<string name="no_contacts">Inga kontakter</string>
|
||||||
<string name="no_contacts_action">Tryck på plus-ikonen (+) för att lägga till en kontakt</string>
|
<string name="no_contacts_action">Tryck på plus-ikonen (+) för att lägga till en kontakt</string>
|
||||||
@@ -222,6 +223,7 @@ Vänlige installera Briar på en nyare enhet.</string>
|
|||||||
<string name="menu_contact">Kontakt</string>
|
<string name="menu_contact">Kontakt</string>
|
||||||
<!--Adding Contacts-->
|
<!--Adding Contacts-->
|
||||||
<string name="add_contact_title">Lägg till en närvarande kontakt</string>
|
<string name="add_contact_title">Lägg till en närvarande kontakt</string>
|
||||||
|
<string name="add_contact_error_two_way">Skannade ni båda varandras QR-koder?</string>
|
||||||
<string name="face_to_face">Du måste personligen träffa den som du vill lägga till som kontakt.\n\nDetta för att undvika att någon senare låtsas vara du eller läser dina meddelanden.</string>
|
<string name="face_to_face">Du måste personligen träffa den som du vill lägga till som kontakt.\n\nDetta för att undvika att någon senare låtsas vara du eller läser dina meddelanden.</string>
|
||||||
<string name="continue_button">Fortsätt</string>
|
<string name="continue_button">Fortsätt</string>
|
||||||
<string name="try_again_button">Försök igen</string>
|
<string name="try_again_button">Försök igen</string>
|
||||||
@@ -229,9 +231,11 @@ Vänlige installera Briar på en nyare enhet.</string>
|
|||||||
<string name="exchanging_contact_details">Utbyter detaljer om kontakten\u2026</string>
|
<string name="exchanging_contact_details">Utbyter detaljer om kontakten\u2026</string>
|
||||||
<string name="contact_added_toast">Kontakt tillagd: %s</string>
|
<string name="contact_added_toast">Kontakt tillagd: %s</string>
|
||||||
<string name="contact_already_exists">Kontakten %s finns redan</string>
|
<string name="contact_already_exists">Kontakten %s finns redan</string>
|
||||||
|
<string name="contact_already_exists_general">Kontakten finns redan</string>
|
||||||
<string name="qr_code_invalid">QR-koden är felaktig</string>
|
<string name="qr_code_invalid">QR-koden är felaktig</string>
|
||||||
<string name="qr_code_too_old_1">QR-koden som du har skannat kommer från en äldre version av Briar.\n\nVar vänlig och be din kontakt att uppgradera till den senaste versionen och försök sedan igen.</string>
|
<string name="qr_code_too_old_1">QR-koden som du har skannat kommer från en äldre version av Briar.\n\nVar vänlig och be din kontakt att uppgradera till den senaste versionen och försök sedan igen.</string>
|
||||||
<string name="qr_code_too_new_1">QR-koden som du har skannat kommer från en äldre version av Briar.\n\nVänligen uppgradera till den senaste versionen och försök igen.</string>
|
<string name="qr_code_too_new_1">QR-koden som du har skannat kommer från en äldre version av Briar.\n\nVänligen uppgradera till den senaste versionen och försök igen.</string>
|
||||||
|
<string name="mailbox_qr_code_for_contact">QR-koden du skannade kommer från Briar Mailbox.\n\nOm du vill länka en Mailbox, välj Inställningar > Mailbox från Briar-menyn.</string>
|
||||||
<string name="camera_error">Kamerafel</string>
|
<string name="camera_error">Kamerafel</string>
|
||||||
<string name="connecting_to_device">Ansluter till enhet\u2026</string>
|
<string name="connecting_to_device">Ansluter till enhet\u2026</string>
|
||||||
<string name="authenticating_with_device">Autentiserar med enhet\u2026</string>
|
<string name="authenticating_with_device">Autentiserar med enhet\u2026</string>
|
||||||
|
|||||||
@@ -474,7 +474,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_progress">导入 RSS 订阅源中…</string>
|
<string name="blogs_rss_feeds_import_progress">导入 RSS 订阅源中…</string>
|
||||||
<string name="blogs_rss_feeds_import_error">抱歉!导入订阅源时发生错误。</string>
|
<string name="blogs_rss_feeds_import_error">抱歉!导入订阅源时发生错误。</string>
|
||||||
<string name="blogs_rss_feeds_import_title">从文件导入源</string>
|
<string name="blogs_rss_feeds_import_title">从文件导入源</string>
|
||||||
<string name="blogs_rss_feeds">RSS源 </string>
|
<string name="blogs_rss_feeds">RSS 源 </string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">已导入:</string>
|
<string name="blogs_rss_feeds_manage_imported">已导入:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">作者:</string>
|
<string name="blogs_rss_feeds_manage_author">作者:</string>
|
||||||
<string name="blogs_rss_feeds_manage_updated">最后更新于:</string>
|
<string name="blogs_rss_feeds_manage_updated">最后更新于:</string>
|
||||||
@@ -676,6 +676,8 @@
|
|||||||
<string name="disappearing_messages_summary">在7\u00A0天之后,使此对话中的后续消息自动消失。</string>
|
<string name="disappearing_messages_summary">在7\u00A0天之后,使此对话中的后续消息自动消失。</string>
|
||||||
<!--Settings Actions-->
|
<!--Settings Actions-->
|
||||||
<string name="pref_category_actions">操作</string>
|
<string name="pref_category_actions">操作</string>
|
||||||
|
<string name="share_app_link">分享下载链接</string>
|
||||||
|
<string name="share_app_link_text">Briar 下载地址 %s</string>
|
||||||
<string name="send_feedback">提交反馈</string>
|
<string name="send_feedback">提交反馈</string>
|
||||||
<!--Link Warning-->
|
<!--Link Warning-->
|
||||||
<string name="link_warning_title">链接警告</string>
|
<string name="link_warning_title">链接警告</string>
|
||||||
@@ -725,6 +727,7 @@
|
|||||||
<string name="permission_camera_title">相机权限</string>
|
<string name="permission_camera_title">相机权限</string>
|
||||||
<string name="permission_camera_request_body">Briar 需要获得相机权限以扫描二维码。</string>
|
<string name="permission_camera_request_body">Briar 需要获得相机权限以扫描二维码。</string>
|
||||||
<string name="permission_location_title">位置权限</string>
|
<string name="permission_location_title">位置权限</string>
|
||||||
|
<string name="permission_nearby_devices_title">“附近设备”权限</string>
|
||||||
<string name="permission_location_request_body">Briar 需要位置信息权限以发现蓝牙设备。\n\nBriar 不会存储您的位置或将它分享给任何人。</string>
|
<string name="permission_location_request_body">Briar 需要位置信息权限以发现蓝牙设备。\n\nBriar 不会存储您的位置或将它分享给任何人。</string>
|
||||||
<string name="permission_camera_location_title">相机和位置</string>
|
<string name="permission_camera_location_title">相机和位置</string>
|
||||||
<string name="permission_camera_location_request_body"> Briar 需要相机权限以扫描二维码。\n\nBriar 需要位置信息权限以发现蓝牙设备。\n\nBriar 不会存储您的位置或将它分享给任何人。</string>
|
<string name="permission_camera_location_request_body"> Briar 需要相机权限以扫描二维码。\n\nBriar 需要位置信息权限以发现蓝牙设备。\n\nBriar 不会存储您的位置或将它分享给任何人。</string>
|
||||||
@@ -764,6 +767,8 @@
|
|||||||
<string name="permission_hotspot_location_request_precise_body">要创建无线热点,Briar 需要访问你的精确位置。\n\nBriar 不会储存你的位置也不会和任何人分享它。</string>
|
<string name="permission_hotspot_location_request_precise_body">要创建无线热点,Briar 需要访问你的精确位置。\n\nBriar 不会储存你的位置也不会和任何人分享它。</string>
|
||||||
<string name="permission_hotspot_location_denied_body">你拒绝了访问你的位置,但 Briar 需要这个权限才能创建 Wi-Fi 热点。\n\n请考虑授予访问权限。</string>
|
<string name="permission_hotspot_location_denied_body">你拒绝了访问你的位置,但 Briar 需要这个权限才能创建 Wi-Fi 热点。\n\n请考虑授予访问权限。</string>
|
||||||
<string name="permission_hotspot_location_denied_precise_body">你拒绝了 Briar 访问你的精确位置,但 Briar 需要这个权限才能创建 无线热点。\n\n请考虑授予访问权限。</string>
|
<string name="permission_hotspot_location_denied_precise_body">你拒绝了 Briar 访问你的精确位置,但 Briar 需要这个权限才能创建 无线热点。\n\n请考虑授予访问权限。</string>
|
||||||
|
<string name="permission_hotspot_nearby_wifi_request_body">要创建 Wi-FI 热点,Briar 需要访问附近设备的权限。</string>
|
||||||
|
<string name="permission_hotspot_nearby_wifi_denied_body">你已拒绝对附近设备的访问,但 Briar 需要此权限在创建 Wi-FI 热点。\n\n请考虑授予权限。</string>
|
||||||
<string name="wifi_settings_title">Wi-Fi 设置</string>
|
<string name="wifi_settings_title">Wi-Fi 设置</string>
|
||||||
<string name="wifi_settings_request_enable_body">要创建 Wi-Fi 热点,Briar 需要使用 Wi-Fi。请允许它。</string>
|
<string name="wifi_settings_request_enable_body">要创建 Wi-Fi 热点,Briar 需要使用 Wi-Fi。请允许它。</string>
|
||||||
<string name="hotspot_tab_manual">手动</string>
|
<string name="hotspot_tab_manual">手动</string>
|
||||||
|
|||||||
@@ -87,8 +87,6 @@ dependencyVerification {
|
|||||||
'androidx.window:window:1.0.0:window-1.0.0.aar:3212985be4127373ca4d0ea7f8b81a250ae2105e924f7940105d067a0f9ac130',
|
'androidx.window:window:1.0.0:window-1.0.0.aar:3212985be4127373ca4d0ea7f8b81a250ae2105e924f7940105d067a0f9ac130',
|
||||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||||
'com.almworks.sqlite4java:sqlite4java:1.0.392:sqlite4java-1.0.392.jar:243a64470fda0e86a6fddeb0af4c7aa9426ce84e68cbfe18d75ee5da4b7e0b92',
|
'com.almworks.sqlite4java:sqlite4java:1.0.392:sqlite4java-1.0.392.jar:243a64470fda0e86a6fddeb0af4c7aa9426ce84e68cbfe18d75ee5da4b7e0b92',
|
||||||
'com.android.tools:desugar_jdk_libs_configuration_nio:2.0.3:desugar_jdk_libs_configuration_nio-2.0.3.jar:1e46fd75ae4db46ae592a17afeda3865321492020847c16ec82b1d2026ed967a',
|
|
||||||
'com.android.tools:desugar_jdk_libs_nio:2.0.3:desugar_jdk_libs_nio-2.0.3.jar:7f4e68385dfe88eba4344ff71912912bdc731806b9b2ce4a12bef9aa6a7d4565',
|
|
||||||
'com.github.bumptech.glide:annotations:4.14.2:annotations-4.14.2.jar:8419bf262be70edeb6b9582b386546be66d2e8659c7aae65fd69a9ede02c4877',
|
'com.github.bumptech.glide:annotations:4.14.2:annotations-4.14.2.jar:8419bf262be70edeb6b9582b386546be66d2e8659c7aae65fd69a9ede02c4877',
|
||||||
'com.github.bumptech.glide:compiler:4.14.2:compiler-4.14.2.jar:315b1325283c3d0cf9bc0599c1ecdb85e5f7863b1aa25991b63d616b13930cb6',
|
'com.github.bumptech.glide:compiler:4.14.2:compiler-4.14.2.jar:315b1325283c3d0cf9bc0599c1ecdb85e5f7863b1aa25991b63d616b13930cb6',
|
||||||
'com.github.bumptech.glide:gifdecoder:4.14.2:gifdecoder-4.14.2.aar:d021eee1ac1a036fcdc377b6dc3b218f4a0cc2bc2f096d69b474198b635e8302',
|
'com.github.bumptech.glide:gifdecoder:4.14.2:gifdecoder-4.14.2.aar:d021eee1ac1a036fcdc377b6dc3b218f4a0cc2bc2f096d69b474198b635e8302',
|
||||||
@@ -150,10 +148,10 @@ dependencyVerification {
|
|||||||
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
||||||
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
||||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||||
'org.jacoco:org.jacoco.agent:0.8.8:org.jacoco.agent-0.8.8.jar:072ecbd496896623899a696fff12c01c1615f737616d2792e6d0e10cdf8a610d',
|
'org.jacoco:org.jacoco.agent:0.8.7:org.jacoco.agent-0.8.7.jar:9cbcc986e0fbe821a78ff1f8f7d5216f200e5eb124e7f6837d1dc4a77b28b143',
|
||||||
'org.jacoco:org.jacoco.ant:0.8.8:org.jacoco.ant-0.8.8.jar:02e33bd2c48dc0be67c2fea84d43beececfd400da6797c58153253d4c30aca15',
|
'org.jacoco:org.jacoco.ant:0.8.7:org.jacoco.ant-0.8.7.jar:97ca96a382c3f23a44d8eb4c4e6c3742a30cb8005774a76ced0fc4806ce49605',
|
||||||
'org.jacoco:org.jacoco.core:0.8.8:org.jacoco.core-0.8.8.jar:474c782f809d88924713dfdbf0acb79d330f904be576484803463d0465611643',
|
'org.jacoco:org.jacoco.core:0.8.7:org.jacoco.core-0.8.7.jar:ad7739b5fb5969aa1a8aead3d74ed54dc82ed012f1f10f336bd1b96e71c1a13c',
|
||||||
'org.jacoco:org.jacoco.report:0.8.8:org.jacoco.report-0.8.8.jar:2c129110f3e3fcaa1f8179578ea3894586199cb0826be5c7790278084c9622a9',
|
'org.jacoco:org.jacoco.report:0.8.7:org.jacoco.report-0.8.7.jar:cc89258623700a6c932592153cb528785876b6da183d5431f97efbba6f020e5b',
|
||||||
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20:kotlin-stdlib-common-1.8.20.jar:fa20188abaa8ecf1d0035e93a969b071f10e45a1c8378c314521eade73f75fd5',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20:kotlin-stdlib-common-1.8.20.jar:fa20188abaa8ecf1d0035e93a969b071f10e45a1c8378c314521eade73f75fd5',
|
||||||
@@ -176,10 +174,14 @@ dependencyVerification {
|
|||||||
'org.mockito:mockito-core:5.1.1:mockito-core-5.1.1.jar:447bdedceaef4107c50db3d33e252bf030c6ae0e46454b40dbcfc0dfbf041264',
|
'org.mockito:mockito-core:5.1.1:mockito-core-5.1.1.jar:447bdedceaef4107c50db3d33e252bf030c6ae0e46454b40dbcfc0dfbf041264',
|
||||||
'org.nanohttpd:nanohttpd:2.3.1:nanohttpd-2.3.1.jar:de864c47818157141a24c9acb36df0c47d7bf15b7ff48c90610f3eb4e5df0e58',
|
'org.nanohttpd:nanohttpd:2.3.1:nanohttpd-2.3.1.jar:de864c47818157141a24c9acb36df0c47d7bf15b7ff48c90610f3eb4e5df0e58',
|
||||||
'org.objenesis:objenesis:3.3:objenesis-3.3.jar:02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb',
|
'org.objenesis:objenesis:3.3:objenesis-3.3.jar:02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb',
|
||||||
|
'org.ow2.asm:asm-analysis:9.1:asm-analysis-9.1.jar:81a88041b1b8beda5a8a99646098046c48709538270c49def68abff25ac3be34',
|
||||||
'org.ow2.asm:asm-analysis:9.2:asm-analysis-9.2.jar:878fbe521731c072d14d2d65b983b1beae6ad06fda0007b6a8bae81f73f433c4',
|
'org.ow2.asm:asm-analysis:9.2:asm-analysis-9.2.jar:878fbe521731c072d14d2d65b983b1beae6ad06fda0007b6a8bae81f73f433c4',
|
||||||
|
'org.ow2.asm:asm-commons:9.1:asm-commons-9.1.jar:afcb26dc1fc12c0c4a99ada670908dd82e18dfc488caf5ee92546996b470c00c',
|
||||||
'org.ow2.asm:asm-commons:9.2:asm-commons-9.2.jar:be4ce53138a238bb522cd781cf91f3ba5ce2f6ca93ec62d46a162a127225e0a6',
|
'org.ow2.asm:asm-commons:9.2:asm-commons-9.2.jar:be4ce53138a238bb522cd781cf91f3ba5ce2f6ca93ec62d46a162a127225e0a6',
|
||||||
|
'org.ow2.asm:asm-tree:9.1:asm-tree-9.1.jar:fd00afa49e9595d7646205b09cecb4a776a8ff0ba06f2d59b8f7bf9c704b4a73',
|
||||||
'org.ow2.asm:asm-tree:9.2:asm-tree-9.2.jar:aabf9bd23091a4ebfc109c1f3ee7cf3e4b89f6ba2d3f51c5243f16b3cffae011',
|
'org.ow2.asm:asm-tree:9.2:asm-tree-9.2.jar:aabf9bd23091a4ebfc109c1f3ee7cf3e4b89f6ba2d3f51c5243f16b3cffae011',
|
||||||
'org.ow2.asm:asm-util:9.2:asm-util-9.2.jar:ff5b3cd331ae8a9a804768280da98f50f424fef23dd3c788bb320e08c94ee598',
|
'org.ow2.asm:asm-util:9.2:asm-util-9.2.jar:ff5b3cd331ae8a9a804768280da98f50f424fef23dd3c788bb320e08c94ee598',
|
||||||
|
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
|
||||||
'org.ow2.asm:asm:9.2:asm-9.2.jar:b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5',
|
'org.ow2.asm:asm:9.2:asm-9.2.jar:b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5',
|
||||||
'org.robolectric:annotations:4.8.2:annotations-4.8.2.jar:998a02f2573884d017b04e1c0cc3ff3a416620daa8cc8d93d6aa15fc00b02c4b',
|
'org.robolectric:annotations:4.8.2:annotations-4.8.2.jar:998a02f2573884d017b04e1c0cc3ff3a416620daa8cc8d93d6aa15fc00b02c4b',
|
||||||
'org.robolectric:junit:4.8.2:junit-4.8.2.jar:eb0996f147566d722a178b1e1dcb849f69f5dbdd45a0149f10ce0d823b9e5a61',
|
'org.robolectric:junit:4.8.2:junit-4.8.2.jar:eb0996f147566d722a178b1e1dcb849f69f5dbdd45a0149f10ce0d823b9e5a61',
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ buildscript {
|
|||||||
onionwrapper_version = '0.0.5'
|
onionwrapper_version = '0.0.5'
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
// upgrading this let's us run into https://github.com/gradle/gradle/issues/20330
|
||||||
|
classpath 'com.android.tools.build:gradle:7.2.2'
|
||||||
classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.7.0'
|
classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.7.0'
|
||||||
classpath files('libs/gradle-witness.jar')
|
classpath files('libs/gradle-witness.jar')
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|||||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||||
distributionSha256Sum=97a52d145762adc241bad7fd18289bf7f6801e08ece6badf80402fe2b9f250b1
|
distributionSha256Sum=c9490e938b221daf0094982288e4038deed954a3f12fb54cbf270ddf4e37d879
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
Reference in New Issue
Block a user