mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Compare commits
36 Commits
lock-down-
...
beta-1.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51794424ce | ||
|
|
5db099bae6 | ||
|
|
a2faa3bd3b | ||
|
|
a3fb7b5680 | ||
|
|
264d110dbd | ||
|
|
839b871a45 | ||
|
|
2fb4825b8f | ||
|
|
3f9a66b1b6 | ||
|
|
d796916387 | ||
|
|
fe07b760ea | ||
|
|
e21e6267d7 | ||
|
|
d7afbdf690 | ||
|
|
c5d2661c1d | ||
|
|
b738bdd14e | ||
|
|
629cff20a3 | ||
|
|
6cfb70db95 | ||
|
|
737ecfb620 | ||
|
|
5a424b178e | ||
|
|
59f4e7c34a | ||
|
|
2480824d69 | ||
|
|
a6c2000d81 | ||
|
|
a38a3139d9 | ||
|
|
4c8adaa02b | ||
|
|
8a534b4503 | ||
|
|
e5b2275c82 | ||
|
|
5159593825 | ||
|
|
a546fecc01 | ||
|
|
3e7e37f5f6 | ||
|
|
d095ba0b15 | ||
|
|
7fab97d26c | ||
|
|
6fbc82ee27 | ||
|
|
885b03cfd7 | ||
|
|
f81bfcafeb | ||
|
|
6b61725c6a | ||
|
|
fb2b4209cf | ||
|
|
e4a66615a7 |
@@ -8,11 +8,15 @@ android {
|
|||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
buildToolsVersion '30.0.2'
|
buildToolsVersion '30.0.2'
|
||||||
|
|
||||||
|
packagingOptions {
|
||||||
|
doNotStrip '**/*.so'
|
||||||
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 10214
|
versionCode 10218
|
||||||
versionName "1.2.14"
|
versionName "1.2.18"
|
||||||
consumerProguardFiles 'proguard-rules.txt'
|
consumerProguardFiles 'proguard-rules.txt'
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ Bridge obfs4 192.95.36.142:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUV
|
|||||||
Bridge obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1
|
Bridge obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1
|
||||||
Bridge obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0
|
Bridge obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0
|
||||||
Bridge obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0
|
Bridge obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0
|
||||||
Bridge obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0
|
Bridge obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0
|
||||||
Bridge obfs4 193.11.166.194:27015 2D82C2E354D531A68469ADF7F878FA6060C6BACA cert=4TLQPJrTSaDffMK7Nbao6LC7G9OW/NHkUwIdjLSS3KYf0Nv4/nQiiI8dY2TcsQx01NniOg iat-mode=0
|
Bridge obfs4 193.11.166.194:27015 2D82C2E354D531A68469ADF7F878FA6060C6BACA cert=4TLQPJrTSaDffMK7Nbao6LC7G9OW/NHkUwIdjLSS3KYf0Nv4/nQiiI8dY2TcsQx01NniOg iat-mode=0
|
||||||
Bridge obfs4 193.11.166.194:27020 86AC7B8D430DAC4117E9F42C9EAED18133863AAF cert=0LDeJH4JzMDtkJJrFphJCiPqKx7loozKN7VNfuukMGfHO0Z8OGdzHVkhVAOfo1mUdv9cMg iat-mode=0
|
Bridge obfs4 193.11.166.194:27020 86AC7B8D430DAC4117E9F42C9EAED18133863AAF cert=0LDeJH4JzMDtkJJrFphJCiPqKx7loozKN7VNfuukMGfHO0Z8OGdzHVkhVAOfo1mUdv9cMg iat-mode=0
|
||||||
Bridge obfs4 193.11.166.194:27025 1AE2C08904527FEA90C4C4F8C1083EA59FBC6FAF cert=ItvYZzW5tn6v3G4UnQa6Qz04Npro6e81AP70YujmK/KXwDFPTs3aHXcHp4n8Vt6w/bv8cA iat-mode=0
|
Bridge obfs4 193.11.166.194:27025 1AE2C08904527FEA90C4C4F8C1083EA59FBC6FAF cert=ItvYZzW5tn6v3G4UnQa6Qz04Npro6e81AP70YujmK/KXwDFPTs3aHXcHp4n8Vt6w/bv8cA iat-mode=0
|
||||||
Bridge obfs4 209.148.46.65:443 74FAD13168806246602538555B5521A0383A1875 cert=ssH+9rP8dG2NLDN2XuFw63hIO/9MNNinLmxQDpVa+7kTOa9/m+tGWT1SmSYpQ9uTBGa6Hw iat-mode=0
|
Bridge obfs4 209.148.46.65:443 74FAD13168806246602538555B5521A0383A1875 cert=ssH+9rP8dG2NLDN2XuFw63hIO/9MNNinLmxQDpVa+7kTOa9/m+tGWT1SmSYpQ9uTBGa6Hw iat-mode=0
|
||||||
Bridge obfs4 146.57.248.225:22 10A6CD36A537FCE513A322361547444B393989F0 cert=K1gDtDAIcUfeLqbstggjIw2rtgIKqdIhUlHp82XRqNSq/mtAjp1BIC9vHKJ2FAEpGssTPw iat-mode=0
|
|
||||||
Bridge obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0
|
Bridge obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0
|
||||||
Bridge obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0
|
Bridge obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0
|
||||||
Bridge obfs4 78.46.188.239:37356 5A2D2F4158D0453E00C7C176978D3F41D69C45DB cert=3c0SwxpOisbohNxEc4tb875RVW8eOu1opRTVXJhafaKA/PNNtI7ElQIVOVZg1AdL5bxGCw iat-mode=0
|
Bridge obfs4 78.46.188.239:37356 5A2D2F4158D0453E00C7C176978D3F41D69C45DB cert=3c0SwxpOisbohNxEc4tb875RVW8eOu1opRTVXJhafaKA/PNNtI7ElQIVOVZg1AdL5bxGCw iat-mode=0
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ dependencies {
|
|||||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||||
implementation 'net.java.dev.jna:jna:4.5.2'
|
implementation 'net.java.dev.jna:jna:4.5.2'
|
||||||
implementation 'net.java.dev.jna:jna-platform:4.5.2'
|
implementation 'net.java.dev.jna:jna-platform:4.5.2'
|
||||||
tor 'org.briarproject:tor:0.3.5.13@zip'
|
tor 'org.briarproject:tor:0.3.5.13-1@zip'
|
||||||
tor 'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a@zip'
|
tor 'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a@zip'
|
||||||
|
|
||||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
|
annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
||||||
|
|
||||||
@@ -96,8 +97,15 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
String architecture = null;
|
String architecture = null;
|
||||||
if (isLinux()) {
|
if (isLinux()) {
|
||||||
String arch = System.getProperty("os.arch");
|
String arch = System.getProperty("os.arch");
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("System's os.arch is " + arch);
|
||||||
|
}
|
||||||
if (arch.equals("amd64")) {
|
if (arch.equals("amd64")) {
|
||||||
architecture = "linux-x86_64";
|
architecture = "linux-x86_64";
|
||||||
|
} else if (arch.equals("aarch64")) {
|
||||||
|
architecture = "linux-aarch64";
|
||||||
|
} else if (arch.equals("arm")) {
|
||||||
|
architecture = "linux-armhf";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (architecture == null) {
|
if (architecture == null) {
|
||||||
@@ -105,6 +113,10 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("The selected architecture for Tor is " + architecture);
|
||||||
|
}
|
||||||
|
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ dependencyVerification {
|
|||||||
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
||||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||||
'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a:obfs4proxy-0.0.12-dev-40245c4a.zip:172029e7058b3a83ac93ac4991a44bf76e16ce8d46f558f5836d57da3cb3a766',
|
'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a:obfs4proxy-0.0.12-dev-40245c4a.zip:172029e7058b3a83ac93ac4991a44bf76e16ce8d46f558f5836d57da3cb3a766',
|
||||||
'org.briarproject:tor:0.3.5.13:tor-0.3.5.13.zip:1c5f0b821ee2aadb0ea04aa96caab3ca0a08370cce8de81c2dfe04d172f8a2a0',
|
'org.briarproject:tor:0.3.5.13-1:tor-0.3.5.13-1.zip:ef35c16bf8dc1f4c75ed71d9f55e4514f383d124ec96b859aca647c990927c99',
|
||||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
'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.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.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||||
|
|||||||
@@ -19,11 +19,15 @@ android {
|
|||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
buildToolsVersion '30.0.2'
|
buildToolsVersion '30.0.2'
|
||||||
|
|
||||||
|
packagingOptions {
|
||||||
|
doNotStrip '**/*.so'
|
||||||
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 10214
|
versionCode 10218
|
||||||
versionName "1.2.14"
|
versionName "1.2.18"
|
||||||
applicationId "org.briarproject.briar.android"
|
applicationId "org.briarproject.briar.android"
|
||||||
|
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
@@ -95,6 +99,7 @@ dependencies {
|
|||||||
implementation project(path: ':bramble-core', configuration: 'default')
|
implementation project(path: ':bramble-core', configuration: 'default')
|
||||||
implementation project(':bramble-android')
|
implementation project(':bramble-android')
|
||||||
|
|
||||||
|
implementation 'androidx.fragment:fragment:1.3.0'
|
||||||
implementation 'androidx.preference:preference:1.1.1'
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
implementation 'androidx.exifinterface:exifinterface:1.3.1'
|
implementation 'androidx.exifinterface:exifinterface:1.3.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import javax.inject.Inject;
|
|||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
|
|
||||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||||
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
|
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
|
||||||
import static android.content.Intent.ACTION_SHUTDOWN;
|
import static android.content.Intent.ACTION_SHUTDOWN;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
||||||
@@ -46,6 +46,7 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
|||||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
import static android.os.Process.myPid;
|
||||||
import static androidx.core.app.NotificationCompat.VISIBILITY_SECRET;
|
import static androidx.core.app.NotificationCompat.VISIBILITY_SECRET;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
@@ -56,8 +57,10 @@ import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY;
|
|||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_CHANNEL_ID;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_CHANNEL_ID;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_NOTIFICATION_ID;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_NOTIFICATION_ID;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_CHANNEL_ID;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_CHANNEL_ID;
|
||||||
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_CHANNEL_OLD_ID;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_NOTIFICATION_ID;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_NOTIFICATION_ID;
|
||||||
import static org.briarproject.briar.api.android.LockManager.ACTION_LOCK;
|
import static org.briarproject.briar.api.android.LockManager.ACTION_LOCK;
|
||||||
|
import static org.briarproject.briar.api.android.LockManager.EXTRA_PID;
|
||||||
|
|
||||||
public class BriarService extends Service {
|
public class BriarService extends Service {
|
||||||
|
|
||||||
@@ -120,11 +123,17 @@ public class BriarService extends Service {
|
|||||||
if (SDK_INT >= 26) {
|
if (SDK_INT >= 26) {
|
||||||
NotificationManager nm = (NotificationManager)
|
NotificationManager nm = (NotificationManager)
|
||||||
requireNonNull(getSystemService(NOTIFICATION_SERVICE));
|
requireNonNull(getSystemService(NOTIFICATION_SERVICE));
|
||||||
|
// Delete the old notification channel, which had
|
||||||
|
// IMPORTANCE_NONE and showed a badge
|
||||||
|
nm.deleteNotificationChannel(ONGOING_CHANNEL_OLD_ID);
|
||||||
|
// Use IMPORTANCE_LOW so the system doesn't show its own
|
||||||
|
// notification on API 26-27
|
||||||
NotificationChannel ongoingChannel = new NotificationChannel(
|
NotificationChannel ongoingChannel = new NotificationChannel(
|
||||||
ONGOING_CHANNEL_ID,
|
ONGOING_CHANNEL_ID,
|
||||||
getString(R.string.ongoing_notification_title),
|
getString(R.string.ongoing_notification_title),
|
||||||
IMPORTANCE_NONE);
|
IMPORTANCE_LOW);
|
||||||
ongoingChannel.setLockscreenVisibility(VISIBILITY_SECRET);
|
ongoingChannel.setLockscreenVisibility(VISIBILITY_SECRET);
|
||||||
|
ongoingChannel.setShowBadge(false);
|
||||||
nm.createNotificationChannel(ongoingChannel);
|
nm.createNotificationChannel(ongoingChannel);
|
||||||
NotificationChannel failureChannel = new NotificationChannel(
|
NotificationChannel failureChannel = new NotificationChannel(
|
||||||
FAILURE_CHANNEL_ID,
|
FAILURE_CHANNEL_ID,
|
||||||
@@ -203,7 +212,12 @@ public class BriarService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
if (ACTION_LOCK.equals(intent.getAction())) {
|
if (ACTION_LOCK.equals(intent.getAction())) {
|
||||||
lockManager.setLocked(true);
|
int pid = intent.getIntExtra(EXTRA_PID, -1);
|
||||||
|
if (pid == myPid()) lockManager.setLocked(true);
|
||||||
|
else if (LOG.isLoggable(WARNING)) {
|
||||||
|
LOG.warning("Tried to lock process " + pid + " but this is " +
|
||||||
|
myPid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return START_NOT_STICKY; // Don't restart automatically if killed
|
return START_NOT_STICKY; // Don't restart automatically if killed
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ public class DozeFragment extends SetupFragment
|
|||||||
private DozeView dozeView;
|
private DozeView dozeView;
|
||||||
private HuaweiView huaweiView;
|
private HuaweiView huaweiView;
|
||||||
private Button next;
|
private Button next;
|
||||||
private ProgressBar progressBar;
|
|
||||||
private boolean secondAttempt = false;
|
private boolean secondAttempt = false;
|
||||||
|
|
||||||
public static DozeFragment newInstance() {
|
public static DozeFragment newInstance() {
|
||||||
@@ -58,11 +57,19 @@ public class DozeFragment extends SetupFragment
|
|||||||
huaweiView = v.findViewById(R.id.huaweiView);
|
huaweiView = v.findViewById(R.id.huaweiView);
|
||||||
huaweiView.setOnCheckedChangedListener(this);
|
huaweiView.setOnCheckedChangedListener(this);
|
||||||
next = v.findViewById(R.id.next);
|
next = v.findViewById(R.id.next);
|
||||||
progressBar = v.findViewById(R.id.progress);
|
ProgressBar progressBar = v.findViewById(R.id.progress);
|
||||||
|
|
||||||
dozeView.setOnButtonClickListener(this::askForDozeWhitelisting);
|
dozeView.setOnButtonClickListener(this::askForDozeWhitelisting);
|
||||||
next.setOnClickListener(this);
|
next.setOnClickListener(this);
|
||||||
|
|
||||||
|
viewModel.getIsCreatingAccount()
|
||||||
|
.observe(getViewLifecycleOwner(), isCreatingAccount -> {
|
||||||
|
if (isCreatingAccount) {
|
||||||
|
next.setVisibility(INVISIBLE);
|
||||||
|
progressBar.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,15 +111,6 @@ public class DozeFragment extends SetupFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
setNextClicked();
|
|
||||||
viewModel.dozeExceptionConfirmed();
|
viewModel.dozeExceptionConfirmed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
void setNextClicked() {
|
|
||||||
super.setNextClicked();
|
|
||||||
|
|
||||||
next.setVisibility(INVISIBLE);
|
|
||||||
progressBar.setVisibility(VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,10 @@ import androidx.lifecycle.LiveData;
|
|||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import static android.app.AlarmManager.ELAPSED_REALTIME;
|
import static android.app.AlarmManager.ELAPSED_REALTIME;
|
||||||
|
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
|
||||||
import static android.app.PendingIntent.getService;
|
import static android.app.PendingIntent.getService;
|
||||||
import static android.content.Context.ALARM_SERVICE;
|
import static android.content.Context.ALARM_SERVICE;
|
||||||
|
import static android.os.Process.myPid;
|
||||||
import static android.os.SystemClock.elapsedRealtime;
|
import static android.os.SystemClock.elapsedRealtime;
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
@@ -75,23 +77,25 @@ public class LockManagerImpl implements LockManager, Service, EventListener {
|
|||||||
LockManagerImpl(Application app, SettingsManager settingsManager,
|
LockManagerImpl(Application app, SettingsManager settingsManager,
|
||||||
AndroidNotificationManager notificationManager,
|
AndroidNotificationManager notificationManager,
|
||||||
@DatabaseExecutor Executor dbExecutor) {
|
@DatabaseExecutor Executor dbExecutor) {
|
||||||
this.appContext = app.getApplicationContext();
|
appContext = app.getApplicationContext();
|
||||||
this.settingsManager = settingsManager;
|
this.settingsManager = settingsManager;
|
||||||
this.notificationManager = notificationManager;
|
this.notificationManager = notificationManager;
|
||||||
this.dbExecutor = dbExecutor;
|
this.dbExecutor = dbExecutor;
|
||||||
this.alarmManager =
|
alarmManager =
|
||||||
(AlarmManager) appContext.getSystemService(ALARM_SERVICE);
|
(AlarmManager) appContext.getSystemService(ALARM_SERVICE);
|
||||||
Intent i =
|
Intent i =
|
||||||
new Intent(ACTION_LOCK, null, appContext, BriarService.class);
|
new Intent(ACTION_LOCK, null, appContext, BriarService.class);
|
||||||
this.lockIntent = getService(appContext, 0, i, 0);
|
i.putExtra(EXTRA_PID, myPid());
|
||||||
this.timeoutNever = Integer.valueOf(
|
// When not using FLAG_UPDATE_CURRENT, the intent might have no extras
|
||||||
|
lockIntent = getService(appContext, 0, i, FLAG_UPDATE_CURRENT);
|
||||||
|
timeoutNever = Integer.parseInt(
|
||||||
appContext.getString(R.string.pref_lock_timeout_value_never));
|
appContext.getString(R.string.pref_lock_timeout_value_never));
|
||||||
this.timeoutDefault = Integer.valueOf(
|
timeoutDefault = Integer.parseInt(
|
||||||
appContext.getString(R.string.pref_lock_timeout_value_default));
|
appContext.getString(R.string.pref_lock_timeout_value_default));
|
||||||
this.timeoutMinutes = timeoutNever;
|
timeoutMinutes = timeoutNever;
|
||||||
|
|
||||||
// setting this in the constructor makes #getValue() @NonNull
|
// setting this in the constructor makes #getValue() @NonNull
|
||||||
this.lockable.setValue(false);
|
lockable.setValue(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -148,7 +152,7 @@ public class LockManagerImpl implements LockManager, Service, EventListener {
|
|||||||
boolean oldValue = lockable.getValue();
|
boolean oldValue = lockable.getValue();
|
||||||
boolean newValue = hasScreenLock(appContext) && lockableSetting;
|
boolean newValue = hasScreenLock(appContext) && lockableSetting;
|
||||||
if (oldValue != newValue) {
|
if (oldValue != newValue) {
|
||||||
this.lockable.setValue(newValue);
|
lockable.setValue(newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ public class SetPasswordFragment extends SetupFragment {
|
|||||||
private TextInputEditText passwordConfirmation;
|
private TextInputEditText passwordConfirmation;
|
||||||
private StrengthMeter strengthMeter;
|
private StrengthMeter strengthMeter;
|
||||||
private Button nextButton;
|
private Button nextButton;
|
||||||
private ProgressBar progressBar;
|
|
||||||
|
|
||||||
public static SetPasswordFragment newInstance() {
|
public static SetPasswordFragment newInstance() {
|
||||||
return new SetPasswordFragment();
|
return new SetPasswordFragment();
|
||||||
@@ -64,7 +63,7 @@ public class SetPasswordFragment extends SetupFragment {
|
|||||||
v.findViewById(R.id.password_confirm_wrapper);
|
v.findViewById(R.id.password_confirm_wrapper);
|
||||||
passwordConfirmation = v.findViewById(R.id.password_confirm);
|
passwordConfirmation = v.findViewById(R.id.password_confirm);
|
||||||
nextButton = v.findViewById(R.id.next);
|
nextButton = v.findViewById(R.id.next);
|
||||||
progressBar = v.findViewById(R.id.progress);
|
ProgressBar progressBar = v.findViewById(R.id.progress);
|
||||||
|
|
||||||
passwordEntry.addTextChangedListener(this);
|
passwordEntry.addTextChangedListener(this);
|
||||||
passwordConfirmation.addTextChangedListener(this);
|
passwordConfirmation.addTextChangedListener(this);
|
||||||
@@ -75,6 +74,17 @@ public class SetPasswordFragment extends SetupFragment {
|
|||||||
passwordConfirmation.setImeOptions(IME_ACTION_DONE);
|
passwordConfirmation.setImeOptions(IME_ACTION_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.getIsCreatingAccount()
|
||||||
|
.observe(getViewLifecycleOwner(), isCreatingAccount -> {
|
||||||
|
if (isCreatingAccount) {
|
||||||
|
nextButton.setVisibility(INVISIBLE);
|
||||||
|
progressBar.setVisibility(VISIBLE);
|
||||||
|
// this also avoids the keyboard popping up
|
||||||
|
passwordEntry.setFocusable(false);
|
||||||
|
passwordConfirmation.setFocusable(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,20 +126,6 @@ public class SetPasswordFragment extends SetupFragment {
|
|||||||
IBinder token = passwordEntry.getWindowToken();
|
IBinder token = passwordEntry.getWindowToken();
|
||||||
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
|
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||||
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
|
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
|
||||||
|
|
||||||
setNextClicked();
|
|
||||||
viewModel.setPassword(passwordEntry.getText().toString());
|
viewModel.setPassword(passwordEntry.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
void setNextClicked() {
|
|
||||||
super.setNextClicked();
|
|
||||||
|
|
||||||
passwordEntry.setFocusable(false);
|
|
||||||
passwordConfirmation.setFocusable(false);
|
|
||||||
if (!viewModel.needToShowDozeFragment()) {
|
|
||||||
nextButton.setVisibility(INVISIBLE);
|
|
||||||
progressBar.setVisibility(VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import android.view.KeyEvent;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.TextView.OnEditorActionListener;
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
@@ -19,8 +18,6 @@ import org.briarproject.briar.android.fragment.BaseFragment;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
@@ -35,7 +32,6 @@ abstract class SetupFragment extends BaseFragment implements TextWatcher,
|
|||||||
OnEditorActionListener, OnClickListener {
|
OnEditorActionListener, OnClickListener {
|
||||||
|
|
||||||
private final static String STATE_KEY_CLICKED = "setupFragmentClicked";
|
private final static String STATE_KEY_CLICKED = "setupFragmentClicked";
|
||||||
private boolean clicked = false;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
@@ -48,27 +44,6 @@ abstract class SetupFragment extends BaseFragment implements TextWatcher,
|
|||||||
.get(SetupViewModel.class);
|
.get(SetupViewModel.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
clicked = savedInstanceState.getBoolean(STATE_KEY_CLICKED);
|
|
||||||
}
|
|
||||||
if (clicked) {
|
|
||||||
setNextClicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putBoolean(STATE_KEY_CLICKED, clicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
@CallSuper
|
|
||||||
void setNextClicked() {
|
|
||||||
this.clicked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
inflater.inflate(R.menu.help_action, menu);
|
inflater.inflate(R.menu.help_action, menu);
|
||||||
@@ -114,5 +89,4 @@ abstract class SetupFragment extends BaseFragment implements TextWatcher,
|
|||||||
public void afterTextChanged(Editable editable) {
|
public void afterTextChanged(Editable editable) {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.briar.android.account.SetupViewModel.State.AUTHOR_NAME;
|
import static org.briarproject.briar.android.account.SetupViewModel.State.AUTHOR_NAME;
|
||||||
@@ -36,6 +38,8 @@ class SetupViewModel extends AndroidViewModel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private String authorName, password;
|
private String authorName, password;
|
||||||
private final MutableLiveEvent<State> state = new MutableLiveEvent<>();
|
private final MutableLiveEvent<State> state = new MutableLiveEvent<>();
|
||||||
|
private final MutableLiveData<Boolean> isCreatingAccount =
|
||||||
|
new MutableLiveData<>(false);
|
||||||
|
|
||||||
private final AccountManager accountManager;
|
private final AccountManager accountManager;
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
@@ -67,6 +71,10 @@ class SetupViewModel extends AndroidViewModel {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LiveData<Boolean> getIsCreatingAccount() {
|
||||||
|
return isCreatingAccount;
|
||||||
|
}
|
||||||
|
|
||||||
void setAuthorName(String authorName) {
|
void setAuthorName(String authorName) {
|
||||||
this.authorName = authorName;
|
this.authorName = authorName;
|
||||||
state.setEvent(SET_PASSWORD);
|
state.setEvent(SET_PASSWORD);
|
||||||
@@ -97,6 +105,7 @@ class SetupViewModel extends AndroidViewModel {
|
|||||||
private void createAccount() {
|
private void createAccount() {
|
||||||
if (authorName == null) throw new IllegalStateException();
|
if (authorName == null) throw new IllegalStateException();
|
||||||
if (password == null) throw new IllegalStateException();
|
if (password == null) throw new IllegalStateException();
|
||||||
|
isCreatingAccount.setValue(true);
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
if (accountManager.createAccount(authorName, password)) {
|
if (accountManager.createAccount(authorName, password)) {
|
||||||
LOG.info("Created account");
|
LOG.info("Created account");
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class UnlockActivity extends BaseActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode,
|
protected void onActivityResult(int requestCode, int resultCode,
|
||||||
Intent data) {
|
@Nullable Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
if (requestCode == REQUEST_KEYGUARD_UNLOCK) {
|
if (requestCode == REQUEST_KEYGUARD_UNLOCK) {
|
||||||
if (resultCode == RESULT_OK) unlock();
|
if (resultCode == RESULT_OK) unlock();
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import io.github.kobakei.materialfabspeeddial.FabSpeedDial;
|
|||||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDial.OnMenuItemClickListener;
|
import io.github.kobakei.materialfabspeeddial.FabSpeedDial.OnMenuItemClickListener;
|
||||||
|
|
||||||
import static com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_INDEFINITE;
|
import static com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_INDEFINITE;
|
||||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
|
||||||
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
|
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -102,7 +101,8 @@ public class ContactListFragment extends BaseFragment
|
|||||||
.observe(getViewLifecycleOwner(), result -> {
|
.observe(getViewLifecycleOwner(), result -> {
|
||||||
result.onError(this::handleException).onSuccess(items -> {
|
result.onError(this::handleException).onSuccess(items -> {
|
||||||
adapter.submitList(items);
|
adapter.submitList(items);
|
||||||
if (requireNonNull(items).size() == 0) list.showData();
|
// TODO remove when BriarRecyclerView was adapted
|
||||||
|
list.showData();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
viewModel.getHasPendingContacts()
|
viewModel.getHasPendingContacts()
|
||||||
|
|||||||
@@ -24,10 +24,7 @@ import org.briarproject.briar.android.attachment.AttachmentItem;
|
|||||||
import org.briarproject.briar.android.util.BriarSnackbarBuilder;
|
import org.briarproject.briar.android.util.BriarSnackbarBuilder;
|
||||||
import org.briarproject.briar.android.view.PullDownLayout;
|
import org.briarproject.briar.android.view.PullDownLayout;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -293,13 +290,10 @@ public class ImageActivity extends BriarActivity
|
|||||||
|
|
||||||
@RequiresApi(api = 19)
|
@RequiresApi(api = 19)
|
||||||
private Intent getCreationIntent() {
|
private Intent getCreationIntent() {
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",
|
|
||||||
Locale.getDefault());
|
|
||||||
String fileName = sdf.format(new Date());
|
|
||||||
Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
|
Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
|
||||||
intent.addCategory(CATEGORY_OPENABLE);
|
intent.addCategory(CATEGORY_OPENABLE);
|
||||||
intent.setType(getVisibleAttachment().getMimeType());
|
intent.setType(getVisibleAttachment().getMimeType());
|
||||||
intent.putExtra(EXTRA_TITLE, fileName);
|
intent.putExtra(EXTRA_TITLE, viewModel.getFileName());
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -225,8 +225,8 @@ public class ImageViewModel extends DbViewModel implements EventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFileName() {
|
String getFileName() {
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd",
|
||||||
Locale.getDefault());
|
Locale.getDefault());
|
||||||
return sdf.format(new Date());
|
return sdf.format(new Date());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,8 @@ import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
|||||||
import org.briarproject.briar.android.DestroyableContext;
|
import org.briarproject.briar.android.DestroyableContext;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
@@ -47,13 +46,11 @@ public abstract class BaseFragment extends Fragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
if (item.getItemId() == android.R.id.home) {
|
||||||
case android.R.id.home:
|
requireActivity().onBackPressed();
|
||||||
listener.onBackPressed();
|
return true;
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@@ -79,6 +76,7 @@ public abstract class BaseFragment extends Fragment
|
|||||||
void handleException(Exception e);
|
void handleException(Exception e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@CallSuper
|
@CallSuper
|
||||||
@Override
|
@Override
|
||||||
public void runOnUiThreadUnlessDestroyed(Runnable r) {
|
public void runOnUiThreadUnlessDestroyed(Runnable r) {
|
||||||
|
|||||||
@@ -411,6 +411,8 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
@UiThread
|
@UiThread
|
||||||
public void onRequestPermissionsResult(int requestCode,
|
public void onRequestPermissionsResult(int requestCode,
|
||||||
String[] permissions, int[] grantResults) {
|
String[] permissions, int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions,
|
||||||
|
grantResults);
|
||||||
if (requestCode != REQUEST_PERMISSION_CAMERA_LOCATION)
|
if (requestCode != REQUEST_PERMISSION_CAMERA_LOCATION)
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
if (gotPermission(CAMERA, permissions, grantResults)) {
|
if (gotPermission(CAMERA, permissions, grantResults)) {
|
||||||
|
|||||||
@@ -49,14 +49,12 @@ import androidx.annotation.DrawableRes;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.lifecycle.ViewModelProviders;
|
import androidx.lifecycle.ViewModelProviders;
|
||||||
@@ -67,9 +65,7 @@ import static android.view.View.GONE;
|
|||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static androidx.core.view.GravityCompat.START;
|
import static androidx.core.view.GravityCompat.START;
|
||||||
import static androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED;
|
import static androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED;
|
||||||
import static androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
|
|
||||||
import static androidx.lifecycle.Lifecycle.State.STARTED;
|
import static androidx.lifecycle.Lifecycle.State.STARTED;
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
|
||||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||||
@@ -146,7 +142,7 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
if (ask) showDozeDialog(getString(R.string.setup_doze_intro));
|
if (ask) showDozeDialog(getString(R.string.setup_doze_intro));
|
||||||
});
|
});
|
||||||
|
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = setUpCustomToolbar(false);
|
||||||
drawerLayout = findViewById(R.id.drawer_layout);
|
drawerLayout = findViewById(R.id.drawer_layout);
|
||||||
navigation = findViewById(R.id.navigation);
|
navigation = findViewById(R.id.navigation);
|
||||||
GridView transportsView = findViewById(R.id.transportsView);
|
GridView transportsView = findViewById(R.id.transportsView);
|
||||||
@@ -156,11 +152,6 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
startActivity(new Intent(this, TransportsActivity.class));
|
startActivity(new Intent(this, TransportsActivity.class));
|
||||||
});
|
});
|
||||||
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
ActionBar actionBar = requireNonNull(getSupportActionBar());
|
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
||||||
actionBar.setHomeButtonEnabled(true);
|
|
||||||
|
|
||||||
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
|
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
|
||||||
R.string.nav_drawer_open_description,
|
R.string.nav_drawer_open_description,
|
||||||
R.string.nav_drawer_close_description) {
|
R.string.nav_drawer_close_description) {
|
||||||
@@ -184,9 +175,6 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
|
|
||||||
if (lifecycleManager.getLifecycleState().isAfter(RUNNING)) {
|
if (lifecycleManager.getLifecycleState().isAfter(RUNNING)) {
|
||||||
showSignOutFragment();
|
showSignOutFragment();
|
||||||
} else if (state == null) {
|
|
||||||
startFragment(ContactListFragment.newInstance(),
|
|
||||||
R.id.nav_btn_contacts);
|
|
||||||
}
|
}
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
// do not call this again when there's existing state
|
// do not call this again when there's existing state
|
||||||
@@ -276,7 +264,6 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
drawerLayout.closeDrawer(START);
|
drawerLayout.closeDrawer(START);
|
||||||
clearBackStack();
|
|
||||||
if (item.getItemId() == R.id.nav_btn_lock) {
|
if (item.getItemId() == R.id.nav_btn_lock) {
|
||||||
lockManager.setLocked(true);
|
lockManager.setLocked(true);
|
||||||
ActivityCompat.finishAfterTransition(this);
|
ActivityCompat.finishAfterTransition(this);
|
||||||
@@ -296,8 +283,8 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
FragmentManager fm = getSupportFragmentManager();
|
FragmentManager fm = getSupportFragmentManager();
|
||||||
if (fm.findFragmentByTag(SignOutFragment.TAG) != null) {
|
if (fm.findFragmentByTag(SignOutFragment.TAG) != null) {
|
||||||
finish();
|
finish();
|
||||||
} else if (fm.getBackStackEntryCount() == 0
|
} else if (fm.getBackStackEntryCount() == 0 &&
|
||||||
&& fm.findFragmentByTag(ContactListFragment.TAG) == null) {
|
fm.findFragmentByTag(ContactListFragment.TAG) == null) {
|
||||||
// don't start fragments in the wrong part of lifecycle (#1904)
|
// don't start fragments in the wrong part of lifecycle (#1904)
|
||||||
if (!getLifecycle().getCurrentState().isAtLeast(STARTED)) {
|
if (!getLifecycle().getCurrentState().isAtLeast(STARTED)) {
|
||||||
LOG.warning("Tried to start contacts fragment in state " +
|
LOG.warning("Tried to start contacts fragment in state " +
|
||||||
@@ -346,30 +333,12 @@ public class NavDrawerActivity extends BriarActivity implements
|
|||||||
startFragment(fragment);
|
startFragment(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startFragment(BaseFragment fragment) {
|
private void startFragment(BaseFragment f) {
|
||||||
if (getSupportFragmentManager().getBackStackEntryCount() == 0)
|
getSupportFragmentManager().beginTransaction()
|
||||||
startFragment(fragment, false);
|
.setCustomAnimations(R.anim.fade_in, R.anim.fade_out,
|
||||||
else startFragment(fragment, true);
|
R.anim.fade_in, R.anim.fade_out)
|
||||||
}
|
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||||
|
.commit();
|
||||||
private void startFragment(BaseFragment fragment,
|
|
||||||
boolean isAddedToBackStack) {
|
|
||||||
FragmentTransaction trans =
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
|
||||||
.setCustomAnimations(R.anim.fade_in,
|
|
||||||
R.anim.fade_out, R.anim.fade_in,
|
|
||||||
R.anim.fade_out)
|
|
||||||
.replace(R.id.fragmentContainer, fragment,
|
|
||||||
fragment.getUniqueTag());
|
|
||||||
if (isAddedToBackStack) {
|
|
||||||
trans.addToBackStack(fragment.getUniqueTag());
|
|
||||||
}
|
|
||||||
trans.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearBackStack() {
|
|
||||||
getSupportFragmentManager().popBackStackImmediate(null,
|
|
||||||
POP_BACK_STACK_INCLUSIVE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -9,10 +9,13 @@ import android.view.View;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.BaseActivity;
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
|
import org.briarproject.briar.android.conversation.glide.GlideApp;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -32,7 +35,7 @@ public class ConfirmAvatarDialogFragment extends DialogFragment {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
private SettingsViewModel settingsViewModel;
|
private SettingsViewModel viewModel;
|
||||||
|
|
||||||
private static final String ARG_URI = "uri";
|
private static final String ARG_URI = "uri";
|
||||||
private Uri uri;
|
private Uri uri;
|
||||||
@@ -51,6 +54,9 @@ public class ConfirmAvatarDialogFragment extends DialogFragment {
|
|||||||
public void onAttach(Context ctx) {
|
public void onAttach(Context ctx) {
|
||||||
super.onAttach(ctx);
|
super.onAttach(ctx);
|
||||||
((BaseActivity) requireActivity()).getActivityComponent().inject(this);
|
((BaseActivity) requireActivity()).getActivityComponent().inject(this);
|
||||||
|
ViewModelProvider provider =
|
||||||
|
new ViewModelProvider(requireActivity(), viewModelFactory);
|
||||||
|
viewModel = provider.get(SettingsViewModel.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -60,32 +66,34 @@ public class ConfirmAvatarDialogFragment extends DialogFragment {
|
|||||||
uri = Uri.parse(argUri);
|
uri = Uri.parse(argUri);
|
||||||
|
|
||||||
FragmentActivity activity = requireActivity();
|
FragmentActivity activity = requireActivity();
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(activity);
|
||||||
ViewModelProvider provider =
|
|
||||||
new ViewModelProvider(activity, viewModelFactory);
|
|
||||||
settingsViewModel = provider.get(SettingsViewModel.class);
|
|
||||||
|
|
||||||
AlertDialog.Builder builder =
|
|
||||||
new AlertDialog.Builder(activity, R.style.BriarDialogTheme);
|
|
||||||
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
|
||||||
final View view =
|
final View view =
|
||||||
inflater.inflate(R.layout.fragment_confirm_avatar_dialog, null);
|
inflater.inflate(R.layout.fragment_confirm_avatar_dialog, null);
|
||||||
builder.setView(view);
|
|
||||||
|
|
||||||
builder.setTitle(R.string.dialog_confirm_profile_picture_title);
|
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
|
||||||
builder.setPositiveButton(R.string.change,
|
|
||||||
(dialog, id) -> settingsViewModel.setAvatar(uri));
|
|
||||||
|
|
||||||
ImageView imageView = view.findViewById(R.id.image);
|
ImageView imageView = view.findViewById(R.id.image);
|
||||||
imageView.setImageURI(uri);
|
|
||||||
|
|
||||||
TextView textViewUserName = view.findViewById(R.id.username);
|
TextView textViewUserName = view.findViewById(R.id.username);
|
||||||
settingsViewModel.getOwnIdentityInfo().observe(activity,
|
|
||||||
us -> textViewUserName.setText(us.getLocalAuthor().getName()));
|
|
||||||
|
|
||||||
return builder.create();
|
GlideApp.with(imageView)
|
||||||
|
.load(uri)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||||
|
.error(R.drawable.ic_image_broken)
|
||||||
|
.into(imageView)
|
||||||
|
.waitForLayout();
|
||||||
|
|
||||||
|
// we can't use getViewLifecycleOwner() here
|
||||||
|
// as this fragment technically doesn't have a view
|
||||||
|
viewModel.getOwnIdentityInfo().observe(activity, us ->
|
||||||
|
textViewUserName.setText(us.getLocalAuthor().getName())
|
||||||
|
);
|
||||||
|
|
||||||
|
int theme = R.style.BriarDialogTheme;
|
||||||
|
return new AlertDialog.Builder(activity, theme)
|
||||||
|
.setView(view)
|
||||||
|
.setTitle(R.string.dialog_confirm_profile_picture_title)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.change, (d, id) ->
|
||||||
|
viewModel.setAvatar(uri)
|
||||||
|
)
|
||||||
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class SettingsViewModel extends AndroidViewModel {
|
|||||||
return ownIdentityInfo;
|
return ownIdentityInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveEvent<Boolean> getSetAvatarFailed() {
|
LiveEvent<Boolean> getSetAvatarFailed() {
|
||||||
return setAvatarFailed;
|
return setAvatarFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,10 @@ public abstract class ThreadListViewModel<I extends ThreadItem>
|
|||||||
*/
|
*/
|
||||||
@UiThread
|
@UiThread
|
||||||
protected void addItem(I item, boolean scrollToItem) {
|
protected void addItem(I item, boolean scrollToItem) {
|
||||||
|
// If items haven't loaded, we need to wait until they have.
|
||||||
|
// Since this was a R/W DB transaction, the load will pick up this item.
|
||||||
|
if (items.getValue() == null) return;
|
||||||
|
|
||||||
messageTree.add(item);
|
messageTree.add(item);
|
||||||
if (scrollToItem) this.scrollToItem.set(item.getId());
|
if (scrollToItem) this.scrollToItem.set(item.getId());
|
||||||
items.setValue(new LiveResult<>(messageTree.depthFirstOrder()));
|
items.setValue(new LiveResult<>(messageTree.depthFirstOrder()));
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ public interface AndroidNotificationManager {
|
|||||||
String BLOG_CHANNEL_ID = "blogs";
|
String BLOG_CHANNEL_ID = "blogs";
|
||||||
// Channels are sorted by channel ID in the Settings app, so use IDs
|
// Channels are sorted by channel ID in the Settings app, so use IDs
|
||||||
// that will sort below the main channels such as contacts
|
// that will sort below the main channels such as contacts
|
||||||
String ONGOING_CHANNEL_ID = "zForegroundService";
|
String ONGOING_CHANNEL_OLD_ID = "zForegroundService";
|
||||||
|
String ONGOING_CHANNEL_ID = "zForegroundService2";
|
||||||
String FAILURE_CHANNEL_ID = "zStartupFailure";
|
String FAILURE_CHANNEL_ID = "zStartupFailure";
|
||||||
String REMINDER_CHANNEL_ID = "zSignInReminder";
|
String REMINDER_CHANNEL_ID = "zSignInReminder";
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import androidx.lifecycle.LiveData;
|
|||||||
public interface LockManager {
|
public interface LockManager {
|
||||||
|
|
||||||
String ACTION_LOCK = "lock";
|
String ACTION_LOCK = "lock";
|
||||||
|
String EXTRA_PID = "PID";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the inactivity timer when the user interacts with the app.
|
* Stops the inactivity timer when the user interacts with the app.
|
||||||
|
|||||||
@@ -52,16 +52,17 @@
|
|||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:contentDescription="@string/close"
|
android:contentDescription="@string/close"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
app:srcCompat="@drawable/ic_close"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_close"
|
||||||
app:tint="@color/briar_text_tertiary_inverse" />
|
app:tint="@color/briar_text_tertiary_inverse" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/fragmentContainer"
|
android:id="@+id/fragmentContainer"
|
||||||
|
android:name="org.briarproject.briar.android.contact.ContactListFragment"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
|||||||
@@ -5,27 +5,28 @@
|
|||||||
<group android:checkableBehavior="single">
|
<group android:checkableBehavior="single">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_btn_contacts"
|
android:id="@+id/nav_btn_contacts"
|
||||||
|
android:checked="true"
|
||||||
android:icon="@drawable/ic_contacts"
|
android:icon="@drawable/ic_contacts"
|
||||||
android:title="@string/contact_list_button"/>
|
android:title="@string/contact_list_button" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_btn_groups"
|
android:id="@+id/nav_btn_groups"
|
||||||
android:icon="@drawable/ic_group"
|
android:icon="@drawable/ic_group"
|
||||||
android:title="@string/groups_button"/>
|
android:title="@string/groups_button" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_btn_forums"
|
android:id="@+id/nav_btn_forums"
|
||||||
android:icon="@drawable/ic_forums_black_24dp"
|
android:icon="@drawable/ic_forums_black_24dp"
|
||||||
android:title="@string/forums_button"/>
|
android:title="@string/forums_button" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_btn_blogs"
|
android:id="@+id/nav_btn_blogs"
|
||||||
android:icon="@drawable/blogs"
|
android:icon="@drawable/blogs"
|
||||||
android:title="@string/blogs_button"/>
|
android:title="@string/blogs_button" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group android:checkableBehavior="single">
|
<group android:checkableBehavior="single">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_btn_settings"
|
android:id="@+id/nav_btn_settings"
|
||||||
android:icon="@drawable/ic_settings_black"
|
android:icon="@drawable/ic_settings_black"
|
||||||
android:title="@string/settings_button"/>
|
android:title="@string/settings_button" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_btn_lock"
|
android:id="@+id/nav_btn_lock"
|
||||||
android:icon="@drawable/startup_lock"
|
android:icon="@drawable/startup_lock"
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/nav_btn_signout"
|
android:id="@+id/nav_btn_signout"
|
||||||
android:icon="@drawable/ic_signout"
|
android:icon="@drawable/ic_signout"
|
||||||
android:title="@string/sign_out_button"/>
|
android:title="@string/sign_out_button" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
@@ -67,8 +67,11 @@
|
|||||||
<string name="lock_button">قفل کردن برنامه</string>
|
<string name="lock_button">قفل کردن برنامه</string>
|
||||||
<string name="settings_button">تنظیمات</string>
|
<string name="settings_button">تنظیمات</string>
|
||||||
<string name="sign_out_button">خروج</string>
|
<string name="sign_out_button">خروج</string>
|
||||||
|
<string name="transports_onboarding_text">برای کنترل چگونگی اتصال Briar (برایر) به مخاطبین خود، اینجا را لمس کنید.</string>
|
||||||
<!--Transports: Tor-->
|
<!--Transports: Tor-->
|
||||||
<string name="transport_tor">اینترنت</string>
|
<string name="transport_tor">اینترنت</string>
|
||||||
|
<string name="tor_device_status_online_wifi">تلفن شما از طریق Wi-Fi به اینترنت دسترسی دارد.</string>
|
||||||
|
<string name="tor_device_status_online_mobile">تلفن شما از طریق دیتا سیمکارت به اینترنت دسترسی دارد.</string>
|
||||||
<string name="tor_device_status_offline">تلفن شما دارای دسترسی اینترنتی نیست</string>
|
<string name="tor_device_status_offline">تلفن شما دارای دسترسی اینترنتی نیست</string>
|
||||||
<string name="tor_plugin_status_enabling">Briar در حال اتصال به اینترنت می باشد</string>
|
<string name="tor_plugin_status_enabling">Briar در حال اتصال به اینترنت می باشد</string>
|
||||||
<string name="tor_plugin_status_active">Briar به اینترنت متصل شد</string>
|
<string name="tor_plugin_status_active">Briar به اینترنت متصل شد</string>
|
||||||
@@ -462,6 +465,10 @@
|
|||||||
برای وارد کردن خوراک روی آیکون + ضربه بزنید</string>
|
برای وارد کردن خوراک روی آیکون + ضربه بزنید</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">مشکلی با بارگذاری فیدهای شما وجود داشت. لطفا بعدا امتحان کنید.</string>
|
<string name="blogs_rss_feeds_manage_error">مشکلی با بارگذاری فیدهای شما وجود داشت. لطفا بعدا امتحان کنید.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">برای تغییر تصویر نمایه خود اینجا را لمس کنید.</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">تغییر تصویر نمایه</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">تنها مخاطبین شما میتوانند تصویر نمایه شما را مشاهده کنند.</string>
|
||||||
|
<string name="change_profile_picture_failed_message">تاسفیم اما هنگام بروزرسانی تصویر نمایه شما مشکلی رخ داد.</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">زبان و منطقه</string>
|
<string name="pref_language_title">زبان و منطقه</string>
|
||||||
<string name="pref_language_changed">این تنظیمات زمانی که Briar (برایر) را ری استارت کنید تاثیر خود را می گذارند. لطفا خارج شوید و Briar (برایر) را دوباره راه اندازی کنید.</string>
|
<string name="pref_language_changed">این تنظیمات زمانی که Briar (برایر) را ری استارت کنید تاثیر خود را می گذارند. لطفا خارج شوید و Briar (برایر) را دوباره راه اندازی کنید.</string>
|
||||||
@@ -571,17 +578,20 @@
|
|||||||
<string name="include_debug_report_feedback">قرار دادن داده های ناشناس درباره این دستگاه</string>
|
<string name="include_debug_report_feedback">قرار دادن داده های ناشناس درباره این دستگاه</string>
|
||||||
<string name="dev_report_basic_info">اطلاعات پایه</string>
|
<string name="dev_report_basic_info">اطلاعات پایه</string>
|
||||||
<string name="dev_report_device_info">اطلاعات دستگاه</string>
|
<string name="dev_report_device_info">اطلاعات دستگاه</string>
|
||||||
|
<string name="dev_report_stacktrace">Stacktrace</string>
|
||||||
<string name="dev_report_time_info">اطلاعات زمانی</string>
|
<string name="dev_report_time_info">اطلاعات زمانی</string>
|
||||||
<string name="dev_report_memory">حافظه</string>
|
<string name="dev_report_memory">حافظه</string>
|
||||||
<string name="dev_report_storage">حافظه</string>
|
<string name="dev_report_storage">حافظه</string>
|
||||||
<string name="dev_report_connectivity">اتصال</string>
|
<string name="dev_report_connectivity">اتصال</string>
|
||||||
<string name="dev_report_build_config">پیکربندی ساخت</string>
|
<string name="dev_report_build_config">پیکربندی ساخت</string>
|
||||||
|
<string name="dev_report_logcat">لاگ برنامه</string>
|
||||||
<string name="dev_report_device_features">ویژگیهای دستگاه</string>
|
<string name="dev_report_device_features">ویژگیهای دستگاه</string>
|
||||||
<string name="send_report">ارسال گزارش</string>
|
<string name="send_report">ارسال گزارش</string>
|
||||||
<string name="close">بستن</string>
|
<string name="close">بستن</string>
|
||||||
<string name="dev_report_sending">در حال فرستادن نظر...</string>
|
<string name="dev_report_sending">در حال فرستادن نظر...</string>
|
||||||
<string name="dev_report_sent">بازخورد ارسال شد</string>
|
<string name="dev_report_sent">بازخورد ارسال شد</string>
|
||||||
<string name="dev_report_saved">گزارش ذخیره شد. دفعه بعدی که وارد Briar (برایر) شدید فرستاده خواهد شد.</string>
|
<string name="dev_report_saved">گزارش ذخیره شد. دفعه بعدی که وارد Briar (برایر) شدید فرستاده خواهد شد.</string>
|
||||||
|
<string name="dev_report_error">خطا در ارسال گزارش</string>
|
||||||
<!--Sign Out-->
|
<!--Sign Out-->
|
||||||
<string name="progress_title_logout">خروج از Briar (برایر)...</string>
|
<string name="progress_title_logout">خروج از Briar (برایر)...</string>
|
||||||
<!--Screen Filters & Tapjacking-->
|
<!--Screen Filters & Tapjacking-->
|
||||||
@@ -591,7 +601,9 @@
|
|||||||
این برنامه ها ممکن است روی Briar (برایر) قرار گرفته باشند:
|
این برنامه ها ممکن است روی Briar (برایر) قرار گرفته باشند:
|
||||||
|
|
||||||
%1$s</string>
|
%1$s</string>
|
||||||
|
<string name="screen_filter_body_api_30">برنامه دیگری بر روی برنامه Briar (برایر) قرار دارد. برای محافظت از امنیت شما، Briar (برایر) هنگامی که برنامه دیگری روی آن باز است، به لمس پاسخ نخواهد داد. \n\nبرای یافتن برنامه مذکور، برنامههای زیر را بررسی کنید.</string>
|
||||||
<string name="screen_filter_allow">به این برنامه ها اجازه بده تا روی Briar (برایر) قرار بگیرند</string>
|
<string name="screen_filter_allow">به این برنامه ها اجازه بده تا روی Briar (برایر) قرار بگیرند</string>
|
||||||
|
<string name="screen_filter_review_apps">بررسی برنامهها</string>
|
||||||
<!--Permission Requests-->
|
<!--Permission Requests-->
|
||||||
<string name="permission_camera_title">دسترسی به دوربین</string>
|
<string name="permission_camera_title">دسترسی به دوربین</string>
|
||||||
<string name="permission_camera_request_body">برای اسکن کردن کد کیوآر دسترسی به دوربین لازم است.</string>
|
<string name="permission_camera_request_body">برای اسکن کردن کد کیوآر دسترسی به دوربین لازم است.</string>
|
||||||
@@ -608,6 +620,7 @@ Briar (برایر) موقعیت شما را ذخیره نمیکند و آن
|
|||||||
<string name="permission_camera_denied_body">شما دسترسی به دوربین را رد کرده اید، اما افزودن مخاطب نیاز به دوربین دارد.
|
<string name="permission_camera_denied_body">شما دسترسی به دوربین را رد کرده اید، اما افزودن مخاطب نیاز به دوربین دارد.
|
||||||
|
|
||||||
لطفا اجازه دسترسی را بدهید.</string>
|
لطفا اجازه دسترسی را بدهید.</string>
|
||||||
|
<string name="permission_location_denied_body">شما دسترسی به موقعیت خود را ندادهاید اما Briar (برایر) برای یافتن دستگاههای بلوتوث نیاز به این دسترسی دارد.\n\nلطفا این دسترسی را فراهم کنید.</string>
|
||||||
<string name="qr_code">کد کیوآر</string>
|
<string name="qr_code">کد کیوآر</string>
|
||||||
<string name="show_qr_code_fullscreen">نمایش کد کیوآر به صورت فول اسکرین</string>
|
<string name="show_qr_code_fullscreen">نمایش کد کیوآر به صورت فول اسکرین</string>
|
||||||
<!--App Locking-->
|
<!--App Locking-->
|
||||||
@@ -618,6 +631,7 @@ Briar (برایر) موقعیت شما را ذخیره نمیکند و آن
|
|||||||
<string name="lock_is_locked">Briar (برایر) قفل می باشد</string>
|
<string name="lock_is_locked">Briar (برایر) قفل می باشد</string>
|
||||||
<string name="lock_tap_to_unlock">برای آنلاک کردن کلیک کنید</string>
|
<string name="lock_tap_to_unlock">برای آنلاک کردن کلیک کنید</string>
|
||||||
<!--Connections Screen-->
|
<!--Connections Screen-->
|
||||||
|
<string name="transports_help_text">Briar (برایر) میتواند از طریق اینترنت، Wi-Fi و یا بلوتوث به مخاطبین شما متصل گردد.\n\nارتباط با اینترنت از طریق شبکهی تور صورت میپذیرد.\n\nاگر دسترسی به مخاطب شما از روشهای مختلفی ممکن باشد، Briar (برایر) به صورت موازی از آنها استفاده خواهد کرد.</string>
|
||||||
<!--Screenshots-->
|
<!--Screenshots-->
|
||||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||||
<string name="screenshot_alice">آلیس</string>
|
<string name="screenshot_alice">آلیس</string>
|
||||||
|
|||||||
@@ -425,6 +425,10 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">Sen fontes RSS que mostrar\n\nToque na icona + para importar unha fonte</string>
|
<string name="blogs_rss_feeds_manage_empty_state">Sen fontes RSS que mostrar\n\nToque na icona + para importar unha fonte</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">Aconteceu un problema ao cargar as súas fontes. Por favor, inténteo máis tarde.</string>
|
<string name="blogs_rss_feeds_manage_error">Aconteceu un problema ao cargar as súas fontes. Por favor, inténteo máis tarde.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">Toca para cambiar a túa imaxe de perfil</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">Mudar imaxe de perfil</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">Só os teus contactos poden ver a túa imaxe de perfil</string>
|
||||||
|
<string name="change_profile_picture_failed_message">Lamentámolo, pero algo fallou cando intentamos actualizar a túa imaxe de pefil</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">Idioma & rexión</string>
|
<string name="pref_language_title">Idioma & rexión</string>
|
||||||
<string name="pref_language_changed">Este axuste terá efecto cando reinicie Briar. Por favor desconecte e volte a iniciar Briar.</string>
|
<string name="pref_language_changed">Este axuste terá efecto cando reinicie Briar. Por favor desconecte e volte a iniciar Briar.</string>
|
||||||
|
|||||||
@@ -449,6 +449,10 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">אין הזנות RSS להראות\n\nהקש על הצלמית + כדי לייבא הזנה</string>
|
<string name="blogs_rss_feeds_manage_empty_state">אין הזנות RSS להראות\n\nהקש על הצלמית + כדי לייבא הזנה</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">הייתה בעיה בטעינת ההזנות שלך. אנא נסה שוב מאוחר יותר.</string>
|
<string name="blogs_rss_feeds_manage_error">הייתה בעיה בטעינת ההזנות שלך. אנא נסה שוב מאוחר יותר.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">הקש כדי לשנות את תמונת הפרופיל שלך</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">שנה תמונת פרופיל</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">רק אנשי הקשר שלך יכולים לראות את תמונת הפרופיל שלך</string>
|
||||||
|
<string name="change_profile_picture_failed_message">אנו מצטערים משהו השתבש בעת עדכון תמונת הפרופיל שלך</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">שפה ואזור</string>
|
<string name="pref_language_title">שפה ואזור</string>
|
||||||
<string name="pref_language_changed">הגדרה זו תיכנס לתוקף כשתפעיל מחדש את Briar. אנא התנתק והפעל מחדש את Briar.</string>
|
<string name="pref_language_changed">הגדרה זו תיכנס לתוקף כשתפעיל מחדש את Briar. אנא התנתק והפעל מחדש את Briar.</string>
|
||||||
@@ -558,6 +562,7 @@
|
|||||||
<string name="include_debug_report_feedback">כלול נתונים אלמוניים לגבי מכשיר זה</string>
|
<string name="include_debug_report_feedback">כלול נתונים אלמוניים לגבי מכשיר זה</string>
|
||||||
<string name="dev_report_basic_info">מידע בסיסי</string>
|
<string name="dev_report_basic_info">מידע בסיסי</string>
|
||||||
<string name="dev_report_device_info">מידע מכשיר</string>
|
<string name="dev_report_device_info">מידע מכשיר</string>
|
||||||
|
<string name="dev_report_stacktrace">מחסנית עקיבה (Stacktrace)</string>
|
||||||
<string name="dev_report_time_info">מידע זמן</string>
|
<string name="dev_report_time_info">מידע זמן</string>
|
||||||
<string name="dev_report_memory">זיכרון</string>
|
<string name="dev_report_memory">זיכרון</string>
|
||||||
<string name="dev_report_storage">אחסון</string>
|
<string name="dev_report_storage">אחסון</string>
|
||||||
|
|||||||
@@ -425,6 +425,10 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">Engin RSS-streymi til að birta\n\nÝttu á + táknið til að flytja inn streymi</string>
|
<string name="blogs_rss_feeds_manage_empty_state">Engin RSS-streymi til að birta\n\nÝttu á + táknið til að flytja inn streymi</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">Vandamál hefur komið upp með að hlaða inn streymunum þínum. Reyndu aftur síðar.</string>
|
<string name="blogs_rss_feeds_manage_error">Vandamál hefur komið upp með að hlaða inn streymunum þínum. Reyndu aftur síðar.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">Ýttu til að skipta um auðkennismyndina þína</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">Skipta um auðkennismynd</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">Einungis tengiliðirnir þínir geta séð auðkennismyndina þína</string>
|
||||||
|
<string name="change_profile_picture_failed_message">Því miður, eitthvað fór úrskeiðis við að uppfæra auðkennismyndina þína.</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">Tungumál og landsvæði</string>
|
<string name="pref_language_title">Tungumál og landsvæði</string>
|
||||||
<string name="pref_language_changed">Þessi stilling tekur gildi í næst þegar þú skráir þig inn í Briar. Skráðu þig út og endurræstu Briar.</string>
|
<string name="pref_language_changed">Þessi stilling tekur gildi í næst þegar þú skráir þig inn í Briar. Skráðu þig út og endurræstu Briar.</string>
|
||||||
|
|||||||
@@ -425,6 +425,10 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">Nessun feed RSS da mostrare\n\nClicca l\'icona + per importare un feed</string>
|
<string name="blogs_rss_feeds_manage_empty_state">Nessun feed RSS da mostrare\n\nClicca l\'icona + per importare un feed</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">C\'è stato un problema nel caricare i tuoi feeds. Per favore riprova fra poco.</string>
|
<string name="blogs_rss_feeds_manage_error">C\'è stato un problema nel caricare i tuoi feeds. Per favore riprova fra poco.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">Tocca per cambiare l\'immagine del profilo</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">Cambia immagine profilo</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">Solo i tuoi contatti possono vedere l\'immagine del profilo</string>
|
||||||
|
<string name="change_profile_picture_failed_message">Spiacenti, qualcosa è andato storto aggiornando la tua foto del profilo.</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">Lingua & regione</string>
|
<string name="pref_language_title">Lingua & regione</string>
|
||||||
<string name="pref_language_changed">Questa impostazione avrà effetto quando riavvierai Briar. Per favore, esci e riavvia Briar.</string>
|
<string name="pref_language_changed">Questa impostazione avrà effetto quando riavvierai Briar. Per favore, esci e riavvia Briar.</string>
|
||||||
|
|||||||
@@ -425,6 +425,10 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">Geen RSS-feeds om te tonen\n\nTik op het +-icoon om een feed te importeren</string>
|
<string name="blogs_rss_feeds_manage_empty_state">Geen RSS-feeds om te tonen\n\nTik op het +-icoon om een feed te importeren</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">Er was een probleem met het laden van je feeds. Probeer het alsjeblieft later nog een keer.</string>
|
<string name="blogs_rss_feeds_manage_error">Er was een probleem met het laden van je feeds. Probeer het alsjeblieft later nog een keer.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">Tik om je profielfoto te wijzigen</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">Wijzig profielfoto</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">Alleen je contacten kunnen je profielfoto zien</string>
|
||||||
|
<string name="change_profile_picture_failed_message">Excuses, maar er is iets misgegaan met het updaten van je profielfoto</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">Taal & regio</string>
|
<string name="pref_language_title">Taal & regio</string>
|
||||||
<string name="pref_language_changed">Deze instelling zal werken wanneer u Briar opnieuw opstart. Gelieve uit te loggen en Briar opnieuw te starten.</string>
|
<string name="pref_language_changed">Deze instelling zal werken wanneer u Briar opnieuw opstart. Gelieve uit te loggen en Briar opnieuw te starten.</string>
|
||||||
@@ -564,7 +568,7 @@
|
|||||||
<string name="permission_camera_location_title">Camera en locatie</string>
|
<string name="permission_camera_location_title">Camera en locatie</string>
|
||||||
<string name="permission_camera_location_request_body">Om de QR-code in te scannen heeft Briar toegang nodig tot de camera.\n\nOm bluetoothapparaten te ontdekken heeft Briar toestemming nodig tot je locatie.\n\nBriar slaat je locatie niet op en deelt het met niemand.</string>
|
<string name="permission_camera_location_request_body">Om de QR-code in te scannen heeft Briar toegang nodig tot de camera.\n\nOm bluetoothapparaten te ontdekken heeft Briar toestemming nodig tot je locatie.\n\nBriar slaat je locatie niet op en deelt het met niemand.</string>
|
||||||
<string name="permission_camera_denied_body">Je hebt toegang tot de camera niet vrijgegeven, terwijl het toevoegen van contacten de camera nodig heeft.\n\nOverweeg alsjeblieft toegang vrij te geven.</string>
|
<string name="permission_camera_denied_body">Je hebt toegang tot de camera niet vrijgegeven, terwijl het toevoegen van contacten de camera nodig heeft.\n\nOverweeg alsjeblieft toegang vrij te geven.</string>
|
||||||
<string name="permission_location_denied_body">Je hebt geen toegang tot je locatie gegeven, maar Briar heeft deze rechten nodig om apparaten via bleutooth te vinden.\n\nOverweeg a.u.b. deze rechten te geven.</string>
|
<string name="permission_location_denied_body">Je hebt geen toegang tot je locatie gegeven, maar Briar heeft deze rechten nodig om apparaten via bluetooth te vinden.\n\nOverweeg a.u.b. deze rechten te geven.</string>
|
||||||
<string name="qr_code">QR-code</string>
|
<string name="qr_code">QR-code</string>
|
||||||
<string name="show_qr_code_fullscreen">Toon QR-code op volledig scherm</string>
|
<string name="show_qr_code_fullscreen">Toon QR-code op volledig scherm</string>
|
||||||
<!--App Locking-->
|
<!--App Locking-->
|
||||||
|
|||||||
@@ -435,6 +435,10 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">Nici un flux RSS de arătat\n\nAtingeți iconița + pentru a adăuga un flux</string>
|
<string name="blogs_rss_feeds_manage_empty_state">Nici un flux RSS de arătat\n\nAtingeți iconița + pentru a adăuga un flux</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">A apărut o eroare la încărcarea fluxurilor dumneavoastră. Vă rugăm să încercați din nou mai târziu.</string>
|
<string name="blogs_rss_feeds_manage_error">A apărut o eroare la încărcarea fluxurilor dumneavoastră. Vă rugăm să încercați din nou mai târziu.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">Atingeți pentru a vă schimba poza de profil</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">Schimbare poză de profil</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">Doar contactele vor vedea poza de contact</string>
|
||||||
|
<string name="change_profile_picture_failed_message">Ne pare rău, dar ceva nu a funcționat cum trebuie la actualizarea pozei de profil</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">Limbă & Regiune</string>
|
<string name="pref_language_title">Limbă & Regiune</string>
|
||||||
<string name="pref_language_changed">Această setare va avea efect după repornirea Briar. Vă rugăm să ieșiți din Briar și să reporniți aplicația.</string>
|
<string name="pref_language_changed">Această setare va avea efect după repornirea Briar. Vă rugăm să ieșiți din Briar și să reporniți aplicația.</string>
|
||||||
|
|||||||
@@ -447,6 +447,10 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">Нет RSS-лент для отображения\n\nКоснитесь значка + для импорта ленты</string>
|
<string name="blogs_rss_feeds_manage_empty_state">Нет RSS-лент для отображения\n\nКоснитесь значка + для импорта ленты</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">Ошибка при загрузке вашей ленты. Повторите попытку позже.</string>
|
<string name="blogs_rss_feeds_manage_error">Ошибка при загрузке вашей ленты. Повторите попытку позже.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
|
<string name="change_profile_picture">Нажмите, чтобы изменить изображение вашего профиля </string>
|
||||||
|
<string name="dialog_confirm_profile_picture_title">Изменить изображение профиля</string>
|
||||||
|
<string name="dialog_confirm_profile_picture_remark">Только ваши контакты могут видеть изображение вашего профиля</string>
|
||||||
|
<string name="change_profile_picture_failed_message">Нам очень жаль, но что-то пошло не так во время обновления изображения вашего профиля.</string>
|
||||||
<!--Settings Display-->
|
<!--Settings Display-->
|
||||||
<string name="pref_language_title">Язык и регион</string>
|
<string name="pref_language_title">Язык и регион</string>
|
||||||
<string name="pref_language_changed">Этот параметр вступит в силу после перезапуска Briar. Пожалуйста, выйдите и перезапустите Briar.</string>
|
<string name="pref_language_changed">Этот параметр вступит в силу после перезапуска Briar. Пожалуйста, выйдите и перезапустите Briar.</string>
|
||||||
|
|||||||
@@ -456,7 +456,7 @@
|
|||||||
<!-- Settings Profile Picture -->
|
<!-- Settings Profile Picture -->
|
||||||
<string name="change_profile_picture">Tap to change your profile picture</string>
|
<string name="change_profile_picture">Tap to change your profile picture</string>
|
||||||
<string name="dialog_confirm_profile_picture_title">Change profile picture</string>
|
<string name="dialog_confirm_profile_picture_title">Change profile picture</string>
|
||||||
<string name="dialog_confirm_profile_picture_remark">Only your contacts can see your profile image</string>
|
<string name="dialog_confirm_profile_picture_remark">Only your contacts can see this picture</string>
|
||||||
<string name="change_profile_picture_failed_message">We\'re sorry, but something went wrong while updating your profile picture</string>
|
<string name="change_profile_picture_failed_message">We\'re sorry, but something went wrong while updating your profile picture</string>
|
||||||
|
|
||||||
<!-- Settings Display -->
|
<!-- Settings Display -->
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
dependencyVerification {
|
dependencyVerification {
|
||||||
verify = [
|
verify = [
|
||||||
'androidx.activity:activity-ktx:1.1.0:activity-ktx-1.1.0.aar:1996c36d3d2d62db5020b8ec634b5f854b1a698960c3552e1a00c69221baeabe',
|
'androidx.activity:activity-ktx:1.1.0:activity-ktx-1.1.0.aar:1996c36d3d2d62db5020b8ec634b5f854b1a698960c3552e1a00c69221baeabe',
|
||||||
'androidx.activity:activity:1.1.0:activity-1.1.0.aar:4f2b35916768032f7d0c20e250e28b29037ed4ce9ebf3da4fcd51bcb0c6067ef',
|
'androidx.activity:activity:1.2.0:activity-1.2.0.aar:ac27a810554e47b2122bce1f338934e77b173a5a9267eb35f134b6d34f931bae',
|
||||||
'androidx.annotation:annotation-experimental:1.0.0:annotation-experimental-1.0.0.aar:b219d2b568e7e4ba534e09f8c2fd242343df6ccbdfbbe938846f5d740e6b0b11',
|
'androidx.annotation:annotation-experimental:1.0.0:annotation-experimental-1.0.0.aar:b219d2b568e7e4ba534e09f8c2fd242343df6ccbdfbbe938846f5d740e6b0b11',
|
||||||
'androidx.annotation:annotation:1.1.0:annotation-1.1.0.jar:d38d63edb30f1467818d50aaf05f8a692dea8b31392a049bfa991b159ad5b692',
|
'androidx.annotation:annotation:1.1.0:annotation-1.1.0.jar:d38d63edb30f1467818d50aaf05f8a692dea8b31392a049bfa991b159ad5b692',
|
||||||
'androidx.appcompat:appcompat-resources:1.2.0:appcompat-resources-1.2.0.aar:c470297c03ff3de1c3d15dacf0be0cae63abc10b52f021dd07ae28daa3100fe5',
|
'androidx.appcompat:appcompat-resources:1.2.0:appcompat-resources-1.2.0.aar:c470297c03ff3de1c3d15dacf0be0cae63abc10b52f021dd07ae28daa3100fe5',
|
||||||
@@ -24,29 +24,28 @@ dependencyVerification {
|
|||||||
'androidx.exifinterface:exifinterface:1.3.1:exifinterface-1.3.1.aar:ef168daa6eb744c8395c22b49afa5235e6099868a0377175b6d5e3cdff8d7ffc',
|
'androidx.exifinterface:exifinterface:1.3.1:exifinterface-1.3.1.aar:ef168daa6eb744c8395c22b49afa5235e6099868a0377175b6d5e3cdff8d7ffc',
|
||||||
'androidx.fragment:fragment-ktx:1.2.5:fragment-ktx-1.2.5.aar:50f0f3b734f93829eeac7456b7cb13e5430741e555c535911a958ee4a8242bca',
|
'androidx.fragment:fragment-ktx:1.2.5:fragment-ktx-1.2.5.aar:50f0f3b734f93829eeac7456b7cb13e5430741e555c535911a958ee4a8242bca',
|
||||||
'androidx.fragment:fragment-testing:1.2.5:fragment-testing-1.2.5.aar:ef3cc3387115f9187665b283e313b13a2bb8826673380317057e2972351df09c',
|
'androidx.fragment:fragment-testing:1.2.5:fragment-testing-1.2.5.aar:ef3cc3387115f9187665b283e313b13a2bb8826673380317057e2972351df09c',
|
||||||
'androidx.fragment:fragment:1.2.4:fragment-1.2.4.aar:1dc194942574302bf35dae7b81b82273505ec2d38f81d9258ad5c0448daddd82',
|
'androidx.fragment:fragment:1.3.0:fragment-1.3.0.aar:66db3ed2b11bb5e572a079b87cd3fae9bc5c33c373c71b25f1e3eac7607ab526',
|
||||||
'androidx.fragment:fragment:1.2.5:fragment-1.2.5.aar:d19e82d142def6c4e136da70bf92f194c0ecc61d14ab4e84567b2ced0920fa93',
|
|
||||||
'androidx.interpolator:interpolator:1.0.0:interpolator-1.0.0.aar:33193135a64fe21fa2c35eec6688f1a76e512606c0fc83dc1b689e37add7732a',
|
'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.legacy:legacy-support-core-utils:1.0.0:legacy-support-core-utils-1.0.0.aar:a7edcf01d5b52b3034073027bc4775b78a4764bb6202bb91d61c829add8dd1c7',
|
||||||
'androidx.lifecycle:lifecycle-common:2.2.0:lifecycle-common-2.2.0.jar:63898dabf7cfe5ec5d7ed8b8c2564c1427be876e1496ead95c2703cf59d3734b',
|
'androidx.lifecycle:lifecycle-common:2.3.0:lifecycle-common-2.3.0.jar:15848fb56db32f4c7cdc72b324003183d52a4884d6bf09be708ac7f587d139b5',
|
||||||
'androidx.lifecycle:lifecycle-extensions:2.2.0:lifecycle-extensions-2.2.0.aar:648c8de1d10b025d524a2e46ac994fc3f6bf186826c09ec1a62d250bf1b877ae',
|
'androidx.lifecycle:lifecycle-extensions:2.2.0:lifecycle-extensions-2.2.0.aar:648c8de1d10b025d524a2e46ac994fc3f6bf186826c09ec1a62d250bf1b877ae',
|
||||||
'androidx.lifecycle:lifecycle-livedata-core-ktx:2.2.0:lifecycle-livedata-core-ktx-2.2.0.aar:5951f882e95b7e05ceb9adfca0fa2ebd511d63ea5a00da4eae6c6d0c1903da18',
|
'androidx.lifecycle:lifecycle-livedata-core-ktx:2.2.0:lifecycle-livedata-core-ktx-2.2.0.aar:5951f882e95b7e05ceb9adfca0fa2ebd511d63ea5a00da4eae6c6d0c1903da18',
|
||||||
'androidx.lifecycle:lifecycle-livedata-core:2.2.0:lifecycle-livedata-core-2.2.0.aar:556c1f3af90aa9d7d0d330565adbf6da71b2429148bac91e07c485f4f9abf614',
|
'androidx.lifecycle:lifecycle-livedata-core:2.3.0:lifecycle-livedata-core-2.3.0.aar:89f480888f2bb8eb62d9b7b1eb34be69b59ec84b24a1b0bdbeb49973478c6da3',
|
||||||
'androidx.lifecycle:lifecycle-livedata:2.2.0:lifecycle-livedata-2.2.0.aar:d83af94860aa9f64cbdc51f40796a7cf55b116f0e6efd752e845c0104c8b16f6',
|
'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-process:2.2.0:lifecycle-process-2.2.0.aar:3a977e7778fc8418742d388409daaba7ea8fea8823d21ffb96e4c4236f715070',
|
||||||
'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0:lifecycle-runtime-ktx-2.2.0.aar:c29fc87694e6ce116b61207221e53ed285862a6628055790b0bcf9ce45d8cc68',
|
'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0:lifecycle-runtime-ktx-2.2.0.aar:c29fc87694e6ce116b61207221e53ed285862a6628055790b0bcf9ce45d8cc68',
|
||||||
'androidx.lifecycle:lifecycle-runtime:2.2.0:lifecycle-runtime-2.2.0.aar:2f866c07a1f33a8c9bb69a9545d4f20b4f0628cd0a155432386d7cb081e1e0bc',
|
'androidx.lifecycle:lifecycle-runtime:2.3.0:lifecycle-runtime-2.3.0.aar:94f528fd5fb123f75b6e65d07a6ef5cd6c0e69ac604d106aaa12705282456234',
|
||||||
'androidx.lifecycle:lifecycle-service:2.2.0:lifecycle-service-2.2.0.aar:ca2801ffc069555afed8eddd2292130f436956452bc8bbad30fb56f8e4e382a0',
|
'androidx.lifecycle:lifecycle-service:2.2.0:lifecycle-service-2.2.0.aar:ca2801ffc069555afed8eddd2292130f436956452bc8bbad30fb56f8e4e382a0',
|
||||||
'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0:lifecycle-viewmodel-ktx-2.2.0.aar:f791001f2211947e56ad3d96d12c9ae93fc5589b88f08603f69a2265c9a7d702',
|
'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0:lifecycle-viewmodel-ktx-2.2.0.aar:f791001f2211947e56ad3d96d12c9ae93fc5589b88f08603f69a2265c9a7d702',
|
||||||
'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0:lifecycle-viewmodel-savedstate-2.2.0.aar:3ce866fb822b20fe2f188f974992869a0a6233fe40acbefcff090d6def5e7f33',
|
'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.0:lifecycle-viewmodel-savedstate-2.3.0.aar:49f9532b5104cc1ee64900ed4f696d031d807fba726e0d5d6a52459e8fba4a1d',
|
||||||
'androidx.lifecycle:lifecycle-viewmodel:2.2.0:lifecycle-viewmodel-2.2.0.aar:967efab24d6c49dd414a8c0ac4a1cd09b018f0b8bb43b739ad360c4158ebde27',
|
'androidx.lifecycle:lifecycle-viewmodel:2.3.0:lifecycle-viewmodel-2.3.0.aar:cea8f26fa232037922b69af9cd1bde2df1211acc8b75253e425b7150a5fca59d',
|
||||||
'androidx.loader:loader:1.0.0:loader-1.0.0.aar:11f735cb3b55c458d470bed9e25254375b518b4b1bad6926783a7026db0f5025',
|
'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.localbroadcastmanager:localbroadcastmanager:1.0.0:localbroadcastmanager-1.0.0.aar:e71c328ceef5c4a7d76f2d86df1b65d65fe2acf868b1a4efd84a3f34336186d8',
|
||||||
'androidx.preference:preference:1.1.1:preference-1.1.1.aar:317dcbc38242aea2f6262c06d51b8a22827e98959967edd40f82600a15cb4bff',
|
'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.print:print:1.0.0:print-1.0.0.aar:1d5c7f3135a1bba661fc373fd72e11eb0a4adbb3396787826dd8e4190d5d9edd',
|
||||||
'androidx.recyclerview:recyclerview-selection:1.1.0-rc03:recyclerview-selection-1.1.0-rc03.aar:a548a0771c2c8ca8cf98f1f755b0eef4fac73d1697e6eeb1a6383f557e0eba13',
|
'androidx.recyclerview:recyclerview-selection:1.1.0-rc03:recyclerview-selection-1.1.0-rc03.aar:a548a0771c2c8ca8cf98f1f755b0eef4fac73d1697e6eeb1a6383f557e0eba13',
|
||||||
'androidx.recyclerview:recyclerview:1.1.0:recyclerview-1.1.0.aar:f0d2b5a67d0a91ee1b1c73ef2b636a81f3563925ddd15a1d4e1c41ec28de7a4f',
|
'androidx.recyclerview:recyclerview:1.1.0:recyclerview-1.1.0.aar:f0d2b5a67d0a91ee1b1c73ef2b636a81f3563925ddd15a1d4e1c41ec28de7a4f',
|
||||||
'androidx.savedstate:savedstate:1.0.0:savedstate-1.0.0.aar:2510a5619c37579c9ce1a04574faaf323cd0ffe2fc4e20fa8f8f01e5bb402e83',
|
'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-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-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-idling-resource:3.3.0:espresso-idling-resource-3.3.0.aar:29519b112731f289cc6e2f9b2eccc5ea72c754b04272bb93370f45d7e170a7c6',
|
||||||
@@ -57,6 +56,7 @@ dependencyVerification {
|
|||||||
'androidx.test:monitor:1.3.0:monitor-1.3.0.aar:f73a31306a783e63150c60c49e140dc38da39a1b7947690f4b73387b5ebad77e',
|
'androidx.test:monitor:1.3.0:monitor-1.3.0.aar:f73a31306a783e63150c60c49e140dc38da39a1b7947690f4b73387b5ebad77e',
|
||||||
'androidx.test:rules:1.3.0:rules-1.3.0.aar:c1753946c498b0d5d7cf341cfed661f66915c4c9deb4ed10462a08ae33b2429a',
|
'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.3.0:runner-1.3.0.aar:61d13f5a9fcbbd73ba18fa84e1d6a0111c6e1c665a89b418126966e61fffd93b',
|
||||||
|
'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.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-animated:1.1.0:vectordrawable-animated-1.1.0.aar:76da2c502371d9c38054df5e2b248d00da87809ed058f3363eae87ce5e2403f8',
|
||||||
'androidx.vectordrawable:vectordrawable:1.1.0:vectordrawable-1.1.0.aar:46fd633ac01b49b7fcabc263bf098c5a8b9e9a69774d234edcca04fb02df8e26',
|
'androidx.vectordrawable:vectordrawable:1.1.0:vectordrawable-1.1.0.aar:46fd633ac01b49b7fcabc263bf098c5a8b9e9a69774d234edcca04fb02df8e26',
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ The REST API peer comes as a `jar` file
|
|||||||
and needs a Java Runtime Environment (JRE) that supports at least Java 8.
|
and needs a Java Runtime Environment (JRE) that supports at least Java 8.
|
||||||
It currently works only on GNU/Linux operating systems.
|
It currently works only on GNU/Linux operating systems.
|
||||||
|
|
||||||
To build the `jar` file, you can do this:
|
To build the `jar` file, you need to specify the combination of architecture and platform:
|
||||||
|
|
||||||
$ ./gradlew --configure-on-demand briar-headless:jar
|
$ ./gradlew --configure-on-demand briar-headless:x86LinuxJar
|
||||||
|
$ ./gradlew --configure-on-demand briar-headless:aarch64LinuxJar
|
||||||
|
$ ./gradlew --configure-on-demand briar-headless:armhfLinuxJar
|
||||||
|
|
||||||
You can start the peer (and its API server) like this:
|
You can start the peer (and its API server) like this:
|
||||||
|
|
||||||
@@ -105,7 +107,7 @@ The link and the alias should be posted as a JSON object:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This starts the process of adding the contact.
|
Adding a pending contact starts the process of adding the contact.
|
||||||
Until it is completed, a pending contact is returned as JSON:
|
Until it is completed, a pending contact is returned as JSON:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -116,6 +118,71 @@ Until it is completed, a pending contact is returned as JSON:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Possible errors when adding a pending contact are:
|
||||||
|
|
||||||
|
#### 400: Pending contact's link is invalid
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "INVALID_LINK"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 400: Pending contact's handshake public key is invalid
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "INVALID_PUBLIC_KEY"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 403: A contact with the same handshake public key already exists
|
||||||
|
|
||||||
|
This error may be caused by someone attacking the user with the goal
|
||||||
|
of discovering the contacts of the user.
|
||||||
|
|
||||||
|
In the Android client, upon encountering this issue a message dialog
|
||||||
|
is shown that asks whether the contact and the just added pending contact
|
||||||
|
are the same person. If that's the case, a message is shown that the
|
||||||
|
contact already exists and the pending contact isn't added.
|
||||||
|
If that's not the case and they are two different persons, the Android
|
||||||
|
client
|
||||||
|
[shows the following message](https://code.briarproject.org/briar/briar/-/blob/beta-1.2.14/briar-android/src/main/res/values/strings.xml#L271)
|
||||||
|
when this happens:
|
||||||
|
> [Alice] and [Bob] sent you the same link.
|
||||||
|
>
|
||||||
|
> One of them may be trying to discover who your contacts are.
|
||||||
|
>
|
||||||
|
> Don't tell them you received the same link from someone else.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "CONTACT_EXISTS",
|
||||||
|
"remoteAuthorName": "Bob"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 403: A pending contact with the same handshake public key already exists
|
||||||
|
|
||||||
|
This error, too, may be caused by someone attacking the user with the goal
|
||||||
|
of discovering the contacts of the user.
|
||||||
|
|
||||||
|
Just like above, upon encountering this issue a message dialog is shown in
|
||||||
|
the Android client that asks whether the contact and the just added pending
|
||||||
|
contact are the same person. If that's the case, the pending contact gets
|
||||||
|
updated. If that's not the case and they are two different persons, the
|
||||||
|
Android client shows the same message as above, warning the user about the
|
||||||
|
possible attack.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "PENDING_EXISTS",
|
||||||
|
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
||||||
|
"pendingContactAlias": "Alice"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
-----------
|
||||||
|
|
||||||
Before users can send messages to contacts, they become pending contacts.
|
Before users can send messages to contacts, they become pending contacts.
|
||||||
In this state Briar still needs to do some work in the background (e.g.
|
In this state Briar still needs to do some work in the background (e.g.
|
||||||
spinning up a dedicated hidden service and letting the contact connect to it).
|
spinning up a dedicated hidden service and letting the contact connect to it).
|
||||||
|
|||||||
@@ -44,18 +44,32 @@ dependencies {
|
|||||||
kaptTest "com.google.dagger:dagger-compiler:$daggerVersion"
|
kaptTest "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
void jarFactory(Jar jarTask, jarArchitecture) {
|
||||||
manifest {
|
jarTask.doFirst {
|
||||||
|
println 'Building ' + jarArchitecture + ' version has started'
|
||||||
|
}
|
||||||
|
jarTask.manifest {
|
||||||
attributes(
|
attributes(
|
||||||
'Main-Class': 'org.briarproject.briar.headless.MainKt'
|
'Main-Class': 'org.briarproject.briar.headless.MainKt'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
from {
|
jarTask.setArchiveClassifier(jarArchitecture)
|
||||||
|
jarTask.from {
|
||||||
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
}
|
}
|
||||||
doLast() {
|
{
|
||||||
|
String[] architectures = ["linux-aarch64", "linux-armhf", "linux-x86_64"]
|
||||||
|
for (String arch : architectures) {
|
||||||
|
if (arch != jarArchitecture) {
|
||||||
|
exclude "obfs4proxy_" + arch + ".zip"
|
||||||
|
exclude "tor_" + arch + ".zip"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jarTask.with jar
|
||||||
|
jarTask.doLast {
|
||||||
// Rename the original jar
|
// Rename the original jar
|
||||||
File jar = project.jar.archivePath
|
File jar = jarTask.archivePath
|
||||||
String srcPath = jar.toString().replaceFirst('\\.jar$', '.unsorted.jar')
|
String srcPath = jar.toString().replaceFirst('\\.jar$', '.unsorted.jar')
|
||||||
File srcFile = new File(srcPath)
|
File srcFile = new File(srcPath)
|
||||||
jar.renameTo(srcFile)
|
jar.renameTo(srcFile)
|
||||||
@@ -80,9 +94,22 @@ jar {
|
|||||||
}
|
}
|
||||||
destStream.close()
|
destStream.close()
|
||||||
srcJarFile.close()
|
srcJarFile.close()
|
||||||
|
println 'Building ' + jarArchitecture + ' version has finished'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task aarch64LinuxJar(type: Jar) {
|
||||||
|
jarFactory(it, 'linux-aarch64')
|
||||||
|
}
|
||||||
|
|
||||||
|
task armhfLinuxJar(type: Jar) {
|
||||||
|
jarFactory(it, 'linux-armhf')
|
||||||
|
}
|
||||||
|
|
||||||
|
task x86LinuxJar(type: Jar) {
|
||||||
|
jarFactory(it, 'linux-x86_64')
|
||||||
|
}
|
||||||
|
|
||||||
// At the moment for non-Android projects we need to explicitly mark the code generated by kapt
|
// At the moment for non-Android projects we need to explicitly mark the code generated by kapt
|
||||||
// as 'generated source code' for correct highlighting and resolve in IDE.
|
// as 'generated source code' for correct highlighting and resolve in IDE.
|
||||||
idea {
|
idea {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.briarproject.briar.headless.contact
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import io.javalin.http.BadRequestResponse
|
import io.javalin.http.BadRequestResponse
|
||||||
import io.javalin.http.Context
|
import io.javalin.http.Context
|
||||||
|
import io.javalin.http.ForbiddenResponse
|
||||||
|
import io.javalin.http.HttpResponseException
|
||||||
import io.javalin.http.NotFoundResponse
|
import io.javalin.http.NotFoundResponse
|
||||||
import org.briarproject.bramble.api.connection.ConnectionRegistry
|
import org.briarproject.bramble.api.connection.ConnectionRegistry
|
||||||
import org.briarproject.bramble.api.contact.ContactManager
|
import org.briarproject.bramble.api.contact.ContactManager
|
||||||
@@ -12,8 +14,10 @@ import org.briarproject.bramble.api.contact.event.ContactAddedEvent
|
|||||||
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||||
|
import org.briarproject.bramble.api.db.ContactExistsException
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException
|
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||||
import org.briarproject.bramble.api.db.NoSuchPendingContactException
|
import org.briarproject.bramble.api.db.NoSuchPendingContactException
|
||||||
|
import org.briarproject.bramble.api.db.PendingContactExistsException
|
||||||
import org.briarproject.bramble.api.event.Event
|
import org.briarproject.bramble.api.event.Event
|
||||||
import org.briarproject.bramble.api.event.EventListener
|
import org.briarproject.bramble.api.event.EventListener
|
||||||
import org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH
|
import org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH
|
||||||
@@ -25,8 +29,11 @@ import org.briarproject.briar.headless.event.WebSocketController
|
|||||||
import org.briarproject.briar.headless.getContactIdFromPathParam
|
import org.briarproject.briar.headless.getContactIdFromPathParam
|
||||||
import org.briarproject.briar.headless.getFromJson
|
import org.briarproject.briar.headless.getFromJson
|
||||||
import org.briarproject.briar.headless.json.JsonDict
|
import org.briarproject.briar.headless.json.JsonDict
|
||||||
|
import org.eclipse.jetty.http.HttpStatus.BAD_REQUEST_400
|
||||||
|
import org.eclipse.jetty.http.HttpStatus.FORBIDDEN_403
|
||||||
import org.spongycastle.util.encoders.Base64
|
import org.spongycastle.util.encoders.Base64
|
||||||
import org.spongycastle.util.encoders.DecoderException
|
import org.spongycastle.util.encoders.DecoderException
|
||||||
|
import java.security.GeneralSecurityException
|
||||||
import javax.annotation.concurrent.Immutable
|
import javax.annotation.concurrent.Immutable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@@ -91,9 +98,32 @@ constructor(
|
|||||||
override fun addPendingContact(ctx: Context): Context {
|
override fun addPendingContact(ctx: Context): Context {
|
||||||
val link = ctx.getFromJson(objectMapper, "link")
|
val link = ctx.getFromJson(objectMapper, "link")
|
||||||
val alias = ctx.getFromJson(objectMapper, "alias")
|
val alias = ctx.getFromJson(objectMapper, "alias")
|
||||||
if (!LINK_REGEX.matcher(link).find()) throw BadRequestResponse("Invalid Link")
|
if (!LINK_REGEX.matcher(link).find()) {
|
||||||
|
ctx.status(BAD_REQUEST_400)
|
||||||
|
val details = mapOf("error" to "INVALID_LINK")
|
||||||
|
return ctx.json(details)
|
||||||
|
}
|
||||||
checkAliasLength(alias)
|
checkAliasLength(alias)
|
||||||
val pendingContact = contactManager.addPendingContact(link, alias)
|
val pendingContact = try {
|
||||||
|
contactManager.addPendingContact(link, alias)
|
||||||
|
} catch (e: GeneralSecurityException) {
|
||||||
|
ctx.status(BAD_REQUEST_400)
|
||||||
|
val details = mapOf("error" to "INVALID_PUBLIC_KEY")
|
||||||
|
return ctx.json(details)
|
||||||
|
} catch (e: ContactExistsException) {
|
||||||
|
ctx.status(FORBIDDEN_403)
|
||||||
|
val details =
|
||||||
|
mapOf("error" to "CONTACT_EXISTS", "remoteAuthorName" to e.remoteAuthor.name)
|
||||||
|
return ctx.json(details)
|
||||||
|
} catch (e: PendingContactExistsException) {
|
||||||
|
ctx.status(FORBIDDEN_403)
|
||||||
|
val details = mapOf(
|
||||||
|
"error" to "PENDING_EXISTS",
|
||||||
|
"pendingContactId" to e.pendingContact.id.bytes,
|
||||||
|
"pendingContactAlias" to e.pendingContact.alias
|
||||||
|
)
|
||||||
|
return ctx.json(details)
|
||||||
|
}
|
||||||
return ctx.json(pendingContact.output())
|
return ctx.json(pendingContact.output())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,49 @@ class ContactControllerIntegrationTest: IntegrationTest() {
|
|||||||
assertEquals(401, response.statusCode)
|
assertEquals(401, response.statusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `adding a pending contact with invalid link`() {
|
||||||
|
val alias = "AliasFoo"
|
||||||
|
val json = """{
|
||||||
|
"link": "briar://invalid",
|
||||||
|
"alias": "$alias"
|
||||||
|
}"""
|
||||||
|
val response = post("$url/contacts/add/pending", json)
|
||||||
|
assertEquals(400, response.statusCode)
|
||||||
|
assertEquals("INVALID_LINK", response.jsonObject.getString("error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `adding a pending contact with invalid public key`() {
|
||||||
|
val alias = "AliasFoo"
|
||||||
|
val json = """{
|
||||||
|
"link": "briar://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"alias": "$alias"
|
||||||
|
}"""
|
||||||
|
val response = post("$url/contacts/add/pending", json)
|
||||||
|
assertEquals(400, response.statusCode)
|
||||||
|
assertEquals("INVALID_PUBLIC_KEY", response.jsonObject.getString("error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `adding a pending contact that already exists as pending contact`() {
|
||||||
|
val alias = "AliasFoo"
|
||||||
|
val json = """{
|
||||||
|
"link": "${getRealHandshakeLink(crypto)}",
|
||||||
|
"alias": "$alias"
|
||||||
|
}"""
|
||||||
|
var response = post("$url/contacts/add/pending", json)
|
||||||
|
assertEquals(200, response.statusCode)
|
||||||
|
|
||||||
|
val pendingContactId = response.jsonObject.getString("pendingContactId")
|
||||||
|
|
||||||
|
response = post("$url/contacts/add/pending", json)
|
||||||
|
assertEquals(403, response.statusCode)
|
||||||
|
assertEquals("PENDING_EXISTS", response.jsonObject.getString("error"))
|
||||||
|
assertEquals(pendingContactId, response.jsonObject.getString("pendingContactId"))
|
||||||
|
assertEquals(alias, response.jsonObject.getString("pendingContactAlias"))
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `removing a pending contact needs authentication token`() {
|
fun `removing a pending contact needs authentication token`() {
|
||||||
val response = deleteWithWrongToken("$url/contacts/add/pending")
|
val response = deleteWithWrongToken("$url/contacts/add/pending")
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.briarproject.briar.headless.contact
|
package org.briarproject.briar.headless.contact
|
||||||
|
|
||||||
import io.javalin.http.BadRequestResponse
|
import io.javalin.http.BadRequestResponse
|
||||||
|
import io.javalin.http.ForbiddenResponse
|
||||||
|
import io.javalin.http.HttpResponseException
|
||||||
import io.javalin.http.NotFoundResponse
|
import io.javalin.http.NotFoundResponse
|
||||||
import io.javalin.plugin.json.JavalinJson.toJson
|
import io.javalin.plugin.json.JavalinJson.toJson
|
||||||
import io.mockk.Runs
|
import io.mockk.Runs
|
||||||
@@ -8,6 +10,7 @@ import io.mockk.every
|
|||||||
import io.mockk.just
|
import io.mockk.just
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
import io.mockk.runs
|
import io.mockk.runs
|
||||||
|
import io.mockk.verify
|
||||||
import org.briarproject.bramble.api.Pair
|
import org.briarproject.bramble.api.Pair
|
||||||
import org.briarproject.bramble.api.contact.Contact
|
import org.briarproject.bramble.api.contact.Contact
|
||||||
import org.briarproject.bramble.api.contact.ContactId
|
import org.briarproject.bramble.api.contact.ContactId
|
||||||
@@ -18,8 +21,10 @@ import org.briarproject.bramble.api.contact.event.ContactAddedEvent
|
|||||||
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||||
|
import org.briarproject.bramble.api.db.ContactExistsException
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException
|
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||||
import org.briarproject.bramble.api.db.NoSuchPendingContactException
|
import org.briarproject.bramble.api.db.NoSuchPendingContactException
|
||||||
|
import org.briarproject.bramble.api.db.PendingContactExistsException
|
||||||
import org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH
|
import org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH
|
||||||
import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent
|
import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent
|
||||||
import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent
|
import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent
|
||||||
@@ -30,9 +35,11 @@ import org.briarproject.bramble.util.StringUtils.getRandomString
|
|||||||
import org.briarproject.briar.headless.ControllerTest
|
import org.briarproject.briar.headless.ControllerTest
|
||||||
import org.briarproject.briar.headless.getFromJson
|
import org.briarproject.briar.headless.getFromJson
|
||||||
import org.briarproject.briar.headless.json.JsonDict
|
import org.briarproject.briar.headless.json.JsonDict
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertNotNull
|
import org.junit.jupiter.api.Assertions.assertNotNull
|
||||||
import org.junit.jupiter.api.Assertions.assertThrows
|
import org.junit.jupiter.api.Assertions.assertThrows
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import java.security.GeneralSecurityException
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
internal class ContactControllerTest : ControllerTest() {
|
internal class ContactControllerTest : ControllerTest() {
|
||||||
@@ -96,9 +103,10 @@ internal class ContactControllerTest : ControllerTest() {
|
|||||||
"alias": "$alias"
|
"alias": "$alias"
|
||||||
}"""
|
}"""
|
||||||
every { ctx.body() } returns body
|
every { ctx.body() } returns body
|
||||||
assertThrows(BadRequestResponse::class.java) {
|
every { ctx.status(400) } returns ctx
|
||||||
controller.addPendingContact(ctx)
|
every { ctx.json(mapOf("error" to "INVALID_LINK")) } returns ctx
|
||||||
}
|
controller.addPendingContact(ctx)
|
||||||
|
verify { ctx.status(400) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -139,6 +147,84 @@ internal class ContactControllerTest : ControllerTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAddPendingContactPublicKeyInvalid() {
|
||||||
|
val link = "briar://adnsyffpsenoc3yzlhr24aegfq2pwan7kkselocill2choov6sbhs"
|
||||||
|
val alias = "Alias123"
|
||||||
|
val body = """{
|
||||||
|
"link": "$link",
|
||||||
|
"alias": "$alias"
|
||||||
|
}"""
|
||||||
|
every { ctx.body() } returns body
|
||||||
|
every { ctx.status(400) } returns ctx
|
||||||
|
every {
|
||||||
|
contactManager.addPendingContact(
|
||||||
|
link,
|
||||||
|
alias
|
||||||
|
)
|
||||||
|
} throws GeneralSecurityException()
|
||||||
|
every { ctx.json(mapOf("error" to "INVALID_PUBLIC_KEY")) } returns ctx
|
||||||
|
controller.addPendingContact(ctx)
|
||||||
|
verify { ctx.status(400) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAddPendingContactSameContactKey() {
|
||||||
|
val link = "briar://adnsyffpsenoc3yzlhr24aegfq2pwan7kkselocill2choov6sbhs"
|
||||||
|
val alias = "Alias123"
|
||||||
|
val body = """{
|
||||||
|
"link": "$link",
|
||||||
|
"alias": "$alias"
|
||||||
|
}"""
|
||||||
|
every { ctx.body() } returns body
|
||||||
|
every { ctx.status(403) } returns ctx
|
||||||
|
every {
|
||||||
|
contactManager.addPendingContact(
|
||||||
|
link,
|
||||||
|
alias
|
||||||
|
)
|
||||||
|
} throws ContactExistsException(null, author)
|
||||||
|
every {
|
||||||
|
ctx.json(
|
||||||
|
mapOf(
|
||||||
|
"error" to "CONTACT_EXISTS",
|
||||||
|
"remoteAuthorName" to author.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} returns ctx
|
||||||
|
controller.addPendingContact(ctx)
|
||||||
|
verify { ctx.status(403) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testAddPendingContactSamePendingContactKey() {
|
||||||
|
val link = "briar://adnsyffpsenoc3yzlhr24aegfq2pwan7kkselocill2choov6sbhs"
|
||||||
|
val alias = "Alias123"
|
||||||
|
val body = """{
|
||||||
|
"link": "$link",
|
||||||
|
"alias": "$alias"
|
||||||
|
}"""
|
||||||
|
every { ctx.body() } returns body
|
||||||
|
every { ctx.status(403) } returns ctx
|
||||||
|
every {
|
||||||
|
contactManager.addPendingContact(
|
||||||
|
link,
|
||||||
|
alias
|
||||||
|
)
|
||||||
|
} throws PendingContactExistsException(pendingContact)
|
||||||
|
every {
|
||||||
|
ctx.json(
|
||||||
|
mapOf(
|
||||||
|
"error" to "PENDING_EXISTS",
|
||||||
|
"pendingContactId" to pendingContact.id.bytes,
|
||||||
|
"pendingContactAlias" to pendingContact.alias
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} returns ctx
|
||||||
|
controller.addPendingContact(ctx)
|
||||||
|
verify { ctx.status(403) }
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testListPendingContacts() {
|
fun testListPendingContacts() {
|
||||||
every { contactManager.pendingContacts } returns listOf(
|
every { contactManager.pendingContacts } returns listOf(
|
||||||
|
|||||||
Reference in New Issue
Block a user