mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Compare commits
40 Commits
release-1.
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a4147b563 | ||
|
|
08b72af647 | ||
|
|
528e090c6f | ||
|
|
652f9e5705 | ||
|
|
6a91ec7a6b | ||
|
|
c3a9eff96b | ||
|
|
bd05d893eb | ||
|
|
6965bc0acd | ||
|
|
c6e9554026 | ||
|
|
ab8734e373 | ||
|
|
267956b36c | ||
|
|
ec84ddb38b | ||
|
|
ba2db48d8e | ||
|
|
186f61f771 | ||
|
|
47971517cd | ||
|
|
8db182d7e5 | ||
|
|
d44a609d0c | ||
|
|
0a1892d39f | ||
|
|
9b092da37a | ||
|
|
852e2c29e3 | ||
|
|
1b087d59d4 | ||
|
|
30ce8651b5 | ||
|
|
80a8ee4de9 | ||
|
|
354f3bc1cf | ||
|
|
1e6b018ff4 | ||
|
|
eba489bb98 | ||
|
|
2bfdcaaa42 | ||
|
|
c2e71ef52f | ||
|
|
9ee8fe74ba | ||
|
|
95d8783852 | ||
|
|
b4f3604584 | ||
|
|
badccac90c | ||
|
|
1b8d1a5a8d | ||
|
|
2fe57d2597 | ||
|
|
904d5b2ce2 | ||
|
|
1911b3dd97 | ||
|
|
bd430a1009 | ||
|
|
c16d0e8f45 | ||
|
|
847273c558 | ||
|
|
b9bac8b6a5 |
@@ -13,8 +13,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 31
|
||||
versionCode 10417
|
||||
versionName "1.4.17"
|
||||
versionCode 10419
|
||||
versionName "1.4.19"
|
||||
consumerProguardFiles 'proguard-rules.txt'
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@@ -40,8 +40,16 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
// 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 bramble-android tests,
|
||||
// even though the bramble-api test classes are provided by the testImplementation dependency
|
||||
// below and the compiler can find them
|
||||
implementation project(':bramble-api')
|
||||
|
||||
implementation project(':bramble-core')
|
||||
|
||||
implementation 'androidx.annotation:annotation:1.5.0'
|
||||
|
||||
tor "org.briarproject:tor-android:$tor_version"
|
||||
tor "org.briarproject:obfs4proxy-android:$obfs4proxy_version"
|
||||
tor "org.briarproject:snowflake-android:$snowflake_version"
|
||||
@@ -51,6 +59,7 @@ dependencies {
|
||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "org.jmock:jmock:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmock_version"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="org.briarproject.bramble">
|
||||
|
||||
<uses-feature
|
||||
@@ -7,15 +8,17 @@
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<!-- The BLUETOOTH permission was supposed to be removed in API 31 but is still needed on some Xiaomi/Redmi/POCO devices running API 31 -->
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH"
|
||||
android:maxSdkVersion="30" />
|
||||
android:maxSdkVersion="31" />
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH_ADMIN"
|
||||
android:maxSdkVersion="30" />
|
||||
<uses-permission
|
||||
android:name="android.permission.BLUETOOTH_SCAN"
|
||||
android:usesPermissionFlags="neverForLocation" />
|
||||
android:usesPermissionFlags="neverForLocation"
|
||||
tools:targetApi="31" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
@@ -26,7 +26,6 @@ import static android.os.Process.myPid;
|
||||
import static android.os.Process.myTid;
|
||||
import static android.os.Process.myUid;
|
||||
import static android.provider.Settings.Secure.ANDROID_ID;
|
||||
import static org.briarproject.bramble.util.AndroidUtils.hasBtConnectPermission;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
@@ -53,8 +52,8 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
|
||||
ContentResolver contentResolver = appContext.getContentResolver();
|
||||
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
|
||||
if (id != null) out.writeUTF(id);
|
||||
// use bluetooth paired devices as well, if allowed
|
||||
if (hasBtConnectPermission(appContext)) {
|
||||
// On API 31 and higher we need permission to access bonded devices
|
||||
if (SDK_INT < 31) {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||
if (bt != null) {
|
||||
|
||||
@@ -65,6 +65,9 @@ public class AndroidUtils {
|
||||
|
||||
public static Pair<String, String> getBluetoothAddressAndMethod(Context ctx,
|
||||
BluetoothAdapter adapter) {
|
||||
// If we don't have permission to access the adapter's address, let
|
||||
// the caller know we can't find it
|
||||
if (!hasBtConnectPermission(ctx)) return new Pair<>("", "");
|
||||
// Return the adapter's address if it's valid and not fake
|
||||
@SuppressLint("HardwareIds")
|
||||
String address = adapter.getAddress();
|
||||
|
||||
@@ -8,9 +8,10 @@ apply from: 'witness.gradle'
|
||||
|
||||
dependencies {
|
||||
api 'org.briarproject:null-safety:0.1'
|
||||
api 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
api 'javax.inject:javax.inject:1'
|
||||
api "com.google.dagger:dagger:$dagger_version"
|
||||
|
||||
implementation "com.google.dagger:dagger:$dagger_version"
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
implementation "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
@@ -25,7 +26,7 @@ configurations {
|
||||
testOutput.extendsFrom(testCompile)
|
||||
}
|
||||
task jarTest(type: Jar, dependsOn: testClasses) {
|
||||
from sourceSets.test.output
|
||||
from sourceSets.test.output, sourceSets.main.output
|
||||
classifier = 'test'
|
||||
}
|
||||
artifacts {
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
package org.briarproject.bramble.api.keyagreement;
|
||||
|
||||
public interface KeyAgreementConstants {
|
||||
import org.briarproject.bramble.api.mailbox.MailboxConstants;
|
||||
|
||||
/**
|
||||
* The version of the BQP protocol used in beta releases. This version
|
||||
* number is reserved.
|
||||
*/
|
||||
byte BETA_PROTOCOL_VERSION = 89;
|
||||
public interface KeyAgreementConstants {
|
||||
|
||||
/**
|
||||
* The current version of the BQP protocol.
|
||||
*/
|
||||
byte PROTOCOL_VERSION = 4;
|
||||
|
||||
/**
|
||||
* The QR code format identifier, used to distinguish BQP QR codes from
|
||||
* QR codes used for other purposes. See
|
||||
* {@link MailboxConstants#QR_FORMAT_ID}.
|
||||
*/
|
||||
byte QR_FORMAT_ID = 0;
|
||||
|
||||
/**
|
||||
* The QR code format version.
|
||||
*/
|
||||
byte QR_FORMAT_VERSION = PROTOCOL_VERSION;
|
||||
|
||||
/**
|
||||
* The length of the BQP key commitment in bytes.
|
||||
*/
|
||||
|
||||
@@ -7,5 +7,5 @@ import java.io.IOException;
|
||||
@NotNullByDefault
|
||||
public interface PayloadParser {
|
||||
|
||||
Payload parse(byte[] raw) throws IOException;
|
||||
Payload parse(String payload) throws IOException;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.api.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
|
||||
import java.util.List;
|
||||
@@ -19,6 +20,18 @@ public interface MailboxConstants {
|
||||
*/
|
||||
TransportId ID = new TransportId("org.briarproject.bramble.mailbox");
|
||||
|
||||
/**
|
||||
* The QR code format identifier, used to distinguish mailbox QR codes
|
||||
* from QR codes used for other purposes. See
|
||||
* {@link KeyAgreementConstants#QR_FORMAT_ID};
|
||||
*/
|
||||
byte QR_FORMAT_ID = 1;
|
||||
|
||||
/**
|
||||
* The QR code format version.
|
||||
*/
|
||||
byte QR_FORMAT_VERSION = 0;
|
||||
|
||||
/**
|
||||
* Mailbox API versions that we support as a client. This is reported to our
|
||||
* contacts by {@link MailboxUpdateManager}.
|
||||
|
||||
@@ -1,17 +1,44 @@
|
||||
package org.briarproject.bramble.api.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
|
||||
public abstract class MailboxPairingState {
|
||||
|
||||
public static class QrCodeReceived extends MailboxPairingState {
|
||||
public abstract static class Pending extends MailboxPairingState {
|
||||
|
||||
public final long timeStarted;
|
||||
|
||||
private Pending(long timeStarted) {
|
||||
this.timeStarted = timeStarted;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Pairing extends MailboxPairingState {
|
||||
public static class QrCodeReceived extends Pending {
|
||||
|
||||
public QrCodeReceived(long timeStarted) {
|
||||
super(timeStarted);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Pairing extends Pending {
|
||||
|
||||
public Pairing(long timeStarted) {
|
||||
super(timeStarted);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Paired extends MailboxPairingState {
|
||||
}
|
||||
|
||||
public static class InvalidQrCode extends MailboxPairingState {
|
||||
|
||||
public final QrCodeType qrCodeType;
|
||||
public final int formatVersion;
|
||||
|
||||
public InvalidQrCode(QrCodeType qrCodeType, int formatVersion) {
|
||||
this.qrCodeType = qrCodeType;
|
||||
this.formatVersion = formatVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MailboxAlreadyPaired extends MailboxPairingState {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.bramble.api.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface QrCodeClassifier {
|
||||
|
||||
enum QrCodeType {
|
||||
BQP,
|
||||
MAILBOX,
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
Pair<QrCodeType, Integer> classifyQrCode(String payload);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.bramble.api.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* Thrown when a QR code that has been scanned does not have the expected type.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class WrongQrCodeTypeException extends FormatException {
|
||||
|
||||
private final QrCodeType qrCodeType;
|
||||
|
||||
public WrongQrCodeTypeException(QrCodeType qrCodeType) {
|
||||
this.qrCodeType = qrCodeType;
|
||||
}
|
||||
|
||||
public QrCodeType getQrCodeType() {
|
||||
return qrCodeType;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.util;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -17,13 +16,18 @@ import javax.annotation.Nullable;
|
||||
import static java.nio.charset.CodingErrorAction.IGNORE;
|
||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||
|
||||
@SuppressWarnings("CharsetObjectCanBeUsed")
|
||||
@NotNullByDefault
|
||||
public class StringUtils {
|
||||
|
||||
private static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
private static Pattern MAC = Pattern.compile("[0-9a-f]{2}:[0-9a-f]{2}:" +
|
||||
"[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}",
|
||||
CASE_INSENSITIVE);
|
||||
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
public static final Charset US_ASCII = Charset.forName("US-ASCII");
|
||||
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
|
||||
private static final Pattern MAC =
|
||||
Pattern.compile("[0-9a-f]{2}:[0-9a-f]{2}:" +
|
||||
"[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}",
|
||||
CASE_INSENSITIVE);
|
||||
|
||||
private static final char[] HEX = new char[] {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
@@ -45,11 +49,7 @@ public class StringUtils {
|
||||
}
|
||||
|
||||
public static byte[] toUtf8(String s) {
|
||||
try {
|
||||
return s.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return s.getBytes(UTF_8);
|
||||
}
|
||||
|
||||
public static String fromUtf8(byte[] bytes) {
|
||||
|
||||
@@ -9,23 +9,24 @@ apply from: 'witness.gradle'
|
||||
apply from: '../dagger.gradle'
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-api', configuration: 'default')
|
||||
implementation 'org.bouncycastle:bcprov-jdk15to18:1.71'
|
||||
api project(':bramble-api')
|
||||
|
||||
api 'org.briarproject:jtorctl:0.5'
|
||||
|
||||
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
|
||||
//noinspection GradleDependency
|
||||
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6
|
||||
implementation 'org.bitlet:weupnp:0.1.4'
|
||||
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
||||
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
||||
implementation 'org.briarproject:jtorctl:0.5'
|
||||
implementation 'org.briarproject:socks-socket:0.1'
|
||||
|
||||
//noinspection GradleDependency
|
||||
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
|
||||
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
|
||||
testImplementation 'org.hsqldb:hsqldb:2.3.5' // The last version that supports Java 1.6
|
||||
testImplementation 'net.jodah:concurrentunit:0.4.2'
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
@@ -52,7 +53,7 @@ configurations {
|
||||
testOutput.extendsFrom(testCompile)
|
||||
}
|
||||
task jarTest(type: Jar, dependsOn: testClasses) {
|
||||
from sourceSets.test.output
|
||||
from sourceSets.test.output, sourceSets.main.output
|
||||
classifier = 'test'
|
||||
}
|
||||
artifacts {
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
import org.briarproject.bramble.mailbox.MailboxModule;
|
||||
import org.briarproject.bramble.plugin.PluginModule;
|
||||
import org.briarproject.bramble.properties.PropertiesModule;
|
||||
import org.briarproject.bramble.qrcode.QrCodeModule;
|
||||
import org.briarproject.bramble.record.RecordModule;
|
||||
import org.briarproject.bramble.reliability.ReliabilityModule;
|
||||
import org.briarproject.bramble.rendezvous.RendezvousModule;
|
||||
@@ -47,6 +48,7 @@ import dagger.Module;
|
||||
MailboxModule.class,
|
||||
PluginModule.class,
|
||||
PropertiesModule.class,
|
||||
QrCodeModule.class,
|
||||
RecordModule.class,
|
||||
ReliabilityModule.class,
|
||||
RendezvousModule.class,
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -29,6 +28,7 @@ import javax.inject.Inject;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.bramble.api.crypto.DecryptionResult.INVALID_CIPHERTEXT;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||
|
||||
@@ -99,7 +99,7 @@ class AccountManagerImpl implements AccountManager {
|
||||
}
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(f), Charset.forName("UTF-8")));
|
||||
new FileInputStream(f), UTF_8));
|
||||
String key = reader.readLine();
|
||||
reader.close();
|
||||
return key;
|
||||
@@ -151,7 +151,7 @@ class AccountManagerImpl implements AccountManager {
|
||||
@GuardedBy("stateChangeLock")
|
||||
private void writeDbKeyToFile(String key, File f) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
out.write(key.getBytes(Charset.forName("UTF-8")));
|
||||
out.write(key.getBytes(UTF_8));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.briarproject.nullsafety.NotNullByDefault;
|
||||
import org.whispersystems.curve25519.Curve25519;
|
||||
import org.whispersystems.curve25519.Curve25519KeyPair;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
@@ -51,6 +50,7 @@ import static org.briarproject.bramble.api.crypto.DecryptionResult.KEY_STRENGTHE
|
||||
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
|
||||
|
||||
@NotNullByDefault
|
||||
class CryptoComponentImpl implements CryptoComponent {
|
||||
@@ -460,7 +460,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
@Override
|
||||
public String encodeOnion(byte[] publicKey) {
|
||||
Digest digest = new SHA3Digest(256);
|
||||
byte[] label = ".onion checksum".getBytes(Charset.forName("US-ASCII"));
|
||||
byte[] label = ".onion checksum".getBytes(US_ASCII);
|
||||
digest.update(label, 0, label.length);
|
||||
digest.update(publicKey, 0, publicKey.length);
|
||||
digest.update(ONION_HS_PROTOCOL_VERSION);
|
||||
|
||||
@@ -39,12 +39,13 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class MessageEncrypter {
|
||||
@@ -228,7 +229,7 @@ public class MessageEncrypter {
|
||||
PublicKey publicKey =
|
||||
encrypter.getKeyParser().parsePublicKey(keyBytes);
|
||||
String message = readFully(System.in);
|
||||
byte[] plaintext = message.getBytes(Charset.forName("UTF-8"));
|
||||
byte[] plaintext = message.getBytes(UTF_8);
|
||||
byte[] ciphertext = encrypter.encrypt(publicKey, plaintext);
|
||||
System.out.println(AsciiArmour.wrap(ciphertext, LINE_LENGTH));
|
||||
}
|
||||
@@ -242,7 +243,7 @@ public class MessageEncrypter {
|
||||
encrypter.getKeyParser().parsePrivateKey(keyBytes);
|
||||
byte[] ciphertext = AsciiArmour.unwrap(readFully(System.in));
|
||||
byte[] plaintext = encrypter.decrypt(privateKey, ciphertext);
|
||||
System.out.println(new String(plaintext, Charset.forName("UTF-8")));
|
||||
System.out.println(new String(plaintext, UTF_8));
|
||||
}
|
||||
|
||||
private static String readFully(InputStream in) throws IOException {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
||||
@@ -19,13 +17,13 @@ public class KeyAgreementModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
PayloadEncoder providePayloadEncoder(BdfWriterFactory bdfWriterFactory) {
|
||||
return new PayloadEncoderImpl(bdfWriterFactory);
|
||||
PayloadEncoder providePayloadEncoder(PayloadEncoderImpl payloadEncoder) {
|
||||
return payloadEncoder;
|
||||
}
|
||||
|
||||
@Provides
|
||||
PayloadParser providePayloadParser(BdfReaderFactory bdfReaderFactory) {
|
||||
return new PayloadParserImpl(bdfReaderFactory);
|
||||
PayloadParser providePayloadParser(PayloadParserImpl payloadParser) {
|
||||
return payloadParser;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -13,7 +13,8 @@ import java.io.IOException;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_ID;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
@@ -29,7 +30,8 @@ class PayloadEncoderImpl implements PayloadEncoder {
|
||||
@Override
|
||||
public byte[] encode(Payload p) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(PROTOCOL_VERSION);
|
||||
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
|
||||
out.write(formatIdAndVersion);
|
||||
BdfWriter w = bdfWriterFactory.createWriter(out);
|
||||
try {
|
||||
w.writeListStart(); // Payload start
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.BdfReader;
|
||||
@@ -11,6 +12,9 @@ import org.briarproject.bramble.api.keyagreement.TransportDescriptor;
|
||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.api.qrcode.WrongQrCodeTypeException;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -21,34 +25,42 @@ import java.util.List;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class PayloadParserImpl implements PayloadParser {
|
||||
|
||||
private final BdfReaderFactory bdfReaderFactory;
|
||||
private final QrCodeClassifier qrCodeClassifier;
|
||||
|
||||
@Inject
|
||||
PayloadParserImpl(BdfReaderFactory bdfReaderFactory) {
|
||||
PayloadParserImpl(BdfReaderFactory bdfReaderFactory,
|
||||
QrCodeClassifier qrCodeClassifier) {
|
||||
this.bdfReaderFactory = bdfReaderFactory;
|
||||
this.qrCodeClassifier = qrCodeClassifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Payload parse(byte[] raw) throws IOException {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(raw);
|
||||
// First byte: the protocol version
|
||||
int protocolVersion = in.read();
|
||||
if (protocolVersion == -1) throw new FormatException();
|
||||
if (protocolVersion != PROTOCOL_VERSION) {
|
||||
boolean tooOld = protocolVersion < PROTOCOL_VERSION ||
|
||||
protocolVersion == BETA_PROTOCOL_VERSION;
|
||||
public Payload parse(String payloadString) throws IOException {
|
||||
Pair<QrCodeType, Integer> typeAndVersion =
|
||||
qrCodeClassifier.classifyQrCode(payloadString);
|
||||
QrCodeType qrCodeType = typeAndVersion.getFirst();
|
||||
if (qrCodeType != BQP) throw new WrongQrCodeTypeException(qrCodeType);
|
||||
int formatVersion = typeAndVersion.getSecond();
|
||||
if (formatVersion != QR_FORMAT_VERSION) {
|
||||
boolean tooOld = formatVersion < QR_FORMAT_VERSION;
|
||||
throw new UnsupportedVersionException(tooOld);
|
||||
}
|
||||
byte[] raw = payloadString.getBytes(ISO_8859_1);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(raw);
|
||||
// First byte: the format identifier and version (already parsed)
|
||||
if (in.read() == -1) throw new AssertionError();
|
||||
// The rest of the payload is a BDF list with one or more elements
|
||||
BdfReader r = bdfReaderFactory.createReader(in);
|
||||
BdfList payload = r.readList();
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.event.EventExecutor;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
@@ -25,6 +26,7 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
|
||||
private final MailboxApi api;
|
||||
private final MailboxSettingsManager mailboxSettingsManager;
|
||||
private final MailboxUpdateManager mailboxUpdateManager;
|
||||
private final QrCodeClassifier qrCodeClassifier;
|
||||
|
||||
@Inject
|
||||
MailboxPairingTaskFactoryImpl(
|
||||
@@ -34,7 +36,8 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
|
||||
Clock clock,
|
||||
MailboxApi api,
|
||||
MailboxSettingsManager mailboxSettingsManager,
|
||||
MailboxUpdateManager mailboxUpdateManager) {
|
||||
MailboxUpdateManager mailboxUpdateManager,
|
||||
QrCodeClassifier qrCodeClassifier) {
|
||||
this.eventExecutor = eventExecutor;
|
||||
this.db = db;
|
||||
this.crypto = crypto;
|
||||
@@ -42,12 +45,13 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
|
||||
this.api = api;
|
||||
this.mailboxSettingsManager = mailboxSettingsManager;
|
||||
this.mailboxUpdateManager = mailboxUpdateManager;
|
||||
this.qrCodeClassifier = qrCodeClassifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailboxPairingTask createPairingTask(String qrCodePayload) {
|
||||
return new MailboxPairingTaskImpl(qrCodePayload, eventExecutor, db,
|
||||
crypto, clock, api, mailboxSettingsManager,
|
||||
mailboxUpdateManager);
|
||||
mailboxUpdateManager, qrCodeClassifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.Consumer;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
@@ -9,18 +10,26 @@ import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.event.EventExecutor;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.ConnectionError;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.InvalidQrCode;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.MailboxAlreadyPaired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Pairing;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.QrCodeReceived;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.UnexpectedError;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.mailbox.MailboxApi.ApiException;
|
||||
import org.briarproject.bramble.mailbox.MailboxApi.MailboxAlreadyPairedException;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -32,7 +41,10 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
@ThreadSafe
|
||||
@NotNullByDefault
|
||||
@@ -40,9 +52,6 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
|
||||
private final static Logger LOG =
|
||||
getLogger(MailboxPairingTaskImpl.class.getName());
|
||||
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
||||
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
private static final int VERSION_REQUIRED = 32;
|
||||
|
||||
private final String payload;
|
||||
private final Executor eventExecutor;
|
||||
@@ -52,6 +61,8 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
private final MailboxApi api;
|
||||
private final MailboxSettingsManager mailboxSettingsManager;
|
||||
private final MailboxUpdateManager mailboxUpdateManager;
|
||||
private final QrCodeClassifier qrCodeClassifier;
|
||||
private final long timeStarted;
|
||||
|
||||
private final Object lock = new Object();
|
||||
@GuardedBy("lock")
|
||||
@@ -68,7 +79,8 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
Clock clock,
|
||||
MailboxApi api,
|
||||
MailboxSettingsManager mailboxSettingsManager,
|
||||
MailboxUpdateManager mailboxUpdateManager) {
|
||||
MailboxUpdateManager mailboxUpdateManager,
|
||||
QrCodeClassifier qrCodeClassifier) {
|
||||
this.payload = payload;
|
||||
this.eventExecutor = eventExecutor;
|
||||
this.db = db;
|
||||
@@ -77,7 +89,9 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
this.api = api;
|
||||
this.mailboxSettingsManager = mailboxSettingsManager;
|
||||
this.mailboxUpdateManager = mailboxUpdateManager;
|
||||
state = new MailboxPairingState.QrCodeReceived();
|
||||
this.qrCodeClassifier = qrCodeClassifier;
|
||||
timeStarted = clock.currentTimeMillis();
|
||||
state = new QrCodeReceived(timeStarted);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,22 +113,30 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Pair<QrCodeType, Integer> typeAndVersion =
|
||||
qrCodeClassifier.classifyQrCode(payload);
|
||||
QrCodeType qrCodeType = typeAndVersion.getFirst();
|
||||
int formatVersion = typeAndVersion.getSecond();
|
||||
if (qrCodeType != MAILBOX || formatVersion != QR_FORMAT_VERSION) {
|
||||
setState(new InvalidQrCode(qrCodeType, formatVersion));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
pairMailbox();
|
||||
} catch (FormatException e) {
|
||||
onMailboxError(e, new MailboxPairingState.InvalidQrCode());
|
||||
onMailboxError(e, new InvalidQrCode(qrCodeType, formatVersion));
|
||||
} catch (MailboxAlreadyPairedException e) {
|
||||
onMailboxError(e, new MailboxPairingState.MailboxAlreadyPaired());
|
||||
onMailboxError(e, new MailboxAlreadyPaired());
|
||||
} catch (IOException e) {
|
||||
onMailboxError(e, new MailboxPairingState.ConnectionError());
|
||||
onMailboxError(e, new ConnectionError());
|
||||
} catch (ApiException | DbException e) {
|
||||
onMailboxError(e, new MailboxPairingState.UnexpectedError());
|
||||
onMailboxError(e, new UnexpectedError());
|
||||
}
|
||||
}
|
||||
|
||||
private void pairMailbox() throws IOException, ApiException, DbException {
|
||||
MailboxProperties mailboxProperties = decodeQrCodePayload(payload);
|
||||
setState(new MailboxPairingState.Pairing());
|
||||
setState(new Pairing(timeStarted));
|
||||
MailboxProperties ownerProperties = api.setup(mailboxProperties);
|
||||
long time = clock.currentTimeMillis();
|
||||
db.transaction(false, txn -> {
|
||||
@@ -133,7 +155,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
}
|
||||
}
|
||||
});
|
||||
setState(new MailboxPairingState.Paired());
|
||||
setState(new Paired());
|
||||
}
|
||||
|
||||
private void onMailboxError(Exception e, MailboxPairingState state) {
|
||||
@@ -167,14 +189,6 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
}
|
||||
throw new FormatException();
|
||||
}
|
||||
int version = bytes[0] & 0xFF;
|
||||
if (version != VERSION_REQUIRED) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("QR code has not version " + VERSION_REQUIRED +
|
||||
": " + version);
|
||||
}
|
||||
throw new FormatException();
|
||||
}
|
||||
LOG.info("QR code is valid");
|
||||
byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33);
|
||||
String onion = crypto.encodeOnion(onionPubKey);
|
||||
|
||||
@@ -46,7 +46,6 @@ import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -100,6 +99,7 @@ import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -419,9 +419,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
append(strb, "ClientTransportPlugin meek_lite exec", obfs4Path);
|
||||
String snowflakePath = getSnowflakeExecutableFile().getAbsolutePath();
|
||||
append(strb, "ClientTransportPlugin snowflake exec", snowflakePath);
|
||||
//noinspection CharsetObjectCanBeUsed
|
||||
return new ByteArrayInputStream(
|
||||
strb.toString().getBytes(Charset.forName("UTF-8")));
|
||||
return new ByteArrayInputStream(strb.toString().getBytes(UTF_8));
|
||||
}
|
||||
|
||||
private void listFiles(File f) {
|
||||
@@ -811,7 +809,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
@Override
|
||||
public void controlConnectionClosed() {
|
||||
if (state.isTorRunning()) {
|
||||
throw new RuntimeException("Control connection closed");
|
||||
// TODO: Restart the Tor process
|
||||
LOG.warning("Control connection closed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
|
||||
|
||||
class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
||||
|
||||
@@ -31,6 +31,6 @@ class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
||||
EdDSAPrivateKeySpec spec = new EdDSAPrivateKeySpec(seed, CURVE_SPEC);
|
||||
byte[] hash = spec.getH();
|
||||
byte[] base64 = Base64.encode(hash);
|
||||
return "ED25519-V3:" + new String(base64, Charset.forName("US-ASCII"));
|
||||
return "ED25519-V3:" + new String(base64, US_ASCII);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.briarproject.bramble.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxConstants;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.UNKNOWN;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class QrCodeClassifierImpl implements QrCodeClassifier {
|
||||
|
||||
@Inject
|
||||
QrCodeClassifierImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<QrCodeType, Integer> classifyQrCode(String payload) {
|
||||
byte[] bytes = payload.getBytes(ISO_8859_1);
|
||||
if (bytes.length == 0) return new Pair<>(UNKNOWN, 0);
|
||||
// If this is a Bramble QR code then the first byte encodes the
|
||||
// format ID (3 bits) and version (5 bits)
|
||||
int formatIdAndVersion = bytes[0] & 0xFF;
|
||||
int formatId = formatIdAndVersion >> 5;
|
||||
int formatVersion = formatIdAndVersion & 0x1F;
|
||||
if (formatId == KeyAgreementConstants.QR_FORMAT_ID) {
|
||||
return new Pair<>(BQP, formatVersion);
|
||||
}
|
||||
if (formatId == MailboxConstants.QR_FORMAT_ID) {
|
||||
return new Pair<>(MAILBOX, formatVersion);
|
||||
}
|
||||
return new Pair<>(UNKNOWN, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.bramble.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class QrCodeModule {
|
||||
|
||||
@Provides
|
||||
QrCodeClassifier provideQrCodeClassifier(
|
||||
QrCodeClassifierImpl qrCodeClassifier) {
|
||||
return qrCodeClassifier;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -34,6 +33,7 @@ import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
@@ -342,7 +342,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
private void storeDatabaseKey(File f, String hex) throws IOException {
|
||||
f.getParentFile().mkdirs();
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
out.write(hex.getBytes(Charset.forName("UTF-8")));
|
||||
out.write(hex.getBytes(UTF_8));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
@@ -350,7 +350,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
@Nullable
|
||||
private String loadDatabaseKey(File f) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(f), Charset.forName("UTF-8")));
|
||||
new FileInputStream(f), UTF_8));
|
||||
String hex = reader.readLine();
|
||||
reader.close();
|
||||
return hex;
|
||||
|
||||
@@ -2,21 +2,27 @@ package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.BdfReader;
|
||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.api.qrcode.WrongQrCodeTypeException;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -26,32 +32,29 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final BdfReaderFactory bdfReaderFactory =
|
||||
context.mock(BdfReaderFactory.class);
|
||||
private final QrCodeClassifier qrCodeClassifier =
|
||||
context.mock(QrCodeClassifier.class);
|
||||
private final BdfReader bdfReader = context.mock(BdfReader.class);
|
||||
|
||||
private final PayloadParserImpl payloadParser =
|
||||
new PayloadParserImpl(bdfReaderFactory);
|
||||
private final String payload = getRandomString(123);
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testThrowsFormatExceptionIfPayloadIsEmpty() throws Exception {
|
||||
payloadParser.parse(new byte[0]);
|
||||
private final PayloadParserImpl payloadParser =
|
||||
new PayloadParserImpl(bdfReaderFactory, qrCodeClassifier);
|
||||
|
||||
@Test(expected = WrongQrCodeTypeException.class)
|
||||
public void testThrowsExceptionForWrongQrCodeType() throws Exception {
|
||||
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION);
|
||||
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrowsUnsupportedVersionExceptionForOldVersion()
|
||||
throws Exception {
|
||||
try {
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION - 1});
|
||||
fail();
|
||||
} catch (UnsupportedVersionException e) {
|
||||
assertTrue(e.isTooOld());
|
||||
}
|
||||
}
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION - 1);
|
||||
|
||||
@Test
|
||||
public void testThrowsUnsupportedVersionExceptionForBetaVersion()
|
||||
throws Exception {
|
||||
try {
|
||||
payloadParser.parse(new byte[] {BETA_PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
fail();
|
||||
} catch (UnsupportedVersionException e) {
|
||||
assertTrue(e.isTooOld());
|
||||
@@ -61,8 +64,10 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testThrowsUnsupportedVersionExceptionForNewVersion()
|
||||
throws Exception {
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION + 1);
|
||||
|
||||
try {
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION + 1});
|
||||
payloadParser.parse(payload);
|
||||
fail();
|
||||
} catch (UnsupportedVersionException e) {
|
||||
assertFalse(e.isTooOld());
|
||||
@@ -71,6 +76,8 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testThrowsFormatExceptionForEmptyList() throws Exception {
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -79,7 +86,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(new BdfList()));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
@@ -87,6 +94,8 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -97,7 +106,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(false));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
@@ -105,6 +114,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH - 1);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -115,7 +125,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(true));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
@@ -123,6 +133,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH + 1);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -133,12 +144,14 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(true));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsPayloadWithNoDescriptors() throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -149,8 +162,16 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(true));
|
||||
}});
|
||||
|
||||
Payload p = payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
Payload p = payloadParser.parse(payload);
|
||||
assertArrayEquals(commitment, p.getCommitment());
|
||||
assertTrue(p.getTransportDescriptors().isEmpty());
|
||||
}
|
||||
|
||||
private void expectClassifyQrCode(String payload, QrCodeType qrCodeType,
|
||||
int formatVersion) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(qrCodeClassifier).classifyQrCode(payload);
|
||||
will(returnValue(new Pair<>(qrCodeType, formatVersion)));
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
@@ -7,13 +8,24 @@ import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.ConnectionError;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.InvalidQrCode;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.MailboxAlreadyPaired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Pairing;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.QrCodeReceived;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.UnexpectedError;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.mailbox.MailboxApi.ApiException;
|
||||
import org.briarproject.bramble.mailbox.MailboxApi.MailboxAlreadyPairedException;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||
@@ -27,6 +39,9 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.mailbox.MailboxTestUtils.getQrCodePayload;
|
||||
import static org.briarproject.bramble.test.TestUtils.getContact;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
@@ -48,9 +63,8 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
context.mock(MailboxSettingsManager.class);
|
||||
private final MailboxUpdateManager mailboxUpdateManager =
|
||||
context.mock(MailboxUpdateManager.class);
|
||||
private final MailboxPairingTaskFactory factory =
|
||||
new MailboxPairingTaskFactoryImpl(executor, db, crypto, clock, api,
|
||||
mailboxSettingsManager, mailboxUpdateManager);
|
||||
private final QrCodeClassifier qrCodeClassifier =
|
||||
context.mock(QrCodeClassifier.class);
|
||||
|
||||
private final String onion = getRandomString(56);
|
||||
private final byte[] onionBytes = getRandomBytes(32);
|
||||
@@ -68,32 +82,50 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testInitialQrCodeReceivedState() {
|
||||
MailboxPairingTask task =
|
||||
factory.createPairingTask(getRandomString(42));
|
||||
MailboxPairingTask task = createPairingTask(getRandomString(42));
|
||||
task.addObserver(state ->
|
||||
assertTrue(state instanceof MailboxPairingState.QrCodeReceived)
|
||||
);
|
||||
assertTrue(state instanceof QrCodeReceived));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidQrCode() {
|
||||
MailboxPairingTask task1 =
|
||||
factory.createPairingTask(getRandomString(42));
|
||||
task1.run();
|
||||
task1.addObserver(state ->
|
||||
assertTrue(state instanceof MailboxPairingState.InvalidQrCode)
|
||||
);
|
||||
public void testInvalidQrCodeType() {
|
||||
String payload = getRandomString(65);
|
||||
MailboxPairingTask task = createPairingTask(payload);
|
||||
|
||||
String goodLength = "00" + getRandomString(63);
|
||||
MailboxPairingTask task2 = factory.createPairingTask(goodLength);
|
||||
task2.run();
|
||||
task2.addObserver(state ->
|
||||
assertTrue(state instanceof MailboxPairingState.InvalidQrCode)
|
||||
);
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
|
||||
task.run();
|
||||
task.addObserver(state ->
|
||||
assertTrue(state instanceof InvalidQrCode));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidQrCodeVersion() {
|
||||
String payload = getRandomString(65);
|
||||
MailboxPairingTask task = createPairingTask(payload);
|
||||
|
||||
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION + 1);
|
||||
|
||||
task.run();
|
||||
task.addObserver(state ->
|
||||
assertTrue(state instanceof InvalidQrCode));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidQrCodeLength() {
|
||||
String payload = getRandomString(42);
|
||||
MailboxPairingTask task = createPairingTask(payload);
|
||||
|
||||
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION);
|
||||
|
||||
task.run();
|
||||
task.addObserver(state ->
|
||||
assertTrue(state instanceof InvalidQrCode));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulPairing() throws Exception {
|
||||
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).encodeOnion(onionBytes);
|
||||
will(returnValue(onion));
|
||||
@@ -121,17 +153,14 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
}});
|
||||
|
||||
AtomicInteger i = new AtomicInteger(0);
|
||||
MailboxPairingTask task = factory.createPairingTask(validPayload);
|
||||
MailboxPairingTask task = createPairingTask(validPayload);
|
||||
task.addObserver(state -> {
|
||||
if (i.get() == 0) {
|
||||
assertEquals(MailboxPairingState.QrCodeReceived.class,
|
||||
state.getClass());
|
||||
assertEquals(QrCodeReceived.class, state.getClass());
|
||||
} else if (i.get() == 1) {
|
||||
assertEquals(MailboxPairingState.Pairing.class,
|
||||
state.getClass());
|
||||
assertEquals(Pairing.class, state.getClass());
|
||||
} else if (i.get() == 2) {
|
||||
assertEquals(MailboxPairingState.Paired.class,
|
||||
state.getClass());
|
||||
assertEquals(Paired.class, state.getClass());
|
||||
} else fail("Unexpected change of state " + state.getClass());
|
||||
i.getAndIncrement();
|
||||
});
|
||||
@@ -140,24 +169,23 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testAlreadyPaired() throws Exception {
|
||||
testApiException(new MailboxApi.MailboxAlreadyPairedException(),
|
||||
MailboxPairingState.MailboxAlreadyPaired.class);
|
||||
testApiException(new MailboxAlreadyPairedException(),
|
||||
MailboxAlreadyPaired.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMailboxApiException() throws Exception {
|
||||
testApiException(new MailboxApi.ApiException(),
|
||||
MailboxPairingState.UnexpectedError.class);
|
||||
testApiException(new ApiException(), UnexpectedError.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApiIOException() throws Exception {
|
||||
testApiException(new IOException(),
|
||||
MailboxPairingState.ConnectionError.class);
|
||||
testApiException(new IOException(), ConnectionError.class);
|
||||
}
|
||||
|
||||
private void testApiException(Exception e,
|
||||
Class<? extends MailboxPairingState> s) throws Exception {
|
||||
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).encodeOnion(onionBytes);
|
||||
will(returnValue(onion));
|
||||
@@ -165,13 +193,14 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
will(throwException(e));
|
||||
}});
|
||||
|
||||
MailboxPairingTask task = factory.createPairingTask(validPayload);
|
||||
MailboxPairingTask task = createPairingTask(validPayload);
|
||||
task.run();
|
||||
task.addObserver(state -> assertEquals(state.getClass(), s));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDbException() throws Exception {
|
||||
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).encodeOnion(onionBytes);
|
||||
will(returnValue(onion));
|
||||
@@ -188,10 +217,10 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
will(throwException(new DbException()));
|
||||
}});
|
||||
|
||||
MailboxPairingTask task = factory.createPairingTask(validPayload);
|
||||
MailboxPairingTask task = createPairingTask(validPayload);
|
||||
task.run();
|
||||
task.addObserver(state -> assertEquals(state.getClass(),
|
||||
MailboxPairingState.UnexpectedError.class));
|
||||
task.addObserver(state ->
|
||||
assertEquals(state.getClass(), UnexpectedError.class));
|
||||
}
|
||||
|
||||
private PredicateMatcher<MailboxProperties> matches(MailboxProperties p2) {
|
||||
@@ -202,4 +231,22 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
p1.getServerSupports().equals(p2.getServerSupports()));
|
||||
}
|
||||
|
||||
private MailboxPairingTask createPairingTask(String qrCodePayload) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clock).currentTimeMillis();
|
||||
will(returnValue(time));
|
||||
}});
|
||||
|
||||
return new MailboxPairingTaskImpl(qrCodePayload, executor, db,
|
||||
crypto, clock, api, mailboxSettingsManager,
|
||||
mailboxUpdateManager, qrCodeClassifier);
|
||||
}
|
||||
|
||||
private void expectClassifyQrCode(String payload, QrCodeType qrCodeType,
|
||||
int formatVersion) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(qrCodeClassifier).classifyQrCode(payload);
|
||||
will(returnValue(new Pair<>(qrCodeType, formatVersion)));
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.mailbox;
|
||||
import org.briarproject.bramble.api.WeakSingletonProvider;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.net.SocketFactory;
|
||||
@@ -11,20 +10,24 @@ import javax.net.SocketFactory;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_ID;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
class MailboxTestUtils {
|
||||
|
||||
static String getQrCodePayload(byte[] onionBytes, byte[] setupToken) {
|
||||
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
|
||||
byte[] payloadBytes = ByteBuffer.allocate(65)
|
||||
.put((byte) 32) // 1
|
||||
.put((byte) formatIdAndVersion) // 1
|
||||
.put(onionBytes) // 32
|
||||
.put(setupToken) // 32
|
||||
.array();
|
||||
//noinspection CharsetObjectCanBeUsed
|
||||
return new String(payloadBytes, Charset.forName("ISO-8859-1"));
|
||||
return new String(payloadBytes, ISO_8859_1);
|
||||
}
|
||||
|
||||
// Used by mailbox integration tests
|
||||
static String getQrCodePayload(byte[] setupToken) {
|
||||
return getQrCodePayload(getRandomId(), setupToken);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.briarproject.bramble.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxConstants;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.UNKNOWN;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class QrCodeClassifierImplTest extends BrambleTestCase {
|
||||
|
||||
private final QrCodeClassifier classifier = new QrCodeClassifierImpl();
|
||||
|
||||
@Test
|
||||
public void testClassifiesEmptyStringAsUnknown() {
|
||||
Pair<QrCodeType, Integer> result = classifier.classifyQrCode("");
|
||||
assertEquals(UNKNOWN, result.getFirst());
|
||||
assertEquals(0, result.getSecond().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassifiesKeyAgreement() {
|
||||
byte[] payloadBytes = getRandomBytes(123);
|
||||
for (int version = 0; version < 32; version++) {
|
||||
int typeAndVersion =
|
||||
(KeyAgreementConstants.QR_FORMAT_ID << 5) | version;
|
||||
payloadBytes[0] = (byte) typeAndVersion;
|
||||
String payload = new String(payloadBytes, ISO_8859_1);
|
||||
Pair<QrCodeType, Integer> result =
|
||||
classifier.classifyQrCode(payload);
|
||||
assertEquals(BQP, result.getFirst());
|
||||
assertEquals(version, result.getSecond().intValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassifiesMailbox() {
|
||||
byte[] payloadBytes = getRandomBytes(123);
|
||||
for (int version = 0; version < 32; version++) {
|
||||
int typeAndVersion =
|
||||
(MailboxConstants.QR_FORMAT_ID << 5) | version;
|
||||
payloadBytes[0] = (byte) typeAndVersion;
|
||||
String payload = new String(payloadBytes, ISO_8859_1);
|
||||
Pair<QrCodeType, Integer> result =
|
||||
classifier.classifyQrCode(payload);
|
||||
assertEquals(MAILBOX, result.getFirst());
|
||||
assertEquals(version, result.getSecond().intValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassifiesUnknownFormatIdAsUnknown() {
|
||||
byte[] payloadBytes = getRandomBytes(123);
|
||||
int unknownFormatId = MailboxConstants.QR_FORMAT_ID + 1;
|
||||
int typeAndVersion = unknownFormatId << 5;
|
||||
payloadBytes[0] = (byte) typeAndVersion;
|
||||
String payload = new String(payloadBytes, ISO_8859_1);
|
||||
Pair<QrCodeType, Integer> result = classifier.classifyQrCode(payload);
|
||||
assertEquals(UNKNOWN, result.getFirst());
|
||||
assertEquals(0, result.getSecond().intValue());
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,13 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
implementation project(':bramble-core')
|
||||
|
||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||
def jna_version = '4.5.2'
|
||||
implementation "net.java.dev.jna:jna:$jna_version"
|
||||
implementation "net.java.dev.jna:jna-platform:$jna_version"
|
||||
|
||||
tor "org.briarproject:tor-linux:$tor_version"
|
||||
tor "org.briarproject:tor-windows:$tor_version"
|
||||
tor "org.briarproject:obfs4proxy-linux:$obfs4proxy_version"
|
||||
@@ -28,9 +30,11 @@ dependencies {
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "org.jmock:jmock:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmock_version"
|
||||
testImplementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
||||
|
||||
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Semaphore;
|
||||
@@ -33,6 +32,7 @@ import static java.util.logging.Level.WARNING;
|
||||
import static jssc.SerialPort.PURGE_RXCLEAR;
|
||||
import static jssc.SerialPort.PURGE_TXCLEAR;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -41,7 +41,6 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ModemImpl.class.getName());
|
||||
|
||||
private static final Charset US_ASCII = Charset.forName("US-ASCII");
|
||||
private static final int MAX_LINE_LENGTH = 256;
|
||||
private static final int[] BAUD_RATES = {
|
||||
256000, 128000, 115200, 57600, 38400, 19200, 14400, 9600, 4800, 1200
|
||||
|
||||
@@ -15,6 +15,8 @@ dependencyVerification {
|
||||
'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.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
'com.squareup.okhttp3:okhttp:3.12.13:okhttp-3.12.13.jar:508234e024ef7e270ab1a6d5b356f5b98e786511239ca986d684fd1e2cf7bc82',
|
||||
'com.squareup.okio:okio:1.15.0:okio-1.15.0.jar:693fa319a7e8843300602b204023b7674f106ebcb577f2dd5807212b66118bd2',
|
||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||
|
||||
@@ -26,8 +26,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 31
|
||||
versionCode 10417
|
||||
versionName "1.4.17"
|
||||
versionCode 10419
|
||||
versionName "1.4.19"
|
||||
applicationId "org.briarproject.briar.android"
|
||||
buildConfigField "String", "TorVersion", "\"$tor_version\""
|
||||
|
||||
@@ -98,10 +98,15 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':briar-core', configuration: 'default')
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
// 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,
|
||||
// even though the bramble-api test classes are provided by the testImplementation dependency
|
||||
// below and the compiler can find them
|
||||
implementation project(':bramble-api')
|
||||
|
||||
implementation project(':bramble-core')
|
||||
implementation project(':bramble-android')
|
||||
implementation 'org.briarproject:dont-kill-me-lib:0.2.5'
|
||||
implementation project(':briar-core')
|
||||
|
||||
implementation 'androidx.fragment:fragment:1.3.4'
|
||||
implementation 'androidx.preference:preference:1.1.1'
|
||||
@@ -111,6 +116,9 @@ dependencies {
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'androidx.recyclerview:recyclerview-selection:1.1.0'
|
||||
|
||||
implementation 'org.briarproject:dont-kill-me-lib:0.2.5'
|
||||
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
||||
implementation "org.jsoup:jsoup:$jsoup_version"
|
||||
implementation 'info.guardianproject.panic:panic:1.0'
|
||||
implementation 'de.hdodenhof:circleimageview:3.1.0'
|
||||
implementation 'com.google.zxing:core:3.3.3' // newer version need minSdk 24
|
||||
@@ -130,9 +138,10 @@ dependencies {
|
||||
|
||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
|
||||
def espressoVersion = '3.3.0'
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
|
||||
def espressoVersion = '3.3.0'
|
||||
testImplementation 'androidx.test:runner:1.4.0'
|
||||
testImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
testImplementation 'androidx.fragment:fragment-testing:1.4.0'
|
||||
@@ -144,18 +153,24 @@ dependencies {
|
||||
testImplementation "org.jmock:jmock:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmock_version"
|
||||
testImplementation "org.jmock:jmock-imposters:$jmock_version"
|
||||
|
||||
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
androidTestImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
|
||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||
androidTestUtil 'androidx.test:orchestrator:1.3.0'
|
||||
androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
androidTestCompileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
androidTestImplementation "junit:junit:$junit_version"
|
||||
|
||||
androidTestUtil 'androidx.test:orchestrator:1.3.0'
|
||||
|
||||
androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
androidTestCompileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
|
||||
androidTestScreenshotImplementation 'tools.fastlane:screengrab:2.1.1'
|
||||
androidTestScreenshotImplementation 'com.jraska:falcon:2.2.0'
|
||||
androidTestScreenshotImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
|
||||
@@ -3,12 +3,14 @@ package org.briarproject.briar.android.contact.add.nearby;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
abstract class AddContactState {
|
||||
|
||||
static class KeyAgreementListening extends AddContactState {
|
||||
|
||||
final Bitmap qrCode;
|
||||
|
||||
KeyAgreementListening(Bitmap qrCode) {
|
||||
@@ -29,6 +31,7 @@ abstract class AddContactState {
|
||||
}
|
||||
|
||||
static class ContactExchangeFinished extends AddContactState {
|
||||
|
||||
final ContactExchangeResult result;
|
||||
|
||||
ContactExchangeFinished(ContactExchangeResult result) {
|
||||
@@ -37,25 +40,34 @@ abstract class AddContactState {
|
||||
}
|
||||
|
||||
static class Failed extends AddContactState {
|
||||
/**
|
||||
* Non-null if failed due to the scanned QR code version.
|
||||
* True if the app producing the code is too old.
|
||||
* False if the scanning app is too old.
|
||||
*/
|
||||
@Nullable
|
||||
final Boolean qrCodeTooOld;
|
||||
|
||||
Failed(@Nullable Boolean qrCodeTooOld) {
|
||||
this.qrCodeTooOld = qrCodeTooOld;
|
||||
static class WrongQrCodeType extends Failed {
|
||||
|
||||
final QrCodeType qrCodeType;
|
||||
|
||||
WrongQrCodeType(QrCodeType qrCodeType) {
|
||||
this.qrCodeType = qrCodeType;
|
||||
}
|
||||
}
|
||||
|
||||
Failed() {
|
||||
this(null);
|
||||
static class WrongQrCodeVersion extends Failed {
|
||||
|
||||
/**
|
||||
* True if the app producing the code is too old.
|
||||
* False if the scanning app is too old.
|
||||
*/
|
||||
final boolean qrCodeTooOld;
|
||||
|
||||
WrongQrCodeVersion(boolean qrCodeTooOld) {
|
||||
this.qrCodeTooOld = qrCodeTooOld;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract static class ContactExchangeResult {
|
||||
|
||||
static class Success extends ContactExchangeResult {
|
||||
|
||||
final Author remoteAuthor;
|
||||
|
||||
Success(Author remoteAuthor) {
|
||||
@@ -64,6 +76,7 @@ abstract class AddContactState {
|
||||
}
|
||||
|
||||
static class Error extends ContactExchangeResult {
|
||||
|
||||
@Nullable
|
||||
final Author duplicateAuthor;
|
||||
|
||||
|
||||
@@ -6,12 +6,15 @@ import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeFinished;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeResult;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed.WrongQrCodeType;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed.WrongQrCodeVersion;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||
@@ -34,6 +37,7 @@ import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.ACCEPTED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.REFUSED;
|
||||
|
||||
@@ -141,9 +145,15 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
ContactExchangeResult result =
|
||||
((ContactExchangeFinished) state).result;
|
||||
onContactExchangeResult(result);
|
||||
} else if (state instanceof WrongQrCodeType) {
|
||||
QrCodeType qrCodeType = ((WrongQrCodeType) state).qrCodeType;
|
||||
if (qrCodeType == MAILBOX) onMailboxQrCodeScanned();
|
||||
else onWrongQrCodeType();
|
||||
} else if (state instanceof WrongQrCodeVersion) {
|
||||
boolean qrCodeTooOld = ((WrongQrCodeVersion) state).qrCodeTooOld;
|
||||
onWrongQrCodeVersion(qrCodeTooOld);
|
||||
} else if (state instanceof Failed) {
|
||||
Boolean qrCodeTooOld = ((Failed) state).qrCodeTooOld;
|
||||
onAddingContactFailed(qrCodeTooOld);
|
||||
showErrorFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,15 +180,27 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
} else throw new AssertionError();
|
||||
}
|
||||
|
||||
private void onAddingContactFailed(@Nullable Boolean qrCodeTooOld) {
|
||||
if (qrCodeTooOld == null) {
|
||||
showErrorFragment();
|
||||
} else {
|
||||
String msg;
|
||||
if (qrCodeTooOld) msg = getString(R.string.qr_code_too_old_1);
|
||||
else msg = getString(R.string.qr_code_too_new_1);
|
||||
showNextFragment(AddNearbyContactErrorFragment.newInstance(msg));
|
||||
}
|
||||
private void onMailboxQrCodeScanned() {
|
||||
String title = getString(R.string.qr_code_invalid);
|
||||
String msg = getString(R.string.mailbox_qr_code_for_contact);
|
||||
showNextFragment(
|
||||
AddNearbyContactErrorFragment.newInstance(title, msg, false));
|
||||
}
|
||||
|
||||
private void onWrongQrCodeType() {
|
||||
String title = getString(R.string.qr_code_invalid);
|
||||
String msg = getString(R.string.qr_code_format_unknown);
|
||||
showNextFragment(
|
||||
AddNearbyContactErrorFragment.newInstance(title, msg, false));
|
||||
}
|
||||
|
||||
private void onWrongQrCodeVersion(boolean qrCodeTooOld) {
|
||||
String title = getString(R.string.qr_code_invalid);
|
||||
String msg;
|
||||
if (qrCodeTooOld) msg = getString(R.string.qr_code_too_old_1);
|
||||
else msg = getString(R.string.qr_code_too_new_1);
|
||||
showNextFragment(
|
||||
AddNearbyContactErrorFragment.newInstance(title, msg, false));
|
||||
}
|
||||
|
||||
private void showErrorFragment() {
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
import static android.view.View.GONE;
|
||||
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
|
||||
import static org.briarproject.briar.android.util.UiUtils.onSingleLinkClick;
|
||||
|
||||
@@ -31,17 +32,22 @@ public class AddNearbyContactErrorFragment extends BaseFragment {
|
||||
|
||||
public static final String TAG =
|
||||
AddNearbyContactErrorFragment.class.getName();
|
||||
private static final String ERROR_MSG = "errorMessage";
|
||||
private static final String ARG_TITLE = "title";
|
||||
private static final String ARG_ERROR_MSG = "message";
|
||||
private static final String ARG_FEEDBACK = "feedback";
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private AddNearbyContactViewModel viewModel;
|
||||
|
||||
public static AddNearbyContactErrorFragment newInstance(String errorMsg) {
|
||||
public static AddNearbyContactErrorFragment newInstance(String title,
|
||||
String errorMessage, boolean feedback) {
|
||||
AddNearbyContactErrorFragment f = new AddNearbyContactErrorFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ERROR_MSG, errorMsg);
|
||||
args.putString(ARG_TITLE, title);
|
||||
args.putString(ARG_ERROR_MSG, errorMessage);
|
||||
args.putBoolean(ARG_FEEDBACK, feedback);
|
||||
f.setArguments(args);
|
||||
return f;
|
||||
}
|
||||
@@ -66,19 +72,32 @@ public class AddNearbyContactErrorFragment extends BaseFragment {
|
||||
View v = inflater.inflate(R.layout.fragment_error_contact_exchange,
|
||||
container, false);
|
||||
|
||||
// set optional error message
|
||||
TextView explanation = v.findViewById(R.id.errorMessage);
|
||||
String title = null, errorMessage = null;
|
||||
boolean feedback = true;
|
||||
Bundle args = getArguments();
|
||||
String errorMessage = args == null ? null : args.getString(ERROR_MSG);
|
||||
if (errorMessage == null) {
|
||||
explanation.setText(getString(R.string.add_contact_error_two_way));
|
||||
} else {
|
||||
explanation.setText(args.getString(ERROR_MSG));
|
||||
if (args != null) {
|
||||
title = args.getString(ARG_TITLE);
|
||||
errorMessage = args.getString(ARG_ERROR_MSG);
|
||||
feedback = args.getBoolean(ARG_FEEDBACK, true);
|
||||
}
|
||||
|
||||
if (title != null) {
|
||||
TextView titleView = v.findViewById(R.id.errorTitle);
|
||||
titleView.setText(title);
|
||||
}
|
||||
|
||||
if (errorMessage != null) {
|
||||
TextView messageView = v.findViewById(R.id.errorMessage);
|
||||
messageView.setText(errorMessage);
|
||||
}
|
||||
|
||||
// make feedback link clickable
|
||||
TextView sendFeedback = v.findViewById(R.id.sendFeedback);
|
||||
onSingleLinkClick(sendFeedback, this::triggerFeedback);
|
||||
if (feedback) {
|
||||
// make feedback link clickable
|
||||
onSingleLinkClick(sendFeedback, this::triggerFeedback);
|
||||
} else {
|
||||
sendFeedback.setVisibility(GONE);
|
||||
}
|
||||
|
||||
// buttons
|
||||
Button tryAgain = v.findViewById(R.id.tryAgainButton);
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.briarproject.bramble.api.plugin.PluginManager;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||
import org.briarproject.bramble.api.plugin.event.TransportStateEvent;
|
||||
import org.briarproject.bramble.api.qrcode.WrongQrCodeTypeException;
|
||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.bramble.plugin.bluetooth.BluetoothPlugin;
|
||||
import org.briarproject.briar.R;
|
||||
@@ -50,9 +51,13 @@ import org.briarproject.briar.android.contact.add.nearby.AddContactState.Contact
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeResult.Error;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeResult.Success;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed.WrongQrCodeType;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed.WrongQrCodeVersion;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementListening;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.QrCodeScanned;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeUtils;
|
||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||
@@ -60,7 +65,6 @@ import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -85,6 +89,7 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactPermissionManager.areEssentialPermissionsGranted;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.NO_ADAPTER;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.REFUSED;
|
||||
@@ -126,9 +131,6 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
REFUSED
|
||||
}
|
||||
|
||||
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
||||
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
|
||||
private final EventBus eventBus;
|
||||
private final AndroidExecutor androidExecutor;
|
||||
private final Executor ioExecutor;
|
||||
@@ -376,11 +378,11 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
} else if (e instanceof KeyAgreementAbortedEvent) {
|
||||
LOG.info("KeyAgreementAbortedEvent received");
|
||||
resetPayloadFlags();
|
||||
state.setValue(new AddContactState.Failed());
|
||||
state.setValue(new Failed());
|
||||
} else if (e instanceof KeyAgreementFailedEvent) {
|
||||
LOG.info("KeyAgreementFailedEvent received");
|
||||
resetPayloadFlags();
|
||||
state.setValue(new AddContactState.Failed());
|
||||
state.setValue(new Failed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,22 +448,22 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
// Ignore results until the KeyAgreementTask is ready
|
||||
if (!gotLocalPayload || gotRemotePayload || currentTask == null) return;
|
||||
try {
|
||||
byte[] payloadBytes = result.getText().getBytes(ISO_8859_1);
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Remote payload is " + payloadBytes.length + " bytes");
|
||||
Payload remotePayload = payloadParser.parse(payloadBytes);
|
||||
Payload remotePayload = payloadParser.parse(result.getText());
|
||||
gotRemotePayload = true;
|
||||
currentTask.connectAndRunProtocol(remotePayload);
|
||||
state.postValue(new AddContactState.QrCodeScanned());
|
||||
state.postValue(new QrCodeScanned());
|
||||
} catch (WrongQrCodeTypeException e) {
|
||||
resetPayloadFlags();
|
||||
state.postValue(new WrongQrCodeType(e.getQrCodeType()));
|
||||
} catch (UnsupportedVersionException e) {
|
||||
resetPayloadFlags();
|
||||
state.postValue(new AddContactState.Failed(e.isTooOld()));
|
||||
state.postValue(new WrongQrCodeVersion(e.isTooOld()));
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
LOG.log(WARNING, "QR Code Invalid", e);
|
||||
androidExecutor.runOnUiThread(() -> Toast.makeText(getApplication(),
|
||||
R.string.qr_code_invalid, LENGTH_LONG).show());
|
||||
resetPayloadFlags();
|
||||
state.postValue(new AddContactState.Failed());
|
||||
state.postValue(new Failed());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -436,7 +436,7 @@ class HotspotManager {
|
||||
}
|
||||
|
||||
private static String createWifiLoginString(String ssid, String password) {
|
||||
// https://en.wikipedia.org/wiki/QR_code#WiFi_network_login
|
||||
// https://en.wikipedia.org/wiki/QR_code#Joining_a_Wi%E2%80%91Fi_network
|
||||
// do not remove the dangling ';', it can cause problems to omit it
|
||||
return "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;";
|
||||
}
|
||||
|
||||
@@ -6,10 +6,24 @@ import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.ConnectionError;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.InvalidQrCode;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.MailboxAlreadyPaired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Pending;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.UnexpectedError;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
import org.briarproject.briar.android.fragment.FinalFragment;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.CameraError;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.IsPaired;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.NotSetup;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.OfflineWhenPairing;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.Pairing;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.ScanningQrCode;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.ShowDownload;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.WasUnpaired;
|
||||
import org.briarproject.briar.android.view.BlankFragment;
|
||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||
@@ -25,6 +39,9 @@ import androidx.lifecycle.ViewModelProvider;
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.briar.android.util.UiUtils.showFragment;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -56,24 +73,23 @@ public class MailboxActivity extends BriarActivity {
|
||||
}
|
||||
|
||||
viewModel.getPairingState().observeEvent(this, state -> {
|
||||
if (state instanceof MailboxState.NotSetup) {
|
||||
if (state instanceof NotSetup) {
|
||||
onNotSetup();
|
||||
} else if (state instanceof MailboxState.ShowDownload) {
|
||||
} else if (state instanceof ShowDownload) {
|
||||
onShowDownload();
|
||||
} else if (state instanceof MailboxState.ScanningQrCode) {
|
||||
} else if (state instanceof ScanningQrCode) {
|
||||
onScanningQrCode();
|
||||
} else if (state instanceof MailboxState.Pairing) {
|
||||
MailboxPairingState s =
|
||||
((MailboxState.Pairing) state).pairingState;
|
||||
} else if (state instanceof Pairing) {
|
||||
MailboxPairingState s = ((Pairing) state).pairingState;
|
||||
onMailboxPairingStateChanged(s);
|
||||
} else if (state instanceof MailboxState.OfflineWhenPairing) {
|
||||
} else if (state instanceof OfflineWhenPairing) {
|
||||
onOffline();
|
||||
} else if (state instanceof MailboxState.CameraError) {
|
||||
} else if (state instanceof CameraError) {
|
||||
onCameraError();
|
||||
} else if (state instanceof MailboxState.IsPaired) {
|
||||
onIsPaired(((MailboxState.IsPaired) state).isOnline);
|
||||
} else if (state instanceof MailboxState.WasUnpaired) {
|
||||
MailboxState.WasUnpaired s = (MailboxState.WasUnpaired) state;
|
||||
} else if (state instanceof IsPaired) {
|
||||
onIsPaired(((IsPaired) state).isOnline);
|
||||
} else if (state instanceof WasUnpaired) {
|
||||
WasUnpaired s = (WasUnpaired) state;
|
||||
onUnPaired(s.tellUserToWipeMailbox);
|
||||
} else {
|
||||
throw new AssertionError("Unknown state: " + state);
|
||||
@@ -104,7 +120,7 @@ public class MailboxActivity extends BriarActivity {
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
MailboxState s = viewModel.getPairingState().getLastValue();
|
||||
if (s instanceof MailboxState.Pairing) {
|
||||
if (s instanceof Pairing) {
|
||||
// don't go back in the flow if we are already pairing
|
||||
// with the mailbox. We provide a try-again button instead.
|
||||
supportFinishAfterTransition();
|
||||
@@ -158,33 +174,44 @@ public class MailboxActivity extends BriarActivity {
|
||||
}
|
||||
Fragment f;
|
||||
String tag;
|
||||
if (s instanceof MailboxPairingState.QrCodeReceived) {
|
||||
f = new MailboxConnectingFragment();
|
||||
if (s instanceof Pending) {
|
||||
long timeStarted = ((Pending) s).timeStarted;
|
||||
f = MailboxConnectingFragment.newInstance(timeStarted);
|
||||
tag = MailboxConnectingFragment.TAG;
|
||||
} else if (s instanceof MailboxPairingState.Pairing) {
|
||||
f = new MailboxConnectingFragment();
|
||||
tag = MailboxConnectingFragment.TAG;
|
||||
} else if (s instanceof MailboxPairingState.InvalidQrCode) {
|
||||
f = ErrorFragment.newInstance(
|
||||
R.string.mailbox_setup_qr_code_wrong_title,
|
||||
R.string.mailbox_setup_qr_code_wrong_description);
|
||||
} else if (s instanceof InvalidQrCode) {
|
||||
InvalidQrCode i = (InvalidQrCode) s;
|
||||
int errorRes;
|
||||
if (i.qrCodeType == MAILBOX) {
|
||||
if (i.formatVersion < QR_FORMAT_VERSION) {
|
||||
errorRes = R.string.mailbox_qr_code_too_old;
|
||||
} else if (i.formatVersion > QR_FORMAT_VERSION) {
|
||||
errorRes = R.string.mailbox_qr_code_too_new;
|
||||
} else {
|
||||
errorRes = R.string.mailbox_setup_qr_code_wrong_description;
|
||||
}
|
||||
} else if (i.qrCodeType == BQP) {
|
||||
errorRes = R.string.contact_qr_code_for_mailbox;
|
||||
} else {
|
||||
errorRes = R.string.mailbox_setup_qr_code_wrong_description;
|
||||
}
|
||||
f = ErrorFragment.newInstance(R.string.qr_code_invalid, errorRes);
|
||||
tag = ErrorFragment.TAG;
|
||||
} else if (s instanceof MailboxPairingState.MailboxAlreadyPaired) {
|
||||
} else if (s instanceof MailboxAlreadyPaired) {
|
||||
f = ErrorFragment.newInstance(
|
||||
R.string.mailbox_setup_already_paired_title,
|
||||
R.string.mailbox_setup_already_paired_description);
|
||||
tag = ErrorFragment.TAG;
|
||||
} else if (s instanceof MailboxPairingState.ConnectionError) {
|
||||
} else if (s instanceof ConnectionError) {
|
||||
f = ErrorFragment.newInstance(
|
||||
R.string.mailbox_setup_io_error_title,
|
||||
R.string.mailbox_setup_io_error_description);
|
||||
tag = ErrorFragment.TAG;
|
||||
} else if (s instanceof MailboxPairingState.UnexpectedError) {
|
||||
} else if (s instanceof UnexpectedError) {
|
||||
f = ErrorFragment.newInstance(
|
||||
R.string.mailbox_setup_assertion_error_title,
|
||||
R.string.mailbox_setup_assertion_error_description);
|
||||
tag = ErrorFragment.TAG;
|
||||
} else if (s instanceof MailboxPairingState.Paired) {
|
||||
} else if (s instanceof Paired) {
|
||||
f = FinalFragment.newInstance(R.string.mailbox_setup_paired_title,
|
||||
R.drawable.ic_check_circle_outline,
|
||||
R.color.briar_brand_green,
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package org.briarproject.briar.android.mailbox;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||
@@ -12,25 +17,71 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import static org.briarproject.briar.android.util.UiUtils.formatDuration;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class MailboxConnectingFragment extends Fragment {
|
||||
|
||||
static final String TAG = MailboxConnectingFragment.class.getName();
|
||||
|
||||
private static final String ARG_STARTED = "started";
|
||||
private static final long TIMEOUT_MS = TorConstants.EXTRA_CONNECT_TIMEOUT;
|
||||
private static final long REFRESH_INTERVAL_MS = 1_000;
|
||||
|
||||
private final Handler handler = new Handler(Looper.getMainLooper());
|
||||
// Capture a method reference so we use the same reference for posting
|
||||
// and removing
|
||||
private final Runnable refresher = this::updateProgressBar;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private long timeStarted;
|
||||
|
||||
public static MailboxConnectingFragment newInstance(long timeStarted) {
|
||||
MailboxConnectingFragment f = new MailboxConnectingFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putLong(ARG_STARTED, timeStarted);
|
||||
f.setArguments(args);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_mailbox_connecting,
|
||||
View v = inflater.inflate(R.layout.fragment_mailbox_connecting,
|
||||
container, false);
|
||||
|
||||
progressBar = v.findViewById(R.id.progressBar);
|
||||
TextView info = v.findViewById(R.id.info);
|
||||
String duration = formatDuration(requireContext(), TIMEOUT_MS);
|
||||
info.setText(getString(R.string.mailbox_setup_connecting_info,
|
||||
duration));
|
||||
|
||||
timeStarted = requireArguments().getLong(ARG_STARTED);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
requireActivity().setTitle(R.string.mailbox_setup_title);
|
||||
updateProgressBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
handler.removeCallbacks(refresher);
|
||||
}
|
||||
|
||||
private void updateProgressBar() {
|
||||
long elapsedMs = System.currentTimeMillis() - timeStarted;
|
||||
int percent = (int) (elapsedMs * 100 / TIMEOUT_MS);
|
||||
percent = Math.min(Math.max(percent, 0), 100);
|
||||
progressBar.setProgress(percent);
|
||||
handler.postDelayed(refresher, REFRESH_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||
import org.briarproject.bramble.api.mailbox.event.OwnMailboxConnectionStatusEvent;
|
||||
@@ -24,7 +25,14 @@ import org.briarproject.bramble.api.plugin.TorConstants;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.event.TransportInactiveEvent;
|
||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.CameraError;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.IsPaired;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.NotSetup;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.OfflineWhenPairing;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.Pairing;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.ScanningQrCode;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.ShowDownload;
|
||||
import org.briarproject.briar.android.mailbox.MailboxState.WasUnpaired;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||
import org.briarproject.briar.android.viewmodel.DbViewModel;
|
||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||
@@ -113,7 +121,7 @@ class MailboxViewModel extends DbViewModel
|
||||
MailboxStatus mailboxStatus =
|
||||
mailboxManager.getMailboxStatus(txn);
|
||||
boolean isOnline = isTorActive();
|
||||
pairingState.postEvent(new MailboxState.IsPaired(isOnline));
|
||||
pairingState.postEvent(new IsPaired(isOnline));
|
||||
status.postValue(mailboxStatus);
|
||||
} else {
|
||||
pairingState.postEvent(new NotSetup());
|
||||
@@ -142,14 +150,14 @@ class MailboxViewModel extends DbViewModel
|
||||
@UiThread
|
||||
private void onTorInactive() {
|
||||
MailboxState lastState = pairingState.getLastValue();
|
||||
if (lastState instanceof MailboxState.IsPaired) {
|
||||
if (lastState instanceof IsPaired) {
|
||||
// we are already paired, so use IsPaired state
|
||||
pairingState.setEvent(new MailboxState.IsPaired(false));
|
||||
} else if (lastState instanceof MailboxState.Pairing) {
|
||||
MailboxState.Pairing p = (MailboxState.Pairing) lastState;
|
||||
pairingState.setEvent(new IsPaired(false));
|
||||
} else if (lastState instanceof Pairing) {
|
||||
Pairing p = (Pairing) lastState;
|
||||
// check that we not just finished pairing (showing success screen)
|
||||
if (!(p.pairingState instanceof MailboxPairingState.Paired)) {
|
||||
pairingState.setEvent(new MailboxState.OfflineWhenPairing());
|
||||
if (!(p.pairingState instanceof Paired)) {
|
||||
pairingState.setEvent(new OfflineWhenPairing());
|
||||
}
|
||||
// else ignore offline event as user will be leaving UI flow anyway
|
||||
}
|
||||
@@ -158,15 +166,15 @@ class MailboxViewModel extends DbViewModel
|
||||
@UiThread
|
||||
void onScanButtonClicked() {
|
||||
if (isTorActive()) {
|
||||
pairingState.setEvent(new MailboxState.ScanningQrCode());
|
||||
pairingState.setEvent(new ScanningQrCode());
|
||||
} else {
|
||||
pairingState.setEvent(new MailboxState.OfflineWhenPairing());
|
||||
pairingState.setEvent(new OfflineWhenPairing());
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void onCameraError() {
|
||||
pairingState.setEvent(new MailboxState.CameraError());
|
||||
pairingState.setEvent(new CameraError());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,7 +190,7 @@ class MailboxViewModel extends DbViewModel
|
||||
pairingTask = mailboxManager.startPairingTask(qrCodePayload);
|
||||
pairingTask.addObserver(this);
|
||||
} else {
|
||||
pairingState.postEvent(new MailboxState.OfflineWhenPairing());
|
||||
pairingState.postEvent(new OfflineWhenPairing());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +201,7 @@ class MailboxViewModel extends DbViewModel
|
||||
LOG.info("New pairing state: " +
|
||||
mailboxPairingState.getClass().getSimpleName());
|
||||
}
|
||||
pairingState.setEvent(new MailboxState.Pairing(mailboxPairingState));
|
||||
pairingState.setEvent(new Pairing(mailboxPairingState));
|
||||
}
|
||||
|
||||
private boolean isTorActive() {
|
||||
@@ -203,7 +211,7 @@ class MailboxViewModel extends DbViewModel
|
||||
|
||||
@UiThread
|
||||
void showDownloadFragment() {
|
||||
pairingState.setEvent(new MailboxState.ShowDownload());
|
||||
pairingState.setEvent(new ShowDownload());
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -214,7 +222,7 @@ class MailboxViewModel extends DbViewModel
|
||||
@UiThread
|
||||
void checkIfOnlineWhenPaired() {
|
||||
boolean isOnline = isTorActive();
|
||||
pairingState.setEvent(new MailboxState.IsPaired(isOnline));
|
||||
pairingState.setEvent(new IsPaired(isOnline));
|
||||
}
|
||||
|
||||
LiveData<Boolean> checkConnection() {
|
||||
@@ -227,7 +235,7 @@ class MailboxViewModel extends DbViewModel
|
||||
checkConnection(success -> {
|
||||
boolean isOnline = isTorActive();
|
||||
// make UI move back to status fragment by changing pairingState
|
||||
pairingState.postEvent(new MailboxState.IsPaired(isOnline));
|
||||
pairingState.postEvent(new IsPaired(isOnline));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -246,7 +254,7 @@ class MailboxViewModel extends DbViewModel
|
||||
ioExecutor.execute(() -> {
|
||||
try {
|
||||
boolean wasWiped = mailboxManager.unPair();
|
||||
pairingState.postEvent(new MailboxState.WasUnpaired(!wasWiped));
|
||||
pairingState.postEvent(new WasUnpaired(!wasWiped));
|
||||
} catch (DbException e) {
|
||||
handleException(e);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,12 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import static android.view.View.FOCUS_DOWN;
|
||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -35,8 +34,6 @@ public class OfflineFragment extends Fragment {
|
||||
|
||||
protected MailboxViewModel viewModel;
|
||||
|
||||
private NestedScrollView scrollView;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
@@ -54,7 +51,6 @@ public class OfflineFragment extends Fragment {
|
||||
View v = inflater
|
||||
.inflate(R.layout.fragment_offline, container, false);
|
||||
|
||||
scrollView = (NestedScrollView) v;
|
||||
Button checkButton = v.findViewById(R.id.checkButton);
|
||||
checkButton.setOnClickListener(view -> {
|
||||
Intent i = new Intent(requireContext(), TransportsActivity.class);
|
||||
@@ -69,8 +65,7 @@ public class OfflineFragment extends Fragment {
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
// Scroll down in case the screen is small, so the button is visible
|
||||
scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
|
||||
hideViewOnSmallScreen(requireView().findViewById(R.id.iconView));
|
||||
}
|
||||
|
||||
protected void onTryAgainClicked() {
|
||||
|
||||
@@ -41,7 +41,6 @@ public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
private final ResultCallback callback;
|
||||
|
||||
private Camera camera = null;
|
||||
private int cameraIndex = 0;
|
||||
|
||||
public QrCodeDecoder(AndroidExecutor androidExecutor,
|
||||
@IoExecutor Executor ioExecutor, ResultCallback callback) {
|
||||
@@ -53,14 +52,12 @@ public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
@Override
|
||||
public void start(Camera camera, int cameraIndex) {
|
||||
this.camera = camera;
|
||||
this.cameraIndex = cameraIndex;
|
||||
askForPreviewFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
camera = null;
|
||||
cameraIndex = 0;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
||||
@@ -310,14 +310,12 @@ class BriarReportCollector {
|
||||
btLeAdvertise);
|
||||
}
|
||||
|
||||
if (hasBtConnectPermission(ctx)) {
|
||||
Pair<String, String> p = getBluetoothAddressAndMethod(ctx, bt);
|
||||
String address = p.getFirst();
|
||||
String method = p.getSecond();
|
||||
connectivityInfo.add("BluetoothAddress",
|
||||
scrubMacAddress(address));
|
||||
connectivityInfo.add("BluetoothAddressMethod", method);
|
||||
}
|
||||
Pair<String, String> p = getBluetoothAddressAndMethod(ctx, bt);
|
||||
String address = p.getFirst();
|
||||
String method = p.getSecond();
|
||||
connectivityInfo.add("BluetoothAddress",
|
||||
scrubMacAddress(address));
|
||||
connectivityInfo.add("BluetoothAddressMethod", method);
|
||||
}
|
||||
return new ReportItem("Connectivity", R.string.dev_report_connectivity,
|
||||
connectivityInfo);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?attr/colorControlHighlight">
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
android:drawable="@drawable/button_outline_mask" />
|
||||
<item android:drawable="@drawable/button_outline_background" />
|
||||
</ripple>
|
||||
@@ -0,0 +1,19 @@
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:insetLeft="4dp"
|
||||
android:insetTop="6dp"
|
||||
android:insetRight="4dp"
|
||||
android:insetBottom="6dp">
|
||||
<shape
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/briar_button_outline" />
|
||||
<padding
|
||||
android:bottom="4dp"
|
||||
android:left="8dp"
|
||||
android:right="8dp"
|
||||
android:top="4dp" />
|
||||
</shape>
|
||||
</inset>
|
||||
@@ -0,0 +1,19 @@
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:insetLeft="4dp"
|
||||
android:insetTop="6dp"
|
||||
android:insetRight="4dp"
|
||||
android:insetBottom="6dp">
|
||||
<shape
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="@android:color/white" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@android:color/white" />
|
||||
<padding
|
||||
android:bottom="4dp"
|
||||
android:left="8dp"
|
||||
android:right="8dp"
|
||||
android:top="4dp" />
|
||||
</shape>
|
||||
</inset>
|
||||
16
briar-android/src/main/res/drawable/button_outline.xml
Normal file
16
briar-android/src/main/res/drawable/button_outline.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:bottom="6dp"
|
||||
android:left="4dp"
|
||||
android:right="4dp"
|
||||
android:top="6dp">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/briar_button_outline" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -51,12 +51,12 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
android:text="@string/add_contact_error_two_way"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
app:layout_constraintBottom_toTopOf="@+id/sendFeedback"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/errorTitle"
|
||||
tools:text="error explanation" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/errorTitle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sendFeedback"
|
||||
|
||||
@@ -56,9 +56,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/feedbackButton"
|
||||
style="@style/BriarButtonFlat.Positive"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/BriarButtonOutline.Neutral"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/send_feedback"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/fallbackButton"
|
||||
style="@style/BriarButtonFlat.Positive"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/BriarButtonOutline.Neutral"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/hotspot_help_fallback_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
||||
@@ -62,13 +62,12 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/hotspot_no_peers_connected"
|
||||
app:layout_constraintTop_toBottomOf="@+id/coordinatorLayout"
|
||||
app:layout_constraintBottom_toTopOf="@+id/connectedButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/coordinatorLayout" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/connectedButton"
|
||||
@@ -76,8 +75,8 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:drawablePadding="8dp"
|
||||
android:text="@string/hotspot_button_connected"
|
||||
app:drawableLeftCompat="@drawable/ic_check_white"
|
||||
app:drawableStartCompat="@drawable/ic_check_white"
|
||||
@@ -85,16 +84,16 @@
|
||||
app:layout_constraintBottom_toTopOf="@+id/stopButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/connectedView"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/stopButton"
|
||||
style="@style/BriarButtonFlat.Negative"
|
||||
android:layout_width="wrap_content"
|
||||
style="@style/BriarButtonOutline.Negative"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:drawablePadding="8dp"
|
||||
android:text="@string/hotspot_button_stop_sharing"
|
||||
app:drawableLeftCompat="@drawable/ic_portable_wifi_off"
|
||||
@@ -103,6 +102,7 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/connectedButton"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,31 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.AppCompat.Large"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/textView"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
android:gravity="center"
|
||||
android:text="@string/mailbox_setup_connecting"
|
||||
app:layout_constraintBottom_toTopOf="@+id/progressBar"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
style="@style/TextAppearance.AppCompat.Large"
|
||||
android:layout_width="wrap_content"
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/mailbox_setup_connecting"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
android:max="100"
|
||||
app:layout_constraintBottom_toTopOf="@+id/info"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/info"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
android:layout_marginBottom="@dimen/margin_xlarge"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/progressBar" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/progressBar"
|
||||
tools:text="This may take up to 2 minutes" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -79,10 +79,11 @@
|
||||
|
||||
<org.briarproject.briar.android.view.BriarButton
|
||||
android:id="@+id/button3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:buttonStyle="@style/BriarButtonFlat.Negative"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
app:buttonStyle="@style/BriarButtonOutline.Negative"
|
||||
app:text="@string/mailbox_status_unlink_button" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
tools:context=".android.mailbox.MailboxActivity">
|
||||
|
||||
@@ -75,10 +75,11 @@
|
||||
|
||||
<org.briarproject.briar.android.view.BriarButton
|
||||
android:id="@+id/button1_1_1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:buttonStyle="@style/BriarButtonFlat.Negative"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
app:buttonStyle="@style/BriarButtonOutline.Negative"
|
||||
app:text="@string/mailbox_status_unlink_button" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -100,10 +101,11 @@
|
||||
|
||||
<org.briarproject.briar.android.view.BriarButton
|
||||
android:id="@+id/button1_1_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:buttonStyle="@style/BriarButtonFlat.Negative"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
app:buttonStyle="@style/BriarButtonOutline.Negative"
|
||||
app:text="@string/mailbox_status_unlink_button" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -125,10 +127,11 @@
|
||||
|
||||
<org.briarproject.briar.android.view.BriarButton
|
||||
android:id="@+id/button1_1_3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:buttonStyle="@style/BriarButtonFlat.Positive"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
app:buttonStyle="@style/BriarButtonOutline.Positive"
|
||||
app:text="@string/mailbox_status_check_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
android:id="@+id/statusTitleView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
app:layout_constrainedWidth="true"
|
||||
@@ -47,62 +48,65 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:visibility="gone"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/checkButton"
|
||||
app:layout_constraintBottom_toTopOf="@+id/statusInfoView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/statusTitleView"
|
||||
tools:text="@string/mailbox_status_mailbox_too_old_message"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<org.briarproject.briar.android.view.BriarButton
|
||||
android:id="@+id/checkButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
app:buttonStyle="@style/BriarButtonFlat.Neutral"
|
||||
app:layout_constraintBottom_toTopOf="@+id/statusInfoView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/statusMessageView"
|
||||
app:text="@string/mailbox_status_check_button" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/statusInfoView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
app:layout_constraintBottom_toTopOf="@+id/unlinkButton"
|
||||
app:layout_constraintBottom_toTopOf="@+id/checkButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/checkButton"
|
||||
app:layout_constraintTop_toBottomOf="@+id/statusMessageView"
|
||||
tools:text="@string/mailbox_status_connected_info" />
|
||||
|
||||
<org.briarproject.briar.android.view.BriarButton
|
||||
android:id="@+id/checkButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:buttonStyle="@style/BriarButtonOutline.Neutral"
|
||||
app:layout_constraintBottom_toTopOf="@+id/wizardButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/statusInfoView"
|
||||
app:text="@string/mailbox_status_check_button" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/wizardButton"
|
||||
style="@style/BriarButtonFlat.Positive"
|
||||
android:layout_width="wrap_content"
|
||||
style="@style/BriarButtonOutline.Neutral"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/mailbox_error_wizard_button"
|
||||
android:visibility="gone"
|
||||
app:drawableTint="@color/briar_button_text_positive"
|
||||
app:layout_constraintBottom_toTopOf="@+id/unlinkButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/statusInfoView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/checkButton"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/unlinkButton"
|
||||
style="@style/BriarButtonFlat.Negative"
|
||||
android:layout_width="wrap_content"
|
||||
style="@style/BriarButtonOutline.Negative"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/mailbox_status_unlink_button"
|
||||
|
||||
@@ -1,81 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconView"
|
||||
android:layout_width="@dimen/hero_square"
|
||||
android:layout_height="@dimen/hero_square"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
app:layout_constraintBottom_toTopOf="@+id/titleView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.25"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:srcCompat="@drawable/transport_tor"
|
||||
app:tint="@color/briar_red_500"
|
||||
tools:ignore="ContentDescription" />
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
android:gravity="center"
|
||||
android:text="@string/offline"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
|
||||
app:layout_constraintBottom_toTopOf="@+id/textView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iconView" />
|
||||
<ImageView
|
||||
android:id="@+id/iconView"
|
||||
android:layout_width="@dimen/hero_square"
|
||||
android:layout_height="@dimen/hero_square"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
app:layout_constraintBottom_toTopOf="@+id/titleView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.25"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:srcCompat="@drawable/transport_tor"
|
||||
app:tint="@color/briar_red_500"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
android:layout_marginBottom="@dimen/margin_large"
|
||||
android:text="@string/tor_offline_description"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
app:layout_constraintBottom_toTopOf="@+id/checkButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/titleView" />
|
||||
<TextView
|
||||
android:id="@+id/titleView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
android:gravity="center"
|
||||
android:text="@string/offline"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
|
||||
app:layout_constraintBottom_toTopOf="@+id/textView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iconView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/checkButton"
|
||||
style="@style/BriarButtonFlat.Neutral"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_large"
|
||||
android:text="@string/tor_offline_button_check"
|
||||
app:layout_constraintBottom_toTopOf="@+id/button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_large"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:text="@string/tor_offline_description"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/titleView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
style="@style/BriarButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_large"
|
||||
android:text="@string/try_again_button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
<Button
|
||||
android:id="@+id/checkButton"
|
||||
style="@style/BriarButtonOutline.Neutral"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:text="@string/tor_offline_button_check" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
style="@style/BriarButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/try_again_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -224,6 +224,7 @@
|
||||
<string name="menu_contact">Контакт</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">Добавяне на контакт на живо</string>
|
||||
<string name="add_contact_error_two_way">Сканирахте ли взаимно кодовете си за QR?</string>
|
||||
<string name="face_to_face">Трябва да се срещнете лично с човека, чиито контакт искате да добавите.\n\nТака никой не може да се представи за вас или да чете съобщенията ви в бъдеще.</string>
|
||||
<string name="continue_button">Напред</string>
|
||||
<string name="try_again_button">Нов опит</string>
|
||||
@@ -239,6 +240,7 @@
|
||||
<string name="authenticating_with_device">Удостоверяване с устройство\u2026</string>
|
||||
<string name="connection_error_title">Не може да бъде установена връзка с контакта</string>
|
||||
<string name="connection_error_feedback">Ако проблемът продължава, <a href="feedback">изпратете обратна връзка</a>, за да ни помогнете да подобрим приложението.</string>
|
||||
<string name="info_both_must_scan">Трябва взаимно да сканирате кодовете си за QR</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Добавяне на контакт отдалечено</string>
|
||||
<string name="add_contact_nearby_title">Добавяне на контакт на живо</string>
|
||||
@@ -296,6 +298,7 @@
|
||||
<string name="different_person_button">Не</string>
|
||||
<string name="duplicate_link_dialog_text_3">%1$s и %2$s са изпратили еднакви препратки.\n\nЕдиният от двамата вероятно се опитва да разбере кои са контактите ви.\n\nНе им споделяйте, че сте получили същата препратка от друг човек.</string>
|
||||
<string name="pending_contact_updated_toast">Обновена чакаща заявка за контакт</string>
|
||||
<string name="info_both_must_enter_links">Трябва взаимно да добавите препратките си</string>
|
||||
<!--Peer trust levels-->
|
||||
<string name="peer_trust_level_unverified">Непроверен контакт</string>
|
||||
<string name="peer_trust_level_verified">Проверен контакт</string>
|
||||
@@ -329,6 +332,7 @@
|
||||
<string name="connect_via_bluetooth_intro">В случай, че връзка чрез Bluetooth не се установява автоматично можете да използвате този екран, за да се свържете ръчно.\n\nВие и контакта трябва да бъдете близо един до друг.\n\nДвамата трябва да докоснете бутона „Старт“ едновременно.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Осъществява св връзка през Bluetooth. По-късно опитайте отново.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Не може да продължи без разрешение за местоположение</string>
|
||||
<string name="connect_via_bluetooth_no_bluetooth_permission">Не може да продължи без разрешение за устройства наблизо</string>
|
||||
<string name="connect_via_bluetooth_start">Свързване чрез Bluetooth…</string>
|
||||
<string name="connect_via_bluetooth_success">Успешно е създaдена връзка чрез Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">Не може да бъде установена връзка чрез Bluetooth.</string>
|
||||
@@ -586,10 +590,8 @@
|
||||
\nСлед това свържете Mailbox с Briar чрез сканиране на кода за QR от приложението Mailbox.</string>
|
||||
<string name="mailbox_setup_download_link">Споделяне на препратка за изтегляне</string>
|
||||
<string name="mailbox_setup_button_scan">Сканиране на кода за QR на пощенска кутия</string>
|
||||
<string name="permission_camera_qr_denied_body">Отказахте достъп до камерата, но тя е необходима за добавянето на контакти.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="mailbox_setup_connecting">Свързване…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Грешен код на QR</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Сканираният код е недействителен. Отворете приложението Briar Malibox на устройството, на което е инсталирано и сканирайте кода, който то предостави.</string>
|
||||
<string name="permission_camera_qr_denied_body">Отказахте достъп до камерата, но достъп е необходим за сканиране на кодове за QR.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Пощенската кутия е вече свързана</string>
|
||||
<string name="mailbox_setup_already_paired_description">Прекъснете връзката с пощенската кутия от другото устройство и опитайте отново.</string>
|
||||
<string name="mailbox_setup_io_error_title">Грешка при свързване</string>
|
||||
@@ -718,14 +720,20 @@
|
||||
<string name="permission_camera_title">Разрешение за камера</string>
|
||||
<string name="permission_camera_request_body">За да сканира кода за QR, Briar трябва да използва камерата.</string>
|
||||
<string name="permission_location_title">Разрешение за местоположение</string>
|
||||
<string name="permission_location_request_body">За да открива устройства чрез Bluetooth, на Briar му е необходимо разрешение за достъп до местоположението.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_location_request_body">За да открива устройства чрез Bluetooth, Briar се нуждае от разрешение за достъп до местоположението.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_camera_location_title">Камера и местоположение</string>
|
||||
<string name="permission_camera_location_request_body">За да сканира кодове за QR, на Briar му е необходимо разрешение за достъп до камерата.\n\nЗа да открива устройства чрез Bluetooth, на Briar му е необходимо разрешение за достъп до местоположението.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_camera_denied_body">Отказахте достъп до камерата, но тя е необходима за добавянето на контакти.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="permission_location_denied_body">Отказахте достъп до местоположението, но то е необходимо за откриване на устройства чрез Bluetooth.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="permission_camera_location_request_body">За да сканира кода за QR, Briar трябва да използва камерата.\n\nЗа да открива устройства чрез Bluetooth, Briar трябва да има достъп до местоположението.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_camera_bluetooth_title">Камера и устройства наблизо</string>
|
||||
<string name="permission_camera_bluetooth_request_body">За да сканира кода за QR, Briar трябва да използва камерата.\n\nЗа да открива устройства чрез Bluetooth, Briar се нуждае от достъп до местоположението. Briar се нуждае от разрешение да намира и да се свързва с устройства наблизо.</string>
|
||||
<string name="permission_camera_denied_body">Отказахте достъп до камерата, но достъп е необходим за добавяне на контакти.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="permission_location_denied_body">Отказахте достъп до местоположението, но достъп е необходим за откриване на устройства чрез Bluetooth.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="permission_location_setting_title">Настройки на местоположението</string>
|
||||
<string name="permission_location_setting_body">Местоположението на устройството ви трябва да е включено, за да бъдат откривани устройства чрез Bluetooth. За да продължите включете местоположението. След това можете да го изключите.</string>
|
||||
<string name="permission_location_setting_body">За да бъдат откривани устройства чрез Bluetooth местоположението на устройството ви трябва да е включено. За да продължите включете местоположението. След това можете да го изключите.</string>
|
||||
<string name="permission_location_setting_hotspot_body">За да създаде безжична точка за достъп местоположението на устройството ви трябва да е включено. За да продължите включете местоположението. След това можете да го изключите.</string>
|
||||
<string name="permission_location_setting_button">Включване на местеположение</string>
|
||||
<string name="permission_bluetooth_title">Разрешение за устройства наблизо</string>
|
||||
<string name="permission_bluetooth_body">За да извършва разговори чрез Bluetooth, Briar се нуждае от разрешение да намира и да се свързва с устройства наблизо.</string>
|
||||
<string name="permission_bluetooth_denied_body">Отказахте достъп до устройства наблизо, но достъп е необходим за използване на Bluetooth.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="qr_code">Код за QR</string>
|
||||
<string name="show_qr_code_fullscreen">Код за QR на цял екран</string>
|
||||
<!--App Locking-->
|
||||
@@ -747,8 +755,10 @@
|
||||
<string name="hotspot_notification_channel_title">Безжична точка за достъп</string>
|
||||
<string name="hotspot_notification_title">Споделяне на Briar извън мрежа</string>
|
||||
<string name="hotspot_button_connected">Напред</string>
|
||||
<string name="permission_hotspot_location_request_body">За да създаде безжична точка за достъп, на Briar му е необходимо разрешение за достъп до местоположението.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Отказахте достъп до местоположението, но то е необходимо за създаване на безжична точка за достъп.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="permission_hotspot_location_request_body">За да създаде безжична точка за достъп, Briar се нуждае от разрешение за достъп до местоположението.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_hotspot_location_request_precise_body">За да създаде безжична точка за достъп, Briar се нуждае от разрешение за достъп до точното местоположение.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Отказахте достъп до местоположението, но достъп е необходим за създаване на безжична точка за достъп.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="permission_hotspot_location_denied_precise_body">Отказахте достъп до точното местоположение, но достъп е необходим за създаване на безжична точка за достъп.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="wifi_settings_title">Настройки на Wi-Fi</string>
|
||||
<string name="wifi_settings_request_enable_body">За да създаде безжична точка за достъп, Briar се нуждае от безжична мрежа. Включете Wi-Fi.</string>
|
||||
<string name="hotspot_tab_manual">Ръчно</string>
|
||||
|
||||
@@ -594,9 +594,7 @@
|
||||
<string name="mailbox_setup_download_link">Download-Link teilen</string>
|
||||
<string name="mailbox_setup_button_scan">Mailbox QR-Code scannen</string>
|
||||
<string name="permission_camera_qr_denied_body">Du hast den Zugriff auf die Kamera verweigert, aber das Scannen eines QR-Codes erfordert die Verwendung der Kamera.\n\nBitte gewähre den Zugriff.</string>
|
||||
<string name="mailbox_setup_connecting">Verbinde…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Falscher QR-Code</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Der gescannte Code ist ungültig. Bitte öffne die Briar Mailbox-App auf deinem Mailbox-Gerät und scanne den dort angezeigten QR-Code.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Mailbox bereits verknüpft</string>
|
||||
<string name="mailbox_setup_already_paired_description">Verknüpfung der Mailbox auf deinem anderen Gerät aufheben und erneut versuchen.</string>
|
||||
<string name="mailbox_setup_io_error_title">Keine Verknüpfung möglich</string>
|
||||
|
||||
@@ -235,6 +235,7 @@
|
||||
<string name="menu_contact">Contacto</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">Agregar contacto cercano</string>
|
||||
<string name="add_contact_error_two_way">¿Ambos escanearon los códigos QR del otro?</string>
|
||||
<string name="face_to_face">Debes reunirte con la persona a la que quieras añadir como contacto.\n\nHaciéndolo así prevendrás que nadie te suplante o pueda leer tus mensajes en el futuro.</string>
|
||||
<string name="continue_button">Continuar</string>
|
||||
<string name="try_again_button">Prueba de nuevo</string>
|
||||
@@ -308,6 +309,7 @@
|
||||
<string name="different_person_button">Diferente Persona</string>
|
||||
<string name="duplicate_link_dialog_text_3">%1$s y %2$s te enviaron el mismo enlace.\n\nUno de ellos puede estar tratando de descubrir quiénes son tus contactos.\n\nNo les digas que recibiste el mismo enlace de otra persona.</string>
|
||||
<string name="pending_contact_updated_toast">Contacto pendiente actualizado</string>
|
||||
<string name="info_both_must_enter_links">Ambos deben agregar los enlaces del otro</string>
|
||||
<!--Peer trust levels-->
|
||||
<string name="peer_trust_level_unverified">Contacto no verificado</string>
|
||||
<string name="peer_trust_level_verified">Contacto verificado</string>
|
||||
@@ -341,6 +343,7 @@
|
||||
<string name="connect_via_bluetooth_intro">En el caso que las conexiones Bluetooth no funcionen automáticamente, puedes usar esta pantalla para conectarte manualmente.\n\nTu contacto necesita estar cerca para que esto funcione.\n\nAmbos deberían presionar \"Inicio\" al mismo tiempo.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Ya se está intentando conectar vía Bluetooth. Por favor inténtalo de nuevo en unos segundos.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">No se puede continuar sin permiso de ubicación</string>
|
||||
<string name="connect_via_bluetooth_no_bluetooth_permission">No se puede continuar sin el permiso de dispositivos cercanos</string>
|
||||
<string name="connect_via_bluetooth_start">Conectar mediante Bluetooth...</string>
|
||||
<string name="connect_via_bluetooth_success">Conectado exitosamente mediante Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">No se pudo conectar mediante Bluetooth.</string>
|
||||
@@ -604,9 +607,7 @@
|
||||
<string name="mailbox_setup_download_link">Compartir enlace de descarga</string>
|
||||
<string name="mailbox_setup_button_scan">Escanear código QR de Buzón</string>
|
||||
<string name="permission_camera_qr_denied_body">Has denegado el acceso a la cámara, pero para escanear un código QR se requiere el uso de la cámara.\n\nPor favor considera conceder el acceso.</string>
|
||||
<string name="mailbox_setup_connecting">Conectando...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Código QR erróneo</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">El código escaneado no es válido. Por favor abre la aplicación Buzón de Briar en tu dispositivo de buzón y escanea el código QR que presenta.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Buzón ya vinculado</string>
|
||||
<string name="mailbox_setup_already_paired_description">Desvincula el Buzón en tu otro dispositivo e inténtalo de nuevo.</string>
|
||||
<string name="mailbox_setup_io_error_title">No se pudo conectar</string>
|
||||
@@ -743,6 +744,7 @@
|
||||
<string name="permission_location_request_body">Para descubrir dispositivos Bluetooth, Briar necesita permiso para acceder tu ubicación.\n\nBriar no la almacena o la comparte con nadie.</string>
|
||||
<string name="permission_camera_location_title">Cámara y ubicación</string>
|
||||
<string name="permission_camera_location_request_body">Para escanear el código QR, Briar necesita acceso a la cámara.\n\nPara descubrir dispositivos Bluetooth, Briar necesita permiso para acceder tu ubicación.\n\nBriar no la almacena o la comparte con nadie.</string>
|
||||
<string name="permission_camera_bluetooth_title">Cámara y dispositivos cercanos</string>
|
||||
<string name="permission_camera_denied_body">Has denegado el acceso a la cámara, pero para añadir contactos se requiere el uso de la cámara.\n\nPor favor considera la posibilidad de conceder el acceso.</string>
|
||||
<string name="permission_location_denied_body">Has denegado el acceso a tu ubicación, pero Briar necesita este permiso para descubrir dispositivos Bluetooth.\n\nPor favor considera la posibilidad de conceder el acceso.</string>
|
||||
<string name="permission_location_setting_title">Configuración de ubicación</string>
|
||||
|
||||
@@ -247,6 +247,8 @@
|
||||
<string name="qr_code_invalid">کد کیوآر نامعتبر می باشد</string>
|
||||
<string name="qr_code_too_old_1">کد QR که اسکن کردهاید مربوط به نسخه قدیمی Briar است.\n\nلطفا از مخاطب خود بخواهید به آخرین نسخه ارتقا دهد و سپس دوباره امتحان کنید.</string>
|
||||
<string name="qr_code_too_new_1">کد QR که اسکن کردهاید مربوط به نسخه جدیدتری از Briar است.\n\nلطفا به آخرین نسخه ارتقا دهید و سپس دوباره امتحان کنید.</string>
|
||||
<string name="mailbox_qr_code_for_contact">کد QR که اسکن کردهاید از صندوق پستی Briar میآید.\n\nاگر میخواهید یک صندوق پستی را پیوند دهید، لطفا تنظیمات > صندوق پستی از منوی Briar را انتخاب کنید.</string>
|
||||
<string name="qr_code_format_unknown">کد QR که اسکن کرده اید برای افزودن مخاطب Briar نیست.\n\nلطفا کد QR نشان داده شده در صفحه مخاطب خود را اسکن کنید.</string>
|
||||
<string name="camera_error">خطای دوربین</string>
|
||||
<string name="connecting_to_device">اتصال به دستگاهu2026\</string>
|
||||
<string name="authenticating_with_device">تصدیق سازی با دستگاه u2026\</string>
|
||||
@@ -626,9 +628,13 @@
|
||||
<string name="mailbox_setup_download_link">اشتراک لینک دانلود</string>
|
||||
<string name="mailbox_setup_button_scan">اسکن کد QR Mailbox</string>
|
||||
<string name="permission_camera_qr_denied_body">شما دسترسی به دوربین را رد کردهاید، اما اسکن کد QR مستلزم استفاده از دوربین است.\n\nلطفا دسترسی به دوربین را بدهید.</string>
|
||||
<string name="mailbox_setup_connecting">در حال اتصال...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">کد QR اشتباه است</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">کد اسکنشده نامعتبر است. لطفا برنامه Briar Mailbox را در دستگاه Mailbox خود باز کنید و کد QR ارائهشده را اسکن کنید.</string>
|
||||
<string name="mailbox_setup_connecting">در حال اتصال به صندوق پست…</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_connecting_info">این ممکن است تا %1s طول بکشد</string>
|
||||
<string name="mailbox_qr_code_too_old">کد QR که اسکن کردهاید از نسخه قدیمیتری از صندوق پستی Briar آمده است.\n\nلطفا صندوق پستی Briar را به آخرین نسخه ارتقا دهید و سپس دوباره امتحان کنید.</string>
|
||||
<string name="mailbox_qr_code_too_new">کد QR که اسکن کردهاید از نسخه جدیدتری از صندوق پستی Briar آمده است.\n\nلطفا Briar را به آخرین نسخه ارتقا دهید و سپس دوباره امتحان کنید.</string>
|
||||
<string name="contact_qr_code_for_mailbox">کد QR که اسکن کردهاید برای افزودن مخاطب Briar است.\n\nاگر میخواهید مخاطبی را اضافه کنید، لطفا به فهرست مخاطبین بروید و روی نماد + ضربه بزنید.</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">کد QR که اسکن کردهاید از صندوق پستی Briar نمیآید.\n\nلطفا برنامه صندوق پستی Briar را در دستگاه مربوط به صندوق پستی خود باز کنید و کد QR ارائهشده را اسکن کنید.</string>
|
||||
<string name="mailbox_setup_already_paired_title">صندوقپستی قبلا متصل شده است</string>
|
||||
<string name="mailbox_setup_already_paired_description">اتصال صندوقپستی دستگاه دیگرتان را لغو کنید و دوباره امتحان کنید.</string>
|
||||
<string name="mailbox_setup_io_error_title">متصل نشد</string>
|
||||
|
||||
@@ -593,9 +593,7 @@
|
||||
<string name="mailbox_setup_download_link">Partager le lien de téléchargement</string>
|
||||
<string name="mailbox_setup_button_scan">Balayer le code QR de Boîte de courriel</string>
|
||||
<string name="permission_camera_qr_denied_body">Vous avez refusé l’accès à l’appareil photo, mais le balayage d’un code QR de contacts exige de l’utiliser.\n\nVeuillez envisager d’y accorder l’accès.</string>
|
||||
<string name="mailbox_setup_connecting">Connexion…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Le code QR est erroné</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Le code balayé est invalide. Veuillez ouvrir l’appli Boîte de courriel de Briar sur votre appareil Boîte de courriel et balayer le code qu’elle présente.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">La Boîte de courriel est déjà reliée</string>
|
||||
<string name="mailbox_setup_already_paired_description">Annuler le lien avec la Boîte de courriel sur l’autre appareil et réessayer.</string>
|
||||
<string name="mailbox_setup_io_error_title">Connexion impossible</string>
|
||||
|
||||
@@ -578,9 +578,7 @@
|
||||
<string name="mailbox_setup_download_link">Deila niðurhalstengli</string>
|
||||
<string name="mailbox_setup_button_scan">Skanna QR-kóða pósthólfs</string>
|
||||
<string name="permission_camera_qr_denied_body">Þú hefur hafnað aðgangi að myndavélinni, en það að skanna QR-kóða krefst notkun hennar.\n\nÍhugaðu að veita þennan aðgang.</string>
|
||||
<string name="mailbox_setup_connecting">Tengist…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Rangur QR-kóði</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Skannaði kóðinn er ógildur. Opnaðu Briar Mailbox forritið á pósthólfstækinu þínu og skannaðu QR-kóðann sem það birtir.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Pósthólf er þegar tengt</string>
|
||||
<string name="mailbox_setup_already_paired_description">Aftengdu pósthólfið á hinu tækinu þínu og prófaðu aftur.</string>
|
||||
<string name="mailbox_setup_io_error_title">Mistókst að tengjast</string>
|
||||
|
||||
@@ -246,6 +246,8 @@
|
||||
<string name="qr_code_invalid">Il codice QR non è valido</string>
|
||||
<string name="qr_code_too_old_1">Il codice QR che hai scansionato proviene da una versione più vecchia di Briar.\n\nChiedi al tuo contatto di aggiornare all\'ultima versione e poi riprova.</string>
|
||||
<string name="qr_code_too_new_1">Il codice QR che hai scansionato proviene da una versione più recente di Briar.\n\nAggiorna all\'ultima versione e poi riprova.</string>
|
||||
<string name="mailbox_qr_code_for_contact">Il codice QR che hai scansionato proviene da Briar Mailbox\n\nSe vuoi collegare una casella postale, scegli Impostazioni > Casella postale dal menu di Briar.</string>
|
||||
<string name="qr_code_format_unknown">Il codice QR che hai scansionato non è fatto per l\'aggiunta di un contatto Briar.\n\nScansiona il codice QR mostrato nello schermo del tuo contatto.</string>
|
||||
<string name="camera_error">Errore fotocamera</string>
|
||||
<string name="connecting_to_device">Connessione al dispositivo\u2026</string>
|
||||
<string name="authenticating_with_device">Autenticazione con il dispositivo\u2026</string>
|
||||
@@ -608,9 +610,13 @@
|
||||
<string name="mailbox_setup_download_link">Condividi link di download</string>
|
||||
<string name="mailbox_setup_button_scan">Scansiona codice QR Mailbox</string>
|
||||
<string name="permission_camera_qr_denied_body">Hai negato l\'accesso alla fotocamera, ma la scansione di un codice QR ne richiede l\'utilizzo.\n\nPrendi in considerazione di consentirne l\'accesso.</string>
|
||||
<string name="mailbox_setup_connecting">Connessione in corso...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Codice QR errato</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Il codice scansionato non è valido. Apri l\'app Briar Mailbox nel tuo dispositivo della casella postale e scansiona il codice QR che mostra.</string>
|
||||
<string name="mailbox_setup_connecting">Connessione alla casella postale…</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_connecting_info">Potrebbe impiegarci %1s</string>
|
||||
<string name="mailbox_qr_code_too_old">Il codice QR che hai scansionato proviene da una versione più vecchia di Briar Mailbox.\n\nAggiorna Briar Mailbox all\'ultima versione e poi riprova.</string>
|
||||
<string name="mailbox_qr_code_too_new">Il codice QR che hai scansionato proviene da una versione più recente di Briar Mailbox.\n\nAggiorna Briar all\'ultima versione e poi riprova.</string>
|
||||
<string name="contact_qr_code_for_mailbox">Il codice QR che hai scansionato è fatto per l\'aggiunta di un contatto Briar.\n\nSe vuoi aggiungere un contatto, vai nell\'elenco dei contatti e tocca l\'icona + .</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Il codice QR che hai scansionato non proviene da Briar Mailbox.\n\nApri l\'app Briar Mailbox sul tuo dispositivo della casella postale e scansiona il codice QR mostrato.</string>
|
||||
<string name="mailbox_setup_already_paired_title">Casella postale già collegata</string>
|
||||
<string name="mailbox_setup_already_paired_description">Scollega la casella postale sul tuo altro dispositivo e riprova.</string>
|
||||
<string name="mailbox_setup_io_error_title">Impossibile connettere</string>
|
||||
|
||||
@@ -573,9 +573,7 @@
|
||||
<string name="mailbox_setup_download_link">ダウンロードリンクを共有</string>
|
||||
<string name="mailbox_setup_button_scan">メールボックスのQRコードをスキャン</string>
|
||||
<string name="permission_camera_qr_denied_body">カメラへのアクセスをが拒否されましたが、QRコードをスキャンするにはカメラを使用する必要があります。\n\nカメラへのアクセスの許可を考えてください。</string>
|
||||
<string name="mailbox_setup_connecting">接続中…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">不正なQRコード</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">スキャンされたコードは無効です。メールボックス端末上のBriarメールボックスアプリを開き、提示されたQRコードをスキャンしてください。</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">メールボックスは既に結びつけられています</string>
|
||||
<string name="mailbox_setup_already_paired_description">あなたの端末上のメールボックスの結びつけを解き、再試行してください。</string>
|
||||
<string name="mailbox_setup_io_error_title">接続できません</string>
|
||||
|
||||
@@ -588,9 +588,7 @@
|
||||
<string name="mailbox_setup_download_link">ჩამოტვირთვის ბმულის გაზიარება</string>
|
||||
<string name="mailbox_setup_button_scan">საფოსტო ყუთის QR კოდის სკანირება</string>
|
||||
<string name="permission_camera_qr_denied_body">თქვენ უარყავით კამერაზე წვდომა, მაგრამ QR კოდის სკანირებისთვის საჭიროა კამერის გამოყენება.\n\nგთხოვთ, განიხილოთ წვდომის მინიჭება.</string>
|
||||
<string name="mailbox_setup_connecting">უკავშირდება…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">არასწორი QR კოდი</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">სკანირებული კოდი არასწორია. გთხოვთ გახსნათ Briar Mailbox აპი თქვენს მოწყობილობაზე საფოსტო ყუთით და დაასკანიროთ იქ არსებული QR კოდი.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">საფოსტო ყუთი უკვე დაკავშირებულია</string>
|
||||
<string name="mailbox_setup_already_paired_description">ჩახსენით საფოსტო ყუთი სათადარიგო მოწყობილობაზე და ისევ სცადეთ.</string>
|
||||
<string name="mailbox_setup_io_error_title">დაკავშირება ვერ ხერხდება</string>
|
||||
|
||||
@@ -604,8 +604,7 @@
|
||||
\nGalite įsidiegti Briar pašto dėžutę laisvame atsarginiame įrenginyje. Palikite įrenginį prijungtą prie maitinimo šaltinio ir belaidžio (Wi-Fi) ryšio, kad jis būtų pastoviai prijungtas prie interneto.</string>
|
||||
<string name="mailbox_setup_download_link">Bendrinti atsisiuntimo nuorodą</string>
|
||||
<string name="mailbox_setup_button_scan">Skenuoti pašto dėžutės QR kodą</string>
|
||||
<string name="mailbox_setup_connecting">Jungiamasi…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Neteisingas QR kodas</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Pašto dėžutė jau susieta</string>
|
||||
<string name="mailbox_setup_io_error_title">Nepavyko prisijungti</string>
|
||||
<string name="mailbox_setup_io_error_description">Įsitikinkite, kad abu įrenginiai yra prisijungę prie interneto ir bandykite dar kartą.</string>
|
||||
|
||||
@@ -565,8 +565,7 @@
|
||||
<string name="mailbox_setup_download_link">ဒေါင်းလုဒ်လင့်ခ်ကို မျှဝေပါ</string>
|
||||
<string name="mailbox_setup_button_scan">စာတိုက်ပုံး QR ကုဒ်ကို စကင်န်ဖတ်ပါ</string>
|
||||
<string name="permission_camera_qr_denied_body">သင်သည် ကင်မရာအသုံးပြုခွင့်ကို ငြင်းပယ်ထားသော်လည်း QR ကုဒ်ကို စကင်န်ဖတ်ရန် ကင်မရာကို အသုံးပြုရန် လိုအပ်ပါသည်။ \n\nကျေးဇူးပြု၍ ဝင်ရောက်ခွင့်ပြုရန် စဉ်းစားပါ။</string>
|
||||
<string name="mailbox_setup_connecting">ချိတ်ဆက်နေသည်…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">QR ကုဒ် မှားနေသည်</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_paired_title">ချိတ်ဆက်ပြီးပါပြီ</string>
|
||||
<string name="tor_offline_title">အော့ဖ်လိုင်း</string>
|
||||
<string name="tor_offline_button_check">ချိတ်ဆက်မှု ဆက်တင်များကို စစ်ဆေးပါ</string>
|
||||
|
||||
@@ -589,9 +589,7 @@
|
||||
<string name="mailbox_setup_download_link">Dele nedlastingslenke</string>
|
||||
<string name="mailbox_setup_button_scan">Skanne Mailboks-QR-kode</string>
|
||||
<string name="permission_camera_qr_denied_body">Du har forbudt tilgang til kameraet, men for å kunne skanne QR-koder kreves kameratilgang.\n\nVennligst vurder å gi tilgang.</string>
|
||||
<string name="mailbox_setup_connecting">Kobler til…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Feil QR-kode</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Den skannede koden er ugyldig. Vennligst åpne Briar Mailboks-app\'en på din Mailboks-enhet og skann QR-koden den viser frem.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Mailboks\'en er allerede lenket opp</string>
|
||||
<string name="mailbox_setup_already_paired_description">Lenke fra Mailboks-appen på din andre enhet og prøv igjen.</string>
|
||||
<string name="mailbox_setup_io_error_title">Kunne ikke koble til</string>
|
||||
|
||||
@@ -618,9 +618,7 @@
|
||||
<string name="mailbox_setup_download_link">Udostępnij łącze pobierania</string>
|
||||
<string name="mailbox_setup_button_scan">Zeskanuj kod QR aplikacji Mailbox</string>
|
||||
<string name="permission_camera_qr_denied_body">Odmówiłeś dostępu do aparatu, ale zeskanowanie kodu QR wymaga użycia aparatu.\n\nRozważ przyznanie dostępu.</string>
|
||||
<string name="mailbox_setup_connecting">Trwa łączenie...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Nieprawidłowy kod QR</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Zeskanowany kod jest nieprawidłowy. Otwórz aplikację Briar Mailbox na urządzeniu z Mailbox i zeskanuj wyświetlany kod QR. </string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Mailbox już podłączony</string>
|
||||
<string name="mailbox_setup_already_paired_description">Odłącz Mailbox na drugim urządzeniu i spróbuj ponownie.</string>
|
||||
<string name="mailbox_setup_io_error_title">Nie udało się połączyć</string>
|
||||
|
||||
@@ -600,9 +600,7 @@
|
||||
<string name="mailbox_setup_download_link">Compartilhar Link de Download</string>
|
||||
<string name="mailbox_setup_button_scan">Escanear código QR do Mailbox</string>
|
||||
<string name="permission_camera_qr_denied_body">Você negou acesso à câmera, mas escanear um código QR requer o uso da câmera.\n\nPor favor, considere conceder acesso.</string>
|
||||
<string name="mailbox_setup_connecting">Conectando...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Código QR errado</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">O código escaneado é inválido. Por favor, abra o app Briar Mailbox no seu dispositivo Mailbox e escaneie o código QR apresentado.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Mailbox já vinculado</string>
|
||||
<string name="mailbox_setup_already_paired_description">Desvincule o Mailbox no seu outro dispositivo e tente de novo.</string>
|
||||
<string name="mailbox_setup_io_error_title">Não foi possível conectar</string>
|
||||
|
||||
@@ -161,6 +161,7 @@
|
||||
<string name="error_start_activity">Indisponibil pentru sistemul dvs.</string>
|
||||
<string name="status_heading">Stare:</string>
|
||||
<string name="error">Eroare</string>
|
||||
<string name="info">Informații</string>
|
||||
<!--Contacts and Private Conversations-->
|
||||
<string name="no_contacts">Niciun contact de afișat</string>
|
||||
<string name="no_contacts_action">Atingeți iconița + pentru a adăuga un contact</string>
|
||||
@@ -234,6 +235,7 @@
|
||||
<string name="menu_contact">Contact</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">Adăugați un contact din apropiere</string>
|
||||
<string name="add_contact_error_two_way">Ați scanat amândoi codurile QR ale celuilalt?</string>
|
||||
<string name="face_to_face">Trebuie să vă întâlniți cu persoana pe care doriți să o adăugați la contacte.\n\nAcest pas împiedică alte persoane să se substituie dvs. sau să citească mesajele dvs. în viitor.</string>
|
||||
<string name="continue_button">Continuați</string>
|
||||
<string name="try_again_button">Încercați din nou</string>
|
||||
@@ -244,11 +246,14 @@
|
||||
<string name="qr_code_invalid">Codul QR este nevalid!</string>
|
||||
<string name="qr_code_too_old_1">Codul QR pe care l-ați scanat provine de la o versiune Briar mai veche.\n\nSolicitați contactului să actualizeze aplicația la cea mai recentă versiune, după care încercați din nou.</string>
|
||||
<string name="qr_code_too_new_1">Codul QR pe care l-ați scanat provine de la o versiune Briar mai nouă.\n\nActualizați aplicația la cea mai recentă versiune, după care încercați din nou.</string>
|
||||
<string name="mailbox_qr_code_for_contact">Codul QR pe care l-ați scanat provine de la o Cutie poștală Briar.\n\nDacă doriți să conectați Cutia poștală, vă rugăm să mergeți în Setări > Cutie Poștală în meniul Briar..</string>
|
||||
<string name="qr_code_format_unknown">Codul QR pe care l-ați scanat nu este menit pentru a adăuga un contact Briar.\n\nVă rugăm să scanați codul QR afișat pe ecranul contactului dumneavoastră.</string>
|
||||
<string name="camera_error">Eroare cameră</string>
|
||||
<string name="connecting_to_device">Se conectează la dispozitiv\u2026</string>
|
||||
<string name="authenticating_with_device">Se realizează autentificarea cu dispozitivul\u2026</string>
|
||||
<string name="connection_error_title">Nu a fost posibilă conectarea cu contactul dvs.</string>
|
||||
<string name="connection_error_feedback">Dacă problema persistă, <a href="feedback">trimiteți feedback</a> pentru a ne ajuta să îmbunătățim aplicația.</string>
|
||||
<string name="info_both_must_scan">Trebuie să scanați amândoi codurile QR ale celuilalt.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Adăugați contact de la distanță</string>
|
||||
<string name="add_contact_nearby_title">Adaugă un contact din apropiere</string>
|
||||
@@ -307,6 +312,7 @@
|
||||
<string name="different_person_button">Persoană diferită</string>
|
||||
<string name="duplicate_link_dialog_text_3">%1$s și %2$sv-au trimis același link.\n\nUna dintre aceste persoane ar putea încerca să afle cine sunt contactele dvs.\n\nNu îi spuneți că ați primit același link de la altcineva.</string>
|
||||
<string name="pending_contact_updated_toast">Contact în așteptare actualizat</string>
|
||||
<string name="info_both_must_enter_links">Amândoi trebuie să adăugați linkurile celuilalt</string>
|
||||
<!--Peer trust levels-->
|
||||
<string name="peer_trust_level_unverified">Contact neverificat</string>
|
||||
<string name="peer_trust_level_verified">Contact verificat</string>
|
||||
@@ -340,6 +346,7 @@
|
||||
<string name="connect_via_bluetooth_intro">În cazul în care conexiunile Bluetooth nu funcționează automat, puteți utiliza acest ecran pentru a vă conecta manual.\n\nContactul trebuie să fie în apropiere pentru ca procedura să funcționeze.\n\nDvs. și contactul trebuie să apăsați pe „Start” simultan.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Încercați deja să vă conectați prin Bluetooth. Încercați din nou în scurt timp.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Nu se poate continua fără a permite accesul la locație</string>
|
||||
<string name="connect_via_bluetooth_no_bluetooth_permission">Nu se poate continua fără permisiunea dispozitivelor din apropiere</string>
|
||||
<string name="connect_via_bluetooth_start">Se conectează prin Bluetooth...</string>
|
||||
<string name="connect_via_bluetooth_success">Conectare reușită prin Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">Nu s-a reușit conectarea prin Bluetooth.</string>
|
||||
@@ -603,9 +610,13 @@
|
||||
<string name="mailbox_setup_download_link">Partajați linkul de descărcare</string>
|
||||
<string name="mailbox_setup_button_scan">Scanați codul QR al cutiei poștale</string>
|
||||
<string name="permission_camera_qr_denied_body">Ați refuzat accesul la cameră, dar scanarea unui cod QR necesită utilizarea camerei.\n\nLuați în considerare acordarea accesului.</string>
|
||||
<string name="mailbox_setup_connecting">Se conectează...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Cod QR greșit</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Codul scanat nu este valid. Deschideți aplicația de cutie poștală Briar pe dispozitivul pe care este instalată și scanați codul QR pe care îl afișează.</string>
|
||||
<string name="mailbox_setup_connecting">Se conectează la Cutia poștală…</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_connecting_info">Asta ar putea dura până la %1s</string>
|
||||
<string name="mailbox_qr_code_too_old">Codul QR pe care l-ați scanat provine de la o versiune de Cutie poștală Briar mai veche.\n\nActualizați Cutia poștală la cea mai recentă versiune, după care încercați din nou.</string>
|
||||
<string name="mailbox_qr_code_too_new">Codul QR pe care l-ați scanat provine de la o versiune de Cutie poștală Briar mai nouă.\n\nActualizați Briar la cea mai recentă versiune, după care încercați din nou.</string>
|
||||
<string name="contact_qr_code_for_mailbox">Codul QR pe care l-ați scanat este pentru a adăuga un contact Briar.\n\nDacă doriți să adăugați un contact, vă rugăm să mergeți la lista de contacte și să apăsați +.</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Codul QR pe care l-ați scanat nu provine de la o Cutie poștală Briar.\n\nVă rugăm să deschideți aplicația de Cutie poștală Briar pe dispozitivul pe care este instalată și scanați codul QR pe care îl afișează.</string>
|
||||
<string name="mailbox_setup_already_paired_title">Cutia poștală este deja conectată</string>
|
||||
<string name="mailbox_setup_already_paired_description">Anulați conectarea cutiei poștale la celălalt dispozitiv și încercați din nou.</string>
|
||||
<string name="mailbox_setup_io_error_title">Nu s-a reușit conectarea</string>
|
||||
@@ -742,11 +753,17 @@
|
||||
<string name="permission_location_request_body">Pentru a putea descoperi dispozitive Bluetooth, Briar are nevoie de permisiunea de a accesa locația dvs.\n\nBriar nu stochează locația dvs. și nici nu o partajează cu nimeni. </string>
|
||||
<string name="permission_camera_location_title">Cameră foto și locație</string>
|
||||
<string name="permission_camera_location_request_body">Pentru a scana codul QR, Briar are nevoie de acces la camera foto.\n\nPentru a putea descoperi dispozitive Bluetooth, Briar are nevoie de permisiunea de acces la locația dvs.\n\nBriar nu stochează locația dvs. și nici nu o partajează cu nimeni.</string>
|
||||
<string name="permission_camera_bluetooth_title">Camera și dispozitivele din apropiere</string>
|
||||
<string name="permission_camera_bluetooth_request_body">Pentru a scana codul QR, Briar are nevoie de acces la camera foto.\n\nPentru a descoperi dispozitive Bluetooth, Briar are nevoie de permisiunea de a găsi și de a se conecta la dispozitivele din apropiere.</string>
|
||||
<string name="permission_camera_denied_body">Ați refuzat accesul la camera foto, dar folosirea acesteia este obligatorie pentru a adăuga contacte.\n\nVă rugăm să luați în considerare acordarea accesului.</string>
|
||||
<string name="permission_location_denied_body">Ați refuzat accesul la locație, dar Briar are nevoie de această permisiune pentru a descoperi dispozitive Bluetooth.\n\nVă rugăm să luați în considerare acordarea accesului.</string>
|
||||
<string name="permission_location_setting_title">Setări privind locația</string>
|
||||
<string name="permission_location_setting_body">Funcția de locație a dispozitivului dvs. trebuie să fie activată pentru a găsi alte dispozitive prin Bluetooth. Activați locația pentru a continua. Puteți să o dezactivați din nou ulterior.</string>
|
||||
<string name="permission_location_setting_hotspot_body">Setarea de localizare a dispozitivului dumneavoastră trebuie să fie activată pentru a crea un hotspot Wi-Fi. Vă rugăm să activați localizarea pentru a continua. Puteți să o dezactivați din nou după aceea.</string>
|
||||
<string name="permission_location_setting_button">Activați locația</string>
|
||||
<string name="permission_bluetooth_title">Permisiunea dispozitivelor apropiate</string>
|
||||
<string name="permission_bluetooth_body">Pentru a utiliza comunicarea Bluetooth, Briar are nevoie de permisiunea de a găsi și de a se conecta la dispozitivele din apropiere.</string>
|
||||
<string name="permission_bluetooth_denied_body">Ați refuzat accesul la dispozitivele din apropiere, dar Briar are nevoie de această permisiune pentru a utiliza Bluetooth.\n\nVă rugăm să luați în considerare acordarea accesului.</string>
|
||||
<string name="qr_code">Cod QR</string>
|
||||
<string name="show_qr_code_fullscreen">Afișați codul QR pe tot ecranul</string>
|
||||
<!--App Locking-->
|
||||
@@ -769,7 +786,9 @@
|
||||
<string name="hotspot_notification_title">Se partajează Brian offline</string>
|
||||
<string name="hotspot_button_connected">Înainte</string>
|
||||
<string name="permission_hotspot_location_request_body">Pentru a crea un hotspot Wi-Fi, Briar are nevoie de permisiunea de a accesa locația dvs.\n\nBriar nu stochează locația dvs. și nici nu o partajează cu nimeni.</string>
|
||||
<string name="permission_hotspot_location_request_precise_body">Pentru a crea un hotspot Wi-Fi, Briar are nevoie de permisiunea de a accesa locația dumneavoastră exactă.\n\nBriar nu stochează locația dumneavoastră și nu o împărtășește cu nimeni.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Ați refuzat accesul la locație, dar Briar are nevoie de această permisiune pentru a crea un hotspot Wi-Fi.\n\nVă rugăm să luați în considerare acordarea accesului.</string>
|
||||
<string name="permission_hotspot_location_denied_precise_body">Ați refuzat accesul la locația dumneavoastră exactă, dar Briar are nevoie de această permisiune pentru a crea un hotspot Wi-Fi.Vă rugăm să luați în considerare acordarea accesului.</string>
|
||||
<string name="wifi_settings_title">Se setează Wi-Fi</string>
|
||||
<string name="wifi_settings_request_enable_body">Pentru a crea un hotspot Wi-Fi, Briar trebuie să folosească Wi-Fi. Vă rugăm să activați funcția.</string>
|
||||
<string name="hotspot_tab_manual">Manual</string>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<string name="setup_name_explanation">Ваш псевдоним будет отображаться рядом с любым размещаемым вами контентом. Его нельзя изменить после создания аккаунта.</string>
|
||||
<string name="setup_next">Вперед</string>
|
||||
<string name="setup_password_intro">Придумайте пароль</string>
|
||||
<string name="setup_password_explanation">Ваш аккаунт Briar хранится в зашифрованном виде только на устройстве. Если вы забудете свой пароль или удалите Briar, то не сможете восстановить свою учетную запись.\n\nПридумайте длинный пароль, который трудно угадать, например четыре случайных слова или десять случайных букв, цифр и символов.</string>
|
||||
<string name="setup_password_explanation">Аккаунт Briar хранится в зашифрованном виде только на устройстве. Если вы забудете свой пароль или удалите Briar, восстановить аккаунт будет невозможно.\n\nПридумайте длинный пароль, который трудно угадать, например четыре случайных слова или десять случайных букв, цифр и символов.</string>
|
||||
<string name="dnkm_doze_intro">Для получения сообщений Briar должен работать в фоновом режиме.</string>
|
||||
<string name="dnkm_doze_explanation">Для получения сообщений Briar должен работать в фоновом режиме. Отключите оптимизацию электропитания для Briar.</string>
|
||||
<string name="choose_nickname">Придумайте псевдоним</string>
|
||||
@@ -14,7 +14,7 @@
|
||||
<string name="name_too_long">Слишком длинное имя</string>
|
||||
<string name="password_too_weak">Пароль слишком слабый</string>
|
||||
<string name="passwords_do_not_match">Пароли не совпадают</string>
|
||||
<string name="create_account_button">Создать учетную запись</string>
|
||||
<string name="create_account_button">Создать аккаунт</string>
|
||||
<string name="more_info">Дополнительная информация</string>
|
||||
<string name="don_t_ask_again">Больше не спрашивать</string>
|
||||
<string name="dnkm_huawei_protected_text">Нажмите кнопку ниже и убедитесь, что Briar отображается на экране защищенных приложений.</string>
|
||||
@@ -38,11 +38,11 @@
|
||||
<string name="sign_in_button">Войти</string>
|
||||
<string name="forgotten_password">Я забыл свой пароль</string>
|
||||
<string name="dialog_title_lost_password">Пароль утерян</string>
|
||||
<string name="dialog_message_lost_password">Ваш аккаунт Briar хранится в зашифрованном виде только на устройстве, поэтому мы не можем сбросить пароль. Удалить учетную запись и начать заново?\n\nВнимание: ваши идентификаторы, контакты и сообщения будут потеряны навсегда.</string>
|
||||
<string name="dialog_message_lost_password">Ваш аккаунт Briar хранится в зашифрованном виде только на устройстве, поэтому мы не можем сбросить пароль. Удалить аккаунт и начать заново?\n\nВнимание: ваши идентификаторы, контакты и сообщения будут потеряны навсегда.</string>
|
||||
<string name="startup_failed_activity_title">Сбой при запуске Briar</string>
|
||||
<string name="startup_failed_clock_error">Briar не удалось запустить, поскольку время на устройстве выставлено некорректно.\n\nПожалуйста, установите правильное время на часах вашего устройства и повторите попытку.</string>
|
||||
<string name="startup_failed_db_error">Briar не смог открыть базу данных, содержащую вашу учетную запись, контакты и сообщения.\n\nПожалуйста, обновите приложение до последней версии и повторите попытку, или создайте новую учетную запись, выбрав \'Я забыл пароль\' в подсказке пароля.</string>
|
||||
<string name="startup_failed_data_too_old_error">Ваша учетная запись была создана в старой версии этого приложения и не может быть открыта в текущей версии.\n\nНеобходимо либо повторно установить старую версию, либо создать новую учетную запись, выбрав \'Я забыл пароль\' в подсказке пароля.</string>
|
||||
<string name="startup_failed_db_error">Briar не смог открыть базу данных, содержащую ваш аккаунт, контакты и сообщения.\n\nПожалуйста, обновите приложение до последней версии и повторите попытку, или создайте новый аккаунт, выбрав \'Я забыл пароль\' в подсказке пароля.</string>
|
||||
<string name="startup_failed_data_too_old_error">Ваш аккаунт был создан в старой версии Briar, поэтому открыть его в этой версии приложения не удастся.\n\nВам необходимо либо установить старую версию, либо создать новый аккаунт, выбрав \'я забыл свой пароль\' на этапе авторизации в приложении.</string>
|
||||
<string name="startup_failed_data_too_new_error">Ваш аккаунт был создан в более новой версии этого приложения и не может быть открыт в текущей версии.\n\nПожалуйста, обновите приложение до последней версии и повторите попытку.</string>
|
||||
<string name="startup_failed_service_error">Briar не смог запустить необходимый компонент.\n\nПожалуйста, обновите приложение до последней версии и повторите попытку.</string>
|
||||
<plurals name="expiry_warning">
|
||||
@@ -55,11 +55,11 @@
|
||||
<item quantity="one">Android 4 больше не поддерживается. Briar перестанет работать на %s (через %d день). Пожалуйста, установите Briar на более современное устройство и создайте новую учетную запись.</item>
|
||||
<item quantity="few">Android 4 больше не поддерживается. Briar перестанет работать на %s (через %d дня). Пожалуйста, установите Briar на более современное устройство и создайте новую учетную запись.</item>
|
||||
<item quantity="many">Android 4 больше не поддерживается. Briar перестанет работать на %s (через %d дней). Пожалуйста, установите Briar на более современное устройство и создайте новую учетную запись.</item>
|
||||
<item quantity="other">Android 4 больше не поддерживается. Briar перестанет работать на %s (через %d дней). Пожалуйста, установите Briar на более современное устройство и создайте новую учетную запись.</item>
|
||||
<item quantity="other">Android 4 больше не поддерживается. Briar перестанет работать на %s (через %d дней). Пожалуйста, установите Briar на более современное устройство и создайте новый аккаунт.</item>
|
||||
</plurals>
|
||||
<string name="expiry_date_reached">Срок действия этого программного обеспечения истек.\nСпасибо за тестирование!</string>
|
||||
<string name="download_briar">Для продолжения использования Briar, пожалуйста, скачайте последнюю версию.</string>
|
||||
<string name="create_new_account">Вам необходимо создать новую учетную запись, но вы можете использовать тот же псевдоним.</string>
|
||||
<string name="create_new_account">Вам необходимо создать новый аккаунт, но вы можете использовать тот же псевдоним.</string>
|
||||
<string name="download_briar_button">Загрузить последнюю версию</string>
|
||||
<string name="old_android_expiry_date_reached">Briar больше не работает на Android 4.\nПожалуйста, установите Briar на более современное устройство.</string>
|
||||
<string name="old_android_delete_account">Вы можете нажать кнопку ниже, чтобы удалить свой аккаунт с этого устройства.</string>
|
||||
@@ -255,6 +255,8 @@
|
||||
<string name="qr_code_invalid">Неверный QR-код</string>
|
||||
<string name="qr_code_too_old_1">QR-код, который вы сосканировали, сгенерирован в старой версии Briar.\n\nПопросите вашего собеседника обновиться до последней версии и повторите попытку.</string>
|
||||
<string name="qr_code_too_new_1">QR-код, который вы сосканировали, сгенерирован в новой версии Briar.\n\nОбновите приложение до последней версии и повторите попытку.</string>
|
||||
<string name="mailbox_qr_code_for_contact">QR-код, который вы сосканировали, получен из Briar Mailbox.\n\nЕсли вы хотите связать Mailbox, пожалуйста, выберите Настройки > Mailbox в меню Briar.</string>
|
||||
<string name="qr_code_format_unknown">QR-код, который вы сосканировали, не предназначен для добавления контакта Briar.\n\nПожалуйста, сосканируйте QR-код, показанный на экране вашего контакта.</string>
|
||||
<string name="camera_error">Ошибка камеры</string>
|
||||
<string name="connecting_to_device">Подключение к устройству\u2026</string>
|
||||
<string name="authenticating_with_device">Аутентификация с устройством\u2026</string>
|
||||
@@ -274,7 +276,7 @@
|
||||
<string name="send_link_title">Обмен ссылками</string>
|
||||
<string name="add_contact_choose_nickname">Выберите псевдоним</string>
|
||||
<string name="add_contact_choose_a_nickname">Введите псевдоним</string>
|
||||
<string name="nickname_intro">Задайте этому контакту псевдоним. Его можете видеть только вы.</string>
|
||||
<string name="nickname_intro">Задайте этому контакту псевдоним. Его сможете видеть только вы.</string>
|
||||
<string name="your_link">Передайте эту ссылку контакту, который вы хотите добавить.</string>
|
||||
<string name="link_clip_label">Ссылка Briar</string>
|
||||
<string name="link_copied_toast">Ссылка скопирована</string>
|
||||
@@ -589,7 +591,7 @@
|
||||
<string name="panic_setting_signout_title">Выйти</string>
|
||||
<string name="panic_setting_signout_summary">Выйти из Briar, если нажата тревожная кнопка</string>
|
||||
<string name="purge_setting_title">Удалить аккаунт</string>
|
||||
<string name="purge_setting_summary">Удалить вашу учетную запись Briar при нажатии тревожной кнопки. Внимание: это необратимо удалит ваши идентификаторы, контакты и сообщения</string>
|
||||
<string name="purge_setting_summary">Удалить ваш аккаунт Briar при нажатии тревожной кнопки. Внимание: это необратимо удалит ваши идентификаторы, контакты и сообщения</string>
|
||||
<!--Settings Notifications-->
|
||||
<string name="notification_settings_title">Уведомления</string>
|
||||
<string name="notify_sign_in_title">Напомнить мне войти</string>
|
||||
@@ -622,9 +624,13 @@
|
||||
<string name="mailbox_setup_download_link">Поделиться ссылкой на загрузку</string>
|
||||
<string name="mailbox_setup_button_scan">Сканирование QR-кода Mailbox</string>
|
||||
<string name="permission_camera_qr_denied_body">Вы запретили доступ к камере, однако сканирование QR-кода требует использования камеры.\n\nПожалуйста, рассмотрите возможность предоставления доступа.</string>
|
||||
<string name="mailbox_setup_connecting">Соединение...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Неправильный QR-код</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Отсканированный код недействителен. Пожалуйста, откройте приложение Briar Mailbox на вашем устройстве и просканируйте представленный QR-код.</string>
|
||||
<string name="mailbox_setup_connecting">Подключение к Mailbox…</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_connecting_info">Это может занять до %1s</string>
|
||||
<string name="mailbox_qr_code_too_old">QR-код, который вы сосканировали, получен из старой версии Briar Mailbox.\n\nПожалуйста, обновите Briar Mailbox до последней версии и повторите попытку.</string>
|
||||
<string name="mailbox_qr_code_too_new">QR-код, который вы сосканировали, получен из более новой версии Briar Mailbox.\n\nПожалуйста, обновите Briar до последней версии и повторите попытку.</string>
|
||||
<string name="contact_qr_code_for_mailbox">QR-код, который вы сосканировали, предназначен для добавления контакта Briar.\n\nЕсли вы хотите добавить контакт, перейдите в список контактов и нажмите на значок +.</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">QR-код, который вы сосканировали, получен не от Briar Mailbox.\n\nПожалуйста, откройте приложение Briar Mailbox на вашем устройстве Mailbox и сосканируйте представленный QR-код.</string>
|
||||
<string name="mailbox_setup_already_paired_title">Maibox уже связан</string>
|
||||
<string name="mailbox_setup_already_paired_description">Отвяжите Mailbox на другом устройстве и повторите попытку.</string>
|
||||
<string name="mailbox_setup_io_error_title">Не удалось подключиться</string>
|
||||
|
||||
@@ -595,9 +595,7 @@ dhe s’mund të hapet me këtë version.\n\nJu lutemi, përmirësojeni me versi
|
||||
<string name="mailbox_setup_download_link">Ndani Lidhje Shkarkimi</string>
|
||||
<string name="mailbox_setup_button_scan">Skanoni kod QR Kutie postare</string>
|
||||
<string name="permission_camera_qr_denied_body">Keni mohuar hyrjen te kamera, por skanimi i një kodi QR lyp përdorimin e kamerës.\n\nJu lutemi, shihni mundësinë e dhënies së hyrjes.</string>
|
||||
<string name="mailbox_setup_connecting">Po lidhjet…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Kod QR i gabuar</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Kodi i skanuar është i pavlefshëm. Ju lutemi, hapni aplikacionin Kuti Postare Briar në pajisjen tuaj me Kutinë Postare dhe skanoni kodin QR që paraqitet.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Kuti postare tashmë e lidhur</string>
|
||||
<string name="mailbox_setup_already_paired_description">Shkëputeni Kutinë postare në pajisjen tuaj tjetër dhe riprovoni.</string>
|
||||
<string name="mailbox_setup_io_error_title">S’u bë dot lidhje</string>
|
||||
|
||||
@@ -590,9 +590,7 @@ Vänlige installera Briar på en nyare enhet.</string>
|
||||
<string name="mailbox_setup_download_link">Dela hämtningslänk</string>
|
||||
<string name="mailbox_setup_button_scan">Skanna Mailbox QR-kod</string>
|
||||
<string name="permission_camera_qr_denied_body">Du har nekat åtkomst till kameran, men att skanna en QR-kod kräver användning av kameran.\n\nÖverväg att bevilja tillstånd.</string>
|
||||
<string name="mailbox_setup_connecting">Ansluter...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Felaktig QR-kod</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Den skannade koden är ogiltig. Öppna Briar Mailbox-appen på din Mailbox-enhet och skanna QR-koden som visas.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Mailbox redan länkad</string>
|
||||
<string name="mailbox_setup_already_paired_description">Avlänka Mailbox på din andra enhet och försök igen.</string>
|
||||
<string name="mailbox_setup_io_error_title">Kunde inte ansluta</string>
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
<string name="menu_contact">İletişim</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">Yakındaki Kişiyi Ekle</string>
|
||||
<string name="add_contact_error_two_way">Birbirinizin kare kodunu taradınız mı?</string>
|
||||
<string name="face_to_face">Kişi olarak eklemek istediğiniz kişiyle buluşmanız gerekir.\n\nBu, gelecekte başkalarının sizin kimliğinize bürünmesini veya iletilerinizi okumasını engelleyecektir.</string>
|
||||
<string name="continue_button">Devam et</string>
|
||||
<string name="try_again_button">Tekrar deneyin</string>
|
||||
@@ -241,6 +242,7 @@
|
||||
<string name="authenticating_with_device">Aygıtla kimlik doğrulama\u2026</string>
|
||||
<string name="connection_error_title">Kişinizle bağlantı kurulamadı</string>
|
||||
<string name="connection_error_feedback">Sorun devam ederse, uygulamayı geliştirmemize yardımcı olmak için <a href="feedback">geri bildirim gönderin</a>.</string>
|
||||
<string name="info_both_must_scan">Birbirinizin kare kodunu taramalısınız.</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">Uzaktaki Kişiyi Ekle</string>
|
||||
<string name="add_contact_nearby_title">Yakındaki kişiyi ekle</string>
|
||||
@@ -298,6 +300,7 @@
|
||||
<string name="different_person_button">Farklı Kişi</string>
|
||||
<string name="duplicate_link_dialog_text_3">%1$s ve %2$s size aynı bağlantıyı gönderdi.\n\nAralarından biri kişilerinizin kim olduğunu keşfetmeye çalışıyor olabilir.\n\nOnlara başkasından aynı bağlantıyı aldığınızı söylemeyin.</string>
|
||||
<string name="pending_contact_updated_toast">Bekleyen kişi güncellendi</string>
|
||||
<string name="info_both_must_enter_links">Birbirinizin bağlantısını eklemelisiniz.</string>
|
||||
<!--Peer trust levels-->
|
||||
<string name="peer_trust_level_unverified">Doğrulanmamış kişi</string>
|
||||
<string name="peer_trust_level_verified">Doğrulanmış kişi</string>
|
||||
@@ -331,6 +334,7 @@
|
||||
<string name="connect_via_bluetooth_intro">Bluetooth bağlantıları otomatik olarak çalışmadığında, elle bağlanmak için bu ekranı kullanabilirsiniz.\n\nBunun çalışması için kişinin yakınınızda olması gerekiyor.\n\nSizin ve kişinin aynı anda \"Başlat\" seçeneğine basması gerekiyor.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Bluetooth ile zaten bağlanmaya çalışıyor. Lütfen daha sonra tekrar deneyin.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Konum izni olmadan devam edilemez</string>
|
||||
<string name="connect_via_bluetooth_no_bluetooth_permission">Yakındaki cihazlar izni olmadan devam edilemez</string>
|
||||
<string name="connect_via_bluetooth_start">Bluetooth ile bağlanılıyor…</string>
|
||||
<string name="connect_via_bluetooth_success">Bluetooth ile başarılı bir şekilde bağlandı</string>
|
||||
<string name="connect_via_bluetooth_error">Bluetooth ile bağlanamıyor.</string>
|
||||
@@ -729,11 +733,17 @@
|
||||
<string name="permission_location_request_body">Bluetooth aygıtlarını keşfetmek için, Briar\'ın konumunuza erişmesi gerekiyor.\n\nBriar konum bilginizi kaydetmez ve kimseyle paylaşmaz.</string>
|
||||
<string name="permission_camera_location_title">Kamera ve konum</string>
|
||||
<string name="permission_camera_location_request_body">QR kodunu taramak için, Briar\'ın kameranıza erişmesi gerekiyor.\n\nBluetooth aygıtlarını keşfetmek için Briar\'ın konumunuza erişmesi gerekiyor.\n\nBriar konumunuzu saklamaz ve hiç kimseyle paylaşmaz.</string>
|
||||
<string name="permission_camera_bluetooth_title">Kamera ve yakındaki cihazlar</string>
|
||||
<string name="permission_camera_bluetooth_request_body">Kare kodunu taramak için Briar\'ın kameraya erişmesi gerekiyor.\n\nBluetooth cihazlarını keşfetmek için, Briar\'a yakındaki cihazları bulma ve bağlanma izni gerekiyor.</string>
|
||||
<string name="permission_camera_denied_body">Kameraya erişimi engellediniz, ancak kişi eklemek için kamerayı kullanmanız gerekiyor.\n\nLütfen erişim izni vermeyi düşünün.</string>
|
||||
<string name="permission_location_denied_body">Konuma erişimi engellediniz, ancak Briar\'ın Bluetooth aygıtlarını bulabilmek için bu izne ihtiyacı var.\n\nLütfen erişim izni vermeyi düşünün.</string>
|
||||
<string name="permission_location_setting_title">Konum ayarı</string>
|
||||
<string name="permission_location_setting_body">Diğer aygıtları Bluetooth aracılığıyla bulmak için aygıtınızın konum ayarını açmanız gerekiyor. Devam etmek için lütfen konumu etkinleştirin. Daha sonra tekrar etkisizleştirebilirsiniz. </string>
|
||||
<string name="permission_location_setting_hotspot_body">Wi-Fi bağlantı noktası oluşturmak için aygıtınızın konum ayarını açmanız gerekiyor. Devam etmek için lütfen konumu etkinleştirin. Daha sonra tekrar kapatabilirsiniz. </string>
|
||||
<string name="permission_location_setting_button">Konumu etkinleştir</string>
|
||||
<string name="permission_bluetooth_title">Yakındaki cihazlar izni</string>
|
||||
<string name="permission_bluetooth_body">Bluetooth iletişimini kullanmak için Briar\'a yakındaki cihazları bulma ve bağlanma izni gerekiyor.</string>
|
||||
<string name="permission_bluetooth_denied_body">Yakındaki cihazlar iznini engellediniz, ancak Briar\'ın Bluetooth kullanması için bu izne ihtiyacı var.\n\nLütfen erişim izni vermeyi düşünün.</string>
|
||||
<string name="qr_code">QR kodu</string>
|
||||
<string name="show_qr_code_fullscreen">QR kodunu tam ekran göster</string>
|
||||
<!--App Locking-->
|
||||
@@ -756,7 +766,9 @@
|
||||
<string name="hotspot_notification_title">Briar çevrimdışı paylaşılıyor</string>
|
||||
<string name="hotspot_button_connected">İleri</string>
|
||||
<string name="permission_hotspot_location_request_body">Bir kablosuz erişim noktası oluşturmak için, Briar konumunuza erişme iznine ihtiyaç duyar.\n\nBriar konum bilginizi kaydetmez ve kimseyle paylaşmaz.</string>
|
||||
<string name="permission_hotspot_location_request_precise_body">Bir kablosuz erişim noktası oluşturmak için, Briar kesin konumunuza erişim iznine ihtiyaç duyar.\n\nBriar konum bilginizi kaydetmez ve kimseyle paylaşmaz.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Konuma erişimi engellediniz, ancak Briar\'ın Wi-Fi erişim noktası oluşturmak için bu izne ihtiyacı var.\n\nLütfen erişim izni vermeyi düşünün.</string>
|
||||
<string name="permission_hotspot_location_denied_precise_body">Kesin konumunuza erişimi engellediniz, ancak Briar\'ın Wi-Fi erişim noktası oluşturmak için bu izne ihtiyacı var.\n\nLütfen erişim izni vermeyi düşünün.</string>
|
||||
<string name="wifi_settings_title">Kablosuz ağ ayarları</string>
|
||||
<string name="wifi_settings_request_enable_body">Bir kablosuz erişim noktası oluşturmak için Briar\'ın kablosuz ağı kullanması gerekiyor. Lütfen kablosuz ağı etkinleştirin.</string>
|
||||
<string name="hotspot_tab_manual">El ile</string>
|
||||
|
||||
@@ -608,9 +608,7 @@
|
||||
<string name="mailbox_setup_download_link">Поширити посилання на завантаження</string>
|
||||
<string name="mailbox_setup_button_scan">Сканувати QR-код Mailbox</string>
|
||||
<string name="permission_camera_qr_denied_body">Ви заборонили доступ до камери, але камера потрібна для сканування QR-коду.\n\nБудь ласка, надайте доступ.</string>
|
||||
<string name="mailbox_setup_connecting">Під\'єднання...</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Хибний QR-код</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">Проскановано хибний код. Будь ласка, відкрийте застосунок Briar Mailbox на своєму Mailbox-пристрої та проскануйте показаний ним QR-код.</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_already_paired_title">Mailbox уже під\'єднано</string>
|
||||
<string name="mailbox_setup_already_paired_description">Від\'єднайте Mailbox від свого іншого пристрою й повторіть спробу.</string>
|
||||
<string name="mailbox_setup_io_error_title">Не вдалося з\'єднатися</string>
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
<string name="dnkm_huawei_protected_text">轻按下方的按钮将 Briar 加入“受保护的应用”列表。</string>
|
||||
<string name="dnkm_huawei_protected_button">保护 Briar</string>
|
||||
<string name="dnkm_huawei_protected_help">如果 Briar 未被加入受保护应用列表,它将无法在后台运行。</string>
|
||||
<string name="dnkm_huawei_app_launch_text">轻按下方按钮,打开“App launch”界面,确保 Briar 被设置为“手动管理”。</string>
|
||||
<string name="dnkm_huawei_app_launch_help">如果“App 启动”界面中 Briar 没有被设置为“手动管理”,则其将无法在后台运行。</string>
|
||||
<string name="dnkm_huawei_app_launch_text">轻按下方按钮,打开“应用启动管理”界面,确保 Briar 被设置为“手动管理”。</string>
|
||||
<string name="dnkm_huawei_app_launch_help">如果“应用启动管理”界面中 Briar 没有设置为“手动管理”,将无法在后台运行。</string>
|
||||
<string name="dnkm_xiaomi_text">要在后台运行,需将 Briar 锁定在最近的应用列表中。</string>
|
||||
<string name="dnkm_xiaomi_button">保护 Briar</string>
|
||||
<string name="dnkm_xiaomi_help">如果未将 Briar 锁定到最近的应用列表,它将无法在后台运行。</string>
|
||||
<string name="dnkm_xiaomi_dialog_body_old">1. 打开最近的应用列表(也称为应用切换器)\n\n2. 向下滑动 Briar 的图像,显示挂锁图标\n\n3.如果挂锁没有被锁上,轻按锁定它</string>
|
||||
<string name="dnkm_xiaomi_dialog_body_new">1. 打开最近的应用列表 (也称为应用切换器)\n\n2. 如果 Briar 名称边上有挂锁图片,那么你无需做任何事 \n\n3. 如果没有挂锁图片,按住 Briar 图片直到挂锁按钮出现,接着轻按它</string>
|
||||
<string name="dnkm_xiaomi_dialog_body_new">1. 打开最近的应用列表 (也称为应用切换器)\n\n2. 如果 Briar 名称边上有挂锁图标,那么您无需做任何事 \n\n3. 如果没有挂锁图标,按住 Briar 直到挂锁按钮出现,接着轻按它</string>
|
||||
<string name="dnkm_xiaomi_lock_apps_text">请轻按下方图片打开安全性设置。轻按 “提高速度”,接着轻按 “锁定应用”,并确保 Briar 状态被设为 “已锁定”</string>
|
||||
<string name="dnkm_xiaomi_lock_apps_help">如 Briar 未在“锁定应用”屏幕中被设为“已锁定”,它将无法在后台运行。</string>
|
||||
<string name="dnkm_warning_dozed_1">Briar 无法在后台运行</string>
|
||||
@@ -40,10 +40,10 @@
|
||||
<string name="dialog_title_lost_password">密码遗失</string>
|
||||
<string name="dialog_message_lost_password">您的 Briar 帐户被加密储存在您的设备上,而非云端,因此我们无法重置您的密码。您是否希望删除帐户,重新开始?\n\n注意:删除帐户将导致您的身份信息、联系人和消息永久丢失。</string>
|
||||
<string name="startup_failed_activity_title">Briar 启动失败</string>
|
||||
<string name="startup_failed_clock_error">无法启动 Briar,因为你设备的时间错误。\n\n请设置您的设备时钟到正确的时间,然后再试一次。</string>
|
||||
<string name="startup_failed_db_error">Bria r无法打开包含您的帐户、联系人和信息的数据库。\n\n请升级到最新版本再试一次,或者在密码提示时选择“我忘记密码”建立新账号。</string>
|
||||
<string name="startup_failed_data_too_old_error">您的帐户是用这个应用程序的旧版本创建的,不能用这个版本打开。\n\n你必须重新安装旧版本,或者在密码提示时选择“我忘记密码”,建立一个新帐户。</string>
|
||||
<string name="startup_failed_data_too_new_error">您的帐户是用这个应用程序的较新版本创建的,不能用这个版本打开。\n\n请升级到最新版本,然后重试。</string>
|
||||
<string name="startup_failed_clock_error">无法启动 Briar,因为设备的时钟错误。\n\n请将设备的时钟设置为正确的时间,然后重试。</string>
|
||||
<string name="startup_failed_db_error">Briar 无法打开包含您的帐户、联系人和信息的数据库。\n\n请升级到最新版本再试一次,或者在密码提示时选择“我忘记密码”建立新账号。</string>
|
||||
<string name="startup_failed_data_too_old_error">您的帐户是用此应用程序的旧版本创建的,不能用此版本打开。\n\n您必须重新安装旧版本,或者在密码提示时选择“我忘记密码”,建立一个新帐户。</string>
|
||||
<string name="startup_failed_data_too_new_error">您的帐户是用此应用程序的较新版本创建的,不能用此版本打开。\n\n请升级到最新版本,然后重试。</string>
|
||||
<string name="startup_failed_service_error">Briar 无法启动必需的组件。\n\n请升级到最新版并重新尝试。</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="other">这是 Briar 的一个测试版本。您的帐户将在 %d 天后到期,且无法延期。</item>
|
||||
@@ -167,9 +167,9 @@
|
||||
<string name="set_contact_alias_hint">联系人姓名</string>
|
||||
<string name="menu_item_disappearing_messages">让消息自动消失 </string>
|
||||
<!--The first placeholder will show a duration like "7 days". The second placeholder at the end will add "Tap to learn more."-->
|
||||
<string name="auto_delete_msg_you_enabled">你的消息将在 %1$s 后消失。%2$s</string>
|
||||
<string name="auto_delete_msg_you_enabled">您的消息将在 %1$s 后消失。%2$s</string>
|
||||
<!--The placeholder at the end will add "Tap to learn more."-->
|
||||
<string name="auto_delete_msg_you_disabled">你的消息不会消失。%1$s</string>
|
||||
<string name="auto_delete_msg_you_disabled">您的消息不会消失。%1$s</string>
|
||||
<!--The first placeholder will show a contact's name. The second placeholder will show a duration like "7 days". The third placeholder at the end will add "Tap to learn more."-->
|
||||
<string name="auto_delete_msg_contact_enabled">%1$s的消息将在%2$s后消失。%3$s</string>
|
||||
<plurals name="duration_minutes">
|
||||
@@ -185,8 +185,8 @@
|
||||
<string name="auto_delete_msg_contact_disabled">%1$s的消息不会消失。%2$s</string>
|
||||
<string name="tap_to_learn_more">轻按了解更多</string>
|
||||
<string name="auto_delete_changed_warning_title">更改了让消息自动消失的设置</string>
|
||||
<string name="auto_delete_changed_warning_message_enabled">自你开始编辑你的消息,使消息消失的设置已经启用。</string>
|
||||
<string name="auto_delete_changed_warning_message_disabled">自你开始编辑你的消息,使消息消失的设置已经启用。 </string>
|
||||
<string name="auto_delete_changed_warning_message_enabled">因为您开始编写您的消息,已启用消息自动消失。</string>
|
||||
<string name="auto_delete_changed_warning_message_disabled">因为您开始编写您的消息,已关闭消息自动消失。</string>
|
||||
<string name="auto_delete_changed_warning_send">不论如何都要发送</string>
|
||||
<string name="delete_all_messages">删除全部消息</string>
|
||||
<string name="dialog_title_delete_all_messages">确认删除消息</string>
|
||||
@@ -217,7 +217,7 @@
|
||||
<string name="menu_contact">联系人</string>
|
||||
<!--Adding Contacts-->
|
||||
<string name="add_contact_title">添加附近的联系人</string>
|
||||
<string name="add_contact_error_two_way">你和联系人互扫二维码了吗?</string>
|
||||
<string name="add_contact_error_two_way">您和联系人互扫二维码了吗?</string>
|
||||
<string name="face_to_face">您必须面对面添加联系人。\n\n这样将防止未来他人冒充您的身份并查看您的信息。</string>
|
||||
<string name="continue_button">继续</string>
|
||||
<string name="try_again_button">重试</string>
|
||||
@@ -226,14 +226,16 @@
|
||||
<string name="contact_added_toast">联系人已添加:%s</string>
|
||||
<string name="contact_already_exists">联系人 %s 已存在</string>
|
||||
<string name="qr_code_invalid">二维码无效</string>
|
||||
<string name="qr_code_too_old_1">你已扫描的二维码来自旧版本的 Briar 。\n\n请让你的联系人升级到最新版本,然后重试。</string>
|
||||
<string name="qr_code_too_new_1">你已扫描的二维码来自较新版本的 Briar。\n\n请升级到最新版本,然后重试。</string>
|
||||
<string name="qr_code_too_old_1">您扫描的二维码来自旧版本的 Briar。\n\n请让您的联系人升级到最新版本,然后重试。</string>
|
||||
<string name="qr_code_too_new_1">您扫描的二维码来自新版本的 Briar。\n\n请升级到最新版本,然后重试。</string>
|
||||
<string name="mailbox_qr_code_for_contact">你已经扫过的二维码来自 Briar Mailbox。\n\n如果你想链接一个 Mailbox,请从 Briar 菜单中选择设置> Mailbox</string>
|
||||
<string name="qr_code_format_unknown">你已经扫过的二维码不是用来添加 Briar 联系人的。\n\n请扫描显示在你联系人设备屏幕上的二维码。</string>
|
||||
<string name="camera_error">相机出错</string>
|
||||
<string name="connecting_to_device">正在连接至设备\u2026</string>
|
||||
<string name="authenticating_with_device">正在验证设备\u2026</string>
|
||||
<string name="connection_error_title">无法连接到您的联系人</string>
|
||||
<string name="connection_error_feedback">如果该问题仍存在,请 <a href="feedback">发送反馈</a> 帮助我们改善应用。</string>
|
||||
<string name="info_both_must_scan">你和联系人必须互扫二维码</string>
|
||||
<string name="info_both_must_scan">您和联系人必须互扫二维码</string>
|
||||
<!--Adding Contacts Remotely-->
|
||||
<string name="add_contact_remotely_title_case">添加远处的联系人</string>
|
||||
<string name="add_contact_nearby_title">添加附近的联系人</string>
|
||||
@@ -288,9 +290,9 @@
|
||||
will be used in a dialog button, so if the translation of this string longer than 20 characters,
|
||||
please use "No" instead, and use "Yes" for the "Same Person" button-->
|
||||
<string name="different_person_button">不同的人</string>
|
||||
<string name="duplicate_link_dialog_text_3">%1$s 和 %2$s 给你发送了同样的链接。\n\n其中一个人可能企图找出谁是你的联系人。\n\n 不要告诉他们你从其他人那里收到了相同的链接。</string>
|
||||
<string name="duplicate_link_dialog_text_3">%1$s 和 %2$s 给您发送了相同的链接。\n\n其中一个人可能企图找出谁是您的联系人。\n\n 不要告诉他们您从其他人那里收到了相同的链接。</string>
|
||||
<string name="pending_contact_updated_toast">待处理联系人已更新</string>
|
||||
<string name="info_both_must_enter_links">你和联系人必须互相添加链接</string>
|
||||
<string name="info_both_must_enter_links">您和联系人必须互相添加链接</string>
|
||||
<!--Peer trust levels-->
|
||||
<string name="peer_trust_level_unverified">未验证的联系人</string>
|
||||
<string name="peer_trust_level_verified">已验证的联系人</string>
|
||||
@@ -298,7 +300,7 @@
|
||||
<string name="peer_trust_level_stranger">陌生人</string>
|
||||
<!--Introductions-->
|
||||
<string name="introduction_onboarding_title">介绍您的联系人</string>
|
||||
<string name="introduction_onboarding_text">向你的联系人互相介绍彼此,这样他们可以在 Briar 上建立联系</string>
|
||||
<string name="introduction_onboarding_text">介绍您的联系人互相认识,这样他们可以在 Briar 上建立联系。</string>
|
||||
<string name="introduction_menu_item">做介绍</string>
|
||||
<string name="introduction_activity_title">选择联系人</string>
|
||||
<string name="introduction_not_possible">您已将这两位联系人互相介绍过。请先等待该任务完成。如果您或您的联系人很少在线,这可能需要一些时间。</string>
|
||||
@@ -321,7 +323,7 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">通过蓝牙连接</string>
|
||||
<string name="connect_via_bluetooth_title">通过蓝牙连接</string>
|
||||
<string name="connect_via_bluetooth_intro">如果蓝牙无法自动连接,您可以使用此界面进行手动连接。\n\n你的联系人需要在附近,这样才能工作。\n\n你和你的联系人应该同时按“开始。</string>
|
||||
<string name="connect_via_bluetooth_intro">如果蓝牙无法自动连接,您可以使用此界面进行手动连接。\n\n您的联系人需要在附近,这样才能工作。\n\n您和您的联系人应该同时按“开始”。</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">已经在尝试通过蓝牙连接。请稍后再试</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">没有位置权限不能继续 </string>
|
||||
<string name="connect_via_bluetooth_no_bluetooth_permission">没有附近设备权限无法继续运行</string>
|
||||
@@ -579,10 +581,14 @@
|
||||
\n然后通过扫描邮箱应用显示的二维码将你的 Mailbox 与Briar 链接起来。</string>
|
||||
<string name="mailbox_setup_download_link">分享下载链接</string>
|
||||
<string name="mailbox_setup_button_scan">扫描 Mailbox 二维码</string>
|
||||
<string name="permission_camera_qr_denied_body">你拒绝了使用相机,但扫描二维码需要使用相机。\n\n请考虑授予访问权限。</string>
|
||||
<string name="mailbox_setup_connecting">连接中……</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">错误的二维码</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">扫描的代码无效。请在安装有 Mailbox 应用的设备上打开 Briar Mailbox 应用,并扫描它显示的二维码。</string>
|
||||
<string name="permission_camera_qr_denied_body">您拒绝了相机权限,但扫描二维码需要使用相机。\n\n请考虑授予访问权限。</string>
|
||||
<string name="mailbox_setup_connecting">正在连接到 Mailbox…</string>
|
||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||
<string name="mailbox_setup_connecting_info">这可能最多需要 %1s 分钟</string>
|
||||
<string name="mailbox_qr_code_too_old">你已经扫过的二维码来自旧版本的 Briar Mailbox。\n\n请升级 Briar Mailbox 到最新版本后再试一次</string>
|
||||
<string name="mailbox_qr_code_too_new">你已经扫过的二维码来自新版本的 Briar Mailbox。\n\n请升级 Briar 到最新版本后再试一次。</string>
|
||||
<string name="contact_qr_code_for_mailbox">你已经扫过的二维码的用途是添加 Briar 联系人。\n\n如果你想添加联系人,请转到联系人列表,并轻按 + 图标。</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">你已经扫过的二维码不是来自 Briar Mailbox。\n\n请在装有 Mailbox 应用的设备商上打开 Briar Mailbox 并扫描该应用显示的二维码。</string>
|
||||
<string name="mailbox_setup_already_paired_title">Mailbox 已链接</string>
|
||||
<string name="mailbox_setup_already_paired_description">取消链接你其他设备上的 Mailbox 并重试。</string>
|
||||
<string name="mailbox_setup_io_error_title">无法连接</string>
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<color name="briar_button_text_neutral">@color/briar_night_500</color>
|
||||
<color name="briar_button_text_negative">@color/briar_red_500</color>
|
||||
<color name="briar_button_text_disabled">#28000000</color>
|
||||
<color name="briar_button_outline">@android:color/secondary_text_dark</color>
|
||||
|
||||
<color name="thread_indicator">@color/briar_gray_500</color>
|
||||
<color name="thread_item_background">@color/window_background</color>
|
||||
|
||||
@@ -74,5 +74,4 @@
|
||||
<dimen name="blogs_avatar_comment_size">20dp</dimen>
|
||||
|
||||
<dimen name="text_input_height">42dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -252,6 +252,8 @@
|
||||
<string name="qr_code_invalid">The QR code is invalid</string>
|
||||
<string name="qr_code_too_old_1">The QR code you have scanned comes from an older version of Briar.\n\nPlease ask your contact to upgrade to the latest version and then try again.</string>
|
||||
<string name="qr_code_too_new_1">The QR code you have scanned comes from a newer version of Briar.\n\nPlease upgrade to the latest version and then try again.</string>
|
||||
<string name="mailbox_qr_code_for_contact">The QR code you have scanned comes from Briar Mailbox.\n\nIf you want to link a Mailbox, please choose Settings > Mailbox from the Briar menu.</string>
|
||||
<string name="qr_code_format_unknown">The QR code you have scanned is not meant for adding a Briar contact.\n\nPlease scan the QR code shown on your contact\'s screen.</string>
|
||||
<string name="camera_error">Camera error</string>
|
||||
<string name="connecting_to_device">Connecting to device\u2026</string>
|
||||
<string name="authenticating_with_device">Authenticating with device\u2026</string>
|
||||
@@ -633,9 +635,13 @@
|
||||
<string name="mailbox_setup_download_link">Share Download Link</string>
|
||||
<string name="mailbox_setup_button_scan">Scan Mailbox QR code</string>
|
||||
<string name="permission_camera_qr_denied_body">You have denied access to the camera, but scanning a QR code requires using the camera.\n\nPlease consider granting access.</string>
|
||||
<string name="mailbox_setup_connecting">Connecting…</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_title">Wrong QR code</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">The scanned code is invalid. Please open the Briar Mailbox app on your Mailbox device and scan the QR code it presents.</string>
|
||||
<string name="mailbox_setup_connecting">Connecting to Mailbox…</string>
|
||||
<!-- This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes". -->
|
||||
<string name="mailbox_setup_connecting_info">This may take up to %1s</string>
|
||||
<string name="mailbox_qr_code_too_old">The QR code you have scanned comes from an older version of Briar Mailbox.\n\nPlease upgrade Briar Mailbox to the latest version and then try again.</string>
|
||||
<string name="mailbox_qr_code_too_new">The QR code you have scanned comes from a newer version of Briar Mailbox.\n\nPlease upgrade Briar to the latest version and then try again.</string>
|
||||
<string name="contact_qr_code_for_mailbox">The QR code you have scanned is for adding a Briar contact.\n\nIf you want to add a contact, please go to the contact list and tap the + icon.</string>
|
||||
<string name="mailbox_setup_qr_code_wrong_description">The QR code you have scanned does not come from Briar Mailbox.\n\nPlease open the Briar Mailbox app on your Mailbox device and scan the QR code it presents.</string>
|
||||
<string name="mailbox_setup_already_paired_title">Mailbox already linked</string>
|
||||
<string name="mailbox_setup_already_paired_description">Unlink the Mailbox on your other device and try again.</string>
|
||||
<string name="mailbox_setup_io_error_title">Could not connect</string>
|
||||
|
||||
@@ -44,19 +44,20 @@
|
||||
<item name="android:textColor">@color/button_text</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonFlat.Negative" parent="Widget.AppCompat.Button.Borderless">
|
||||
<style name="BriarButtonFlat" parent="Widget.AppCompat.Button.Borderless">
|
||||
<item name="android:textSize">@dimen/text_size_medium</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonFlat.Negative" parent="BriarButtonFlat">
|
||||
<item name="android:textColor">@color/briar_button_text_negative</item>
|
||||
<item name="android:textSize">@dimen/text_size_medium</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonFlat.Positive" parent="Widget.AppCompat.Button.Borderless">
|
||||
<style name="BriarButtonFlat.Positive" parent="BriarButtonFlat">
|
||||
<item name="android:textColor">@color/briar_button_text_positive</item>
|
||||
<item name="android:textSize">@dimen/text_size_medium</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonFlat.Neutral" parent="Widget.AppCompat.Button.Borderless">
|
||||
<style name="BriarButtonFlat.Neutral" parent="BriarButtonFlat">
|
||||
<item name="android:textColor">@color/briar_button_text_neutral</item>
|
||||
<item name="android:textSize">@dimen/text_size_medium</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonFlat.Positive.Tiny" parent="BriarButtonFlat.Positive">
|
||||
@@ -65,6 +66,26 @@
|
||||
<item name="android:minWidth">@dimen/button_size</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonOutline" parent="Widget.AppCompat.Button.Borderless">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:textSize">@dimen/text_size_medium</item>
|
||||
<item name="android:background">@drawable/button_outline</item>
|
||||
<item name="android:padding">@dimen/margin_large</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonOutline.Negative" parent="BriarButtonOutline">
|
||||
<item name="android:textColor">@color/briar_button_text_negative</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonOutline.Positive" parent="BriarButtonOutline">
|
||||
<item name="android:textColor">@color/briar_button_text_positive</item>
|
||||
</style>
|
||||
|
||||
<style name="BriarButtonOutline.Neutral" parent="BriarButtonOutline">
|
||||
<item name="android:textColor">@color/briar_button_text_neutral</item>
|
||||
</style>
|
||||
|
||||
<style name="Divider">
|
||||
<item name="android:background">@color/divider</item>
|
||||
</style>
|
||||
|
||||
@@ -1,177 +1,181 @@
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'androidx.activity:activity-ktx:1.2.3:activity-ktx-1.2.3.aar:423c0226e237e08de245cf66f8ccaf103854bc19a584d971a4a075fd15d70df1',
|
||||
'androidx.activity:activity:1.2.2:activity-1.2.2.aar:e165fb20f006b77894d349572cc3acd2760baa8416ae4d33cb8de6a84dd6730c',
|
||||
'androidx.activity:activity:1.2.4:activity-1.2.4.aar:ae8e9c7de57e387d2ad90e73f3a5a5dfd502bd4f034c1dccfdb3506d1d2df81a',
|
||||
'androidx.annotation:annotation-experimental:1.0.0:annotation-experimental-1.0.0.aar:b219d2b568e7e4ba534e09f8c2fd242343df6ccbdfbbe938846f5d740e6b0b11',
|
||||
'androidx.annotation:annotation:1.5.0:annotation-1.5.0.jar:261fb7c0210858500bab66d34354972a75166ab4182add283780b05513d6ec4a',
|
||||
'androidx.appcompat:appcompat-resources:1.2.0:appcompat-resources-1.2.0.aar:c470297c03ff3de1c3d15dacf0be0cae63abc10b52f021dd07ae28daa3100fe5',
|
||||
'androidx.appcompat:appcompat:1.2.0:appcompat-1.2.0.aar:3d2131a55a61a777322e2126e0018011efa6339e53b44153eb651b16020cca70',
|
||||
'androidx.arch.core:core-common:2.1.0:core-common-2.1.0.jar:fe1237bf029d063e7f29fe39aeaf73ef74c8b0a3658486fc29d3c54326653889',
|
||||
'androidx.arch.core:core-runtime:2.1.0:core-runtime-2.1.0.aar:dd77615bd3dd275afb11b62df25bae46b10b4a117cd37943af45bdcbf8755852',
|
||||
'androidx.arch.core:core-testing:2.1.0:core-testing-2.1.0.aar:c57ffade2a9a844bd62b4f4c3916fad5e09e9f24cceba27e932c25bb7a6d1d8f',
|
||||
'androidx.cardview:cardview:1.0.0:cardview-1.0.0.aar:1193c04c22a3d6b5946dae9f4e8c59d6adde6a71b6bd5d87fb99d82dda1afec7',
|
||||
'androidx.collection:collection-ktx:1.1.0:collection-ktx-1.1.0.jar:2bfc54475c047131913361f56d0f7f019c6e5bee53eeb0eb7d94a7c499a05227',
|
||||
'androidx.collection:collection:1.1.0:collection-1.1.0.jar:632a0e5407461de774409352940e292a291037724207a787820c77daf7d33b72',
|
||||
'androidx.constraintlayout:constraintlayout-solver:2.0.4:constraintlayout-solver-2.0.4.jar:9ca19f5448709301c7563488ef941be9dfa55c83538ca7a059b2113e83527b46',
|
||||
'androidx.constraintlayout:constraintlayout:2.0.4:constraintlayout-2.0.4.aar:307a79a4a1ccff44249c72a2bf7f47da09fa1b6b1fab2a25808ca889382b738e',
|
||||
'androidx.coordinatorlayout:coordinatorlayout:1.1.0:coordinatorlayout-1.1.0.aar:44a9e30abf56af1025c52a0af506fee9c4131aa55efda52f9fd9451211c5e8cb',
|
||||
'androidx.core:core-ktx:1.2.0:core-ktx-1.2.0.aar:dcb74d510d552b35eff73b0dd27b829649535f3902e5b5a1f26040383c10a940',
|
||||
'androidx.core:core:1.3.1:core-1.3.1.aar:e92ea65a37d589943d405a6a54d1be9d12a225948f26c4e41e511dd55e81efb6',
|
||||
'androidx.cursoradapter:cursoradapter:1.0.0:cursoradapter-1.0.0.aar:a81c8fe78815fa47df5b749deb52727ad11f9397da58b16017f4eb2c11e28564',
|
||||
'androidx.customview:customview:1.0.0:customview-1.0.0.aar:20e5b8f6526a34595a604f56718da81167c0b40a7a94a57daa355663f2594df2',
|
||||
'androidx.documentfile:documentfile:1.0.0:documentfile-1.0.0.aar:865a061ef2fad16522f8433536b8d47208c46ff7c7745197dfa1eeb481869487',
|
||||
'androidx.drawerlayout:drawerlayout:1.0.0:drawerlayout-1.0.0.aar:9402442cdc5a43cf62fb14f8cf98c63342d4d9d9b805c8033c6cf7e802749ac1',
|
||||
'androidx.dynamicanimation:dynamicanimation:1.0.0:dynamicanimation-1.0.0.aar:ce005162c229bf308d2d5b12fb6cad0874069cbbeaccee63a8193bd08d40de04',
|
||||
'androidx.exifinterface:exifinterface:1.3.3:exifinterface-1.3.3.aar:996814984cb33d90921064c867d0ac41dffa10a1048ada652881c21326602397',
|
||||
'androidx.fragment:fragment-ktx:1.4.0:fragment-ktx-1.4.0.aar:439873b250461eb2245e393fe6683dceb567e7a18d9d6cf4538de9befa4ed1b0',
|
||||
'androidx.fragment:fragment-testing:1.4.0:fragment-testing-1.4.0.aar:1f874b83919c69f2e0df6de0ba2ad87a0d61cc7840d90b481ee0d4db85c2385b',
|
||||
'androidx.fragment:fragment:1.3.4:fragment-1.3.4.aar:c023c0ab666456885284d8e88519a743bc863c2b2effb92741fc789cbdb10db4',
|
||||
'androidx.fragment:fragment:1.4.0:fragment-1.4.0.aar:ec98a3b2f56f25cd247f928ab717d5527d27aea56ca4c02e67fbcd1ec32e5eed',
|
||||
'androidx.interpolator:interpolator:1.0.0:interpolator-1.0.0.aar:33193135a64fe21fa2c35eec6688f1a76e512606c0fc83dc1b689e37add7732a',
|
||||
'androidx.legacy:legacy-support-core-utils:1.0.0:legacy-support-core-utils-1.0.0.aar:a7edcf01d5b52b3034073027bc4775b78a4764bb6202bb91d61c829add8dd1c7',
|
||||
'androidx.lifecycle:lifecycle-common:2.3.1:lifecycle-common-2.3.1.jar:15848fb56db32f4c7cdc72b324003183d52a4884d6bf09be708ac7f587d139b5',
|
||||
'androidx.lifecycle:lifecycle-extensions:2.2.0:lifecycle-extensions-2.2.0.aar:648c8de1d10b025d524a2e46ac994fc3f6bf186826c09ec1a62d250bf1b877ae',
|
||||
'androidx.lifecycle:lifecycle-livedata-core-ktx:2.3.1:lifecycle-livedata-core-ktx-2.3.1.aar:6dd41c3c33daeb503fd87fbfff7043adb0be6c541a9c9e09bf531ca49520fddb',
|
||||
'androidx.lifecycle:lifecycle-livedata-core:2.3.1:lifecycle-livedata-core-2.3.1.aar:e55d38c372460f0a03997ddc950c67227511340fd74f8634d99d29653cd81ab1',
|
||||
'androidx.lifecycle:lifecycle-livedata:2.2.0:lifecycle-livedata-2.2.0.aar:d83af94860aa9f64cbdc51f40796a7cf55b116f0e6efd752e845c0104c8b16f6',
|
||||
'androidx.lifecycle:lifecycle-process:2.2.0:lifecycle-process-2.2.0.aar:3a977e7778fc8418742d388409daaba7ea8fea8823d21ffb96e4c4236f715070',
|
||||
'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1:lifecycle-runtime-ktx-2.3.1.aar:7ad2987dd7f4075c0871a72cf07e9649d9cd790fc23dfab1972eca4710373873',
|
||||
'androidx.lifecycle:lifecycle-runtime:2.3.1:lifecycle-runtime-2.3.1.aar:dd294f4a689c71ff877fd41f3b67a3a62f7760d44ce420e6130f1fc3569d8f00',
|
||||
'androidx.lifecycle:lifecycle-service:2.2.0:lifecycle-service-2.2.0.aar:ca2801ffc069555afed8eddd2292130f436956452bc8bbad30fb56f8e4e382a0',
|
||||
'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1:lifecycle-viewmodel-ktx-2.3.1.aar:5fb3591b6a54eeb3e204be0125d48eb987b8ea45a5048140036865482ccf9de9',
|
||||
'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1:lifecycle-viewmodel-savedstate-2.3.1.aar:97137a8af6a31776a14e4866ab808c7c0a791b484bdbc788bbd83e66407564c0',
|
||||
'androidx.lifecycle:lifecycle-viewmodel:2.3.1:lifecycle-viewmodel-2.3.1.aar:b6db4c274a12ff85a4747e1e6669c7e98aefa2571ace9d1f1a6fa6be417ce838',
|
||||
'androidx.loader:loader:1.0.0:loader-1.0.0.aar:11f735cb3b55c458d470bed9e25254375b518b4b1bad6926783a7026db0f5025',
|
||||
'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0:localbroadcastmanager-1.0.0.aar:e71c328ceef5c4a7d76f2d86df1b65d65fe2acf868b1a4efd84a3f34336186d8',
|
||||
'androidx.preference:preference:1.1.1:preference-1.1.1.aar:317dcbc38242aea2f6262c06d51b8a22827e98959967edd40f82600a15cb4bff',
|
||||
'androidx.print:print:1.0.0:print-1.0.0.aar:1d5c7f3135a1bba661fc373fd72e11eb0a4adbb3396787826dd8e4190d5d9edd',
|
||||
'androidx.recyclerview:recyclerview-selection:1.1.0:recyclerview-selection-1.1.0.aar:9e2ba1c7d6b0eb5e64c10b1b0eb01b51e8511cee002c9bd56ce9cc138ebc4898',
|
||||
'androidx.recyclerview:recyclerview:1.1.0:recyclerview-1.1.0.aar:f0d2b5a67d0a91ee1b1c73ef2b636a81f3563925ddd15a1d4e1c41ec28de7a4f',
|
||||
'androidx.savedstate:savedstate-ktx:1.1.0:savedstate-ktx-1.1.0.aar:e44d61347463b0fafeeb649cbcc3d7109b2eb5e11d1522e986105170cdebbf68',
|
||||
'androidx.savedstate:savedstate:1.1.0:savedstate-1.1.0.aar:d60bbe44c2c08083a17c5dc678a6d6b4d0a2d664858016ab5c049cbea90a63b7',
|
||||
'androidx.test.espresso:espresso-contrib:3.3.0:espresso-contrib-3.3.0.aar:f400cabdc181356acf6b210e4509dcb9649d9e2b6b6e218c60fcfc15e8a756d1',
|
||||
'androidx.test.espresso:espresso-core:3.3.0:espresso-core-3.3.0.aar:23ebf6014645e0c60aec7d1ed924d4d4c848ae8c3673b7d8d06b2ec6a56cafee',
|
||||
'androidx.test.espresso:espresso-idling-resource:3.3.0:espresso-idling-resource-3.3.0.aar:29519b112731f289cc6e2f9b2eccc5ea72c754b04272bb93370f45d7e170a7c6',
|
||||
'androidx.test.espresso:espresso-intents:3.3.0:espresso-intents-3.3.0.aar:5b6cd6aadce78edc705d93c1e81ace3b59be97128aca0e88fd9c5c176aa9bf10',
|
||||
'androidx.test.ext:junit:1.1.3:junit-1.1.3.aar:a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690',
|
||||
'androidx.test.services:storage:1.4.0:storage-1.4.0.aar:35cfbf442abb83e5876cd5deb9de02ae047459f18f831097c5caa76d626bc38a',
|
||||
'androidx.test.services:test-services:1.3.0:test-services-1.3.0.apk:1b88faab6864baf25c5d0b92a610c283c159a566e7a56c03307117fa1b542993',
|
||||
'androidx.test.uiautomator:uiautomator:2.2.0:uiautomator-2.2.0.aar:2838e9d961dbffefbbd229a2bd4f6f82ac4fb2462975862a9e75e9ed325a3197',
|
||||
'androidx.test:core:1.4.0:core-1.4.0.aar:671284e62e393f16ceae1a99a3a9a07bf1aacda29f8fe7b6b884355ef34c09cf',
|
||||
'androidx.test:monitor:1.4.0:monitor-1.4.0.aar:46a912a1e175f27a97521af3f50e5af87c22c49275dd2c57c043740012806325',
|
||||
'androidx.test:orchestrator:1.3.0:orchestrator-1.3.0.apk:676f808d08a3d05050eae30c3b7d92ce5cef1e00a54d68355bb7e7d4b72366fe',
|
||||
'androidx.test:rules:1.3.0:rules-1.3.0.aar:c1753946c498b0d5d7cf341cfed661f66915c4c9deb4ed10462a08ae33b2429a',
|
||||
'androidx.test:runner:1.3.0:runner-1.3.0.aar:61d13f5a9fcbbd73ba18fa84e1d6a0111c6e1c665a89b418126966e61fffd93b',
|
||||
'androidx.test:runner:1.4.0:runner-1.4.0.aar:e3f3d8b8d5d4a3edcacbdaa4a31bda2b0e41d3e704b02b3750466a06367ec5a0',
|
||||
'androidx.tracing:tracing:1.0.0:tracing-1.0.0.aar:07b8b6139665b884a162eccf97891ca50f7f56831233bf25168ae04f7b568612',
|
||||
'androidx.transition:transition:1.2.0:transition-1.2.0.aar:a1e059b3bc0b43a58dec0efecdcaa89c82d2bca552ea5bacf6656c46e853157e',
|
||||
'androidx.vectordrawable:vectordrawable-animated:1.1.0:vectordrawable-animated-1.1.0.aar:76da2c502371d9c38054df5e2b248d00da87809ed058f3363eae87ce5e2403f8',
|
||||
'androidx.vectordrawable:vectordrawable:1.1.0:vectordrawable-1.1.0.aar:46fd633ac01b49b7fcabc263bf098c5a8b9e9a69774d234edcca04fb02df8e26',
|
||||
'androidx.versionedparcelable:versionedparcelable:1.1.0:versionedparcelable-1.1.0.aar:9a1d77140ac222b7866b5054ee7d159bc1800987ed2d46dd6afdd145abb710c1',
|
||||
'androidx.viewpager2:viewpager2:1.0.0:viewpager2-1.0.0.aar:e95c0031d4cc247cd48196c6287e58d2cee54d9c79b85afea7c90920330275af',
|
||||
'androidx.viewpager:viewpager:1.0.0:viewpager-1.0.0.aar:147af4e14a1984010d8f155e5e19d781f03c1d70dfed02a8e0d18428b8fc8682',
|
||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||
'com.almworks.sqlite4java:sqlite4java:0.282:sqlite4java-0.282.jar:9e1d8dd83ca6003f841e3af878ce2dc7c22497493a7bb6d1b62ec1b0d0a83c05',
|
||||
'com.github.bumptech.glide:annotations:4.12.0:annotations-4.12.0.jar:fa430cbf8f931fcd89c38195ab5544ef4d62c8ac6c2e6f49f8f4ae7860fade8e',
|
||||
'com.github.bumptech.glide:compiler:4.12.0:compiler-4.12.0.jar:030297733aa52dd52ef9d45895e02d7446b537d608fe6972514b9f261c23c99a',
|
||||
'com.github.bumptech.glide:gifdecoder:4.12.0:gifdecoder-4.12.0.aar:197a1cd5b76855aa02b230c13974e293229b901dc2b96fab4315201e78baa804',
|
||||
'com.github.bumptech.glide:glide:4.12.0:glide-4.12.0.aar:6ae2944adb62977fe53f42c4f86a22bd326c1828b693441ccce430e92f148384',
|
||||
'com.github.chrisbanes:PhotoView:2.3.0:PhotoView-2.3.0.aar:6c8989f2945d50ab38b3e0300064f1f8d2d75bbcae1434fe535d9fb6898e9ad6',
|
||||
'com.github.kobakei:MaterialFabSpeedDial:1.2.1:MaterialFabSpeedDial-1.2.1.aar:e86198c3c48cd832fb209a769a9f222c2a3cc045743b110ac2391d9737e3ea02',
|
||||
'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.0:accessibility-test-framework-2.0.jar:cdf16ef8f5b8023d003ce3cc1b0d51bda737762e2dab2fedf43d1c4292353f7f',
|
||||
'com.google.android.material:material:1.3.0:material-1.3.0.aar:cbf1e7d69fc236cdadcbd1ec5f6c0a1a41aca6ad1ef7f8481058956270ab1f0a',
|
||||
'com.google.auto.value:auto-value-annotations:1.6.2:auto-value-annotations-1.6.2.jar:b48b04ddba40e8ac33bf036f06fc43995fc5084bd94bdaace807ce27d3bea3fb',
|
||||
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.dagger:dagger-compiler:2.43.2:dagger-compiler-2.43.2.jar:298c020ee6ed2f4cc651ebbfdb7f8de329b07c44b618d65be117846a850e2a03',
|
||||
'com.google.dagger:dagger-producers:2.43.2:dagger-producers-2.43.2.jar:e7f5d9ffc85d48a49c8e22e02833d418f7ccad5d7512f529964db5127ab915ff',
|
||||
'com.google.dagger:dagger-spi:2.43.2:dagger-spi-2.43.2.jar:3bae8d9dadeaaa5927da6f094389a560c12c05fec3d2711d2fa79292c7a7d7ad',
|
||||
'com.google.dagger:dagger:2.43.2:dagger-2.43.2.jar:c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4',
|
||||
'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
|
||||
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
|
||||
'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
|
||||
'com.google.guava:guava:27.0.1-jre:guava-27.0.1-jre.jar:e1c814fd04492a27c38e0317eabeaa1b3e950ec8010239e400fe90ad6c9107b4',
|
||||
'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.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
|
||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
'com.google.zxing:core:3.3.3:core-3.3.3.jar:5820f81e943e4bce0329306621e2d6255d2930b0a6ce934c5c23c0d6d3f20599',
|
||||
'com.ibm.icu:icu4j:53.1:icu4j-53.1.jar:e37a4467bac5cdeb02c5c4b8e5063d2f4e67b69e3c7df6d6b610f13185572bab',
|
||||
'com.jraska:falcon:2.2.0:falcon-2.2.0.aar:8b016c6e016ef99fb493b8614b2362cfba540a68ac16a9bb6da310ae10e30b81',
|
||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||
'com.squareup:javawriter:2.1.1:javawriter-2.1.1.jar:f699823d0081f69cbb676c1845ea222e0ada79bc88a53e5d22d8bd02d328f57e',
|
||||
'com.vanniktech:emoji-google:0.7.0:emoji-google-0.7.0.aar:b98966812e3f607ee823cde15dd9b3823c6f02e5587572b860b9d95e3f971402',
|
||||
'com.vanniktech:emoji:0.7.0:emoji-0.7.0.aar:66f5981f8b5f93e82d2d4b3fa4c6299904d686ca62a2366e61de723b20253707',
|
||||
'de.hdodenhof:circleimageview:3.1.0:circleimageview-3.1.0.aar:8e9965b54072ee159074a55df216e17d5a622c94ce915ef311b1a1f32660c7fb',
|
||||
'info.guardianproject.panic:panic:1.0:panic-1.0.jar:35116ab95212e67f94577faf67b88c11a6b21cbf9178b3f5b51d3dff45203ffd',
|
||||
'javax.annotation:javax.annotation-api:1.3.2:javax.annotation-api-1.3.2.jar:e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||
'net.bytebuddy:byte-buddy-agent:1.10.20:byte-buddy-agent-1.10.20.jar:b592a6c43e752bf41659717956c57fbb790394d2ee5f8941876659f9c5c0e7e8',
|
||||
'net.bytebuddy:byte-buddy:1.10.20:byte-buddy-1.10.20.jar:5fcad05da791e9a22811c255a4a74b7ea094b7243d9dbf3e6fc578c8c94290ac',
|
||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||
'org.bouncycastle:bcprov-jdk15on:1.65:bcprov-jdk15on-1.65.jar:e78f96eb59066c94c94fb2d6b5eb80f52feac6f5f9776898634f8addec6e2137',
|
||||
'org.briarproject:dont-kill-me-lib:0.2.5:dont-kill-me-lib-0.2.5.aar:55cd9d511b7016ab573905d64bc54e222e2633144d36389192b8b34485b31b9d',
|
||||
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
|
||||
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
|
||||
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||
'org.hamcrest:hamcrest-integration:1.3:hamcrest-integration-1.3.jar:70f418efbb506c5155da5f9a5a33262ea08a9e4d7fea186aa9015c41a7224ac2',
|
||||
'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:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||
'org.jacoco:org.jacoco.agent:0.8.7:org.jacoco.agent-0.8.7.jar:9cbcc986e0fbe821a78ff1f8f7d5216f200e5eb124e7f6837d1dc4a77b28b143',
|
||||
'org.jacoco:org.jacoco.ant:0.8.7:org.jacoco.ant-0.8.7.jar:97ca96a382c3f23a44d8eb4c4e6c3742a30cb8005774a76ced0fc4806ce49605',
|
||||
'org.jacoco:org.jacoco.core:0.8.7:org.jacoco.core-0.8.7.jar:ad7739b5fb5969aa1a8aead3d74ed54dc82ed012f1f10f336bd1b96e71c1a13c',
|
||||
'org.jacoco:org.jacoco.report:0.8.7:org.jacoco.report-0.8.7.jar:cc89258623700a6c932592153cb528785876b6da183d5431f97efbba6f020e5b',
|
||||
'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.10:kotlin-stdlib-common-1.7.10.jar:19f102efe9629f8eabc63853ad15c533e47c47f91fca09285c5bde86e59f91d4',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.20:kotlin-stdlib-jdk7-1.6.20.jar:aa2fa2e81355c4d98dd97da2169bf401f842261378f5b1cbea1aa11855d67620',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.7.10:kotlin-stdlib-1.7.10.jar:e771fe74250a943e8f6346713201ff1d8cb95c3a5d1a91a22b65a9e04f6a8901',
|
||||
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1:kotlinx-coroutines-android-1.4.1.jar:d4cadb673b2101f1ee5fbc147956ac78b1cfd9cc255fb53d3aeb88dff11d99ca',
|
||||
'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.4.1:kotlinx-coroutines-core-jvm-1.4.1.jar:6d2f87764b6638f27aff12ed380db4b63c9d46ba55dc32683a650598fa5a3e22',
|
||||
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
|
||||
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
|
||||
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
|
||||
'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd',
|
||||
'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.mockito:mockito-core:3.9.0:mockito-core-3.9.0.jar:a1f64211407b8dc4cf80b16e07cc11aa9e5228d53dc4a5357326d66825f6a4ac',
|
||||
'org.nanohttpd:nanohttpd:2.3.1:nanohttpd-2.3.1.jar:de864c47818157141a24c9acb36df0c47d7bf15b7ff48c90610f3eb4e5df0e58',
|
||||
'org.objenesis:objenesis:3.2:objenesis-3.2.jar:03d960bd5aef03c653eb000413ada15eb77cdd2b8e4448886edf5692805e35f3',
|
||||
'org.ow2.asm:asm-analysis:7.2:asm-analysis-7.2.jar:be922aae60ff1ff1768e8e6544a38a7f92bd0a6d6b0b9791f94955d1bd453de2',
|
||||
'org.ow2.asm:asm-analysis:9.1:asm-analysis-9.1.jar:81a88041b1b8beda5a8a99646098046c48709538270c49def68abff25ac3be34',
|
||||
'org.ow2.asm:asm-commons:7.2:asm-commons-7.2.jar:0e86b8b179c5fb223d1a880a0ff4960b6978223984b94e62e71135f2d8ea3558',
|
||||
'org.ow2.asm:asm-commons:9.1:asm-commons-9.1.jar:afcb26dc1fc12c0c4a99ada670908dd82e18dfc488caf5ee92546996b470c00c',
|
||||
'org.ow2.asm:asm-tree:7.2:asm-tree-7.2.jar:c063f5a67fa03cdc9bd79fd1c2ea6816cc4a19473ecdfbd9e9153b408c6f2656',
|
||||
'org.ow2.asm:asm-tree:9.1:asm-tree-9.1.jar:fd00afa49e9595d7646205b09cecb4a776a8ff0ba06f2d59b8f7bf9c704b4a73',
|
||||
'org.ow2.asm:asm-util:7.2:asm-util-7.2.jar:6e24913b021ffacfe8e7e053d6e0ccc731941148cfa078d4f1ed3d96904530f8',
|
||||
'org.ow2.asm:asm:7.2:asm-7.2.jar:7e6cc9e92eb94d04e39356c6d8144ca058cda961c344a7f62166a405f3206672',
|
||||
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
|
||||
'org.robolectric:annotations:4.4:annotations-4.4.jar:d2b2d71a1f902a5a016dde5a2feb3be521d120192f9217adadbfb483d79f89ff',
|
||||
'org.robolectric:junit:4.4:junit-4.4.jar:c5ebcb20cf9d2173a294a6feff68331fff718a368e332df70c7ea7e3bdce846e',
|
||||
'org.robolectric:pluginapi:4.4:pluginapi-4.4.jar:b2f743db060502cb366f67dcd6c3929c7f4656744d91ab81d749b8bf641f5512',
|
||||
'org.robolectric:plugins-maven-dependency-resolver:4.4:plugins-maven-dependency-resolver-4.4.jar:5279024a6bdbb2ee1791b06da13cc890628c583ad48414ae13a4f57d7db749a3',
|
||||
'org.robolectric:resources:4.4:resources-4.4.jar:e39862f71887561dfde65030aeca5148bf0f6279b25fb9e146b75c2933fcabcf',
|
||||
'org.robolectric:robolectric:4.4:robolectric-4.4.jar:38e0368914a48d6d8e543c12670beb1e36e09d037e664280fb604dbbfd10fe5f',
|
||||
'org.robolectric:sandbox:4.4:sandbox-4.4.jar:e52f3f012f893ca8458cbe3e664f1f9f13cb0501e2d730bd089d693c49ccedda',
|
||||
'org.robolectric:shadowapi:4.4:shadowapi-4.4.jar:48ce6ab59137366eb88138be5ec65bd9c0b8c54a512151140a02391fc723b83f',
|
||||
'org.robolectric:shadows-framework:4.4:shadows-framework-4.4.jar:0602f5bbef601036831e0ce8600b6d08d80ce3c9260be5cb7b362b176ce3d9f0',
|
||||
'org.robolectric:utils-reflector:4.4:utils-reflector-4.4.jar:35a77865bb9a451e99b95575cb154a5f08ecb007bd17e390817c0f31ab9db869',
|
||||
'org.robolectric:utils:4.4:utils-4.4.jar:f9756b5c57116ae9ec55a65ca52b64ba1f77d30b5eb7b55fef5d125fdf7d69d9',
|
||||
'tools.fastlane:screengrab:2.1.1:screengrab-2.1.1.aar:5a02781c0986e71ddbc691263115c2db70bdebb4b48d5b6dcf06ab1cb547d62d',
|
||||
'uk.co.samuelwall:material-tap-target-prompt:3.3.0:material-tap-target-prompt-3.3.0.aar:00f16e8d7e55d01e3b41cf66e09eee8588870ca7285ba3c72267ca0482f1606e',]
|
||||
verify = [
|
||||
'androidx.activity:activity-ktx:1.2.3:activity-ktx-1.2.3.aar:423c0226e237e08de245cf66f8ccaf103854bc19a584d971a4a075fd15d70df1',
|
||||
'androidx.activity:activity:1.2.2:activity-1.2.2.aar:e165fb20f006b77894d349572cc3acd2760baa8416ae4d33cb8de6a84dd6730c',
|
||||
'androidx.activity:activity:1.2.4:activity-1.2.4.aar:ae8e9c7de57e387d2ad90e73f3a5a5dfd502bd4f034c1dccfdb3506d1d2df81a',
|
||||
'androidx.annotation:annotation-experimental:1.0.0:annotation-experimental-1.0.0.aar:b219d2b568e7e4ba534e09f8c2fd242343df6ccbdfbbe938846f5d740e6b0b11',
|
||||
'androidx.annotation:annotation:1.5.0:annotation-1.5.0.jar:261fb7c0210858500bab66d34354972a75166ab4182add283780b05513d6ec4a',
|
||||
'androidx.appcompat:appcompat-resources:1.2.0:appcompat-resources-1.2.0.aar:c470297c03ff3de1c3d15dacf0be0cae63abc10b52f021dd07ae28daa3100fe5',
|
||||
'androidx.appcompat:appcompat:1.2.0:appcompat-1.2.0.aar:3d2131a55a61a777322e2126e0018011efa6339e53b44153eb651b16020cca70',
|
||||
'androidx.arch.core:core-common:2.1.0:core-common-2.1.0.jar:fe1237bf029d063e7f29fe39aeaf73ef74c8b0a3658486fc29d3c54326653889',
|
||||
'androidx.arch.core:core-runtime:2.1.0:core-runtime-2.1.0.aar:dd77615bd3dd275afb11b62df25bae46b10b4a117cd37943af45bdcbf8755852',
|
||||
'androidx.arch.core:core-testing:2.1.0:core-testing-2.1.0.aar:c57ffade2a9a844bd62b4f4c3916fad5e09e9f24cceba27e932c25bb7a6d1d8f',
|
||||
'androidx.cardview:cardview:1.0.0:cardview-1.0.0.aar:1193c04c22a3d6b5946dae9f4e8c59d6adde6a71b6bd5d87fb99d82dda1afec7',
|
||||
'androidx.collection:collection-ktx:1.1.0:collection-ktx-1.1.0.jar:2bfc54475c047131913361f56d0f7f019c6e5bee53eeb0eb7d94a7c499a05227',
|
||||
'androidx.collection:collection:1.1.0:collection-1.1.0.jar:632a0e5407461de774409352940e292a291037724207a787820c77daf7d33b72',
|
||||
'androidx.constraintlayout:constraintlayout-solver:2.0.4:constraintlayout-solver-2.0.4.jar:9ca19f5448709301c7563488ef941be9dfa55c83538ca7a059b2113e83527b46',
|
||||
'androidx.constraintlayout:constraintlayout:2.0.4:constraintlayout-2.0.4.aar:307a79a4a1ccff44249c72a2bf7f47da09fa1b6b1fab2a25808ca889382b738e',
|
||||
'androidx.coordinatorlayout:coordinatorlayout:1.1.0:coordinatorlayout-1.1.0.aar:44a9e30abf56af1025c52a0af506fee9c4131aa55efda52f9fd9451211c5e8cb',
|
||||
'androidx.core:core-ktx:1.2.0:core-ktx-1.2.0.aar:dcb74d510d552b35eff73b0dd27b829649535f3902e5b5a1f26040383c10a940',
|
||||
'androidx.core:core:1.3.1:core-1.3.1.aar:e92ea65a37d589943d405a6a54d1be9d12a225948f26c4e41e511dd55e81efb6',
|
||||
'androidx.cursoradapter:cursoradapter:1.0.0:cursoradapter-1.0.0.aar:a81c8fe78815fa47df5b749deb52727ad11f9397da58b16017f4eb2c11e28564',
|
||||
'androidx.customview:customview:1.0.0:customview-1.0.0.aar:20e5b8f6526a34595a604f56718da81167c0b40a7a94a57daa355663f2594df2',
|
||||
'androidx.documentfile:documentfile:1.0.0:documentfile-1.0.0.aar:865a061ef2fad16522f8433536b8d47208c46ff7c7745197dfa1eeb481869487',
|
||||
'androidx.drawerlayout:drawerlayout:1.0.0:drawerlayout-1.0.0.aar:9402442cdc5a43cf62fb14f8cf98c63342d4d9d9b805c8033c6cf7e802749ac1',
|
||||
'androidx.dynamicanimation:dynamicanimation:1.0.0:dynamicanimation-1.0.0.aar:ce005162c229bf308d2d5b12fb6cad0874069cbbeaccee63a8193bd08d40de04',
|
||||
'androidx.exifinterface:exifinterface:1.3.3:exifinterface-1.3.3.aar:996814984cb33d90921064c867d0ac41dffa10a1048ada652881c21326602397',
|
||||
'androidx.fragment:fragment-ktx:1.4.0:fragment-ktx-1.4.0.aar:439873b250461eb2245e393fe6683dceb567e7a18d9d6cf4538de9befa4ed1b0',
|
||||
'androidx.fragment:fragment-testing:1.4.0:fragment-testing-1.4.0.aar:1f874b83919c69f2e0df6de0ba2ad87a0d61cc7840d90b481ee0d4db85c2385b',
|
||||
'androidx.fragment:fragment:1.3.4:fragment-1.3.4.aar:c023c0ab666456885284d8e88519a743bc863c2b2effb92741fc789cbdb10db4',
|
||||
'androidx.fragment:fragment:1.4.0:fragment-1.4.0.aar:ec98a3b2f56f25cd247f928ab717d5527d27aea56ca4c02e67fbcd1ec32e5eed',
|
||||
'androidx.interpolator:interpolator:1.0.0:interpolator-1.0.0.aar:33193135a64fe21fa2c35eec6688f1a76e512606c0fc83dc1b689e37add7732a',
|
||||
'androidx.legacy:legacy-support-core-utils:1.0.0:legacy-support-core-utils-1.0.0.aar:a7edcf01d5b52b3034073027bc4775b78a4764bb6202bb91d61c829add8dd1c7',
|
||||
'androidx.lifecycle:lifecycle-common:2.3.1:lifecycle-common-2.3.1.jar:15848fb56db32f4c7cdc72b324003183d52a4884d6bf09be708ac7f587d139b5',
|
||||
'androidx.lifecycle:lifecycle-extensions:2.2.0:lifecycle-extensions-2.2.0.aar:648c8de1d10b025d524a2e46ac994fc3f6bf186826c09ec1a62d250bf1b877ae',
|
||||
'androidx.lifecycle:lifecycle-livedata-core-ktx:2.3.1:lifecycle-livedata-core-ktx-2.3.1.aar:6dd41c3c33daeb503fd87fbfff7043adb0be6c541a9c9e09bf531ca49520fddb',
|
||||
'androidx.lifecycle:lifecycle-livedata-core:2.3.1:lifecycle-livedata-core-2.3.1.aar:e55d38c372460f0a03997ddc950c67227511340fd74f8634d99d29653cd81ab1',
|
||||
'androidx.lifecycle:lifecycle-livedata:2.2.0:lifecycle-livedata-2.2.0.aar:d83af94860aa9f64cbdc51f40796a7cf55b116f0e6efd752e845c0104c8b16f6',
|
||||
'androidx.lifecycle:lifecycle-process:2.2.0:lifecycle-process-2.2.0.aar:3a977e7778fc8418742d388409daaba7ea8fea8823d21ffb96e4c4236f715070',
|
||||
'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1:lifecycle-runtime-ktx-2.3.1.aar:7ad2987dd7f4075c0871a72cf07e9649d9cd790fc23dfab1972eca4710373873',
|
||||
'androidx.lifecycle:lifecycle-runtime:2.3.1:lifecycle-runtime-2.3.1.aar:dd294f4a689c71ff877fd41f3b67a3a62f7760d44ce420e6130f1fc3569d8f00',
|
||||
'androidx.lifecycle:lifecycle-service:2.2.0:lifecycle-service-2.2.0.aar:ca2801ffc069555afed8eddd2292130f436956452bc8bbad30fb56f8e4e382a0',
|
||||
'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1:lifecycle-viewmodel-ktx-2.3.1.aar:5fb3591b6a54eeb3e204be0125d48eb987b8ea45a5048140036865482ccf9de9',
|
||||
'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1:lifecycle-viewmodel-savedstate-2.3.1.aar:97137a8af6a31776a14e4866ab808c7c0a791b484bdbc788bbd83e66407564c0',
|
||||
'androidx.lifecycle:lifecycle-viewmodel:2.3.1:lifecycle-viewmodel-2.3.1.aar:b6db4c274a12ff85a4747e1e6669c7e98aefa2571ace9d1f1a6fa6be417ce838',
|
||||
'androidx.loader:loader:1.0.0:loader-1.0.0.aar:11f735cb3b55c458d470bed9e25254375b518b4b1bad6926783a7026db0f5025',
|
||||
'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0:localbroadcastmanager-1.0.0.aar:e71c328ceef5c4a7d76f2d86df1b65d65fe2acf868b1a4efd84a3f34336186d8',
|
||||
'androidx.preference:preference:1.1.1:preference-1.1.1.aar:317dcbc38242aea2f6262c06d51b8a22827e98959967edd40f82600a15cb4bff',
|
||||
'androidx.print:print:1.0.0:print-1.0.0.aar:1d5c7f3135a1bba661fc373fd72e11eb0a4adbb3396787826dd8e4190d5d9edd',
|
||||
'androidx.recyclerview:recyclerview-selection:1.1.0:recyclerview-selection-1.1.0.aar:9e2ba1c7d6b0eb5e64c10b1b0eb01b51e8511cee002c9bd56ce9cc138ebc4898',
|
||||
'androidx.recyclerview:recyclerview:1.1.0:recyclerview-1.1.0.aar:f0d2b5a67d0a91ee1b1c73ef2b636a81f3563925ddd15a1d4e1c41ec28de7a4f',
|
||||
'androidx.savedstate:savedstate-ktx:1.1.0:savedstate-ktx-1.1.0.aar:e44d61347463b0fafeeb649cbcc3d7109b2eb5e11d1522e986105170cdebbf68',
|
||||
'androidx.savedstate:savedstate:1.1.0:savedstate-1.1.0.aar:d60bbe44c2c08083a17c5dc678a6d6b4d0a2d664858016ab5c049cbea90a63b7',
|
||||
'androidx.test.espresso:espresso-contrib:3.3.0:espresso-contrib-3.3.0.aar:f400cabdc181356acf6b210e4509dcb9649d9e2b6b6e218c60fcfc15e8a756d1',
|
||||
'androidx.test.espresso:espresso-core:3.3.0:espresso-core-3.3.0.aar:23ebf6014645e0c60aec7d1ed924d4d4c848ae8c3673b7d8d06b2ec6a56cafee',
|
||||
'androidx.test.espresso:espresso-idling-resource:3.3.0:espresso-idling-resource-3.3.0.aar:29519b112731f289cc6e2f9b2eccc5ea72c754b04272bb93370f45d7e170a7c6',
|
||||
'androidx.test.espresso:espresso-intents:3.3.0:espresso-intents-3.3.0.aar:5b6cd6aadce78edc705d93c1e81ace3b59be97128aca0e88fd9c5c176aa9bf10',
|
||||
'androidx.test.ext:junit:1.1.3:junit-1.1.3.aar:a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690',
|
||||
'androidx.test.services:storage:1.4.0:storage-1.4.0.aar:35cfbf442abb83e5876cd5deb9de02ae047459f18f831097c5caa76d626bc38a',
|
||||
'androidx.test.services:test-services:1.3.0:test-services-1.3.0.apk:1b88faab6864baf25c5d0b92a610c283c159a566e7a56c03307117fa1b542993',
|
||||
'androidx.test.uiautomator:uiautomator:2.2.0:uiautomator-2.2.0.aar:2838e9d961dbffefbbd229a2bd4f6f82ac4fb2462975862a9e75e9ed325a3197',
|
||||
'androidx.test:core:1.4.0:core-1.4.0.aar:671284e62e393f16ceae1a99a3a9a07bf1aacda29f8fe7b6b884355ef34c09cf',
|
||||
'androidx.test:monitor:1.4.0:monitor-1.4.0.aar:46a912a1e175f27a97521af3f50e5af87c22c49275dd2c57c043740012806325',
|
||||
'androidx.test:orchestrator:1.3.0:orchestrator-1.3.0.apk:676f808d08a3d05050eae30c3b7d92ce5cef1e00a54d68355bb7e7d4b72366fe',
|
||||
'androidx.test:rules:1.3.0:rules-1.3.0.aar:c1753946c498b0d5d7cf341cfed661f66915c4c9deb4ed10462a08ae33b2429a',
|
||||
'androidx.test:runner:1.3.0:runner-1.3.0.aar:61d13f5a9fcbbd73ba18fa84e1d6a0111c6e1c665a89b418126966e61fffd93b',
|
||||
'androidx.test:runner:1.4.0:runner-1.4.0.aar:e3f3d8b8d5d4a3edcacbdaa4a31bda2b0e41d3e704b02b3750466a06367ec5a0',
|
||||
'androidx.tracing:tracing:1.0.0:tracing-1.0.0.aar:07b8b6139665b884a162eccf97891ca50f7f56831233bf25168ae04f7b568612',
|
||||
'androidx.transition:transition:1.2.0:transition-1.2.0.aar:a1e059b3bc0b43a58dec0efecdcaa89c82d2bca552ea5bacf6656c46e853157e',
|
||||
'androidx.vectordrawable:vectordrawable-animated:1.1.0:vectordrawable-animated-1.1.0.aar:76da2c502371d9c38054df5e2b248d00da87809ed058f3363eae87ce5e2403f8',
|
||||
'androidx.vectordrawable:vectordrawable:1.1.0:vectordrawable-1.1.0.aar:46fd633ac01b49b7fcabc263bf098c5a8b9e9a69774d234edcca04fb02df8e26',
|
||||
'androidx.versionedparcelable:versionedparcelable:1.1.0:versionedparcelable-1.1.0.aar:9a1d77140ac222b7866b5054ee7d159bc1800987ed2d46dd6afdd145abb710c1',
|
||||
'androidx.viewpager2:viewpager2:1.0.0:viewpager2-1.0.0.aar:e95c0031d4cc247cd48196c6287e58d2cee54d9c79b85afea7c90920330275af',
|
||||
'androidx.viewpager:viewpager:1.0.0:viewpager-1.0.0.aar:147af4e14a1984010d8f155e5e19d781f03c1d70dfed02a8e0d18428b8fc8682',
|
||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||
'com.almworks.sqlite4java:sqlite4java:0.282:sqlite4java-0.282.jar:9e1d8dd83ca6003f841e3af878ce2dc7c22497493a7bb6d1b62ec1b0d0a83c05',
|
||||
'com.github.bumptech.glide:annotations:4.12.0:annotations-4.12.0.jar:fa430cbf8f931fcd89c38195ab5544ef4d62c8ac6c2e6f49f8f4ae7860fade8e',
|
||||
'com.github.bumptech.glide:compiler:4.12.0:compiler-4.12.0.jar:030297733aa52dd52ef9d45895e02d7446b537d608fe6972514b9f261c23c99a',
|
||||
'com.github.bumptech.glide:gifdecoder:4.12.0:gifdecoder-4.12.0.aar:197a1cd5b76855aa02b230c13974e293229b901dc2b96fab4315201e78baa804',
|
||||
'com.github.bumptech.glide:glide:4.12.0:glide-4.12.0.aar:6ae2944adb62977fe53f42c4f86a22bd326c1828b693441ccce430e92f148384',
|
||||
'com.github.chrisbanes:PhotoView:2.3.0:PhotoView-2.3.0.aar:6c8989f2945d50ab38b3e0300064f1f8d2d75bbcae1434fe535d9fb6898e9ad6',
|
||||
'com.github.kobakei:MaterialFabSpeedDial:1.2.1:MaterialFabSpeedDial-1.2.1.aar:e86198c3c48cd832fb209a769a9f222c2a3cc045743b110ac2391d9737e3ea02',
|
||||
'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.0:accessibility-test-framework-2.0.jar:cdf16ef8f5b8023d003ce3cc1b0d51bda737762e2dab2fedf43d1c4292353f7f',
|
||||
'com.google.android.material:material:1.3.0:material-1.3.0.aar:cbf1e7d69fc236cdadcbd1ec5f6c0a1a41aca6ad1ef7f8481058956270ab1f0a',
|
||||
'com.google.auto.value:auto-value-annotations:1.6.2:auto-value-annotations-1.6.2.jar:b48b04ddba40e8ac33bf036f06fc43995fc5084bd94bdaace807ce27d3bea3fb',
|
||||
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.dagger:dagger-compiler:2.43.2:dagger-compiler-2.43.2.jar:298c020ee6ed2f4cc651ebbfdb7f8de329b07c44b618d65be117846a850e2a03',
|
||||
'com.google.dagger:dagger-producers:2.43.2:dagger-producers-2.43.2.jar:e7f5d9ffc85d48a49c8e22e02833d418f7ccad5d7512f529964db5127ab915ff',
|
||||
'com.google.dagger:dagger-spi:2.43.2:dagger-spi-2.43.2.jar:3bae8d9dadeaaa5927da6f094389a560c12c05fec3d2711d2fa79292c7a7d7ad',
|
||||
'com.google.dagger:dagger:2.43.2:dagger-2.43.2.jar:c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4',
|
||||
'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
|
||||
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
|
||||
'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
|
||||
'com.google.guava:guava:27.0.1-jre:guava-27.0.1-jre.jar:e1c814fd04492a27c38e0317eabeaa1b3e950ec8010239e400fe90ad6c9107b4',
|
||||
'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.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
|
||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
'com.google.zxing:core:3.3.3:core-3.3.3.jar:5820f81e943e4bce0329306621e2d6255d2930b0a6ce934c5c23c0d6d3f20599',
|
||||
'com.ibm.icu:icu4j:53.1:icu4j-53.1.jar:e37a4467bac5cdeb02c5c4b8e5063d2f4e67b69e3c7df6d6b610f13185572bab',
|
||||
'com.jraska:falcon:2.2.0:falcon-2.2.0.aar:8b016c6e016ef99fb493b8614b2362cfba540a68ac16a9bb6da310ae10e30b81',
|
||||
'com.squareup.okhttp3:okhttp:3.12.13:okhttp-3.12.13.jar:508234e024ef7e270ab1a6d5b356f5b98e786511239ca986d684fd1e2cf7bc82',
|
||||
'com.squareup.okio:okio:1.15.0:okio-1.15.0.jar:693fa319a7e8843300602b204023b7674f106ebcb577f2dd5807212b66118bd2',
|
||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||
'com.squareup:javawriter:2.1.1:javawriter-2.1.1.jar:f699823d0081f69cbb676c1845ea222e0ada79bc88a53e5d22d8bd02d328f57e',
|
||||
'com.vanniktech:emoji-google:0.7.0:emoji-google-0.7.0.aar:b98966812e3f607ee823cde15dd9b3823c6f02e5587572b860b9d95e3f971402',
|
||||
'com.vanniktech:emoji:0.7.0:emoji-0.7.0.aar:66f5981f8b5f93e82d2d4b3fa4c6299904d686ca62a2366e61de723b20253707',
|
||||
'de.hdodenhof:circleimageview:3.1.0:circleimageview-3.1.0.aar:8e9965b54072ee159074a55df216e17d5a622c94ce915ef311b1a1f32660c7fb',
|
||||
'info.guardianproject.panic:panic:1.0:panic-1.0.jar:35116ab95212e67f94577faf67b88c11a6b21cbf9178b3f5b51d3dff45203ffd',
|
||||
'javax.annotation:javax.annotation-api:1.3.2:javax.annotation-api-1.3.2.jar:e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||
'net.bytebuddy:byte-buddy-agent:1.10.20:byte-buddy-agent-1.10.20.jar:b592a6c43e752bf41659717956c57fbb790394d2ee5f8941876659f9c5c0e7e8',
|
||||
'net.bytebuddy:byte-buddy:1.10.20:byte-buddy-1.10.20.jar:5fcad05da791e9a22811c255a4a74b7ea094b7243d9dbf3e6fc578c8c94290ac',
|
||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||
'org.bouncycastle:bcprov-jdk15on:1.65:bcprov-jdk15on-1.65.jar:e78f96eb59066c94c94fb2d6b5eb80f52feac6f5f9776898634f8addec6e2137',
|
||||
'org.briarproject:dont-kill-me-lib:0.2.5:dont-kill-me-lib-0.2.5.aar:55cd9d511b7016ab573905d64bc54e222e2633144d36389192b8b34485b31b9d',
|
||||
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
|
||||
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
|
||||
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||
'org.hamcrest:hamcrest-integration:1.3:hamcrest-integration-1.3.jar:70f418efbb506c5155da5f9a5a33262ea08a9e4d7fea186aa9015c41a7224ac2',
|
||||
'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:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||
'org.jacoco:org.jacoco.agent:0.8.7:org.jacoco.agent-0.8.7.jar:9cbcc986e0fbe821a78ff1f8f7d5216f200e5eb124e7f6837d1dc4a77b28b143',
|
||||
'org.jacoco:org.jacoco.ant:0.8.7:org.jacoco.ant-0.8.7.jar:97ca96a382c3f23a44d8eb4c4e6c3742a30cb8005774a76ced0fc4806ce49605',
|
||||
'org.jacoco:org.jacoco.core:0.8.7:org.jacoco.core-0.8.7.jar:ad7739b5fb5969aa1a8aead3d74ed54dc82ed012f1f10f336bd1b96e71c1a13c',
|
||||
'org.jacoco:org.jacoco.report:0.8.7:org.jacoco.report-0.8.7.jar:cc89258623700a6c932592153cb528785876b6da183d5431f97efbba6f020e5b',
|
||||
'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.10:kotlin-stdlib-common-1.7.10.jar:19f102efe9629f8eabc63853ad15c533e47c47f91fca09285c5bde86e59f91d4',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.20:kotlin-stdlib-jdk7-1.6.20.jar:aa2fa2e81355c4d98dd97da2169bf401f842261378f5b1cbea1aa11855d67620',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.7.10:kotlin-stdlib-1.7.10.jar:e771fe74250a943e8f6346713201ff1d8cb95c3a5d1a91a22b65a9e04f6a8901',
|
||||
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1:kotlinx-coroutines-android-1.4.1.jar:d4cadb673b2101f1ee5fbc147956ac78b1cfd9cc255fb53d3aeb88dff11d99ca',
|
||||
'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.4.1:kotlinx-coroutines-core-jvm-1.4.1.jar:6d2f87764b6638f27aff12ed380db4b63c9d46ba55dc32683a650598fa5a3e22',
|
||||
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
|
||||
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
|
||||
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
|
||||
'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd',
|
||||
'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.jsoup:jsoup:1.15.3:jsoup-1.15.3.jar:e20a5e78b1372f2a4e620832db4442d5077e5cbde280b24c666a3770844999bc',
|
||||
'org.mockito:mockito-core:3.9.0:mockito-core-3.9.0.jar:a1f64211407b8dc4cf80b16e07cc11aa9e5228d53dc4a5357326d66825f6a4ac',
|
||||
'org.nanohttpd:nanohttpd:2.3.1:nanohttpd-2.3.1.jar:de864c47818157141a24c9acb36df0c47d7bf15b7ff48c90610f3eb4e5df0e58',
|
||||
'org.objenesis:objenesis:3.2:objenesis-3.2.jar:03d960bd5aef03c653eb000413ada15eb77cdd2b8e4448886edf5692805e35f3',
|
||||
'org.ow2.asm:asm-analysis:7.2:asm-analysis-7.2.jar:be922aae60ff1ff1768e8e6544a38a7f92bd0a6d6b0b9791f94955d1bd453de2',
|
||||
'org.ow2.asm:asm-analysis:9.1:asm-analysis-9.1.jar:81a88041b1b8beda5a8a99646098046c48709538270c49def68abff25ac3be34',
|
||||
'org.ow2.asm:asm-commons:7.2:asm-commons-7.2.jar:0e86b8b179c5fb223d1a880a0ff4960b6978223984b94e62e71135f2d8ea3558',
|
||||
'org.ow2.asm:asm-commons:9.1:asm-commons-9.1.jar:afcb26dc1fc12c0c4a99ada670908dd82e18dfc488caf5ee92546996b470c00c',
|
||||
'org.ow2.asm:asm-tree:7.2:asm-tree-7.2.jar:c063f5a67fa03cdc9bd79fd1c2ea6816cc4a19473ecdfbd9e9153b408c6f2656',
|
||||
'org.ow2.asm:asm-tree:9.1:asm-tree-9.1.jar:fd00afa49e9595d7646205b09cecb4a776a8ff0ba06f2d59b8f7bf9c704b4a73',
|
||||
'org.ow2.asm:asm-util:7.2:asm-util-7.2.jar:6e24913b021ffacfe8e7e053d6e0ccc731941148cfa078d4f1ed3d96904530f8',
|
||||
'org.ow2.asm:asm:7.2:asm-7.2.jar:7e6cc9e92eb94d04e39356c6d8144ca058cda961c344a7f62166a405f3206672',
|
||||
'org.ow2.asm:asm:9.1:asm-9.1.jar:cda4de455fab48ff0bcb7c48b4639447d4de859a7afc30a094a986f0936beba2',
|
||||
'org.robolectric:annotations:4.4:annotations-4.4.jar:d2b2d71a1f902a5a016dde5a2feb3be521d120192f9217adadbfb483d79f89ff',
|
||||
'org.robolectric:junit:4.4:junit-4.4.jar:c5ebcb20cf9d2173a294a6feff68331fff718a368e332df70c7ea7e3bdce846e',
|
||||
'org.robolectric:pluginapi:4.4:pluginapi-4.4.jar:b2f743db060502cb366f67dcd6c3929c7f4656744d91ab81d749b8bf641f5512',
|
||||
'org.robolectric:plugins-maven-dependency-resolver:4.4:plugins-maven-dependency-resolver-4.4.jar:5279024a6bdbb2ee1791b06da13cc890628c583ad48414ae13a4f57d7db749a3',
|
||||
'org.robolectric:resources:4.4:resources-4.4.jar:e39862f71887561dfde65030aeca5148bf0f6279b25fb9e146b75c2933fcabcf',
|
||||
'org.robolectric:robolectric:4.4:robolectric-4.4.jar:38e0368914a48d6d8e543c12670beb1e36e09d037e664280fb604dbbfd10fe5f',
|
||||
'org.robolectric:sandbox:4.4:sandbox-4.4.jar:e52f3f012f893ca8458cbe3e664f1f9f13cb0501e2d730bd089d693c49ccedda',
|
||||
'org.robolectric:shadowapi:4.4:shadowapi-4.4.jar:48ce6ab59137366eb88138be5ec65bd9c0b8c54a512151140a02391fc723b83f',
|
||||
'org.robolectric:shadows-framework:4.4:shadows-framework-4.4.jar:0602f5bbef601036831e0ce8600b6d08d80ce3c9260be5cb7b362b176ce3d9f0',
|
||||
'org.robolectric:utils-reflector:4.4:utils-reflector-4.4.jar:35a77865bb9a451e99b95575cb154a5f08ecb007bd17e390817c0f31ab9db869',
|
||||
'org.robolectric:utils:4.4:utils-4.4.jar:f9756b5c57116ae9ec55a65ca52b64ba1f77d30b5eb7b55fef5d125fdf7d69d9',
|
||||
'tools.fastlane:screengrab:2.1.1:screengrab-2.1.1.aar:5a02781c0986e71ddbc691263115c2db70bdebb4b48d5b6dcf06ab1cb547d62d',
|
||||
'uk.co.samuelwall:material-tap-target-prompt:3.3.0:material-tap-target-prompt-3.3.0.aar:00f16e8d7e55d01e3b41cf66e09eee8588870ca7285ba3c72267ca0482f1606e',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@ apply plugin: 'witness'
|
||||
apply from: 'witness.gradle'
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-api', configuration: 'default')
|
||||
implementation project(':bramble-api')
|
||||
|
||||
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ public interface ForumManager {
|
||||
*/
|
||||
void removeForum(Forum f) throws DbException;
|
||||
|
||||
/**
|
||||
* Unsubscribes from a forum.
|
||||
*/
|
||||
void removeForum(Transaction txn, Forum f) throws DbException;
|
||||
|
||||
/**
|
||||
* Creates a local forum post.
|
||||
*/
|
||||
@@ -127,6 +132,11 @@ public interface ForumManager {
|
||||
*/
|
||||
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
|
||||
|
||||
/**
|
||||
* Marks a message as read or unread and updates the group count.
|
||||
*/
|
||||
void setReadFlag(Transaction txn, GroupId g, MessageId m, boolean read) throws DbException;
|
||||
|
||||
interface RemoveForumHook {
|
||||
/**
|
||||
* Called when a forum is being removed.
|
||||
|
||||
@@ -24,23 +24,48 @@ public interface SharingManager<S extends Shareable>
|
||||
void sendInvitation(GroupId shareableId, ContactId contactId,
|
||||
@Nullable String text) throws DbException;
|
||||
|
||||
/**
|
||||
* Sends an invitation to share the given group with the given contact,
|
||||
* including optional text.
|
||||
*/
|
||||
void sendInvitation(Transaction txn, GroupId shareableId,
|
||||
ContactId contactId, @Nullable String text) throws DbException;
|
||||
|
||||
/**
|
||||
* Responds to a pending group invitation
|
||||
*/
|
||||
void respondToInvitation(S s, Contact c, boolean accept)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Responds to a pending group invitation
|
||||
*/
|
||||
void respondToInvitation(Transaction txn, S s, Contact c, boolean accept)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Responds to a pending group invitation
|
||||
*/
|
||||
void respondToInvitation(ContactId c, SessionId id, boolean accept)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Responds to a pending group invitation
|
||||
*/
|
||||
void respondToInvitation(Transaction txn, ContactId c, SessionId id,
|
||||
boolean accept) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns all invitations to groups.
|
||||
*/
|
||||
Collection<SharingInvitationItem> getInvitations() throws DbException;
|
||||
|
||||
/**
|
||||
* Returns all invitations to groups.
|
||||
*/
|
||||
Collection<SharingInvitationItem> getInvitations(Transaction txn)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns all contacts with whom the given group is shared.
|
||||
*/
|
||||
@@ -57,4 +82,10 @@ public interface SharingManager<S extends Shareable>
|
||||
*/
|
||||
boolean canBeShared(GroupId g, Contact c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the group not already shared and no invitation is open
|
||||
*/
|
||||
boolean canBeShared(Transaction txn, GroupId g, Contact c)
|
||||
throws DbException;
|
||||
|
||||
}
|
||||
|
||||
@@ -9,18 +9,20 @@ apply from: 'witness.gradle'
|
||||
apply from: '../dagger.gradle'
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':briar-api', configuration: 'default')
|
||||
api project(':briar-api')
|
||||
|
||||
implementation project(':bramble-core')
|
||||
|
||||
implementation 'com.rometools:rome:1.15.0'
|
||||
implementation 'org.jdom:jdom2:2.0.6'
|
||||
//noinspection GradleDependency
|
||||
implementation "org.jsoup:jsoup:$jsoup_version"
|
||||
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
||||
implementation 'org.jsoup:jsoup:1.15.3'
|
||||
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
testImplementation project(path: ':bramble-core', configuration: 'default')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
|
||||
testImplementation 'net.jodah:concurrentunit:0.4.2'
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "org.jmock:jmock:$jmock_version"
|
||||
@@ -37,7 +39,7 @@ configurations {
|
||||
testOutput.extendsFrom(testCompile)
|
||||
}
|
||||
task jarTest(type: Jar, dependsOn: testClasses) {
|
||||
from sourceSets.test.output
|
||||
from sourceSets.test.output, sourceSets.main.output
|
||||
classifier = 'test'
|
||||
}
|
||||
artifacts {
|
||||
|
||||
@@ -105,11 +105,14 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
||||
|
||||
@Override
|
||||
public void removeForum(Forum f) throws DbException {
|
||||
db.transaction(false, txn -> {
|
||||
for (RemoveForumHook hook : removeHooks)
|
||||
hook.removingForum(txn, f);
|
||||
db.removeGroup(txn, f.getGroup());
|
||||
});
|
||||
db.transaction(false, txn -> removeForum(txn, f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeForum(Transaction txn, Forum f) throws DbException {
|
||||
for (RemoveForumHook hook : removeHooks)
|
||||
hook.removingForum(txn, f);
|
||||
db.removeGroup(txn, f.getGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -268,6 +271,12 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
||||
messageTracker.setReadFlag(txn, g, m, read));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadFlag(Transaction txn, GroupId g, MessageId m,
|
||||
boolean read) throws DbException {
|
||||
messageTracker.setReadFlag(txn, g, m, read);
|
||||
}
|
||||
|
||||
private Forum parseForum(Group g) throws FormatException {
|
||||
byte[] descriptor = g.getDescriptor();
|
||||
// Name, salt
|
||||
|
||||
@@ -259,8 +259,14 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
@Override
|
||||
public void sendInvitation(GroupId shareableId, ContactId contactId,
|
||||
@Nullable String text) throws DbException {
|
||||
db.transaction(false,
|
||||
txn -> sendInvitation(txn, shareableId, contactId, text));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInvitation(Transaction txn, GroupId shareableId,
|
||||
ContactId contactId, @Nullable String text) throws DbException {
|
||||
SessionId sessionId = getSessionId(shareableId);
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
Contact contact = db.getContact(txn, contactId);
|
||||
if (!canBeShared(txn, shareableId, contact))
|
||||
@@ -286,11 +292,8 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
session = engine.onInviteAction(txn, session, text);
|
||||
// Store the updated session
|
||||
storeSession(txn, storageId, session);
|
||||
db.commitTransaction(txn);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +303,12 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
respondToInvitation(c.getId(), getSessionId(s.getId()), accept);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respondToInvitation(Transaction txn, S s, Contact c,
|
||||
boolean accept) throws DbException {
|
||||
respondToInvitation(txn, c.getId(), getSessionId(s.getId()), accept);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respondToInvitation(ContactId c, SessionId id, boolean accept)
|
||||
throws DbException {
|
||||
@@ -307,6 +316,12 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
txn -> respondToInvitation(txn, c, id, accept, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respondToInvitation(Transaction txn, ContactId c, SessionId id,
|
||||
boolean accept) throws DbException {
|
||||
respondToInvitation(txn, c, id, accept, false);
|
||||
}
|
||||
|
||||
private void respondToInvitation(Transaction txn, ContactId c,
|
||||
SessionId id, boolean accept, boolean isAutoDecline)
|
||||
throws DbException {
|
||||
@@ -390,10 +405,15 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
@Override
|
||||
public Collection<SharingInvitationItem> getInvitations()
|
||||
throws DbException {
|
||||
return db.transactionWithResult(true, this::getInvitations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SharingInvitationItem> getInvitations(Transaction txn)
|
||||
throws DbException {
|
||||
List<SharingInvitationItem> items = new ArrayList<>();
|
||||
BdfDictionary query = messageParser.getInvitesAvailableToAnswerQuery();
|
||||
Map<S, Collection<Contact>> sharers = new HashMap<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
// get invitations from each contact
|
||||
for (Contact c : db.getContacts(txn)) {
|
||||
@@ -423,12 +443,9 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
new SharingInvitationItem(s, subscribed, contacts);
|
||||
items.add(invitation);
|
||||
}
|
||||
db.commitTransaction(txn);
|
||||
return items;
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,7 +478,8 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canBeShared(Transaction txn, GroupId g, Contact c)
|
||||
@Override
|
||||
public boolean canBeShared(Transaction txn, GroupId g, Contact c)
|
||||
throws DbException {
|
||||
// The group can't be shared unless the contact supports the client
|
||||
Visibility client = clientVersioningManager.getClientVisibility(txn,
|
||||
|
||||
@@ -17,17 +17,19 @@ sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':briar-core', configuration: 'default')
|
||||
implementation project(path: ':bramble-java', configuration: 'default')
|
||||
implementation project(':bramble-core')
|
||||
implementation project(':bramble-java')
|
||||
implementation project(':briar-core')
|
||||
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10'
|
||||
implementation 'io.javalin:javalin:3.5.0'
|
||||
implementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
|
||||
implementation 'com.github.ajalt:clikt:2.2.0'
|
||||
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
|
||||
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
|
||||
|
||||
def daggerVersion = '2.24'
|
||||
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
kapt "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
@@ -36,15 +38,23 @@ dependencies {
|
||||
def junitVersion = '5.5.2'
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion"
|
||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
|
||||
testImplementation 'io.mockk:mockk:1.12.4'
|
||||
testImplementation 'org.skyscreamer:jsonassert:1.5.0'
|
||||
testImplementation "com.squareup.okhttp3:okhttp:4.10.0"
|
||||
|
||||
kaptTest "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
|
||||
|
||||
kaptTest "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
}
|
||||
|
||||
void jarFactory(Jar jarTask, jarArchitecture) {
|
||||
jarTask.dependsOn(
|
||||
':bramble-api:jar',
|
||||
':bramble-core:jar',
|
||||
':bramble-java:jar',
|
||||
':briar-api:jar',
|
||||
':briar-core:jar'
|
||||
)
|
||||
jarTask.dependsOn(jar)
|
||||
jarTask.doFirst {
|
||||
println 'Building ' + jarArchitecture + ' version has started'
|
||||
|
||||
@@ -5,21 +5,24 @@ dependencyVerification {
|
||||
'com.fasterxml.jackson.core:jackson-databind:2.13.4:jackson-databind-2.13.4.jar:c9faff420d9e2c7e1e4711dbeebec2506a32c9942027211c5c293d8d87807eb6',
|
||||
'com.github.ajalt:clikt:2.2.0:clikt-2.2.0.jar:beb3136d06764ec8ce0810a8fd6c8b7b49d04287d1deef3a07c016e43a458d33',
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.dagger:dagger-compiler:2.24:dagger-compiler-2.24.jar:3c5afb955fb188da485cb2c048eff37dce0e1530b9780a0f2f7187d16d1ccc1f',
|
||||
'com.google.dagger:dagger-producers:2.24:dagger-producers-2.24.jar:f10f45b95191954d5d6b043fca9e62fb621d21bf70634b8f8476c7988b504c3a',
|
||||
'com.google.dagger:dagger-spi:2.24:dagger-spi-2.24.jar:c038445d14dbcb4054e61bf49e05009edf26fce4fdc7ec1a9db544784f68e718',
|
||||
'com.google.dagger:dagger:2.24:dagger-2.24.jar:550a6e46a6dfcdf1d764887b6090cea94f783327e50e5c73754f18facfc70b64',
|
||||
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
|
||||
'com.google.dagger:dagger-compiler:2.43.2:dagger-compiler-2.43.2.jar:298c020ee6ed2f4cc651ebbfdb7f8de329b07c44b618d65be117846a850e2a03',
|
||||
'com.google.dagger:dagger-producers:2.43.2:dagger-producers-2.43.2.jar:e7f5d9ffc85d48a49c8e22e02833d418f7ccad5d7512f529964db5127ab915ff',
|
||||
'com.google.dagger:dagger-spi:2.43.2:dagger-spi-2.43.2.jar:3bae8d9dadeaaa5927da6f094389a560c12c05fec3d2711d2fa79292c7a7d7ad',
|
||||
'com.google.dagger:dagger:2.43.2:dagger-2.43.2.jar:c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4',
|
||||
'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
|
||||
'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
|
||||
'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7',
|
||||
'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.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
|
||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
'com.squareup.okhttp3:okhttp:3.12.13:okhttp-3.12.13.jar:508234e024ef7e270ab1a6d5b356f5b98e786511239ca986d684fd1e2cf7bc82',
|
||||
'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:1.15.0:okio-1.15.0.jar:693fa319a7e8843300602b204023b7674f106ebcb577f2dd5807212b66118bd2',
|
||||
'com.squareup.okio:okio:3.0.0:okio-metadata-3.0.0.jar:dcbe63ed43b2c90c325e9e6a0863e2e7605980bff5e728c6de1088be5574979e',
|
||||
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
|
||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||
'com.vaadin.external.google:android-json:0.0.20131108.vaadin1:android-json-0.0.20131108.vaadin1.jar:dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79',
|
||||
'io.javalin:javalin:3.5.0:javalin-3.5.0.jar:6618f99ad4c241eefcaf3a02c85adc52ec346c9710e8eb5a3f1a916e3d7acec4',
|
||||
'io.mockk:mockk-agent-api:1.12.4:mockk-agent-api-1.12.4.jar:6eb3407b1f88c0c0ced9636f82874100786b74b3b06c4354c4d85229779fdec8',
|
||||
@@ -29,7 +32,6 @@ dependencyVerification {
|
||||
'io.mockk:mockk-dsl-jvm:1.12.4:mockk-dsl-jvm-1.12.4.jar:faee4b52def68fa182f89d23c2a45f2246ef88b6b1ba98346aa85f57e5ed630f',
|
||||
'io.mockk:mockk-dsl:1.12.4:mockk-dsl-1.12.4.jar:7fc96f9ed5118c915a3890ba2e4090c9b283ae7bdc37ab83885415bdf77650e4',
|
||||
'io.mockk:mockk:1.12.4:mockk-1.12.4.jar:2c34a3690b958a3cf38b82d0f4910dc9992fb078dce6f56d71498293557bf805',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'javax.servlet:javax.servlet-api:3.1.0:javax.servlet-api-3.1.0.jar:af456b2dd41c4e82cf54f3e743bc678973d9fe35bd4d3071fa05c7e5333b8482',
|
||||
'net.bytebuddy:byte-buddy-agent:1.12.6:byte-buddy-agent-1.12.6.jar:9b29421fe4650b75fc3ed53590f914c54f932e334b3506cc00296dff73024183',
|
||||
@@ -37,9 +39,9 @@ dependencyVerification {
|
||||
'net.java.dev.jna:jna:5.6.0:jna-5.6.0.jar:5557e235a8aa2f9766d5dc609d67948f2a8832c2d796cea9ef1d6cbe0b3b7eaf',
|
||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||
'org.apiguardian:apiguardian-api:1.1.0:apiguardian-api-1.1.0.jar:a9aae9ff8ae3e17a2a18f79175e82b16267c246fbbd3ca9dfbbb290b08dcfdd4',
|
||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||
'org.bouncycastle:bcprov-jdk15to18:1.71:bcprov-jdk15to18-1.71.jar:143aaa4a40edd5fc2a18db7900059f6c16f4d931b94b94b20f7e2238e6662886',
|
||||
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
|
||||
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
|
||||
'org.eclipse.jetty.websocket:websocket-api:9.4.20.v20190813:websocket-api-9.4.20.v20190813.jar:779a29060cc17bdeeeba147efc884ebff972cfff93dad2d37b11c93f95d4f67b',
|
||||
'org.eclipse.jetty.websocket:websocket-client:9.4.20.v20190813:websocket-client-9.4.20.v20190813.jar:df5df7ea0b2d40e1011946cfa5fe27c86047f0c4e77ccc0b8c0c7f5518278bf3',
|
||||
'org.eclipse.jetty.websocket:websocket-common:9.4.20.v20190813:websocket-common-9.4.20.v20190813.jar:a66eb0a5299e2f33addb0dca827cc95a0773c41a12ea70c0d52d51beabaecf65',
|
||||
@@ -66,10 +68,15 @@ dependencyVerification {
|
||||
'org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.7.10:kotlin-scripting-compiler-embeddable-1.7.10.jar:fcb8a0b3b7a95263dab8a0ccdd34fed02888700511eabb5613f75a007a4aa802',
|
||||
'org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.7.10:kotlin-scripting-compiler-impl-embeddable-1.7.10.jar:7119205985ebd721179fb0f35d1d511f96de14fbd48e6465119fcac6bffc8090',
|
||||
'org.jetbrains.kotlin:kotlin-scripting-jvm:1.7.10:kotlin-scripting-jvm-1.7.10.jar:cf85511ce4e26fa3286d722f95ed54f16f2513a39ce3b85f2b567e575cb45a60',
|
||||
'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.10:kotlin-stdlib-common-1.7.10.jar:19f102efe9629f8eabc63853ad15c533e47c47f91fca09285c5bde86e59f91d4',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10:kotlin-stdlib-jdk7-1.7.10.jar:54f61351b1936ad88f4e53059fe781e723eae51d78ed9e7422d8b403574ec682',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10:kotlin-stdlib-jdk8-1.7.10.jar:8aafdd60c94f454c92e5066d266a5ed53ecc63c78f623b3fd9db56fea4032873',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.7.10:kotlin-stdlib-1.7.10.jar:e771fe74250a943e8f6346713201ff1d8cb95c3a5d1a91a22b65a9e04f6a8901',
|
||||
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
|
||||
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||
'org.junit.jupiter:junit-jupiter-api:5.5.2:junit-jupiter-api-5.5.2.jar:249a2fdbd3931987c0298d00ca08ed248496e0fc11e0463c08c4f82e0cc79b1c',
|
||||
'org.junit.jupiter:junit-jupiter-engine:5.5.2:junit-jupiter-engine-5.5.2.jar:6d777da9876e2ef7a0336e8f098f8d74a5a64f810aa3a4a2f5f3b766ce97837b',
|
||||
|
||||
@@ -35,6 +35,8 @@ buildscript {
|
||||
tor_version = "0.4.5.14"
|
||||
obfs4proxy_version = "0.0.14-tor1"
|
||||
snowflake_version = "2.3.1"
|
||||
jsoup_version = '1.15.3'
|
||||
bouncy_castle_version = '1.71'
|
||||
junit_version = "4.13.2"
|
||||
jmock_version = '2.12.0'
|
||||
}
|
||||
|
||||
@@ -6,16 +6,17 @@ apply plugin: 'idea'
|
||||
apply from: '../dagger.gradle'
|
||||
|
||||
dependencies {
|
||||
testImplementation project(path: ':bramble-api', configuration: 'default')
|
||||
testImplementation project(':bramble-api')
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'default')
|
||||
testImplementation project(':bramble-core')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
testImplementation project(path: ':mailbox-core', configuration: 'default')
|
||||
testImplementation project(path: ':mailbox-lib', configuration: 'default')
|
||||
testImplementation project(':mailbox-core')
|
||||
testImplementation project(':mailbox-lib')
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation "ch.qos.logback:logback-classic:1.2.11"
|
||||
testImplementation 'net.jodah:concurrentunit:0.4.6'
|
||||
testImplementation "com.squareup.okhttp3:okhttp:$okhttp_version"
|
||||
|
||||
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingState.Paired;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox;
|
||||
@@ -121,7 +121,7 @@ abstract class AbstractMailboxIntegrationTest
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
pairingTask.addObserver((state) -> {
|
||||
if (state instanceof MailboxPairingState.Paired) {
|
||||
if (state instanceof Paired) {
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user