mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 02:39:05 +01:00
Compare commits
72 Commits
dont-kill-
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e032e0ccd5 | ||
|
|
38a07e1d54 | ||
|
|
07b35db4d4 | ||
|
|
3b03db9f43 | ||
|
|
de3a74eedf | ||
|
|
5a39f9730f | ||
|
|
bdf02bbc6c | ||
|
|
d5b2ebdb23 | ||
|
|
98bb8d4af1 | ||
|
|
75cc19e578 | ||
|
|
aad87e6e98 | ||
|
|
dad895c30d | ||
|
|
f8b3d79813 | ||
|
|
0a98566298 | ||
|
|
93a03d7e15 | ||
|
|
3eb3dbde09 | ||
|
|
fd56176450 | ||
|
|
d29812f055 | ||
|
|
403601b9f2 | ||
|
|
992215b78a | ||
|
|
658ca8de21 | ||
|
|
e0e2c0cc89 | ||
|
|
114d80ad43 | ||
|
|
8d5803098b | ||
|
|
a9ed9da822 | ||
|
|
1d04bbcb4f | ||
|
|
43b0d1d543 | ||
|
|
1bfd9e4eb0 | ||
|
|
2295db4361 | ||
|
|
8fca06e040 | ||
|
|
3f7c9af3a9 | ||
|
|
93178d2f28 | ||
|
|
2755d3f470 | ||
|
|
7efc3ca78f | ||
|
|
d6767a62b9 | ||
|
|
2821460648 | ||
|
|
3ff7349b40 | ||
|
|
22593722a7 | ||
|
|
e91ad962cb | ||
|
|
53d9a9b43b | ||
|
|
6c702bad0a | ||
|
|
0dc2aba22f | ||
|
|
5a8b822e08 | ||
|
|
8ac6b0155b | ||
|
|
372810f48e | ||
|
|
1b4ab4f945 | ||
|
|
407ddad0a8 | ||
|
|
77a986318e | ||
|
|
1809be4656 | ||
|
|
6d1a0a5792 | ||
|
|
85dc27ed77 | ||
|
|
3f8df34f5c | ||
|
|
eb08781460 | ||
|
|
8a4fe7ca49 | ||
|
|
e688448537 | ||
|
|
e0f36ade92 | ||
|
|
6517f3f2d0 | ||
|
|
70d5150faf | ||
|
|
a1f9e80e12 | ||
|
|
770c87c723 | ||
|
|
2b5446759f | ||
|
|
edccb9ae14 | ||
|
|
1337fc46b3 | ||
|
|
ed26dc0b2b | ||
|
|
bf9fe6a146 | ||
|
|
448ea114f3 | ||
|
|
abc523fae3 | ||
|
|
6de5f424b8 | ||
|
|
703559102a | ||
|
|
bf091ef854 | ||
|
|
d4656df384 | ||
|
|
e79abeff2e |
@@ -33,6 +33,7 @@ test:
|
||||
stage: test
|
||||
script:
|
||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom animalSnifferMain animalSnifferTest
|
||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom :briar-headless:linuxJars
|
||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom compileOfficialDebugAndroidTestSources compileScreenshotDebugAndroidTestSources check
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
|
||||
@@ -15,8 +15,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
versionCode 10308
|
||||
versionName "1.3.8"
|
||||
versionCode 10403
|
||||
versionName "1.4.3"
|
||||
consumerProguardFiles 'proguard-rules.txt'
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@@ -42,8 +42,8 @@ configurations {
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
tor 'org.briarproject:tor-android:0.3.5.15'
|
||||
tor 'org.briarproject:obfs4proxy-android:0.0.12-dev-40245c4a@zip'
|
||||
tor "org.briarproject:tor-android:$tor_version"
|
||||
tor "org.briarproject:obfs4proxy-android:$obfs4proxy_version@zip"
|
||||
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
|
||||
@@ -70,12 +70,14 @@ class AndroidTorPlugin extends TorPlugin {
|
||||
String architecture,
|
||||
long maxLatency,
|
||||
int maxIdleTime,
|
||||
File torDirectory) {
|
||||
File torDirectory,
|
||||
int torSocksPort,
|
||||
int torControlPort) {
|
||||
super(ioExecutor, wakefulIoExecutor, networkManager, locationUtils,
|
||||
torSocketFactory, clock, resourceProvider,
|
||||
circumventionProvider, batteryManager, backoff,
|
||||
torRendezvousCrypto, callback, architecture, maxLatency,
|
||||
maxIdleTime, torDirectory);
|
||||
maxIdleTime, torDirectory, torSocksPort, torControlPort);
|
||||
this.app = app;
|
||||
wakeLock = wakeLockManager.createWakeLock("TorPlugin");
|
||||
String nativeLibDir = app.getApplicationInfo().nativeLibraryDir;
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.plugin.tor;
|
||||
import android.app.Application;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
@@ -11,7 +12,9 @@ import org.briarproject.bramble.api.plugin.Backoff;
|
||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||
import org.briarproject.bramble.api.plugin.TorControlPort;
|
||||
import org.briarproject.bramble.api.plugin.TorDirectory;
|
||||
import org.briarproject.bramble.api.plugin.TorSocksPort;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
|
||||
@@ -56,6 +59,9 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
private final AndroidWakeLockManager wakeLockManager;
|
||||
private final Clock clock;
|
||||
private final File torDirectory;
|
||||
private int torSocksPort;
|
||||
private int torControlPort;
|
||||
private final CryptoComponent crypto;
|
||||
|
||||
@Inject
|
||||
AndroidTorPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
@@ -71,7 +77,10 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
BatteryManager batteryManager,
|
||||
AndroidWakeLockManager wakeLockManager,
|
||||
Clock clock,
|
||||
@TorDirectory File torDirectory) {
|
||||
@TorDirectory File torDirectory,
|
||||
@TorSocksPort int torSocksPort,
|
||||
@TorControlPort int torControlPort,
|
||||
CryptoComponent crypto) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.wakefulIoExecutor = wakefulIoExecutor;
|
||||
this.app = app;
|
||||
@@ -86,6 +95,9 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
this.wakeLockManager = wakeLockManager;
|
||||
this.clock = clock;
|
||||
this.torDirectory = torDirectory;
|
||||
this.torSocksPort = torSocksPort;
|
||||
this.torControlPort = torControlPort;
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,13 +139,15 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||
|
||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
||||
TorRendezvousCrypto torRendezvousCrypto =
|
||||
new TorRendezvousCryptoImpl(crypto);
|
||||
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor,
|
||||
wakefulIoExecutor, app, networkManager, locationUtils,
|
||||
torSocketFactory, clock, resourceProvider,
|
||||
circumventionProvider, batteryManager, wakeLockManager,
|
||||
backoff, torRendezvousCrypto, callback, architecture,
|
||||
MAX_LATENCY, MAX_IDLE_TIME, torDirectory);
|
||||
MAX_LATENCY, MAX_IDLE_TIME, torDirectory, torSocksPort,
|
||||
torControlPort);
|
||||
eventBus.addListener(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||
'com.android.tools.analytics-library:protos:27.1.3:protos-27.1.3.jar:0d9e6cff60b318baac250b6f5bb076a8161103338bf2749cdf1db8a5a13a1f12',
|
||||
'com.android.tools.analytics-library:shared:27.1.3:shared-27.1.3.jar:10d2a51d8f89ff4ac849888e5a9c60b10e879c30d78545ec1da4d3df7bd56ae4',
|
||||
'com.android.tools.analytics-library:tracker:27.1.3:tracker-27.1.3.jar:589b355a2ba796cbc0a2b2295737de6661f078262e5f87cd6f540b8d011e5ebb',
|
||||
'com.android.tools.analytics-library:protos:30.0.3:protos-30.0.3.jar:f62b89dcd9de719c6a7b7e15fb1dd20e45b57222e675cf633607bd0ed6bca7e7',
|
||||
'com.android.tools.analytics-library:shared:30.0.3:shared-30.0.3.jar:05aa9ba3cc890354108521fdf99802565aae5dd6ca44a6ac8bb8d594d1c1cd15',
|
||||
'com.android.tools.analytics-library:tracker:30.0.3:tracker-30.0.3.jar:5d0ef35bf6733e96210b5085a2a202152921bf834d345959dce1ca3369b528df',
|
||||
'com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524:aapt2-proto-4.1.0-alpha01-6193524.jar:17e75523e1e92dd4f222c7368ee41df9e964a508232f591e265d0c499baf9dca',
|
||||
'com.android.tools.build:apksig:4.1.3:apksig-4.1.3.jar:a851980c678ff7a6785388b9a9e8cc094788ce3c4a985ad2b19c2028fd3c631a',
|
||||
'com.android.tools.build:apkzlib:4.1.3:apkzlib-4.1.3.jar:475903065e7e83a8c1ba78d267c97a54dc5a04d768b535093850423d7b11f2c8',
|
||||
'com.android.tools.build:builder-model:4.1.3:builder-model-4.1.3.jar:2624a1436c3ab39dd91d3ecf9409a594b0f89ea5cab255f2e9ff11f5ee03d274',
|
||||
'com.android.tools.build:builder-test-api:4.1.3:builder-test-api-4.1.3.jar:3d2af66726b06b53b8d6d497efcee39ff9f77eb2f8d2cce38b31502383a40d2c',
|
||||
'com.android.tools.build:builder:4.1.3:builder-4.1.3.jar:a40426cd6d68f6a722ef4950058c075e4547025e8c2fd78e732ad89f15176f84',
|
||||
'com.android.tools.build:gradle-api:4.1.3:gradle-api-4.1.3.jar:11b1fb9de658bdcf9290b1c1517060d0c4d93f2b27975934989ca4ac890bc077',
|
||||
'com.android.tools.build:manifest-merger:27.1.3:manifest-merger-27.1.3.jar:ce8d4009b1f1584777a7ffa1da3b0551dc316bc8e08112e442c352af70f46f2d',
|
||||
'com.android.tools.ddms:ddmlib:27.1.3:ddmlib-27.1.3.jar:8f76e8236d2b9eebf26378746dad025c4c7c056a02e133dae4ddef47b283c710',
|
||||
'com.android.tools.external.com-intellij:intellij-core:27.1.3:intellij-core-27.1.3.jar:652814fa099b4746fb6f10e19718e476952e8b5bac24e17d914f90650ad21808',
|
||||
'com.android.tools.external.com-intellij:kotlin-compiler:27.1.3:kotlin-compiler-27.1.3.jar:8d7a78d5efd213c5e467e42bd205582aad73ffc77ee5dc18eb1361c9af72f125',
|
||||
'com.android.tools.external.org-jetbrains:uast:27.1.3:uast-27.1.3.jar:aea53944a1ac6a05f12297b55290e8cbecfe54c4166260cfba4405823bfe1c78',
|
||||
'com.android.tools.layoutlib:layoutlib-api:27.1.3:layoutlib-api-27.1.3.jar:23875ce0a8429f33a4e86cc358f658faa0ba9c576f5f05760e544b453d67d04b',
|
||||
'com.android.tools.lint:lint-api:27.1.3:lint-api-27.1.3.jar:97666be32bcadacd944416ea334a9575ef8f4ad0c8f333151491ff4a7df43e1c',
|
||||
'com.android.tools.lint:lint-checks:27.1.3:lint-checks-27.1.3.jar:b2d71ae84a31490fe9ff26c706163fe245b2aea98e3eb747214c1085df444708',
|
||||
'com.android.tools.lint:lint-gradle-api:27.1.3:lint-gradle-api-27.1.3.jar:e54131c287a2954e6ed78a3351e5e10e35a1da2f09ac443bf44b705c71b63a4d',
|
||||
'com.android.tools.lint:lint-gradle:27.1.3:lint-gradle-27.1.3.jar:6a79e48943649d63665db7b17dbaff7af93e94ab9b15072f1a4d90486294ee9f',
|
||||
'com.android.tools.lint:lint-model:27.1.3:lint-model-27.1.3.jar:acb9e792db7000e38e3c3ca21a9b14f2de6549d7a3fc92a97ffba3d06345e5bf',
|
||||
'com.android.tools.lint:lint:27.1.3:lint-27.1.3.jar:5a2e69d0901a3a476a5b2d5001de755868113145f5f6aa557750cfad5389a44b',
|
||||
'com.android.tools:annotations:27.1.3:annotations-27.1.3.jar:904dd771883496d5dfc86619ab2555968ea4e8a29d7a5f4f7cae6fbf5429f8f5',
|
||||
'com.android.tools:common:27.1.3:common-27.1.3.jar:17ab4728e3ea50f047dd5937f0faf35f2c5416962ed74891057087ddc328bf96',
|
||||
'com.android.tools:dvlib:27.1.3:dvlib-27.1.3.jar:cead1c0c356cbe43e6855b0330fe09ef4bec2c72e22bdb4c6e7cf7e6b1dfbc37',
|
||||
'com.android.tools:repository:27.1.3:repository-27.1.3.jar:99de1a178855b56b8cd91a56296f1e0a9399c445e6acc51f1d2927947cc472cb',
|
||||
'com.android.tools:sdk-common:27.1.3:sdk-common-27.1.3.jar:b591e2aa0f1be600795f5c9e2bf81cba9b052bee452fc86c3362b5dd9e427a14',
|
||||
'com.android.tools:sdklib:27.1.3:sdklib-27.1.3.jar:ad6c08a45fe2904d05656bdddf9f623fa5c1d16bbd7b8d6a270a0734136ae02e',
|
||||
'com.android:signflinger:4.1.3:signflinger-4.1.3.jar:f3103b55ccdc8dd9ee2517eb26af93b904d41303726594372d0df59d51156e5c',
|
||||
'com.android:zipflinger:4.1.3:zipflinger-4.1.3.jar:48569896c0497268308a8014c66eb0f2bace2b9e2fc9390f3012823fb86387d5',
|
||||
'com.android.tools.build:apksig:7.0.3:apksig-7.0.3.jar:012337a2803c9a30dfc41dcbc6450686ee9e5f582549f7f126479f743a343ec9',
|
||||
'com.android.tools.build:apkzlib:7.0.3:apkzlib-7.0.3.jar:b31e53174c92db83c5cc6e7dac6734ea4e907a72e452c2bf1818dfd082c59397',
|
||||
'com.android.tools.build:builder-model:7.0.3:builder-model-7.0.3.jar:483f99d7494a5bed027e1e8d29111384cf535d4842f0be5a79805bd44bb68d4e',
|
||||
'com.android.tools.build:builder-test-api:7.0.3:builder-test-api-7.0.3.jar:f6de4bc2cef545e8367bf82d7c733829c7be3b0b3b8b09fd8c58f2150e59ab46',
|
||||
'com.android.tools.build:builder:7.0.3:builder-7.0.3.jar:c6952da0094b094c2ba0fe84c675622097c5d9b9f9beb53485b860320540cf1d',
|
||||
'com.android.tools.build:manifest-merger:30.0.3:manifest-merger-30.0.3.jar:72b346ba6318b4b6260e6e49df4bea5da2e12329ab6c2beb2269c49a9f51f178',
|
||||
'com.android.tools.ddms:ddmlib:30.0.3:ddmlib-30.0.3.jar:7a914a68ab93393657297234e2f37b22410ae9a433cba692ce8c727c9607e3bb',
|
||||
'com.android.tools.external.com-intellij:intellij-core:30.0.3:intellij-core-30.0.3.jar:1ebe858d3f58eeaa8c06507f8ac0f1c7051e6c61f35a70f3c3967d5734d3abc5',
|
||||
'com.android.tools.external.com-intellij:kotlin-compiler:30.0.3:kotlin-compiler-30.0.3.jar:ed00e441f427cb4e0d418287b9da30b12b7f735f9af32e6b5d3dc960b6a742fc',
|
||||
'com.android.tools.external.org-jetbrains:uast:30.0.3:uast-30.0.3.jar:a77801bee6ff509910e459525c9c34d7f04b066ade123547f16f1917548eadea',
|
||||
'com.android.tools.layoutlib:layoutlib-api:30.0.3:layoutlib-api-30.0.3.jar:4caa87e9ca2e11315f650d576cd59fec1793373bc3fca3f6d53c029e7534e7c4',
|
||||
'com.android.tools.lint:lint-api:30.0.3:lint-api-30.0.3.jar:bcecbd2f752a6560096a9029a47d1de6bd788a51bab505c5ebfba6a18524b983',
|
||||
'com.android.tools.lint:lint-checks:30.0.3:lint-checks-30.0.3.jar:25a7cd42dc3ad502337f131fb8b7e873c53301db0a67b1c64dd4ae7a8eb66cec',
|
||||
'com.android.tools.lint:lint-gradle:30.0.3:lint-gradle-30.0.3.jar:94544d6147a809bf2fd3440e51f28a4e42e547d74aab53eefd74938cdad42c26',
|
||||
'com.android.tools.lint:lint-model:30.0.3:lint-model-30.0.3.jar:0b940a7f575c2ff5cbd038260f41dde686a93c672213881ead3ce8af3513b396',
|
||||
'com.android.tools.lint:lint:30.0.3:lint-30.0.3.jar:ee4f11001e0c7e3b776e0d67399ad354b19b0f168822ec2b7db47c0910ed227d',
|
||||
'com.android.tools:annotations:30.0.3:annotations-30.0.3.jar:5c1944982fda8555855c4f5422fabf0dc8e2306e1f5460e9ad82dae71316bc31',
|
||||
'com.android.tools:common:30.0.3:common-30.0.3.jar:8751efaaf2c2ddd1f0a37526c794347def6a3057ca9fc510307c13a6cf0d036f',
|
||||
'com.android.tools:dvlib:30.0.3:dvlib-30.0.3.jar:5affafcec390041e5afd64cb924153f5e474db47ee8ccc2f555b495083141233',
|
||||
'com.android.tools:repository:30.0.3:repository-30.0.3.jar:0a40c6f16c506903ce2c609affd8228aceda73a69d93dfa42d4f02b8491449f6',
|
||||
'com.android.tools:sdk-common:30.0.3:sdk-common-30.0.3.jar:b45570a380360236ffee0f6bb593d66b673bad3834dfe0d6c9871fa7188ee0eb',
|
||||
'com.android.tools:sdklib:30.0.3:sdklib-30.0.3.jar:7088f20a414fab170a21e457825e14ebe099f753558e02c8acc12c67eb412162',
|
||||
'com.android:signflinger:7.0.3:signflinger-7.0.3.jar:903a4536db3e96b4e1e1dc1e400eb0b91bf7866d9b39cd7ec94d75dde158f152',
|
||||
'com.android:zipflinger:7.0.3:zipflinger-7.0.3.jar:fd209c960a3eff7a339e6fcba07d5e9ef4604d1633c69ab2df987460d9804140',
|
||||
'com.beust:jcommander:1.78:jcommander-1.78.jar:7891debb84b5f83e9bd57593ebece3399abbe0fd938cf306b3534c57913b9615',
|
||||
'com.github.javaparser:javaparser-core:3.17.0:javaparser-core-3.17.0.jar:23f5c982e1c7771423d37d52c774e8d2e80fd7ea7305ebe448797a96f67e6fca',
|
||||
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.code.gson:gson:2.8.5:gson-2.8.5.jar:233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81',
|
||||
'com.google.code.gson:gson:2.8.6:gson-2.8.6.jar:c8fb4839054d280b3033f800d1f5a97de2f028eb8ba2eb458ad287e536f3f25f',
|
||||
'com.google.dagger:dagger-compiler:2.33:dagger-compiler-2.33.jar:aa8a0d8370c578fd6999802d0d90b9829377a46d2c1141e11b8f737970e7155e',
|
||||
'com.google.dagger:dagger-producers:2.33:dagger-producers-2.33.jar:5897f0b6eef799c2adfe3ccacc58c0fb374d58acb063c3ebe5366c38a8bce5c8',
|
||||
'com.google.dagger:dagger-spi:2.33:dagger-spi-2.33.jar:e2dcab2221b8afb9556ef0a1c83b0bd5f42552e254322a257330f754cdbbb9d4',
|
||||
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
|
||||
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
|
||||
'com.google.errorprone:error_prone_annotations:2.3.2:error_prone_annotations-2.3.2.jar:357cd6cfb067c969226c442451502aee13800a24e950fdfde77bcdb4565a668d',
|
||||
'com.google.errorprone:error_prone_annotations:2.3.4:error_prone_annotations-2.3.4.jar:baf7d6ea97ce606c53e11b6854ba5f2ce7ef5c24dddf0afa18d1260bd25b002c',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
|
||||
'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7',
|
||||
'com.google.guava:guava:28.1-jre:guava-28.1-jre.jar:30beb8b8527bd07c6e747e77f1a92122c2f29d57ce347461a4a55eb26e382da4',
|
||||
'com.google.guava:guava:30.1-jre:guava-30.1-jre.jar:e6dd072f9d3fe02a4600688380bd422bdac184caf6fe2418cfdd0934f09432aa',
|
||||
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
|
||||
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
|
||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
@@ -54,63 +54,108 @@ dependencyVerification {
|
||||
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
|
||||
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
|
||||
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
|
||||
'com.sun.istack:istack-commons-runtime:3.0.7:istack-commons-runtime-3.0.7.jar:6443e10ba2e259fb821d9b6becf10db5316285fc30c53cec9d7b19a3877e7fdf',
|
||||
'com.sun.xml.fastinfoset:FastInfoset:1.2.15:FastInfoset-1.2.15.jar:785861db11ca1bd0d1956682b974ad73eb19cd3e01a4b3fa82d62eca97210aec',
|
||||
'com.sun.istack:istack-commons-runtime:3.0.8:istack-commons-runtime-3.0.8.jar:4ffabb06be454a05e4398e20c77fa2b6308d4b88dfbef7ca30a76b5b7d5505ef',
|
||||
'com.sun.xml.fastinfoset:FastInfoset:1.2.16:FastInfoset-1.2.16.jar:056f3a1e144409f21ed16afc26805f58e9a21f3fce1543c42d400719d250c511',
|
||||
'com.thoughtworks.qdox:qdox:1.12.1:qdox-1.12.1.jar:21fba22f830e9268f07cf4ab2d99e8181abbdcb0cb91ee0228eb3cb918dcdd1d',
|
||||
'commons-codec:commons-codec:1.10:commons-codec-1.10.jar:4241dfa94e711d435f29a4604a3e2de5c4aa3c165e23bd066be6fc1fc4309569',
|
||||
'commons-io:commons-io:2.4:commons-io-2.4.jar:cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581',
|
||||
'commons-logging:commons-logging:1.2:commons-logging-1.2.jar:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636',
|
||||
'it.unimi.dsi:fastutil:7.2.0:fastutil-7.2.0.jar:74fa208043740642f7e6eb09faba15965218ad2f50ce3020efb100136e4b591c',
|
||||
'javax.activation:javax.activation-api:1.2.0:javax.activation-api-1.2.0.jar:43fdef0b5b6ceb31b0424b208b930c74ab58fac2ceeb7b3f6fd3aeb8b5ca4393',
|
||||
'info.picocli:picocli:4.5.2:picocli-4.5.2.jar:b4395e9a67932616efd2245d984bf5fcd453c2c5049558c3ce959ac2af4d3fac',
|
||||
'it.unimi.dsi:fastutil:8.4.0:fastutil-8.4.0.jar:2ad2824a4a0a0eb836b52ee2fc84ba2134f44bce7bfa54015ae3f31c710a3071',
|
||||
'jakarta.activation:jakarta.activation-api:1.2.1:jakarta.activation-api-1.2.1.jar:8b0a0f52fa8b05c5431921a063ed866efaa41dadf2e3a7ee3e1961f2b0d9645b',
|
||||
'jakarta.xml.bind:jakarta.xml.bind-api:2.3.2:jakarta.xml.bind-api-2.3.2.jar:69156304079bdeed9fc0ae3b39389f19b3cc4ba4443bc80508995394ead742ea',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'javax.xml.bind:jaxb-api:2.3.1:jaxb-api-2.3.1.jar:88b955a0df57880a26a74708bc34f74dcaf8ebf4e78843a28b50eae945732b06',
|
||||
'jline:jline:2.14.6:jline-2.14.6.jar:97d1acaac82409be42e622d7a54d3ae9d08517e8aefdea3d2ba9791150c2f02d',
|
||||
'junit:junit:4.13.1:junit-4.13.1.jar:c30719db974d6452793fe191b3638a5777005485bae145924044530ffa5f6122',
|
||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
|
||||
'net.java.dev.jna:jna-platform:5.6.0:jna-platform-5.6.0.jar:9ecea8bf2b1b39963939d18b70464eef60c508fed8820f9dcaba0c35518eabf7',
|
||||
'net.java.dev.jna:jna:5.6.0:jna-5.6.0.jar:5557e235a8aa2f9766d5dc609d67948f2a8832c2d796cea9ef1d6cbe0b3b7eaf',
|
||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||
'net.sf.jopt-simple:jopt-simple:4.9:jopt-simple-4.9.jar:26c5856e954b5f864db76f13b86919b59c6eecf9fd930b96baa8884626baf2f5',
|
||||
'net.sf.kxml:kxml2:2.3.0:kxml2-2.3.0.jar:f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2',
|
||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||
'org.apache.commons:commons-compress:1.12:commons-compress-1.12.jar:2c1542faf343185b7cab9c3d55c8ae5471d6d095d3887a4adefdbdf2984dc0b6',
|
||||
'org.apache.ant:ant-antlr:1.10.9:ant-antlr-1.10.9.jar:7623dc9d0f20ea713290c6bf1a23f4c059447aef7ff9f5b2be75960f3f028d2e',
|
||||
'org.apache.ant:ant-junit:1.10.9:ant-junit-1.10.9.jar:960bdc8827954d62206ba42d0a68a7ee4476175ba47bb113e17e77cce7394630',
|
||||
'org.apache.ant:ant-launcher:1.10.9:ant-launcher-1.10.9.jar:fcce891f57f3be72149ff96ac2a80574165b3e0839866b95d24528f3027d50c1',
|
||||
'org.apache.ant:ant:1.10.9:ant-1.10.9.jar:0715478af585ea80a18985613ebecdc7922122d45b2c3c970ff9b352cddb75fc',
|
||||
'org.apache.commons:commons-compress:1.20:commons-compress-1.20.jar:0aeb625c948c697ea7b205156e112363b59ed5e2551212cd4e460bdb72c7c06e',
|
||||
'org.apache.httpcomponents:httpclient:4.5.6:httpclient-4.5.6.jar:c03f813195e7a80e3608d0ddd8da80b21696a4c92a6a2298865bf149071551c7',
|
||||
'org.apache.httpcomponents:httpcore:4.4.10:httpcore-4.4.10.jar:78ba1096561957db1b55200a159b648876430342d15d461277e62360da19f6fd',
|
||||
'org.apache.httpcomponents:httpmime:4.5.6:httpmime-4.5.6.jar:0b2b1102c18d3c7e05a77214b9b7501a6f6056174ae5604e0e256776eda7553e',
|
||||
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
||||
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
||||
'org.briarproject:obfs4proxy-android:0.0.12-dev-40245c4a:obfs4proxy-android-0.0.12-dev-40245c4a.zip:8ab05a8f8391be2cb5ab2b665c281a06d9e3a756bd0f95a40a36ca927866ea82',
|
||||
'org.briarproject:tor-android:0.3.5.15:tor-android-0.3.5.15.jar:560c5070166300b396cb2f28d82d9f639ee1fb5479096a3cef67da56d39937ad',
|
||||
'org.briarproject:tor-android:0.3.5.17:tor-android-0.3.5.17.jar:1888afc10a26b93d00a010ea27bf0b1b162a6d524688b08b98d70d14dc363b54',
|
||||
'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.8.1:checker-qual-2.8.1.jar:9103499008bcecd4e948da29b17864abb64304e15706444ae209d17ebe0575df',
|
||||
'org.codehaus.groovy:groovy-all:2.4.15:groovy-all-2.4.15.jar:51d6c4e71782e85674239189499854359d380fb75e1a703756e3aaa5b98a5af0',
|
||||
'org.checkerframework:checker-qual:3.5.0:checker-qual-3.5.0.jar:729990b3f18a95606fc2573836b6958bcdb44cb52bfbd1b7aa9c339cff35a5a4',
|
||||
'org.codehaus.groovy:groovy-ant:3.0.7:groovy-ant-3.0.7.jar:6ed2ba82813d128f7050c24142e87b3dc2ad8b504786280eb03e81f0cf6a5793',
|
||||
'org.codehaus.groovy:groovy-astbuilder:3.0.7:groovy-astbuilder-3.0.7.jar:b290451eb1583666e906c41f7d14747b4cc96363c99c478b244634fd5dfc9013',
|
||||
'org.codehaus.groovy:groovy-cli-picocli:3.0.7:groovy-cli-picocli-3.0.7.jar:71b4bd11fb30a9c7b5618e22122c9c5141958fb27f4dcf0068b6f715088f6916',
|
||||
'org.codehaus.groovy:groovy-console:3.0.7:groovy-console-3.0.7.jar:0541b358b6b8e5363215026736168fccfec1d91bac678d066fa77349eeeaa5dd',
|
||||
'org.codehaus.groovy:groovy-datetime:3.0.7:groovy-datetime-3.0.7.jar:b9823d14b1a4f94236ae2f8a471701aab17e093e1b33402b91550b5c8dd88f04',
|
||||
'org.codehaus.groovy:groovy-docgenerator:3.0.7:groovy-docgenerator-3.0.7.jar:bf53f7a11c9eb1e278e1b8ed2714c741bcf781235c803ad3ba1555f2614573f3',
|
||||
'org.codehaus.groovy:groovy-groovydoc:3.0.7:groovy-groovydoc-3.0.7.jar:86b24dfc23c005066ab83927cdb54177f06c9531773f2e2d2ecc9a131f7c2677',
|
||||
'org.codehaus.groovy:groovy-groovysh:3.0.7:groovy-groovysh-3.0.7.jar:5c40e78cbc09726aedd1c75fab112d245d665d6294870f9119e6cd3013ed14ab',
|
||||
'org.codehaus.groovy:groovy-jmx:3.0.7:groovy-jmx-3.0.7.jar:0a89f3007884eb156751937d93382038b83d39c7c2f0ab156ebf251a7251f2ab',
|
||||
'org.codehaus.groovy:groovy-json:3.0.7:groovy-json-3.0.7.jar:df1f0ee475e3fc93a6a0d17548294e160cca5de6d9d36817a7be1fbe650de03b',
|
||||
'org.codehaus.groovy:groovy-jsr223:3.0.7:groovy-jsr223-3.0.7.jar:1dbd969595332416193baa660fbb45743d19696eaa25fe98e591a2739e13517e',
|
||||
'org.codehaus.groovy:groovy-macro:3.0.7:groovy-macro-3.0.7.jar:c6cc06df526b39e2c359e2435f0071594c5a1c7babafaa6c184fdd8fa931531f',
|
||||
'org.codehaus.groovy:groovy-nio:3.0.7:groovy-nio-3.0.7.jar:db54c577882b294cd8c975ec5451596441baf54781319c61627dca0e0c2361ef',
|
||||
'org.codehaus.groovy:groovy-servlet:3.0.7:groovy-servlet-3.0.7.jar:5b6a909bf501c209adfb6205b9e740649609074455fd979bf9da4853e6ff9a39',
|
||||
'org.codehaus.groovy:groovy-sql:3.0.7:groovy-sql-3.0.7.jar:252bb6c74e1a9f41756ad4fbd3b0d2eddc93bb61109961dd1952a37bf2d57a64',
|
||||
'org.codehaus.groovy:groovy-swing:3.0.7:groovy-swing-3.0.7.jar:bd942032d9328d54c6679c49a41f6caa0d4a0039ebe598493b8a647730d98cff',
|
||||
'org.codehaus.groovy:groovy-templates:3.0.7:groovy-templates-3.0.7.jar:f119e07f650ef186ae5a4b944f9e30915b14311bad47c94a6b32de8d4f69bc80',
|
||||
'org.codehaus.groovy:groovy-test-junit5:3.0.7:groovy-test-junit5-3.0.7.jar:c16eeea07b8e396891e266d7ba9388b24ac804237ffdd9a792b0d08969bad014',
|
||||
'org.codehaus.groovy:groovy-test:3.0.7:groovy-test-3.0.7.jar:f71afd7c25d43017f89ea47e6de6daec971d159047dae083c1513a8422d44b90',
|
||||
'org.codehaus.groovy:groovy-testng:3.0.7:groovy-testng-3.0.7.jar:713d5f2231bbb5712aefd362151b9ffd884aeb7ef2e773315cc54259cbdd063d',
|
||||
'org.codehaus.groovy:groovy-xml:3.0.7:groovy-xml-3.0.7.jar:8a62e7c9ddece3e82676c4bef2f2c100f459602cd1fb6a14e94187bf863e97ff',
|
||||
'org.codehaus.groovy:groovy:3.0.7:groovy-3.0.7.jar:51d1777e8dd1f00e60ea56e00d8a354ff5aab1f00fc8464ae8d39d71867e401f',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.18:animal-sniffer-annotations-1.18.jar:47f05852b48ee9baefef80fa3d8cea60efa4753c0013121dd7fe5eef2e5c729d',
|
||||
'org.glassfish.jaxb:jaxb-runtime:2.3.1:jaxb-runtime-2.3.1.jar:45fecfa5c8217ce1f3652ab95179790ec8cc0dec0384bca51cbeb94a293d9f2f',
|
||||
'org.glassfish.jaxb:txw2:2.3.1:txw2-2.3.1.jar:34975dde1c6920f1a39791142235689bc3cd357e24d05edd8ff93b885bd68d60',
|
||||
'org.glassfish.jaxb:jaxb-runtime:2.3.2:jaxb-runtime-2.3.2.jar:e6e0a1e89fb6ff786279e6a0082d5cef52dc2ebe67053d041800737652b4fd1b',
|
||||
'org.glassfish.jaxb:txw2:2.3.2:txw2-2.3.2.jar:4a6a9f483388d461b81aa9a28c685b8b74c0597993bf1884b04eddbca95f48fe',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||
'org.jetbrains.kotlin:kotlin-reflect:1.3.72:kotlin-reflect-1.3.72.jar:a188d9367de1c4ee9479db630985c0597b20709c83161b1430d24edb27e38c40',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72:kotlin-stdlib-common-1.3.72.jar:5e7d1552863e480c1628b1cc39ce230ef829f5b7230106215a05acda5172203a',
|
||||
'org.jacoco:org.jacoco.agent:0.8.3:org.jacoco.agent-0.8.3.jar:522deb254ee16a04cc8341cc8f335f5cb7232982994d961b9cf3a0454709209f',
|
||||
'org.jacoco:org.jacoco.ant:0.8.3:org.jacoco.ant-0.8.3.jar:735844e1ae15f9b875b42a27ac5cb61cc26e106d9e839e5d1c6756709b424ce0',
|
||||
'org.jacoco:org.jacoco.core:0.8.3:org.jacoco.core-0.8.3.jar:0818437bc060a0c7cc798148f22b713702aae2771aba104444407697d578f1ea',
|
||||
'org.jacoco:org.jacoco.report:0.8.3:org.jacoco.report-0.8.3.jar:aae08fa4ff043c807b8876cdb2d8705eb8449a55efce461baa6c09da245088c1',
|
||||
'org.jetbrains.intellij.deps:trove4j:1.0.20181211:trove4j-1.0.20181211.jar:affb7c85a3c87bdcf69ff1dbb84de11f63dc931293934bc08cd7ab18de083601',
|
||||
'org.jetbrains.kotlin:kotlin-reflect:1.4.32:kotlin-reflect-1.4.32.jar:dbf19e9cdaa9c3c170f3f6f6ce3922f38dfc1d7fa1cab5b7c23a19da8b5eec5b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20:kotlin-stdlib-common-1.4.20.jar:a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72:kotlin-stdlib-jdk7-1.3.72.jar:40566c0c08d414b9413ba556ff7f8a0b04b98b9f0f424d122dd2088510efccc4',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72:kotlin-stdlib-jdk8-1.3.72.jar:133da70cfc07b56094282eac5c59bccd59f167ee2ead22e5282876d8bc10bf95',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.3.72:kotlin-stdlib-1.3.72.jar:3856a7349ebacd6d1be6802b2fed9c4dc2c5a564ea92b6b945ac988243d4b16b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32:kotlin-stdlib-common-1.4.32.jar:e1ff6f55ee9e7591dcc633f7757bac25a7edb1cc7f738b37ec652f10f66a4145',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32:kotlin-stdlib-jdk7-1.4.32.jar:5f801e75ca27d8791c14b07943c608da27620d910a8093022af57f543d5d98b6',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32:kotlin-stdlib-jdk8-1.4.32.jar:adc43e54757b106e0cd7b3b7aa257dff471b61efdabe067fc02b2f57e2396262',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.4.20:kotlin-stdlib-1.4.20.jar:b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.4.32:kotlin-stdlib-1.4.32.jar:13e9fd3e69dc7230ce0fc873a92a4e5d521d179bcf1bef75a6705baac3bfecba',
|
||||
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0:kotlinx-metadata-jvm-0.1.0.jar:9753bb39efef35957c5c15df9a3cb769aabf2cdfa74b47afcb7760e5146be3b5',
|
||||
'org.jetbrains.trove4j:trove4j:20160824:trove4j-20160824.jar:1917871c8deb468307a584680c87a44572f5a8b0b98c6d397fc0f5f86596dbe7',
|
||||
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
|
||||
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
|
||||
'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd',
|
||||
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
|
||||
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
|
||||
'org.jvnet.staxex:stax-ex:1.8:stax-ex-1.8.jar:95b05d9590af4154c6513b9c5dc1fb2e55b539972ba0a9ef28e9a0c01d83ad77',
|
||||
'org.junit.jupiter:junit-jupiter-api:5.7.0:junit-jupiter-api-5.7.0.jar:b03f78e0daeed2d77a0af9bcd662b4cdb9693f7ee72e01a539b508b84c63d182',
|
||||
'org.junit.jupiter:junit-jupiter-engine:5.7.0:junit-jupiter-engine-5.7.0.jar:dfa26af94644ac2612dde6625852fcb550a0d21caa243257de54cba738ba87af',
|
||||
'org.junit.platform:junit-platform-commons:1.7.0:junit-platform-commons-1.7.0.jar:5330ee87cc7586e6e25175a34e9251624ff12ff525269d3415d0b4ca519b6fea',
|
||||
'org.junit.platform:junit-platform-engine:1.7.0:junit-platform-engine-1.7.0.jar:75f21a20dc594afdc875736725b408cec6d0344874d29f34b2dd3075500236f2',
|
||||
'org.junit.platform:junit-platform-launcher:1.7.0:junit-platform-launcher-1.7.0.jar:fbdc748fde4c4279fe1d3c607447cb3b7ccd45d7338fc574f8a894ddf2d16818',
|
||||
'org.jvnet.staxex:stax-ex:1.8.1:stax-ex-1.8.1.jar:20522549056e9e50aa35ef0b445a2e47a53d06be0b0a9467d704e2483ffb049a',
|
||||
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
|
||||
'org.opentest4j:opentest4j:1.2.0:opentest4j-1.2.0.jar:58812de60898d976fb81ef3b62da05c6604c18fd4a249f5044282479fc286af2',
|
||||
'org.ow2.asm:asm-analysis:7.0:asm-analysis-7.0.jar:e981f8f650c4d900bb033650b18e122fa6b161eadd5f88978d08751f72ee8474',
|
||||
'org.ow2.asm:asm-commons:7.0:asm-commons-7.0.jar:fed348ef05958e3e846a3ac074a12af5f7936ef3d21ce44a62c4fa08a771927d',
|
||||
'org.ow2.asm:asm-tree:7.0:asm-tree-7.0.jar:cfd7a0874f9de36a999c127feeadfbfe6e04d4a71ee954d7af3d853f0be48a6c',
|
||||
'org.ow2.asm:asm-util:7.0:asm-util-7.0.jar:75fbbca440ef463f41c2b0ab1a80abe67e910ac486da60a7863cbcb5bae7e145',
|
||||
'org.ow2.asm:asm:7.0:asm-7.0.jar:b88ef66468b3c978ad0c97fd6e90979e56155b4ac69089ba7a44e9aa7ffe9acf',
|
||||
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
|
||||
'org.testng:testng:7.3.0:testng-7.3.0.jar:63727488f9717d57f0d0a0fee5a1fc10a2be9cfcff2ec3a7187656d663c0774e',
|
||||
'xerces:xercesImpl:2.12.0:xercesImpl-2.12.0.jar:b50d3a4ca502faa4d1c838acb8aa9480446953421f7327e338c5dda3da5e76d0',
|
||||
'xml-apis:xml-apis:1.4.01:xml-apis-1.4.01.jar:a840968176645684bb01aed376e067ab39614885f9eee44abe35a5f20ebe7fad',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,8 +10,4 @@ public interface FeatureFlags {
|
||||
boolean shouldEnableProfilePictures();
|
||||
|
||||
boolean shouldEnableDisappearingMessages();
|
||||
|
||||
boolean shouldEnableTransferData();
|
||||
|
||||
boolean shouldEnableShareAppViaOfflineHotspot();
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public interface ClientHelper {
|
||||
* group.
|
||||
*/
|
||||
ContactId getContactId(Transaction txn, GroupId contactGroupId)
|
||||
throws DbException, FormatException;
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Stores the given contact ID in the group metadata of the given contact
|
||||
|
||||
@@ -107,6 +107,12 @@ public interface ContactManager {
|
||||
*/
|
||||
String getHandshakeLink() throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the handshake link that needs to be sent to a contact we want
|
||||
* to add.
|
||||
*/
|
||||
String getHandshakeLink(Transaction txn) throws DbException;
|
||||
|
||||
/**
|
||||
* Creates a {@link PendingContact} from the given handshake link and
|
||||
* alias, adds it to the database and returns it.
|
||||
|
||||
@@ -170,4 +170,11 @@ public interface CryptoComponent {
|
||||
* length. The line terminator is CRLF.
|
||||
*/
|
||||
String asciiArmour(byte[] b, int lineLength);
|
||||
|
||||
/**
|
||||
* Encode the onion/hidden service address given its public key. As
|
||||
* specified here: https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt?id=29245fd5#n2135
|
||||
*/
|
||||
String encodeOnionAddress(byte[] publicKey);
|
||||
|
||||
}
|
||||
|
||||
@@ -471,6 +471,14 @@ public interface DatabaseComponent extends TransactionManager {
|
||||
Map<MessageId, Integer> getUnackedMessagesToSend(Transaction txn,
|
||||
ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Reset the transmission count, expiry time and ETA of all messages that
|
||||
* are eligible to be sent to the given contact. This includes messages that
|
||||
* have already been sent and are not yet due for retransmission.
|
||||
*/
|
||||
void resetUnackedMessagesToSend(Transaction txn, ContactId c)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the total length, including headers, of all messages that are
|
||||
* eligible to be sent to the given contact. This may include messages
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.briarproject.bramble.api.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class MailboxProperties {
|
||||
|
||||
private final String onionAddress, authToken;
|
||||
private final boolean owner;
|
||||
|
||||
public MailboxProperties(String onionAddress, String authToken,
|
||||
boolean owner) {
|
||||
this.onionAddress = onionAddress;
|
||||
this.authToken = authToken;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getOnionAddress() {
|
||||
return onionAddress;
|
||||
}
|
||||
|
||||
public String getAuthToken() {
|
||||
return authToken;
|
||||
}
|
||||
|
||||
public boolean isOwner() {
|
||||
return owner;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.briarproject.bramble.api.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface MailboxSettingsManager {
|
||||
|
||||
@Nullable
|
||||
MailboxProperties getOwnMailboxProperties(Transaction txn)
|
||||
throws DbException;
|
||||
|
||||
void setOwnMailboxProperties(Transaction txn, MailboxProperties p)
|
||||
throws DbException;
|
||||
|
||||
MailboxStatus getOwnMailboxStatus(Transaction txn) throws DbException;
|
||||
|
||||
void recordSuccessfulConnection(Transaction txn, long now)
|
||||
throws DbException;
|
||||
|
||||
void recordFailedConnectionAttempt(Transaction txn, long now)
|
||||
throws DbException;
|
||||
|
||||
void setPendingUpload(Transaction txn, ContactId id,
|
||||
@Nullable String filename) throws DbException;
|
||||
|
||||
@Nullable
|
||||
String getPendingUpload(Transaction txn, ContactId id) throws DbException;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.briarproject.bramble.api.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class MailboxStatus {
|
||||
|
||||
private final long lastAttempt, lastSuccess;
|
||||
private final int attemptsSinceSuccess;
|
||||
|
||||
public MailboxStatus(long lastAttempt, long lastSuccess,
|
||||
int attemptsSinceSuccess) {
|
||||
this.lastAttempt = lastAttempt;
|
||||
this.lastSuccess = lastSuccess;
|
||||
this.attemptsSinceSuccess = attemptsSinceSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of the last attempt to connect to the mailbox, in
|
||||
* milliseconds since the Unix epoch, or -1 if no attempt has been made.
|
||||
* <p>
|
||||
* If an attempt is in progress and has not yet succeeded or failed then
|
||||
* this method returns the time of the previous attempt, or -1 if the
|
||||
* current attempt is the first.
|
||||
*/
|
||||
public long getTimeOfLastAttempt() {
|
||||
return lastAttempt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of the last successful attempt to connect to the
|
||||
* mailbox, in milliseconds since the Unix epoch, or -1 if no attempt has
|
||||
* succeeded.
|
||||
* <p>
|
||||
* If the last attempt was successful then this method returns the same
|
||||
* value as {@link #getTimeOfLastAttempt()}. If an attempt is in progress
|
||||
* and has not yet succeeded or failed then this method returns the time
|
||||
* of the previous successful connection, or -1 if no attempt has
|
||||
* succeeded.
|
||||
*/
|
||||
public long getTimeOfLastSuccess() {
|
||||
return lastSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of attempts to connect to the mailbox that have
|
||||
* failed since the last attempt succeeded, or the number of attempts that
|
||||
* have been made, if no attempt has ever succeeded.
|
||||
* <p>
|
||||
* If an attempt is in progress and has not yet succeeded or failed then
|
||||
* it is not included in this count.
|
||||
*/
|
||||
public int getAttemptsSinceSuccess() {
|
||||
return attemptsSinceSuccess;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,14 @@
|
||||
package org.briarproject.bramble.api.plugin;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
|
||||
public interface TorConstants {
|
||||
|
||||
TransportId ID = new TransportId("org.briarproject.bramble.tor");
|
||||
|
||||
// Transport properties
|
||||
String PROP_ONION_V2 = "onion";
|
||||
String PROP_ONION_V3 = "onion3";
|
||||
|
||||
int SOCKS_PORT = 59050;
|
||||
int CONTROL_PORT = 59051;
|
||||
int DEFAULT_SOCKS_PORT = 59050;
|
||||
int DEFAULT_CONTROL_PORT = 59051;
|
||||
|
||||
int CONNECT_TO_PROXY_TIMEOUT = 5000; // Milliseconds
|
||||
int EXTRA_SOCKET_TIMEOUT = 30000; // Milliseconds
|
||||
@@ -21,14 +18,7 @@ public interface TorConstants {
|
||||
String PREF_TOR_PORT = "port";
|
||||
String PREF_TOR_MOBILE = "useMobileData";
|
||||
String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging";
|
||||
String HS_PRIVATE_KEY_V2 = "onionPrivKey";
|
||||
String HS_PRIVATE_KEY_V3 = "onionPrivKey3";
|
||||
String HS_V3_CREATED = "onionPrivKey3Created";
|
||||
|
||||
/**
|
||||
* How long to publish a v3 hidden service before retiring the v2 service.
|
||||
*/
|
||||
long V3_MIGRATION_PERIOD_MS = DAYS.toMillis(180);
|
||||
|
||||
// Values for PREF_TOR_NETWORK
|
||||
int PREF_TOR_NETWORK_AUTOMATIC = 0;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.briarproject.bramble.api.plugin;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Annotation for injecting the control port for the Tor plugin.
|
||||
*/
|
||||
@Qualifier
|
||||
@Target({FIELD, METHOD, PARAMETER})
|
||||
@Retention(RUNTIME)
|
||||
public @interface TorControlPort {
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.briarproject.bramble.api.plugin;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Annotation for injecting the socks port for the Tor plugin.
|
||||
*/
|
||||
@Qualifier
|
||||
@Target({FIELD, METHOD, PARAMETER})
|
||||
@Retention(RUNTIME)
|
||||
public @interface TorSocksPort {
|
||||
}
|
||||
@@ -22,4 +22,11 @@ public interface SettingsManager {
|
||||
* namespace.
|
||||
*/
|
||||
void mergeSettings(Settings s, String namespace) throws DbException;
|
||||
|
||||
/**
|
||||
* Merges the given settings with any existing settings in the given
|
||||
* namespace.
|
||||
*/
|
||||
void mergeSettings(Transaction txn, Settings s, String namespace)
|
||||
throws DbException;
|
||||
}
|
||||
|
||||
@@ -113,9 +113,25 @@ public interface KeyManager {
|
||||
/**
|
||||
* Looks up the given tag and returns a {@link StreamContext} for reading
|
||||
* from the corresponding stream, or null if an error occurs or the tag was
|
||||
* unexpected.
|
||||
* unexpected. Marks the tag as recognised and updates the reordering
|
||||
* window.
|
||||
*/
|
||||
@Nullable
|
||||
StreamContext getStreamContext(TransportId t, byte[] tag)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Looks up the given tag and returns a {@link StreamContext} for reading
|
||||
* from the corresponding stream, or null if an error occurs or the tag was
|
||||
* unexpected. Only returns the StreamContext; does not mark the tag as
|
||||
* recognised.
|
||||
*/
|
||||
@Nullable
|
||||
StreamContext getStreamContextOnly(TransportId t, byte[] tag)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the tag as recognised and updates the reordering window.
|
||||
*/
|
||||
void markTagAsRecognised(TransportId t, byte[] tag) throws DbException;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
package org.briarproject.bramble.test;
|
||||
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.lib.concurrent.Synchroniser;
|
||||
import org.junit.After;
|
||||
|
||||
public abstract class BrambleMockTestCase extends BrambleTestCase {
|
||||
|
||||
protected final Mockery context = new Mockery();
|
||||
|
||||
public BrambleMockTestCase() {
|
||||
context.setThreadingPolicy(new Synchroniser());
|
||||
}
|
||||
|
||||
@After
|
||||
public void checkExpectations() {
|
||||
context.assertIsSatisfied();
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.briarproject.bramble.identity.IdentityModule;
|
||||
import org.briarproject.bramble.io.IoModule;
|
||||
import org.briarproject.bramble.keyagreement.KeyAgreementModule;
|
||||
import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
import org.briarproject.bramble.mailbox.MailboxModule;
|
||||
import org.briarproject.bramble.plugin.PluginModule;
|
||||
import org.briarproject.bramble.properties.PropertiesModule;
|
||||
import org.briarproject.bramble.record.RecordModule;
|
||||
@@ -43,6 +44,7 @@ import dagger.Module;
|
||||
IoModule.class,
|
||||
KeyAgreementModule.class,
|
||||
LifecycleModule.class,
|
||||
MailboxModule.class,
|
||||
PluginModule.class,
|
||||
PropertiesModule.class,
|
||||
RecordModule.class,
|
||||
|
||||
@@ -121,8 +121,12 @@ class ContactManagerImpl implements ContactManager, EventListener {
|
||||
|
||||
@Override
|
||||
public String getHandshakeLink() throws DbException {
|
||||
KeyPair keyPair = db.transactionWithResult(true,
|
||||
identityManager::getHandshakeKeys);
|
||||
return db.transactionWithResult(true, this::getHandshakeLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHandshakeLink(Transaction txn) throws DbException {
|
||||
KeyPair keyPair = identityManager.getHandshakeKeys(txn);
|
||||
return pendingContactFactory.createHandshakeLink(keyPair.getPublic());
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.i2p.crypto.eddsa.KeyPairGenerator;
|
||||
import org.bouncycastle.crypto.CryptoException;
|
||||
import org.bouncycastle.crypto.Digest;
|
||||
import org.bouncycastle.crypto.digests.Blake2bDigest;
|
||||
import org.bouncycastle.crypto.digests.SHA3Digest;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
@@ -21,11 +22,13 @@ import org.briarproject.bramble.api.crypto.SignaturePrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
||||
import org.briarproject.bramble.util.Base32;
|
||||
import org.briarproject.bramble.util.ByteUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.whispersystems.curve25519.Curve25519;
|
||||
import org.whispersystems.curve25519.Curve25519KeyPair;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
@@ -58,6 +61,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
private static final int PBKDF_SALT_BYTES = 32; // 256 bits
|
||||
private static final byte PBKDF_FORMAT_SCRYPT = 0;
|
||||
private static final byte PBKDF_FORMAT_SCRYPT_STRENGTHENED = 1;
|
||||
private static final byte ONION_HS_PROTOCOL_VERSION = 3;
|
||||
private static final int ONION_CHECKSUM_BYTES = 2;
|
||||
|
||||
private final SecureRandom secureRandom;
|
||||
private final PasswordBasedKdf passwordBasedKdf;
|
||||
@@ -442,4 +447,21 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
public String asciiArmour(byte[] b, int lineLength) {
|
||||
return AsciiArmour.wrap(b, lineLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeOnionAddress(byte[] publicKey) {
|
||||
Digest digest = new SHA3Digest(256);
|
||||
byte[] label = ".onion checksum".getBytes(Charset.forName("US-ASCII"));
|
||||
digest.update(label, 0, label.length);
|
||||
digest.update(publicKey, 0, publicKey.length);
|
||||
digest.update(ONION_HS_PROTOCOL_VERSION);
|
||||
byte[] checksum = new byte[digest.getDigestSize()];
|
||||
digest.doFinal(checksum, 0);
|
||||
byte[] address = new byte[publicKey.length + ONION_CHECKSUM_BYTES + 1];
|
||||
arraycopy(publicKey, 0, address, 0, publicKey.length);
|
||||
arraycopy(checksum, 0, address, publicKey.length, ONION_CHECKSUM_BYTES);
|
||||
address[address.length - 1] = ONION_HS_PROTOCOL_VERSION;
|
||||
return Base32.encode(address).toLowerCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -757,6 +757,13 @@ interface Database<T> {
|
||||
*/
|
||||
void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Resets the transmission count, expiry time and ETA of all messages that
|
||||
* are eligible to be sent to the given contact. This includes messages that
|
||||
* have already been sent and are not yet due for retransmission.
|
||||
*/
|
||||
void resetUnackedMessagesToSend(T txn, ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the cleanup timer duration for the given message. This does not
|
||||
* start the message's cleanup timer.
|
||||
@@ -845,8 +852,8 @@ interface Database<T> {
|
||||
* of the given message with respect to the given contact, using the latency
|
||||
* of the transport over which it was sent.
|
||||
*/
|
||||
void updateExpiryTimeAndEta(T txn, ContactId c, MessageId m, long maxLatency)
|
||||
throws DbException;
|
||||
void updateExpiryTimeAndEta(T txn, ContactId c, MessageId m,
|
||||
long maxLatency) throws DbException;
|
||||
|
||||
/**
|
||||
* Stores the given transport keys, deleting any keys they have replaced.
|
||||
|
||||
@@ -750,6 +750,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
return db.getUnackedMessagesToSend(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetUnackedMessagesToSend(Transaction transaction, ContactId c)
|
||||
throws DbException {
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
db.resetUnackedMessagesToSend(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUnackedMessageBytesToSend(Transaction transaction,
|
||||
ContactId c) throws DbException {
|
||||
|
||||
@@ -429,8 +429,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
compactAndClose();
|
||||
logDuration(LOG, "Compacting database", start);
|
||||
// Allow the next transaction to reopen the DB
|
||||
synchronized (connectionsLock) {
|
||||
connectionsLock.lock();
|
||||
try {
|
||||
closed = false;
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
txn = startTransaction();
|
||||
try {
|
||||
@@ -3290,6 +3293,29 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetUnackedMessagesToSend(Connection txn, ContactId c)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "UPDATE statuses SET expiry = 0, txCount = 0, eta = 0"
|
||||
+ " WHERE contactId = ? AND state = ?"
|
||||
+ " AND groupShared = TRUE AND messageShared = TRUE"
|
||||
+ " AND deleted = FALSE AND seen = FALSE";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
ps.setInt(2, DELIVERED.getValue());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected < 0) {
|
||||
throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
tryToClose(ps, LOG, WARNING);
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCleanupTimerDuration(Connection txn, MessageId m,
|
||||
long duration) throws DbException {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.bramble.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class MailboxModule {
|
||||
|
||||
@Provides
|
||||
MailboxSettingsManager provideMailboxSettingsManager(
|
||||
MailboxSettingsManagerImpl mailboxSettingsManager) {
|
||||
return mailboxSettingsManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package org.briarproject.bramble.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.settings.Settings;
|
||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class MailboxSettingsManagerImpl implements MailboxSettingsManager {
|
||||
|
||||
// Package access for testing
|
||||
static final String SETTINGS_NAMESPACE = "mailbox";
|
||||
static final String SETTINGS_KEY_ONION = "onion";
|
||||
static final String SETTINGS_KEY_TOKEN = "token";
|
||||
static final String SETTINGS_KEY_LAST_ATTEMPT = "lastAttempt";
|
||||
static final String SETTINGS_KEY_LAST_SUCCESS = "lastSuccess";
|
||||
static final String SETTINGS_KEY_ATTEMPTS = "attempts";
|
||||
static final String SETTINGS_UPLOADS_NAMESPACE = "mailbox-uploads";
|
||||
|
||||
private final SettingsManager settingsManager;
|
||||
|
||||
@Inject
|
||||
MailboxSettingsManagerImpl(SettingsManager settingsManager) {
|
||||
this.settingsManager = settingsManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailboxProperties getOwnMailboxProperties(Transaction txn)
|
||||
throws DbException {
|
||||
Settings s = settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
||||
String onion = s.get(SETTINGS_KEY_ONION);
|
||||
String token = s.get(SETTINGS_KEY_TOKEN);
|
||||
if (isNullOrEmpty(onion) || isNullOrEmpty(token)) return null;
|
||||
return new MailboxProperties(onion, token, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwnMailboxProperties(Transaction txn, MailboxProperties p)
|
||||
throws DbException {
|
||||
Settings s = new Settings();
|
||||
s.put(SETTINGS_KEY_ONION, p.getOnionAddress());
|
||||
s.put(SETTINGS_KEY_TOKEN, p.getAuthToken());
|
||||
settingsManager.mergeSettings(txn, s, SETTINGS_NAMESPACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailboxStatus getOwnMailboxStatus(Transaction txn)
|
||||
throws DbException {
|
||||
Settings s = settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
||||
long lastAttempt = s.getLong(SETTINGS_KEY_LAST_ATTEMPT, -1);
|
||||
long lastSuccess = s.getLong(SETTINGS_KEY_LAST_SUCCESS, -1);
|
||||
int attempts = s.getInt(SETTINGS_KEY_ATTEMPTS, 0);
|
||||
return new MailboxStatus(lastAttempt, lastSuccess, attempts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordSuccessfulConnection(Transaction txn, long now)
|
||||
throws DbException {
|
||||
Settings s = new Settings();
|
||||
s.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
||||
s.putLong(SETTINGS_KEY_LAST_SUCCESS, now);
|
||||
s.putInt(SETTINGS_KEY_ATTEMPTS, 0);
|
||||
settingsManager.mergeSettings(txn, s, SETTINGS_NAMESPACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFailedConnectionAttempt(Transaction txn, long now)
|
||||
throws DbException {
|
||||
Settings oldSettings =
|
||||
settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
||||
int attempts = oldSettings.getInt(SETTINGS_KEY_ATTEMPTS, 0);
|
||||
Settings newSettings = new Settings();
|
||||
newSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
||||
newSettings.putInt(SETTINGS_KEY_ATTEMPTS, attempts + 1);
|
||||
settingsManager.mergeSettings(txn, newSettings, SETTINGS_NAMESPACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPendingUpload(Transaction txn, ContactId id,
|
||||
@Nullable String filename) throws DbException {
|
||||
Settings s = new Settings();
|
||||
String value = filename == null ? "" : filename;
|
||||
s.put(String.valueOf(id.getInt()), value);
|
||||
settingsManager.mergeSettings(txn, s, SETTINGS_UPLOADS_NAMESPACE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getPendingUpload(Transaction txn, ContactId id)
|
||||
throws DbException {
|
||||
Settings s =
|
||||
settingsManager.getSettings(txn, SETTINGS_UPLOADS_NAMESPACE);
|
||||
String filename = s.get(String.valueOf(id.getInt()));
|
||||
if (isNullOrEmpty(filename)) return null;
|
||||
return filename;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,71 @@
|
||||
package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO: Create a module for this so it doesn't have to be public
|
||||
|
||||
@NotNullByDefault
|
||||
public interface CircumventionProvider {
|
||||
|
||||
enum BridgeType {
|
||||
DEFAULT_OBFS4,
|
||||
NON_DEFAULT_OBFS4,
|
||||
MEEK
|
||||
}
|
||||
|
||||
/**
|
||||
* Countries where Tor is blocked, i.e. vanilla Tor connection won't work.
|
||||
*
|
||||
* <p>
|
||||
* See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
|
||||
* and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki
|
||||
*/
|
||||
String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"};
|
||||
String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE", "RU"};
|
||||
|
||||
/**
|
||||
* Countries where obfs4 or meek bridge connections are likely to work.
|
||||
* Should be a subset of {@link #BLOCKED}.
|
||||
* Should be a subset of {@link #BLOCKED} and the union of
|
||||
* {@link #DEFAULT_OBFS4_BRIDGES}, {@link #NON_DEFAULT_OBFS4_BRIDGES} and
|
||||
* {@link #MEEK_BRIDGES}.
|
||||
*/
|
||||
String[] BRIDGES = { "CN", "IR", "EG", "BY", "TR", "SY", "VE" };
|
||||
String[] BRIDGES = {"CN", "IR", "EG", "BY", "TR", "SY", "VE", "RU"};
|
||||
|
||||
/**
|
||||
* Countries where default obfs4 bridges are likely to work.
|
||||
* Should be a subset of {@link #BRIDGES}.
|
||||
*/
|
||||
String[] DEFAULT_OBFS4_BRIDGES = {"EG", "BY", "TR", "SY", "VE"};
|
||||
|
||||
/**
|
||||
* Countries where non-default obfs4 bridges are likely to work.
|
||||
* Should be a subset of {@link #BRIDGES}.
|
||||
*/
|
||||
String[] NON_DEFAULT_OBFS4_BRIDGES = {"RU"};
|
||||
|
||||
/**
|
||||
* Countries where obfs4 bridges won't work and meek is needed.
|
||||
* Should be a subset of {@link #BRIDGES}.
|
||||
*/
|
||||
String[] NEEDS_MEEK = {"CN", "IR"};
|
||||
String[] MEEK_BRIDGES = {"CN", "IR"};
|
||||
|
||||
/**
|
||||
* Returns true if vanilla Tor connections are blocked in the given country.
|
||||
*/
|
||||
boolean isTorProbablyBlocked(String countryCode);
|
||||
|
||||
/**
|
||||
* Returns true if bridge connections of some type work in the given
|
||||
* country.
|
||||
*/
|
||||
boolean doBridgesWork(String countryCode);
|
||||
|
||||
boolean needsMeek(String countryCode);
|
||||
/**
|
||||
* Returns the best type of bridge connection for the given country, or
|
||||
* {@link #DEFAULT_OBFS4_BRIDGES} if no bridge type is known to work.
|
||||
*/
|
||||
BridgeType getBestBridgeType(String countryCode);
|
||||
|
||||
@IoExecutor
|
||||
List<String> getBridges(boolean meek);
|
||||
List<String> getBridges(BridgeType type);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -9,24 +10,31 @@ import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.DEFAULT_OBFS4;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.MEEK;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.NON_DEFAULT_OBFS4;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class CircumventionProviderImpl implements CircumventionProvider {
|
||||
|
||||
private final static String BRIDGE_FILE_NAME = "bridges";
|
||||
|
||||
private static final Set<String> BLOCKED_IN_COUNTRIES =
|
||||
new HashSet<>(asList(BLOCKED));
|
||||
private static final Set<String> BRIDGES_WORK_IN_COUNTRIES =
|
||||
private static final Set<String> BRIDGE_COUNTRIES =
|
||||
new HashSet<>(asList(BRIDGES));
|
||||
private static final Set<String> BRIDGES_NEED_MEEK =
|
||||
new HashSet<>(asList(NEEDS_MEEK));
|
||||
|
||||
@Nullable
|
||||
private volatile List<String> bridges = null;
|
||||
private static final Set<String> DEFAULT_OBFS4_BRIDGE_COUNTRIES =
|
||||
new HashSet<>(asList(DEFAULT_OBFS4_BRIDGES));
|
||||
private static final Set<String> NON_DEFAULT_OBFS4_BRIDGE_COUNTRIES =
|
||||
new HashSet<>(asList(NON_DEFAULT_OBFS4_BRIDGES));
|
||||
private static final Set<String> MEEK_COUNTRIES =
|
||||
new HashSet<>(asList(MEEK_BRIDGES));
|
||||
|
||||
@Inject
|
||||
CircumventionProviderImpl() {
|
||||
@@ -39,33 +47,42 @@ class CircumventionProviderImpl implements CircumventionProvider {
|
||||
|
||||
@Override
|
||||
public boolean doBridgesWork(String countryCode) {
|
||||
return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode);
|
||||
return BRIDGE_COUNTRIES.contains(countryCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsMeek(String countryCode) {
|
||||
return BRIDGES_NEED_MEEK.contains(countryCode);
|
||||
public BridgeType getBestBridgeType(String countryCode) {
|
||||
if (DEFAULT_OBFS4_BRIDGE_COUNTRIES.contains(countryCode)) {
|
||||
return DEFAULT_OBFS4;
|
||||
} else if (NON_DEFAULT_OBFS4_BRIDGE_COUNTRIES.contains(countryCode)) {
|
||||
return NON_DEFAULT_OBFS4;
|
||||
} else if (MEEK_COUNTRIES.contains(countryCode)) {
|
||||
return MEEK;
|
||||
} else {
|
||||
return DEFAULT_OBFS4;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@IoExecutor
|
||||
public List<String> getBridges(boolean useMeek) {
|
||||
List<String> bridges = this.bridges;
|
||||
if (bridges != null) return new ArrayList<>(bridges);
|
||||
|
||||
InputStream is = getClass().getClassLoader()
|
||||
.getResourceAsStream(BRIDGE_FILE_NAME);
|
||||
public List<String> getBridges(BridgeType type) {
|
||||
InputStream is = requireNonNull(getClass().getClassLoader()
|
||||
.getResourceAsStream(BRIDGE_FILE_NAME));
|
||||
Scanner scanner = new Scanner(is);
|
||||
|
||||
bridges = new ArrayList<>();
|
||||
List<String> bridges = new ArrayList<>();
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
boolean isMeekBridge = line.startsWith("Bridge meek");
|
||||
if (useMeek && !isMeekBridge || !useMeek && isMeekBridge) continue;
|
||||
if (!line.startsWith("#")) bridges.add(line);
|
||||
boolean isDefaultObfs4 = line.startsWith("d ");
|
||||
boolean isNonDefaultObfs4 = line.startsWith("n ");
|
||||
boolean isMeek = line.startsWith("m ");
|
||||
if ((type == DEFAULT_OBFS4 && isDefaultObfs4) ||
|
||||
(type == NON_DEFAULT_OBFS4 && isNonDefaultObfs4) ||
|
||||
(type == MEEK && isMeek)) {
|
||||
bridges.add(line.substring(2));
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
this.bridges = bridges;
|
||||
return bridges;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,9 @@ import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.system.LocationUtils;
|
||||
import org.briarproject.bramble.api.system.ResourceProvider;
|
||||
import org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -44,6 +46,7 @@ import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -68,20 +71,16 @@ import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
|
||||
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_PLUGIN_ENABLE;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_MOBILE;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_NETWORK;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.HS_PRIVATE_KEY_V2;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.HS_PRIVATE_KEY_V3;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.HS_V3_CREATED;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.ID;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
|
||||
@@ -90,12 +89,11 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ONLY_WHEN_CHARGING;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V2;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.V3_MIGRATION_PERIOD_MS;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.MEEK;
|
||||
import static org.briarproject.bramble.plugin.tor.TorRendezvousCrypto.SEED_BYTES;
|
||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||
@@ -115,7 +113,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
private static final String OWNER = "__OwningControllerProcess";
|
||||
private static final int COOKIE_TIMEOUT_MS = 3000;
|
||||
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
|
||||
private static final Pattern ONION_V2 = Pattern.compile("[a-z2-7]{16}");
|
||||
private static final Pattern ONION_V3 = Pattern.compile("[a-z2-7]{56}");
|
||||
|
||||
private final Executor ioExecutor, wakefulIoExecutor;
|
||||
@@ -132,8 +129,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
private final CircumventionProvider circumventionProvider;
|
||||
private final ResourceProvider resourceProvider;
|
||||
private final long maxLatency;
|
||||
private final int maxIdleTime, socketTimeout;
|
||||
private final int maxIdleTime;
|
||||
private final int socketTimeout;
|
||||
private final File torDirectory, geoIpFile, configFile;
|
||||
private final int torSocksPort;
|
||||
private final int torControlPort;
|
||||
private final File doneFile, cookieFile;
|
||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||
|
||||
@@ -162,7 +162,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
String architecture,
|
||||
long maxLatency,
|
||||
int maxIdleTime,
|
||||
File torDirectory) {
|
||||
File torDirectory,
|
||||
int torSocksPort,
|
||||
int torControlPort) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.wakefulIoExecutor = wakefulIoExecutor;
|
||||
this.networkManager = networkManager;
|
||||
@@ -182,6 +184,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
socketTimeout = Integer.MAX_VALUE;
|
||||
else socketTimeout = maxIdleTime * 2;
|
||||
this.torDirectory = torDirectory;
|
||||
this.torSocksPort = torSocksPort;
|
||||
this.torControlPort = torControlPort;
|
||||
geoIpFile = new File(torDirectory, "geoip");
|
||||
configFile = new File(torDirectory, "torrc");
|
||||
doneFile = new File(torDirectory, "done");
|
||||
@@ -277,6 +281,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
|
||||
throw new PluginException();
|
||||
}
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(COOKIE_POLLING_INTERVAL_MS);
|
||||
}
|
||||
LOG.info("Auth cookie created");
|
||||
@@ -287,7 +292,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
}
|
||||
try {
|
||||
// Open a control connection and authenticate using the cookie file
|
||||
controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
|
||||
controlSocket = new Socket("127.0.0.1", torControlPort);
|
||||
controlConnection = new TorControlConnection(controlSocket);
|
||||
controlConnection.authenticate(read(cookieFile));
|
||||
// Tell Tor to exit when the control connection is closed
|
||||
@@ -390,9 +395,24 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
return zin;
|
||||
}
|
||||
|
||||
private static void append(StringBuilder strb, String name, int value) {
|
||||
strb.append(name);
|
||||
strb.append(" ");
|
||||
strb.append(value);
|
||||
strb.append("\n");
|
||||
}
|
||||
|
||||
private InputStream getConfigInputStream() {
|
||||
ClassLoader cl = getClass().getClassLoader();
|
||||
return requireNonNull(cl.getResourceAsStream("torrc"));
|
||||
StringBuilder strb = new StringBuilder();
|
||||
append(strb, "ControlPort", torControlPort);
|
||||
append(strb, "CookieAuthentication", 1);
|
||||
append(strb, "DisableNetwork", 1);
|
||||
append(strb, "RunAsDaemon", 1);
|
||||
append(strb, "SafeSocks", 1);
|
||||
append(strb, "SocksPort", torSocksPort);
|
||||
//noinspection CharsetObjectCanBeUsed
|
||||
return new ByteArrayInputStream(
|
||||
strb.toString().getBytes(Charset.forName("UTF-8")));
|
||||
}
|
||||
|
||||
private void listFiles(File f) {
|
||||
@@ -457,54 +477,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
|
||||
private void publishHiddenService(String port) {
|
||||
if (!state.isTorRunning()) return;
|
||||
// TODO: Remove support for v2 hidden services after a reasonable
|
||||
// migration period (migration started 2020-06-30)
|
||||
String privKey2 = settings.get(HS_PRIVATE_KEY_V2);
|
||||
String privKey3 = settings.get(HS_PRIVATE_KEY_V3);
|
||||
String v3Created = settings.get(HS_V3_CREATED);
|
||||
// Publish a v2 hidden service if we've already created one, and
|
||||
// either we've never published a v3 hidden service or we're still
|
||||
// in the migration period since first publishing it
|
||||
if (!isNullOrEmpty(privKey2)) {
|
||||
long now = clock.currentTimeMillis();
|
||||
long then = v3Created == null ? now : Long.parseLong(v3Created);
|
||||
if (now - then >= V3_MIGRATION_PERIOD_MS) retireV2HiddenService();
|
||||
else publishV2HiddenService(port, privKey2);
|
||||
}
|
||||
publishV3HiddenService(port, privKey3);
|
||||
}
|
||||
|
||||
private void publishV2HiddenService(String port, String privKey) {
|
||||
LOG.info("Creating v2 hidden service");
|
||||
Map<Integer, String> portLines = singletonMap(80, "127.0.0.1:" + port);
|
||||
Map<String, String> response;
|
||||
try {
|
||||
response = controlConnection.addOnion(privKey, portLines);
|
||||
} catch (IOException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
return;
|
||||
}
|
||||
if (!response.containsKey(HS_ADDRESS)) {
|
||||
LOG.warning("Tor did not return a hidden service address");
|
||||
return;
|
||||
}
|
||||
String onion2 = response.get(HS_ADDRESS);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("V2 hidden service " + scrubOnion(onion2));
|
||||
}
|
||||
// The hostname has already been published and the private key stored
|
||||
}
|
||||
|
||||
private void retireV2HiddenService() {
|
||||
LOG.info("Retiring v2 hidden service");
|
||||
TransportProperties p = new TransportProperties();
|
||||
p.put(PROP_ONION_V2, "");
|
||||
callback.mergeLocalProperties(p);
|
||||
Settings s = new Settings();
|
||||
s.put(HS_PRIVATE_KEY_V2, "");
|
||||
callback.mergeSettings(s);
|
||||
}
|
||||
|
||||
private void publishV3HiddenService(String port, @Nullable String privKey) {
|
||||
LOG.info("Creating v3 hidden service");
|
||||
Map<Integer, String> portLines = singletonMap(80, "127.0.0.1:" + port);
|
||||
@@ -541,7 +517,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
// Save the hidden service's private key for next time
|
||||
Settings s = new Settings();
|
||||
s.put(HS_PRIVATE_KEY_V3, response.get(HS_PRIVKEY));
|
||||
s.put(HS_V3_CREATED, String.valueOf(clock.currentTimeMillis()));
|
||||
callback.mergeSettings(s);
|
||||
}
|
||||
}
|
||||
@@ -569,20 +544,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
controlConnection.setConf("DisableNetwork", enable ? "0" : "1");
|
||||
}
|
||||
|
||||
private void enableBridges(boolean enable, boolean needsMeek)
|
||||
private void enableBridges(boolean enable, BridgeType bridgeType)
|
||||
throws IOException {
|
||||
if (enable) {
|
||||
Collection<String> conf = new ArrayList<>();
|
||||
conf.add("UseBridges 1");
|
||||
File obfs4File = getObfs4ExecutableFile();
|
||||
if (needsMeek) {
|
||||
if (bridgeType == MEEK) {
|
||||
conf.add("ClientTransportPlugin meek_lite exec " +
|
||||
obfs4File.getAbsolutePath());
|
||||
} else {
|
||||
conf.add("ClientTransportPlugin obfs4 exec " +
|
||||
obfs4File.getAbsolutePath());
|
||||
}
|
||||
conf.addAll(circumventionProvider.getBridges(needsMeek));
|
||||
conf.addAll(circumventionProvider.getBridges(bridgeType));
|
||||
controlConnection.setConf(conf);
|
||||
} else {
|
||||
controlConnection.setConf("UseBridges", "0");
|
||||
@@ -648,49 +623,30 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
@Override
|
||||
public DuplexTransportConnection createConnection(TransportProperties p) {
|
||||
if (getState() != ACTIVE) return null;
|
||||
// TODO: Remove support for v2 hidden services after a reasonable
|
||||
// migration period (migration started 2020-06-30)
|
||||
String bestOnion = null, version = null;
|
||||
String onion2 = p.get(PROP_ONION_V2);
|
||||
String onion3 = p.get(PROP_ONION_V3);
|
||||
if (!isNullOrEmpty(onion2)) {
|
||||
if (ONION_V2.matcher(onion2).matches()) {
|
||||
bestOnion = onion2;
|
||||
version = "v2";
|
||||
} else {
|
||||
// Don't scrub the address so we can find the problem
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Invalid v2 hostname: " + onion2);
|
||||
if (onion3 != null && !ONION_V3.matcher(onion3).matches()) {
|
||||
// Don't scrub the address so we can find the problem
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Invalid v3 hostname: " + onion3);
|
||||
}
|
||||
onion3 = null;
|
||||
}
|
||||
if (!isNullOrEmpty(onion3)) {
|
||||
if (ONION_V3.matcher(onion3).matches()) {
|
||||
bestOnion = onion3;
|
||||
version = "v3";
|
||||
} else {
|
||||
// Don't scrub the address so we can find the problem
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Invalid v3 hostname: " + onion3);
|
||||
}
|
||||
}
|
||||
if (bestOnion == null) return null;
|
||||
if (onion3 == null) return null;
|
||||
Socket s = null;
|
||||
try {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Connecting to " + version + " "
|
||||
+ scrubOnion(bestOnion));
|
||||
LOG.info("Connecting to v3 " + scrubOnion(onion3));
|
||||
}
|
||||
s = torSocketFactory.createSocket(bestOnion + ".onion", 80);
|
||||
s = torSocketFactory.createSocket(onion3 + ".onion", 80);
|
||||
s.setSoTimeout(socketTimeout);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Connected to " + version + " "
|
||||
+ scrubOnion(bestOnion));
|
||||
LOG.info("Connected to v3 " + scrubOnion(onion3));
|
||||
}
|
||||
return new TorTransportConnection(this, s);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Could not connect to " + version + " "
|
||||
+ scrubOnion(bestOnion) + ": " + e.toString());
|
||||
LOG.info("Could not connect to v3 "
|
||||
+ scrubOnion(onion3) + ": " + e.toString());
|
||||
}
|
||||
tryToClose(s, LOG, WARNING);
|
||||
return null;
|
||||
@@ -890,7 +846,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
|
||||
int reasonsDisabled = 0;
|
||||
boolean enableNetwork = false, enableBridges = false;
|
||||
boolean useMeek = false, enableConnectionPadding = false;
|
||||
boolean enableConnectionPadding = false;
|
||||
BridgeType bridgeType =
|
||||
circumventionProvider.getBestBridgeType(country);
|
||||
|
||||
if (!online) {
|
||||
LOG.info("Disabling network, device is offline");
|
||||
@@ -919,14 +877,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
enableNetwork = true;
|
||||
if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
|
||||
(automatic && bridgesWork)) {
|
||||
if (ipv6Only ||
|
||||
circumventionProvider.needsMeek(country)) {
|
||||
LOG.info("Using meek bridges");
|
||||
enableBridges = true;
|
||||
useMeek = true;
|
||||
} else {
|
||||
LOG.info("Using obfs4 bridges");
|
||||
enableBridges = true;
|
||||
if (ipv6Only) bridgeType = MEEK;
|
||||
enableBridges = true;
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Using bridge type " + bridgeType);
|
||||
}
|
||||
} else {
|
||||
LOG.info("Not using bridges");
|
||||
@@ -944,7 +898,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
|
||||
try {
|
||||
if (enableNetwork) {
|
||||
enableBridges(enableBridges, useMeek);
|
||||
enableBridges(enableBridges, bridgeType);
|
||||
enableConnectionPadding(enableConnectionPadding);
|
||||
useIpv6(ipv6Only);
|
||||
}
|
||||
@@ -984,17 +938,17 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
@Nullable
|
||||
private ServerSocket serverSocket = null;
|
||||
|
||||
synchronized void setStarted() {
|
||||
private synchronized void setStarted() {
|
||||
started = true;
|
||||
callback.pluginStateChanged(getState());
|
||||
}
|
||||
|
||||
synchronized boolean isTorRunning() {
|
||||
private synchronized boolean isTorRunning() {
|
||||
return started && !stopped;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
synchronized ServerSocket setStopped() {
|
||||
private synchronized ServerSocket setStopped() {
|
||||
stopped = true;
|
||||
ServerSocket ss = serverSocket;
|
||||
serverSocket = null;
|
||||
@@ -1002,44 +956,44 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
return ss;
|
||||
}
|
||||
|
||||
synchronized void setBootstrapped() {
|
||||
private synchronized void setBootstrapped() {
|
||||
bootstrapped = true;
|
||||
callback.pluginStateChanged(getState());
|
||||
}
|
||||
|
||||
synchronized boolean getAndSetCircuitBuilt() {
|
||||
private synchronized boolean getAndSetCircuitBuilt() {
|
||||
boolean firstCircuit = !circuitBuilt;
|
||||
circuitBuilt = true;
|
||||
callback.pluginStateChanged(getState());
|
||||
return firstCircuit;
|
||||
}
|
||||
|
||||
synchronized void enableNetwork(boolean enable) {
|
||||
private synchronized void enableNetwork(boolean enable) {
|
||||
networkInitialised = true;
|
||||
networkEnabled = enable;
|
||||
if (!enable) circuitBuilt = false;
|
||||
callback.pluginStateChanged(getState());
|
||||
}
|
||||
|
||||
synchronized void setReasonsDisabled(int reasonsDisabled) {
|
||||
private synchronized void setReasonsDisabled(int reasonsDisabled) {
|
||||
settingsChecked = true;
|
||||
this.reasonsDisabled = reasonsDisabled;
|
||||
callback.pluginStateChanged(getState());
|
||||
}
|
||||
|
||||
// Doesn't affect getState()
|
||||
synchronized boolean setServerSocket(ServerSocket ss) {
|
||||
private synchronized boolean setServerSocket(ServerSocket ss) {
|
||||
if (stopped || serverSocket != null) return false;
|
||||
serverSocket = ss;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Doesn't affect getState()
|
||||
synchronized void clearServerSocket(ServerSocket ss) {
|
||||
private synchronized void clearServerSocket(ServerSocket ss) {
|
||||
if (serverSocket == ss) serverSocket = null;
|
||||
}
|
||||
|
||||
synchronized State getState() {
|
||||
private synchronized State getState() {
|
||||
if (!started || stopped || !settingsChecked) {
|
||||
return STARTING_STOPPING;
|
||||
}
|
||||
@@ -1049,7 +1003,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
return bootstrapped && circuitBuilt ? ACTIVE : ENABLING;
|
||||
}
|
||||
|
||||
synchronized int getReasonsDisabled() {
|
||||
private synchronized int getReasonsDisabled() {
|
||||
return getState() == DISABLED ? reasonsDisabled : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,39 +4,26 @@ import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
||||
|
||||
import org.bouncycastle.crypto.Digest;
|
||||
import org.bouncycastle.crypto.digests.SHA3Digest;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
import org.briarproject.bramble.util.Base32;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static java.lang.System.arraycopy;
|
||||
|
||||
public class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
||||
class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
||||
|
||||
private static final EdDSANamedCurveSpec CURVE_SPEC =
|
||||
EdDSANamedCurveTable.getByName("Ed25519");
|
||||
|
||||
private static final byte HS_PROTOCOL_VERSION = 3;
|
||||
private static final int CHECKSUM_BYTES = 2;
|
||||
private final CryptoComponent crypto;
|
||||
|
||||
TorRendezvousCryptoImpl(CryptoComponent crypto) {
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOnionAddress(byte[] seed) {
|
||||
EdDSAPrivateKeySpec spec = new EdDSAPrivateKeySpec(seed, CURVE_SPEC);
|
||||
byte[] publicKey = spec.getA().toByteArray();
|
||||
Digest digest = new SHA3Digest(256);
|
||||
byte[] label = ".onion checksum".getBytes(Charset.forName("US-ASCII"));
|
||||
digest.update(label, 0, label.length);
|
||||
digest.update(publicKey, 0, publicKey.length);
|
||||
digest.update(HS_PROTOCOL_VERSION);
|
||||
byte[] checksum = new byte[digest.getDigestSize()];
|
||||
digest.doFinal(checksum, 0);
|
||||
byte[] address = new byte[publicKey.length + CHECKSUM_BYTES + 1];
|
||||
arraycopy(publicKey, 0, address, 0, publicKey.length);
|
||||
arraycopy(checksum, 0, address, publicKey.length, CHECKSUM_BYTES);
|
||||
address[address.length - 1] = HS_PROTOCOL_VERSION;
|
||||
return Base32.encode(address).toLowerCase();
|
||||
return crypto.encodeOnionAddress(spec.getA().toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,4 +37,10 @@ class SettingsManagerImpl implements SettingsManager {
|
||||
public void mergeSettings(Settings s, String namespace) throws DbException {
|
||||
db.transaction(false, txn -> db.mergeSettings(txn, s, namespace));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergeSettings(Transaction txn, Settings s, String namespace)
|
||||
throws DbException {
|
||||
db.mergeSettings(txn, s, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.briarproject.bramble.socks;
|
||||
|
||||
import org.briarproject.bramble.api.plugin.TorSocksPort;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
@@ -9,15 +11,14 @@ import dagger.Provides;
|
||||
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.CONNECT_TO_PROXY_TIMEOUT;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.EXTRA_SOCKET_TIMEOUT;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.SOCKS_PORT;
|
||||
|
||||
@Module
|
||||
public class SocksModule {
|
||||
|
||||
@Provides
|
||||
SocketFactory provideTorSocketFactory() {
|
||||
SocketFactory provideTorSocketFactory(@TorSocksPort int torSocksPort) {
|
||||
InetSocketAddress proxy = new InetSocketAddress("127.0.0.1",
|
||||
SOCKS_PORT);
|
||||
torSocksPort);
|
||||
return new SocksSocketFactory(proxy, CONNECT_TO_PROXY_TIMEOUT,
|
||||
EXTRA_SOCKET_TIMEOUT);
|
||||
}
|
||||
|
||||
@@ -215,6 +215,23 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
m.getStreamContext(txn, tag)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamContext getStreamContextOnly(TransportId t, byte[] tag)
|
||||
throws DbException {
|
||||
return withManager(t, m ->
|
||||
db.transactionWithNullableResult(false, txn ->
|
||||
m.getStreamContextOnly(txn, tag)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markTagAsRecognised(TransportId t, byte[] tag)
|
||||
throws DbException {
|
||||
withManager(t, m -> {
|
||||
db.transaction(false, txn -> m.markTagAsRecognised(txn, tag));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
|
||||
@@ -48,4 +48,9 @@ interface TransportKeyManager {
|
||||
StreamContext getStreamContext(Transaction txn, byte[] tag)
|
||||
throws DbException;
|
||||
|
||||
@Nullable
|
||||
StreamContext getStreamContextOnly(Transaction txn, byte[] tag);
|
||||
|
||||
void markTagAsRecognised(Transaction txn, byte[] tag) throws DbException;
|
||||
|
||||
}
|
||||
|
||||
@@ -393,56 +393,82 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
throws DbException {
|
||||
lock.lock();
|
||||
try {
|
||||
// Look up the incoming keys for the tag
|
||||
TagContext tagCtx = inContexts.remove(new Bytes(tag));
|
||||
if (tagCtx == null) return null;
|
||||
MutableIncomingKeys inKeys = tagCtx.inKeys;
|
||||
// Create a stream context
|
||||
StreamContext ctx = new StreamContext(tagCtx.contactId,
|
||||
tagCtx.pendingContactId, transportId,
|
||||
inKeys.getTagKey(), inKeys.getHeaderKey(),
|
||||
tagCtx.streamNumber, tagCtx.handshakeMode);
|
||||
// Update the reordering window
|
||||
ReorderingWindow window = inKeys.getWindow();
|
||||
Change change = window.setSeen(tagCtx.streamNumber);
|
||||
// Add tags for any stream numbers added to the window
|
||||
for (long streamNumber : change.getAdded()) {
|
||||
byte[] addTag = new byte[TAG_LENGTH];
|
||||
transportCrypto.encodeTag(addTag, inKeys.getTagKey(),
|
||||
PROTOCOL_VERSION, streamNumber);
|
||||
TagContext tagCtx1 = new TagContext(tagCtx.keySetId,
|
||||
tagCtx.contactId, tagCtx.pendingContactId, inKeys,
|
||||
streamNumber, tagCtx.handshakeMode);
|
||||
inContexts.put(new Bytes(addTag), tagCtx1);
|
||||
}
|
||||
// Remove tags for any stream numbers removed from the window
|
||||
for (long streamNumber : change.getRemoved()) {
|
||||
if (streamNumber == tagCtx.streamNumber) continue;
|
||||
byte[] removeTag = new byte[TAG_LENGTH];
|
||||
transportCrypto.encodeTag(removeTag, inKeys.getTagKey(),
|
||||
PROTOCOL_VERSION, streamNumber);
|
||||
inContexts.remove(new Bytes(removeTag));
|
||||
}
|
||||
// Write the window back to the DB
|
||||
db.setReorderingWindow(txn, tagCtx.keySetId, transportId,
|
||||
inKeys.getTimePeriod(), window.getBase(),
|
||||
window.getBitmap());
|
||||
// If the outgoing keys are inactive, activate them
|
||||
MutableTransportKeySet ks = keys.get(tagCtx.keySetId);
|
||||
MutableOutgoingKeys outKeys =
|
||||
ks.getKeys().getCurrentOutgoingKeys();
|
||||
if (!outKeys.isActive()) {
|
||||
LOG.info("Activating outgoing keys");
|
||||
outKeys.activate();
|
||||
considerReplacingOutgoingKeys(ks);
|
||||
db.setTransportKeysActive(txn, transportId, tagCtx.keySetId);
|
||||
}
|
||||
StreamContext ctx = streamContextFromTag(tag);
|
||||
if (ctx == null) return null;
|
||||
markTagAsRecognised(txn, tag);
|
||||
return ctx;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamContext getStreamContextOnly(Transaction txn, byte[] tag) {
|
||||
lock.lock();
|
||||
try {
|
||||
return streamContextFromTag(tag);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("lock")
|
||||
@Nullable
|
||||
private StreamContext streamContextFromTag(byte[] tag) {
|
||||
// Look up the incoming keys for the tag
|
||||
TagContext tagCtx = inContexts.get(new Bytes(tag));
|
||||
if (tagCtx == null) return null;
|
||||
MutableIncomingKeys inKeys = tagCtx.inKeys;
|
||||
// Create a stream context
|
||||
return new StreamContext(tagCtx.contactId,
|
||||
tagCtx.pendingContactId, transportId,
|
||||
inKeys.getTagKey(), inKeys.getHeaderKey(),
|
||||
tagCtx.streamNumber, tagCtx.handshakeMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markTagAsRecognised(Transaction txn, byte[] tag)
|
||||
throws DbException {
|
||||
TagContext tagCtx = inContexts.remove(new Bytes(tag));
|
||||
if (tagCtx == null) return;
|
||||
MutableIncomingKeys inKeys = tagCtx.inKeys;
|
||||
// Update the reordering window
|
||||
ReorderingWindow window = inKeys.getWindow();
|
||||
Change change = window.setSeen(tagCtx.streamNumber);
|
||||
// Add tags for any stream numbers added to the window
|
||||
for (long streamNumber : change.getAdded()) {
|
||||
byte[] addTag = new byte[TAG_LENGTH];
|
||||
transportCrypto.encodeTag(addTag, inKeys.getTagKey(),
|
||||
PROTOCOL_VERSION, streamNumber);
|
||||
TagContext tagCtx1 = new TagContext(tagCtx.keySetId,
|
||||
tagCtx.contactId, tagCtx.pendingContactId, inKeys,
|
||||
streamNumber, tagCtx.handshakeMode);
|
||||
inContexts.put(new Bytes(addTag), tagCtx1);
|
||||
}
|
||||
// Remove tags for any stream numbers removed from the window
|
||||
for (long streamNumber : change.getRemoved()) {
|
||||
if (streamNumber == tagCtx.streamNumber) continue;
|
||||
byte[] removeTag = new byte[TAG_LENGTH];
|
||||
transportCrypto.encodeTag(removeTag, inKeys.getTagKey(),
|
||||
PROTOCOL_VERSION, streamNumber);
|
||||
inContexts.remove(new Bytes(removeTag));
|
||||
}
|
||||
// Write the window back to the DB
|
||||
db.setReorderingWindow(txn, tagCtx.keySetId, transportId,
|
||||
inKeys.getTimePeriod(), window.getBase(),
|
||||
window.getBitmap());
|
||||
// If the outgoing keys are inactive, activate them
|
||||
MutableTransportKeySet ks = keys.get(tagCtx.keySetId);
|
||||
MutableOutgoingKeys outKeys =
|
||||
ks.getKeys().getCurrentOutgoingKeys();
|
||||
if (!outKeys.isActive()) {
|
||||
LOG.info("Activating outgoing keys");
|
||||
outKeys.activate();
|
||||
considerReplacingOutgoingKeys(ks);
|
||||
db.setTransportKeysActive(txn, transportId, tagCtx.keySetId);
|
||||
}
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
@Wakeful
|
||||
private void updateKeys(Transaction txn) throws DbException {
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
Bridge obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0
|
||||
Bridge obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw 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: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 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 78.46.188.239:37356 5A2D2F4158D0453E00C7C176978D3F41D69C45DB cert=3c0SwxpOisbohNxEc4tb875RVW8eOu1opRTVXJhafaKA/PNNtI7ElQIVOVZg1AdL5bxGCw iat-mode=0
|
||||
Bridge meek_lite 192.0.2.2:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com
|
||||
d Bridge obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1
|
||||
d Bridge obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0
|
||||
d Bridge obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0
|
||||
d Bridge obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0
|
||||
d Bridge obfs4 193.11.166.194:27015 2D82C2E354D531A68469ADF7F878FA6060C6BACA cert=4TLQPJrTSaDffMK7Nbao6LC7G9OW/NHkUwIdjLSS3KYf0Nv4/nQiiI8dY2TcsQx01NniOg iat-mode=0
|
||||
d Bridge obfs4 193.11.166.194:27020 86AC7B8D430DAC4117E9F42C9EAED18133863AAF cert=0LDeJH4JzMDtkJJrFphJCiPqKx7loozKN7VNfuukMGfHO0Z8OGdzHVkhVAOfo1mUdv9cMg iat-mode=0
|
||||
d Bridge obfs4 193.11.166.194:27025 1AE2C08904527FEA90C4C4F8C1083EA59FBC6FAF cert=ItvYZzW5tn6v3G4UnQa6Qz04Npro6e81AP70YujmK/KXwDFPTs3aHXcHp4n8Vt6w/bv8cA iat-mode=0
|
||||
d Bridge obfs4 209.148.46.65:443 74FAD13168806246602538555B5521A0383A1875 cert=ssH+9rP8dG2NLDN2XuFw63hIO/9MNNinLmxQDpVa+7kTOa9/m+tGWT1SmSYpQ9uTBGa6Hw iat-mode=0
|
||||
d Bridge obfs4 146.57.248.225:22 10A6CD36A537FCE513A322361547444B393989F0 cert=K1gDtDAIcUfeLqbstggjIw2rtgIKqdIhUlHp82XRqNSq/mtAjp1BIC9vHKJ2FAEpGssTPw iat-mode=0
|
||||
d Bridge obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0
|
||||
d Bridge obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0
|
||||
d Bridge obfs4 185.100.85.3:443 5B403DFE34F4872EB027059CECAE30B0C864B3A2 cert=bWUdFUe8io9U6JkSLoGAvSAUDcB779/shovCYmYAQb/pW/iEAMZtO/lCd94OokOF909TPA iat-mode=2
|
||||
n Bridge obfs4 46.226.107.197:10300 A38FD6BDFD902882F5F5B9B7CCC95602A20B0BC4 cert=t8tA9q2AeGlmp/dO6oW9bkY5RqqmvqjArCEM9wjJoDnk6XtnaejkF0JTA7VamdyOzcvuBg iat-mode=0
|
||||
n Bridge obfs4 74.104.165.202:9002 EF432018A6AA5D970B2F84E39CD30A147030141C cert=PhppfUusY85dHGvWtGTybZ1fED4DtbHmALkNMIOIYrAz1B4xN7/2a5gyiZe1epju1BOHVg iat-mode=0
|
||||
n Bridge obfs4 23.88.49.56:443 1CDA1660823AE2565D7F50DE8EB99DFDDE96074B cert=4bwNXedHutVD0ZqCm6ph90Vik9dRY4n9qnBHiLiqQOSsIvui4iHwuMFQK6oqiK8tyhVcDw iat-mode=0
|
||||
n Bridge obfs4 185.65.206.101:443 8A3E001D4C5105ED41060597DEEB21FF19CDC4D3 cert=Nd6XZ+f00sGKL1u6USmyvfqR34HN/pt7jEVbgMpXPF/yyGaLBiXRH/x0SIjX5TceYnd+Dg iat-mode=0
|
||||
m Bridge meek_lite 192.0.2.2:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com
|
||||
@@ -1,6 +0,0 @@
|
||||
ControlPort 59051
|
||||
CookieAuthentication 1
|
||||
DisableNetwork 1
|
||||
RunAsDaemon 1
|
||||
SafeSocks 1
|
||||
SocksPort 59050
|
||||
@@ -24,11 +24,10 @@ import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -53,9 +52,8 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class ClientHelperImplTest extends BrambleTestCase {
|
||||
public class ClientHelperImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final Mockery context = new Mockery();
|
||||
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
private final MessageFactory messageFactory =
|
||||
context.mock(MessageFactory.class);
|
||||
@@ -100,7 +98,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
clientHelper.addLocalMessage(message, dictionary, shared);
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,7 +109,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
clientHelper.createMessage(groupId, timestamp, list);
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -127,7 +123,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
clientHelper.getMessageAsList(messageId);
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -144,7 +139,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
assertEquals(dictionary,
|
||||
clientHelper.getGroupMetadataAsDictionary(groupId));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -161,7 +155,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
assertEquals(dictionary,
|
||||
clientHelper.getMessageMetadataAsDictionary(messageId));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -179,7 +172,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
assertEquals(map, clientHelper.getMessageMetadataAsDictionary(groupId));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -204,7 +196,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
assertEquals(map,
|
||||
clientHelper.getMessageMetadataAsDictionary(groupId, query));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -219,7 +210,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
clientHelper.mergeGroupMetadata(groupId, dictionary);
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -234,7 +224,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
clientHelper.mergeMessageMetadata(messageId, dictionary);
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -242,7 +231,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
byte[] bytes = expectToByteArray(list);
|
||||
|
||||
assertArrayEquals(bytes, clientHelper.toByteArray(list));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -250,7 +238,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
expectToList(true);
|
||||
|
||||
assertEquals(list, clientHelper.toList(getRandomBytes(123)));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -262,7 +249,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
fail();
|
||||
} catch (FormatException e) {
|
||||
// expected
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +265,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
assertArrayEquals(signature,
|
||||
clientHelper.sign(label, list, privateKey));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -295,7 +280,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
clientHelper.verifySignature(signature, label, list, publicKey);
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -315,7 +299,6 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
fail();
|
||||
} catch (GeneralSecurityException e) {
|
||||
// expected
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2197,6 +2197,55 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetRetransmissionTimes() throws Exception {
|
||||
long now = System.currentTimeMillis();
|
||||
AtomicLong time = new AtomicLong(now);
|
||||
Database<Connection> db =
|
||||
open(false, new TestMessageFactory(), new SettableClock(time));
|
||||
Connection txn = db.startTransaction();
|
||||
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addIdentity(txn, identity);
|
||||
assertEquals(contactId,
|
||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||
|
||||
// Time: now
|
||||
// Retrieve the message from the database
|
||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
||||
ONE_MEGABYTE, MAX_LATENCY);
|
||||
assertEquals(singletonList(messageId), ids);
|
||||
|
||||
// Time: now
|
||||
// Mark the message as sent
|
||||
db.updateExpiryTimeAndEta(txn, contactId, messageId, MAX_LATENCY);
|
||||
|
||||
// The message should expire after 2 * MAX_LATENCY
|
||||
assertEquals(now + MAX_LATENCY * 2, db.getNextSendTime(txn, contactId));
|
||||
|
||||
// Time: now + MAX_LATENCY * 2 - 1
|
||||
// The message should not yet be sendable
|
||||
time.set(now + MAX_LATENCY * 2 - 1);
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
||||
assertTrue(ids.isEmpty());
|
||||
|
||||
// Reset the retransmission times
|
||||
db.resetUnackedMessagesToSend(txn, contactId);
|
||||
|
||||
// The message should have infinitely short expiry
|
||||
assertEquals(0, db.getNextSendTime(txn, contactId));
|
||||
|
||||
// The message should be sendable
|
||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE, MAX_LATENCY);
|
||||
assertFalse(ids.isEmpty());
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompactionTime() throws Exception {
|
||||
MessageFactory messageFactory = new TestMessageFactory();
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.auto.Mock;
|
||||
import org.jmock.integration.junit4.JUnitRuleMockery;
|
||||
import org.jmock.lib.concurrent.Synchroniser;
|
||||
import org.jmock.lib.legacy.ClassImposteriser;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -35,6 +36,7 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
public JUnitRuleMockery context = new JUnitRuleMockery() {{
|
||||
// So we can mock concrete classes like KeyAgreementTransport
|
||||
setImposteriser(ClassImposteriser.INSTANCE);
|
||||
setThreadingPolicy(new Synchroniser());
|
||||
}};
|
||||
|
||||
private final PublicKey alicePubKey = getAgreementPublicKey();
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
package org.briarproject.bramble.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||
import org.briarproject.bramble.api.settings.Settings;
|
||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_ATTEMPTS;
|
||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_LAST_ATTEMPT;
|
||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_LAST_SUCCESS;
|
||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_ONION;
|
||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_KEY_TOKEN;
|
||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_NAMESPACE;
|
||||
import static org.briarproject.bramble.mailbox.MailboxSettingsManagerImpl.SETTINGS_UPLOADS_NAMESPACE;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class MailboxSettingsManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final SettingsManager settingsManager =
|
||||
context.mock(SettingsManager.class);
|
||||
|
||||
private final MailboxSettingsManager manager =
|
||||
new MailboxSettingsManagerImpl(settingsManager);
|
||||
private final Random random = new Random();
|
||||
private final String onion = getRandomString(64);
|
||||
private final String token = getRandomString(64);
|
||||
private final ContactId contactId1 = new ContactId(random.nextInt());
|
||||
private final ContactId contactId2 = new ContactId(random.nextInt());
|
||||
private final ContactId contactId3 = new ContactId(random.nextInt());
|
||||
private final long now = System.currentTimeMillis();
|
||||
private final long lastAttempt = now - 1234;
|
||||
private final long lastSuccess = now - 2345;
|
||||
private final int attempts = 123;
|
||||
|
||||
@Test
|
||||
public void testReturnsNullPropertiesIfSettingsAreEmpty() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Settings emptySettings = new Settings();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||
will(returnValue(emptySettings));
|
||||
}});
|
||||
|
||||
assertNull(manager.getOwnMailboxProperties(txn));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsProperties() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Settings settings = new Settings();
|
||||
settings.put(SETTINGS_KEY_ONION, onion);
|
||||
settings.put(SETTINGS_KEY_TOKEN, token);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||
will(returnValue(settings));
|
||||
}});
|
||||
|
||||
MailboxProperties properties = manager.getOwnMailboxProperties(txn);
|
||||
assertNotNull(properties);
|
||||
assertEquals(onion, properties.getOnionAddress());
|
||||
assertEquals(token, properties.getAuthToken());
|
||||
assertTrue(properties.isOwner());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoresProperties() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Settings expectedSettings = new Settings();
|
||||
expectedSettings.put(SETTINGS_KEY_ONION, onion);
|
||||
expectedSettings.put(SETTINGS_KEY_TOKEN, token);
|
||||
MailboxProperties properties =
|
||||
new MailboxProperties(onion, token, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
||||
SETTINGS_NAMESPACE);
|
||||
}});
|
||||
|
||||
manager.setOwnMailboxProperties(txn, properties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsDefaultStatusIfSettingsAreEmpty() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Settings emptySettings = new Settings();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||
will(returnValue(emptySettings));
|
||||
}});
|
||||
|
||||
MailboxStatus status = manager.getOwnMailboxStatus(txn);
|
||||
assertEquals(-1, status.getTimeOfLastAttempt());
|
||||
assertEquals(-1, status.getTimeOfLastSuccess());
|
||||
assertEquals(0, status.getAttemptsSinceSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsStatus() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Settings settings = new Settings();
|
||||
settings.putLong(SETTINGS_KEY_LAST_ATTEMPT, lastAttempt);
|
||||
settings.putLong(SETTINGS_KEY_LAST_SUCCESS, lastSuccess);
|
||||
settings.putInt(SETTINGS_KEY_ATTEMPTS, attempts);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||
will(returnValue(settings));
|
||||
}});
|
||||
|
||||
MailboxStatus status = manager.getOwnMailboxStatus(txn);
|
||||
assertEquals(lastAttempt, status.getTimeOfLastAttempt());
|
||||
assertEquals(lastSuccess, status.getTimeOfLastSuccess());
|
||||
assertEquals(attempts, status.getAttemptsSinceSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecordsSuccess() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Settings expectedSettings = new Settings();
|
||||
expectedSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
||||
expectedSettings.putLong(SETTINGS_KEY_LAST_SUCCESS, now);
|
||||
expectedSettings.putInt(SETTINGS_KEY_ATTEMPTS, 0);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
||||
SETTINGS_NAMESPACE);
|
||||
}});
|
||||
|
||||
manager.recordSuccessfulConnection(txn, now);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecordsFailureOnFirstAttempt() throws Exception {
|
||||
testRecordsFailure(new Settings(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecordsFailureOnLaterAttempt() throws Exception {
|
||||
Settings oldSettings = new Settings();
|
||||
oldSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, lastAttempt);
|
||||
oldSettings.putLong(SETTINGS_KEY_LAST_SUCCESS, lastSuccess);
|
||||
oldSettings.putInt(SETTINGS_KEY_ATTEMPTS, attempts);
|
||||
testRecordsFailure(oldSettings, attempts);
|
||||
}
|
||||
|
||||
private void testRecordsFailure(Settings oldSettings, int oldAttempts)
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Settings expectedSettings = new Settings();
|
||||
expectedSettings.putLong(SETTINGS_KEY_LAST_ATTEMPT, now);
|
||||
expectedSettings.putInt(SETTINGS_KEY_ATTEMPTS, oldAttempts + 1);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).getSettings(txn, SETTINGS_NAMESPACE);
|
||||
will(returnValue(oldSettings));
|
||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings,
|
||||
SETTINGS_NAMESPACE);
|
||||
}});
|
||||
|
||||
manager.recordFailedConnectionAttempt(txn, now);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGettingPendingUploads() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Settings settings = new Settings();
|
||||
settings.put(String.valueOf(contactId1.getInt()), onion);
|
||||
settings.put(String.valueOf(contactId2.getInt()), token);
|
||||
settings.put(String.valueOf(contactId3.getInt()), "");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
exactly(4).of(settingsManager)
|
||||
.getSettings(txn, SETTINGS_UPLOADS_NAMESPACE);
|
||||
will(returnValue(settings));
|
||||
}});
|
||||
|
||||
String filename1 = manager.getPendingUpload(txn, contactId1);
|
||||
assertEquals(onion, filename1);
|
||||
String filename2 = manager.getPendingUpload(txn, contactId2);
|
||||
assertEquals(token, filename2);
|
||||
String filename3 = manager.getPendingUpload(txn, contactId3);
|
||||
assertNull(filename3);
|
||||
String filename4 =
|
||||
manager.getPendingUpload(txn, new ContactId(random.nextInt()));
|
||||
assertNull(filename4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingPendingUploads() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
// setting a pending upload stores expected settings
|
||||
Settings expectedSettings1 = new Settings();
|
||||
expectedSettings1.put(String.valueOf(contactId1.getInt()), onion);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings1,
|
||||
SETTINGS_UPLOADS_NAMESPACE);
|
||||
}});
|
||||
manager.setPendingUpload(txn, contactId1, onion);
|
||||
|
||||
// nulling a pending upload empties stored settings
|
||||
Settings expectedSettings2 = new Settings();
|
||||
expectedSettings2.put(String.valueOf(contactId2.getInt()), "");
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(settingsManager).mergeSettings(txn, expectedSettings2,
|
||||
SETTINGS_UPLOADS_NAMESPACE);
|
||||
}});
|
||||
manager.setPendingUpload(txn, contactId2, null);
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,8 @@ import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin;
|
||||
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
|
||||
import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.lib.concurrent.Synchroniser;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -24,13 +22,10 @@ import java.util.concurrent.Executors;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getTransportId;
|
||||
|
||||
public class PluginManagerImplTest extends BrambleTestCase {
|
||||
public class PluginManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testStartAndStop() throws Exception {
|
||||
Mockery context = new Mockery() {{
|
||||
setThreadingPolicy(new Synchroniser());
|
||||
}};
|
||||
Executor ioExecutor = Executors.newSingleThreadExecutor();
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
PluginConfig pluginConfig = context.mock(PluginConfig.class);
|
||||
@@ -116,7 +111,5 @@ public class PluginManagerImplTest extends BrambleTestCase {
|
||||
// Two plugins should be started and stopped
|
||||
p.startService();
|
||||
p.stopService();
|
||||
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BLOCKED;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BRIDGES;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.DEFAULT_OBFS4;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.MEEK;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.NON_DEFAULT_OBFS4;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.DEFAULT_OBFS4_BRIDGES;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.MEEK_BRIDGES;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.NON_DEFAULT_OBFS4_BRIDGES;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class CircumventionProviderTest extends BrambleTestCase {
|
||||
|
||||
private final CircumventionProvider provider =
|
||||
new CircumventionProviderImpl();
|
||||
|
||||
@Test
|
||||
public void testInvariants() {
|
||||
Set<String> blocked = new HashSet<>(asList(BLOCKED));
|
||||
Set<String> bridges = new HashSet<>(asList(BRIDGES));
|
||||
Set<String> defaultObfs4Bridges =
|
||||
new HashSet<>(asList(DEFAULT_OBFS4_BRIDGES));
|
||||
Set<String> nonDefaultObfs4Bridges =
|
||||
new HashSet<>(asList(NON_DEFAULT_OBFS4_BRIDGES));
|
||||
Set<String> meekBridges = new HashSet<>(asList(MEEK_BRIDGES));
|
||||
// BRIDGES should be a subset of BLOCKED
|
||||
assertTrue(blocked.containsAll(bridges));
|
||||
// BRIDGES should be the union of the bridge type sets
|
||||
Set<String> union = new HashSet<>(defaultObfs4Bridges);
|
||||
union.addAll(nonDefaultObfs4Bridges);
|
||||
union.addAll(meekBridges);
|
||||
assertEquals(bridges, union);
|
||||
// The bridge type sets should not overlap
|
||||
assertEmptyIntersection(defaultObfs4Bridges, nonDefaultObfs4Bridges);
|
||||
assertEmptyIntersection(defaultObfs4Bridges, meekBridges);
|
||||
assertEmptyIntersection(nonDefaultObfs4Bridges, meekBridges);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBestBridgeType() {
|
||||
for (String country : DEFAULT_OBFS4_BRIDGES) {
|
||||
assertEquals(DEFAULT_OBFS4, provider.getBestBridgeType(country));
|
||||
}
|
||||
for (String country : NON_DEFAULT_OBFS4_BRIDGES) {
|
||||
assertEquals(NON_DEFAULT_OBFS4,
|
||||
provider.getBestBridgeType(country));
|
||||
}
|
||||
for (String country : MEEK_BRIDGES) {
|
||||
assertEquals(MEEK, provider.getBestBridgeType(country));
|
||||
}
|
||||
assertEquals(DEFAULT_OBFS4, provider.getBestBridgeType("ZZ"));
|
||||
}
|
||||
|
||||
private <T> void assertEmptyIntersection(Set<T> a, Set<T> b) {
|
||||
Set<T> intersection = new HashSet<>(a);
|
||||
intersection.retainAll(b);
|
||||
assertTrue(intersection.isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -24,16 +24,6 @@ public class TestFeatureFlagModule {
|
||||
public boolean shouldEnableDisappearingMessages() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldEnableTransferData() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldEnableShareAppViaOfflineHotspot() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
package org.briarproject.bramble.transport;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.StreamDecrypter;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class StreamReaderImplTest extends BrambleTestCase {
|
||||
public class StreamReaderImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testEmptyFramesAreSkipped() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
@@ -30,13 +28,11 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
assertEquals(0, r.read()); // Read another byte
|
||||
assertEquals(-1, r.read()); // Skip the second empty frame, reach EOF
|
||||
assertEquals(-1, r.read()); // Still at EOF
|
||||
context.assertIsSatisfied();
|
||||
r.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyFramesAreSkippedWithBuffer() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
@@ -56,13 +52,11 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
assertEquals(-1, r.read(buf));
|
||||
// Still at EOF
|
||||
assertEquals(-1, r.read(buf));
|
||||
context.assertIsSatisfied();
|
||||
r.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleReadsPerFrame() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
@@ -78,13 +72,11 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
assertEquals(MAX_PAYLOAD_LENGTH / 2, r.read(buf));
|
||||
// Reach EOF
|
||||
assertEquals(-1, r.read(buf, 0, buf.length));
|
||||
context.assertIsSatisfied();
|
||||
r.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleReadsPerFrameWithOffsets() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
@@ -102,7 +94,6 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
MAX_PAYLOAD_LENGTH / 2));
|
||||
// Reach EOF
|
||||
assertEquals(-1, r.read(buf, 0, buf.length));
|
||||
context.assertIsSatisfied();
|
||||
r.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
package org.briarproject.bramble.transport;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.StreamEncrypter;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class StreamWriterImplTest extends BrambleTestCase {
|
||||
public class StreamWriterImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testCloseWithoutWritingWritesFinalFrame() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Write an empty final frame
|
||||
@@ -24,13 +22,11 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
}});
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
w.close();
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlushWithoutBufferedDataWritesFrameAndFlushes()
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
@@ -51,13 +47,11 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
oneOf(encrypter).flush();
|
||||
}});
|
||||
w.close();
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlushWithBufferedDataWritesFrameAndFlushes()
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
@@ -79,12 +73,10 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
oneOf(encrypter).flush();
|
||||
}});
|
||||
w.close();
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleByteWritesWriteFullFrame() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
@@ -103,12 +95,10 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
oneOf(encrypter).flush();
|
||||
}});
|
||||
w.close();
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiByteWritesWriteFullFrames() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
@@ -134,12 +124,10 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
oneOf(encrypter).flush();
|
||||
}});
|
||||
w.close();
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLargeMultiByteWriteWritesFullFrames() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
@@ -157,6 +145,5 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
w.write(b);
|
||||
// There should be one byte left in the buffer
|
||||
w.close();
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,6 +393,76 @@ public class TransportKeyManagerImplTest extends BrambleMockTestCase {
|
||||
assertNull(transportKeyManager.getStreamContext(txn, tag));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStreamContextOnlyAndMarkTag() throws Exception {
|
||||
boolean alice = random.nextBoolean();
|
||||
TransportKeys transportKeys = createTransportKeys(1000, 0, true);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
// Keep a copy of the tags
|
||||
List<byte[]> tags = new ArrayList<>();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(transportCrypto).deriveRotationKeys(transportId, rootKey,
|
||||
1000, alice, true);
|
||||
will(returnValue(transportKeys));
|
||||
// Get the current time (the start of time period 1000)
|
||||
oneOf(clock).currentTimeMillis();
|
||||
will(returnValue(timePeriodLength * 1000));
|
||||
// Encode the tags (3 sets)
|
||||
for (long i = 0; i < REORDERING_WINDOW_SIZE; i++) {
|
||||
exactly(3).of(transportCrypto).encodeTag(
|
||||
with(any(byte[].class)), with(tagKey),
|
||||
with(PROTOCOL_VERSION), with(i));
|
||||
will(new EncodeTagAction(tags));
|
||||
}
|
||||
// Updated the transport keys (the keys are unaffected)
|
||||
oneOf(transportCrypto).updateTransportKeys(transportKeys, 1000);
|
||||
will(returnValue(transportKeys));
|
||||
// Save the keys
|
||||
oneOf(db).addTransportKeys(txn, contactId, transportKeys);
|
||||
will(returnValue(keySetId));
|
||||
// Encode a new tag after sliding the window
|
||||
oneOf(transportCrypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagKey), with(PROTOCOL_VERSION),
|
||||
with((long) REORDERING_WINDOW_SIZE));
|
||||
will(new EncodeTagAction(tags));
|
||||
// Save the reordering window (previous time period, base 1)
|
||||
oneOf(db).setReorderingWindow(txn, keySetId, transportId, 999,
|
||||
1, new byte[REORDERING_WINDOW_SIZE / 8]);
|
||||
}});
|
||||
|
||||
// The timestamp is at the start of time period 1000
|
||||
long timestamp = timePeriodLength * 1000;
|
||||
assertEquals(keySetId, transportKeyManager.addRotationKeys(
|
||||
txn, contactId, rootKey, timestamp, alice, true));
|
||||
assertTrue(transportKeyManager.canSendOutgoingStreams(contactId));
|
||||
// Use the first tag (previous time period, stream number 0)
|
||||
assertEquals(REORDERING_WINDOW_SIZE * 3, tags.size());
|
||||
byte[] tag = tags.get(0);
|
||||
// Repeated request should return same stream context
|
||||
StreamContext ctx = transportKeyManager.getStreamContextOnly(txn, tag);
|
||||
assertNotNull(ctx);
|
||||
assertEquals(contactId, ctx.getContactId());
|
||||
assertEquals(transportId, ctx.getTransportId());
|
||||
assertEquals(tagKey, ctx.getTagKey());
|
||||
assertEquals(headerKey, ctx.getHeaderKey());
|
||||
assertEquals(0L, ctx.getStreamNumber());
|
||||
ctx = transportKeyManager.getStreamContextOnly(txn, tag);
|
||||
assertNotNull(ctx);
|
||||
assertEquals(contactId, ctx.getContactId());
|
||||
assertEquals(transportId, ctx.getTransportId());
|
||||
assertEquals(tagKey, ctx.getTagKey());
|
||||
assertEquals(headerKey, ctx.getHeaderKey());
|
||||
assertEquals(0L, ctx.getStreamNumber());
|
||||
// Then mark tag as recognised
|
||||
transportKeyManager.markTagAsRecognised(txn, tag);
|
||||
// Another tag should have been encoded
|
||||
assertEquals(REORDERING_WINDOW_SIZE * 3 + 1, tags.size());
|
||||
// Finally ensure the used tag is not recognised again
|
||||
assertNull(transportKeyManager.getStreamContextOnly(txn, tag));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeysAreUpdatedToCurrentPeriod() throws Exception {
|
||||
TransportKeys transportKeys = createTransportKeys(1000, 0, true);
|
||||
|
||||
@@ -17,8 +17,8 @@ dependencies {
|
||||
def jna_version = '4.5.2'
|
||||
implementation "net.java.dev.jna:jna:$jna_version"
|
||||
implementation "net.java.dev.jna:jna-platform:$jna_version"
|
||||
tor 'org.briarproject:tor:0.3.5.15'
|
||||
tor 'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a@zip'
|
||||
tor "org.briarproject:tor:$tor_version"
|
||||
tor "org.briarproject:obfs4proxy:$obfs4proxy_version@zip"
|
||||
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
|
||||
@@ -35,12 +35,15 @@ abstract class JavaTorPlugin extends TorPlugin {
|
||||
String architecture,
|
||||
long maxLatency,
|
||||
int maxIdleTime,
|
||||
File torDirectory) {
|
||||
File torDirectory,
|
||||
int torSocksPort,
|
||||
int torControlPort) {
|
||||
super(ioExecutor, wakefulIoExecutor, networkManager, locationUtils,
|
||||
torSocketFactory, clock, resourceProvider,
|
||||
circumventionProvider, batteryManager, backoff,
|
||||
torRendezvousCrypto, callback, architecture,
|
||||
maxLatency, maxIdleTime, torDirectory);
|
||||
maxLatency, maxIdleTime, torDirectory, torSocksPort,
|
||||
torControlPort);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,12 +35,15 @@ class UnixTorPlugin extends JavaTorPlugin {
|
||||
String architecture,
|
||||
long maxLatency,
|
||||
int maxIdleTime,
|
||||
File torDirectory) {
|
||||
File torDirectory,
|
||||
int torSocksPort,
|
||||
int torControlPort) {
|
||||
super(ioExecutor, wakefulIoExecutor, networkManager, locationUtils,
|
||||
torSocketFactory, clock, resourceProvider,
|
||||
circumventionProvider, batteryManager, backoff,
|
||||
torRendezvousCrypto, callback, architecture,
|
||||
maxLatency, maxIdleTime, torDirectory);
|
||||
maxLatency, maxIdleTime, torDirectory, torSocksPort,
|
||||
torControlPort);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
@@ -9,7 +10,9 @@ import org.briarproject.bramble.api.plugin.Backoff;
|
||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
||||
import org.briarproject.bramble.api.plugin.PluginCallback;
|
||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||
import org.briarproject.bramble.api.plugin.TorControlPort;
|
||||
import org.briarproject.bramble.api.plugin.TorDirectory;
|
||||
import org.briarproject.bramble.api.plugin.TorSocksPort;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
|
||||
@@ -54,6 +57,9 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
||||
private final BatteryManager batteryManager;
|
||||
private final Clock clock;
|
||||
private final File torDirectory;
|
||||
private int torSocksPort;
|
||||
private int torControlPort;
|
||||
private final CryptoComponent crypto;
|
||||
|
||||
@Inject
|
||||
UnixTorPluginFactory(@IoExecutor Executor ioExecutor,
|
||||
@@ -67,7 +73,10 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
||||
CircumventionProvider circumventionProvider,
|
||||
BatteryManager batteryManager,
|
||||
Clock clock,
|
||||
@TorDirectory File torDirectory) {
|
||||
@TorDirectory File torDirectory,
|
||||
@TorSocksPort int torSocksPort,
|
||||
@TorControlPort int torControlPort,
|
||||
CryptoComponent crypto) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.wakefulIoExecutor = wakefulIoExecutor;
|
||||
this.networkManager = networkManager;
|
||||
@@ -80,6 +89,9 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
||||
this.batteryManager = batteryManager;
|
||||
this.clock = clock;
|
||||
this.torDirectory = torDirectory;
|
||||
this.torSocksPort = torSocksPort;
|
||||
this.torControlPort = torControlPort;
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,12 +132,14 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
||||
|
||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
||||
TorRendezvousCrypto torRendezvousCrypto =
|
||||
new TorRendezvousCryptoImpl(crypto);
|
||||
UnixTorPlugin plugin = new UnixTorPlugin(ioExecutor, wakefulIoExecutor,
|
||||
networkManager, locationUtils, torSocketFactory, clock,
|
||||
resourceProvider, circumventionProvider, batteryManager,
|
||||
backoff, torRendezvousCrypto, callback, architecture,
|
||||
MAX_LATENCY, MAX_IDLE_TIME, torDirectory);
|
||||
MAX_LATENCY, MAX_IDLE_TIME, torDirectory, torSocksPort,
|
||||
torControlPort);
|
||||
eventBus.addListener(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,18 @@ package org.briarproject.bramble.plugin.tor;
|
||||
|
||||
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
|
||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.network.NetworkManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.BackoffFactory;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.system.LocationUtils;
|
||||
import org.briarproject.bramble.api.system.ResourceProvider;
|
||||
import org.briarproject.bramble.api.system.WakefulIoExecutor;
|
||||
import org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType;
|
||||
import org.briarproject.bramble.test.BrambleJavaIntegrationTestComponent;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.DaggerBrambleJavaIntegrationTestComponent;
|
||||
@@ -33,9 +36,14 @@ import javax.inject.Inject;
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_CONTROL_PORT;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_SOCKS_PORT;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.DEFAULT_OBFS4;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.MEEK;
|
||||
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BridgeType.NON_DEFAULT_OBFS4;
|
||||
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||
import static org.briarproject.bramble.test.TestUtils.isOptionalTestEnabled;
|
||||
@@ -54,14 +62,21 @@ public class BridgeTest extends BrambleTestCase {
|
||||
.injectEagerSingletons(component);
|
||||
// Share a failure counter among all the test instances
|
||||
AtomicInteger failures = new AtomicInteger(0);
|
||||
List<String> bridges =
|
||||
component.getCircumventionProvider().getBridges(false);
|
||||
List<Params> states = new ArrayList<>(bridges.size());
|
||||
for (String bridge : bridges) states.add(new Params(bridge, failures));
|
||||
CircumventionProvider provider = component.getCircumventionProvider();
|
||||
List<Params> states = new ArrayList<>();
|
||||
for (String bridge : provider.getBridges(DEFAULT_OBFS4)) {
|
||||
states.add(new Params(bridge, DEFAULT_OBFS4, failures, false));
|
||||
}
|
||||
for (String bridge : provider.getBridges(NON_DEFAULT_OBFS4)) {
|
||||
states.add(new Params(bridge, NON_DEFAULT_OBFS4, failures, false));
|
||||
}
|
||||
for (String bridge : provider.getBridges(MEEK)) {
|
||||
states.add(new Params(bridge, MEEK, failures, true));
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
private final static long TIMEOUT = SECONDS.toMillis(60);
|
||||
private final static long TIMEOUT = MINUTES.toMillis(5);
|
||||
private final static int NUM_FAILURES_ALLOWED = 1;
|
||||
|
||||
private final static Logger LOG = getLogger(BridgeTest.class.getName());
|
||||
@@ -86,16 +101,16 @@ public class BridgeTest extends BrambleTestCase {
|
||||
BackoffFactory backoffFactory;
|
||||
@Inject
|
||||
Clock clock;
|
||||
@Inject
|
||||
CryptoComponent crypto;
|
||||
|
||||
private final File torDir = getTestDirectory();
|
||||
private final String bridge;
|
||||
private final AtomicInteger failures;
|
||||
private final Params params;
|
||||
|
||||
private UnixTorPluginFactory factory;
|
||||
|
||||
public BridgeTest(Params params) {
|
||||
bridge = params.bridge;
|
||||
failures = params.failures;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -115,6 +130,7 @@ public class BridgeTest extends BrambleTestCase {
|
||||
LocationUtils locationUtils = () -> "US";
|
||||
SocketFactory torSocketFactory = SocketFactory.getDefault();
|
||||
|
||||
@NotNullByDefault
|
||||
CircumventionProvider bridgeProvider = new CircumventionProvider() {
|
||||
@Override
|
||||
public boolean isTorProbablyBlocked(String countryCode) {
|
||||
@@ -127,19 +143,20 @@ public class BridgeTest extends BrambleTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsMeek(String countryCode) {
|
||||
return false;
|
||||
public BridgeType getBestBridgeType(String countryCode) {
|
||||
return params.bridgeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getBridges(boolean useMeek) {
|
||||
return singletonList(bridge);
|
||||
public List<String> getBridges(BridgeType bridgeType) {
|
||||
return singletonList(params.bridge);
|
||||
}
|
||||
};
|
||||
factory = new UnixTorPluginFactory(ioExecutor, wakefulIoExecutor,
|
||||
networkManager, locationUtils, eventBus, torSocketFactory,
|
||||
backoffFactory, resourceProvider, bridgeProvider,
|
||||
batteryManager, clock, torDir);
|
||||
batteryManager, clock, torDir, DEFAULT_SOCKS_PORT,
|
||||
DEFAULT_CONTROL_PORT, crypto);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -154,7 +171,7 @@ public class BridgeTest extends BrambleTestCase {
|
||||
assertNotNull(duplexPlugin);
|
||||
UnixTorPlugin plugin = (UnixTorPlugin) duplexPlugin;
|
||||
|
||||
LOG.warning("Testing " + bridge);
|
||||
LOG.warning("Testing " + params.bridge);
|
||||
try {
|
||||
plugin.start();
|
||||
long start = clock.currentTimeMillis();
|
||||
@@ -164,8 +181,11 @@ public class BridgeTest extends BrambleTestCase {
|
||||
}
|
||||
if (plugin.getState() != ACTIVE) {
|
||||
LOG.warning("Could not connect to Tor within timeout");
|
||||
if (failures.incrementAndGet() > NUM_FAILURES_ALLOWED) {
|
||||
fail(failures.get() + " bridges are unreachable");
|
||||
if (params.failures.incrementAndGet() > NUM_FAILURES_ALLOWED) {
|
||||
fail(params.failures.get() + " bridges are unreachable");
|
||||
}
|
||||
if (params.mustSucceed) {
|
||||
fail("essential bridge is unreachable");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -176,11 +196,16 @@ public class BridgeTest extends BrambleTestCase {
|
||||
private static class Params {
|
||||
|
||||
private final String bridge;
|
||||
private final BridgeType bridgeType;
|
||||
private final AtomicInteger failures;
|
||||
private final boolean mustSucceed;
|
||||
|
||||
private Params(String bridge, AtomicInteger failures) {
|
||||
private Params(String bridge, BridgeType bridgeType,
|
||||
AtomicInteger failures, boolean mustSucceed) {
|
||||
this.bridge = bridge;
|
||||
this.bridgeType = bridgeType;
|
||||
this.failures = failures;
|
||||
this.mustSucceed = mustSucceed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ dependencyVerification {
|
||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||
'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a:obfs4proxy-0.0.12-dev-40245c4a.zip:172029e7058b3a83ac93ac4991a44bf76e16ce8d46f558f5836d57da3cb3a766',
|
||||
'org.briarproject:tor:0.3.5.15:tor-0.3.5.15.jar:2ff5b5a3b5eaa97d699629ad24ba9584b3199d0ffdb1ea7d8a02de3016b80e7a',
|
||||
'org.briarproject:tor:0.3.5.17:tor-0.3.5.17.jar:ce0e1f4d8f14878e61b23a35a452bc0f2a8e3117ced5a74773cd78475fa7af39',
|
||||
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||
|
||||
83
briar-android/artwork/share_app.svg
Normal file
83
briar-android/artwork/share_app.svg
Normal file
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="256" height="204"
|
||||
viewBox="0 0 256 204" fill="none" version="1.1" id="svg42" sodipodi:docname="share_app.svg"
|
||||
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
|
||||
<metadata id="metadata48">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs id="defs46" />
|
||||
<sodipodi:namedview pagecolor="#000000" bordercolor="#666666" borderopacity="1"
|
||||
objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2" inkscape:window-width="1920" inkscape:window-height="964"
|
||||
id="namedview44" showgrid="false" inkscape:zoom="2.4705882" inkscape:cx="123.34752"
|
||||
inkscape:cy="83.759737" inkscape:window-x="1920" inkscape:window-y="72"
|
||||
inkscape:window-maximized="0" inkscape:current-layer="svg42" />
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M41.583 100.841H22.1807V102.841H52.7503V136.663H54.7503V102.841H68.0341C70.9241 102.841 73.267 105.184 73.267 108.074C73.267 112.068 76.5053 115.307 80.4999 115.307H92.727V113.307H80.4999C77.6098 113.307 75.267 110.964 75.267 108.074C75.267 104.079 72.0287 100.841 68.0341 100.841H43.583V63.6593H41.583V100.841Z"
|
||||
fill="#657D99" id="path2" />
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M122.611 86.0596V46.2531H124.611V86.0596H122.611Z" fill="#657D99" id="path4" />
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M119.754 179.928L119.754 142.682L121.754 142.682L121.754 179.928L119.754 179.928Z"
|
||||
fill="#657D99" id="path6" />
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M195.251 100.841V86.5962H193.251V113.826H148.362V115.826H194.251C198.125 115.826 201.301 118.969 201.301 122.826V127.044H203.301V122.826C203.301 118.186 199.75 114.378 195.251 113.881V102.841H233.052V100.841H195.251Z"
|
||||
fill="#657D99" id="path8" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M32.1213 57.4112L32.8875 55.5637C33.5961 55.8576 34.3747 56.0208 35.1966 56.0208H37.0795V58.0208H35.1966C34.1072 58.0208 33.0686 57.804 32.1213 57.4112ZM48.3769 58.0208V56.0208H50.2598C51.0816 56.0208 51.8602 55.8576 52.5689 55.5637L53.335 57.4112C52.3877 57.804 51.3491 58.0208 50.2598 58.0208H48.3769ZM58.2935 36.8067H56.2935V34.9238C56.2935 34.102 56.1303 33.3234 55.8364 32.6147L57.6839 31.8486C58.0767 32.7959 58.2935 33.8345 58.2935 34.9238V36.8067ZM37.0795 26.8901H35.1966C34.1072 26.8901 33.0686 27.1069 32.1213 27.4997L32.8875 29.3472C33.5961 29.0533 34.3747 28.8901 35.1966 28.8901H37.0795V26.8901ZM27.1628 48.1042H29.1628V49.9871C29.1628 50.8089 29.326 51.5875 29.6199 52.2962L27.7724 53.0623C27.3796 52.115 27.1628 51.0764 27.1628 49.9871V48.1042ZM27.1628 44.3384H29.1628V40.5725H27.1628V44.3384ZM27.1628 36.8067H29.1628V34.9238C29.1628 34.102 29.326 33.3234 29.6199 32.6147L27.7724 31.8486C27.3796 32.7959 27.1628 33.8345 27.1628 34.9238V36.8067ZM40.8453 26.8901V28.8901H44.6111V26.8901H40.8453ZM48.3769 26.8901V28.8901H50.2598C51.0816 28.8901 51.8602 29.0533 52.5689 29.3472L53.335 27.4997C52.3877 27.1069 51.3491 26.8901 50.2598 26.8901H48.3769ZM58.2935 40.5725H56.2935V44.3383H58.2935V40.5725ZM58.2935 48.1042H56.2935V49.9871C56.2935 50.8089 56.1303 51.5875 55.8364 52.2962L57.6839 53.0623C58.0767 52.115 58.2935 51.0764 58.2935 49.9871V48.1042ZM44.6111 58.0208V56.0208H40.8453V58.0208H44.6111Z"
|
||||
fill="#657D99" id="path10" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M112.487 40.4256L112.875 38.4636C113.41 38.5694 113.964 38.6251 114.533 38.6251H116.99V40.6251H114.533C113.833 40.6251 113.149 40.5565 112.487 40.4256ZM131.733 40.6251V38.6251H134.191C134.76 38.6251 135.314 38.5694 135.848 38.4636L136.237 40.4256C135.575 40.5565 134.891 40.6251 134.191 40.6251H131.733ZM140.016 38.8593L138.903 37.1973C139.829 36.5774 140.627 35.7797 141.247 34.8536L142.909 35.9663C142.143 37.1095 141.159 38.0939 140.016 38.8593ZM144.674 12.9411H142.674V10.4839C142.674 9.91475 142.619 9.36059 142.513 8.82599L144.475 8.43785C144.606 9.0996 144.674 9.78374 144.674 10.4839V12.9411ZM142.909 4.65889L141.247 5.77152C140.627 4.84548 139.829 4.04776 138.903 3.42779L140.016 1.76585C141.159 2.53126 142.143 3.5156 142.909 4.65889ZM116.99 0H114.533C113.833 0 113.149 0.0686375 112.487 0.199551L112.875 2.16153C113.41 2.05577 113.964 2 114.533 2H116.99V0ZM108.708 1.76585L109.821 3.42779C108.895 4.04776 108.097 4.84548 107.477 5.77152L105.815 4.65888C106.581 3.5156 107.565 2.53126 108.708 1.76585ZM104.049 27.6841H106.049V30.1412C106.049 30.7104 106.105 31.2645 106.211 31.7992L104.249 32.1873C104.118 31.5255 104.049 30.8414 104.049 30.1412V27.6841ZM105.815 35.9663L107.477 34.8536C108.097 35.7797 108.895 36.5774 109.821 37.1973L108.708 38.8593C107.565 38.0939 106.581 37.1095 105.815 35.9663ZM104.049 22.7697H106.049V17.8554H104.049V22.7697ZM104.049 12.9411H106.049V10.4839C106.049 9.91475 106.105 9.36059 106.211 8.82598L104.249 8.43785C104.118 9.09959 104.049 9.78374 104.049 10.4839V12.9411ZM121.905 0V2H126.819V0H121.905ZM131.733 0V2H134.191C134.76 2 135.314 2.05577 135.848 2.16153L136.237 0.199552C135.575 0.0686377 134.891 0 134.191 0H131.733ZM144.674 17.8554H142.674V22.7697H144.674V17.8554ZM144.674 27.6841H142.674V30.1412C142.674 30.7104 142.619 31.2645 142.513 31.7992L144.475 32.1873C144.606 31.5255 144.674 30.8414 144.674 30.1412V27.6841ZM126.819 40.6251V38.6251H121.905V40.6251H126.819Z"
|
||||
fill="#657D99" id="path12" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M183.397 81.9904L184.163 80.1429C184.902 80.4493 185.714 80.6194 186.57 80.6194H188.513V82.6194H186.57C185.446 82.6194 184.375 82.3957 183.397 81.9904ZM200.171 82.6194V80.6194H202.114C202.97 80.6194 203.782 80.4493 204.521 80.1429L205.287 81.9904C204.309 82.3957 203.238 82.6194 202.114 82.6194H200.171ZM210.403 60.7295H208.403V58.7866C208.403 57.9301 208.233 57.1184 207.927 56.3795L209.774 55.6134C210.18 56.5908 210.403 57.6626 210.403 58.7866V60.7295ZM188.513 50.4969H186.57C185.446 50.4969 184.375 50.7207 183.397 51.126L184.163 52.9734C184.902 52.667 185.714 52.4969 186.57 52.4969H188.513V50.4969ZM178.281 72.3869H180.281V74.3297C180.281 75.1863 180.451 75.998 180.757 76.7368L178.91 77.5029C178.504 76.5255 178.281 75.4538 178.281 74.3297V72.3869ZM178.281 68.5011H180.281V64.6153H178.281V68.5011ZM178.281 60.7295H180.281V58.7866C180.281 57.9301 180.451 57.1184 180.757 56.3795L178.91 55.6134C178.504 56.5908 178.281 57.6626 178.281 58.7866V60.7295ZM192.399 50.4969V52.4969H196.285V50.4969H192.399ZM200.171 50.4969V52.4969H202.114C202.97 52.4969 203.782 52.667 204.521 52.9734L205.287 51.126C204.309 50.7207 203.238 50.4969 202.114 50.4969H200.171ZM210.403 64.6153H208.403V68.5011H210.403V64.6153ZM210.403 72.3869H208.403V74.3297C208.403 75.1863 208.233 75.998 207.927 76.7368L209.774 77.5029C210.18 76.5255 210.403 75.4538 210.403 74.3297V72.3869ZM196.285 82.6194V80.6194H192.399V82.6194H196.285Z"
|
||||
fill="#657D99" id="path14" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M188.271 180.562L188.659 178.6C189.316 178.73 189.996 178.798 190.694 178.798H192.633V180.798H190.694C189.865 180.798 189.055 180.717 188.271 180.562ZM212.029 180.798V178.798H213.968C214.666 178.798 215.346 178.73 216.003 178.6L216.391 180.562C215.607 180.717 214.797 180.798 213.968 180.798H212.029ZM220.865 178.708L219.753 177.046C220.889 176.285 221.868 175.306 222.629 174.17L224.291 175.282C223.384 176.636 222.219 177.801 220.865 178.708ZM226.381 147.05H224.381V145.111C224.381 144.413 224.313 143.733 224.183 143.077L226.145 142.688C226.3 143.472 226.381 144.282 226.381 145.111V147.05ZM224.291 138.214L222.629 139.327C221.868 138.19 220.889 137.211 219.753 136.451L220.865 134.789C222.219 135.695 223.384 136.86 224.291 138.214ZM192.633 132.698H190.694C189.865 132.698 189.055 132.779 188.271 132.934L188.659 134.896C189.316 134.766 189.996 134.698 190.694 134.698H192.633V132.698ZM183.797 134.789L184.91 136.451C183.773 137.211 182.794 138.19 182.033 139.327L180.372 138.214C181.278 136.86 182.443 135.695 183.797 134.789ZM178.281 166.446H180.281V168.385C180.281 169.083 180.349 169.763 180.479 170.42L178.517 170.808C178.362 170.024 178.281 169.214 178.281 168.385V166.446ZM180.372 175.282L182.033 174.17C182.794 175.306 183.773 176.285 184.91 177.046L183.797 178.708C182.443 177.801 181.278 176.636 180.372 175.282ZM178.281 162.567H180.281V158.688H178.281V162.567ZM178.281 154.809H180.281V150.93H178.281V154.809ZM178.281 147.05H180.281V145.111C180.281 144.413 180.349 143.733 180.479 143.077L178.517 142.688C178.362 143.472 178.281 144.282 178.281 145.111V147.05ZM196.512 132.698V134.698H200.392V132.698H196.512ZM204.271 132.698V134.698H208.15V132.698H204.271ZM212.029 132.698V134.698H213.968C214.666 134.698 215.346 134.766 216.003 134.896L216.391 132.934C215.607 132.779 214.797 132.698 213.968 132.698H212.029ZM226.381 150.93H224.381V154.809H226.381V150.93ZM226.381 158.688H224.381V162.567H226.381V158.688ZM226.381 166.446H224.381V168.385C224.381 169.083 224.313 169.763 224.183 170.42L226.145 170.808C226.3 170.024 226.381 169.214 226.381 168.385V166.446ZM208.15 180.798V178.798H204.271V180.798H208.15ZM200.392 180.798V178.798H196.512V180.798H200.392Z"
|
||||
fill="#657D99" id="path16" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M40.3891 175.457L41.1552 173.609C41.9338 173.932 42.7892 174.111 43.6915 174.111H45.7134V176.111H43.6915C42.5217 176.111 41.4063 175.878 40.3891 175.457ZM57.8451 176.111V174.111H59.8671C60.7693 174.111 61.6247 173.932 62.4033 173.609L63.1694 175.457C62.1522 175.878 61.0368 176.111 59.8671 176.111H57.8451ZM68.4941 153.33H66.4941V151.309C66.4941 150.406 66.3149 149.551 65.992 148.772L67.8395 148.006C68.2613 149.023 68.4941 150.139 68.4941 151.309V153.33ZM45.7134 142.682H43.6915C42.5217 142.682 41.4063 142.914 40.3891 143.336L41.1552 145.184C41.9338 144.861 42.7892 144.682 43.6915 144.682H45.7134V142.682ZM35.0645 165.462H37.0645V167.484C37.0645 168.386 37.2437 169.242 37.5665 170.02L35.7191 170.786C35.2973 169.769 35.0645 168.654 35.0645 167.484V165.462ZM35.0645 161.418H37.0645V157.374H35.0645V161.418ZM35.0645 153.33H37.0645V151.309C37.0645 150.406 37.2437 149.551 37.5665 148.772L35.7191 148.006C35.2973 149.023 35.0645 150.139 35.0645 151.309V153.33ZM49.7573 142.682V144.682H53.8012V142.682H49.7573ZM57.8451 142.682V144.682H59.8671C60.7693 144.682 61.6247 144.861 62.4033 145.184L63.1694 143.336C62.1522 142.914 61.0368 142.682 59.8671 142.682H57.8451ZM68.4941 157.374H66.4941V161.418H68.4941V157.374ZM68.4941 165.462H66.4941V167.484C66.4941 168.386 66.3149 169.242 65.992 170.02L67.8395 170.786C68.2613 169.769 68.4941 168.654 68.4941 167.484V165.462ZM53.8012 176.111V174.111H49.7573V176.111H53.8012Z"
|
||||
fill="#657D99" id="path18" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M2.84 110.802L3.60611 108.954C3.91005 109.081 4.24493 109.151 4.60133 109.151H6.75821V111.151H4.60133C3.97743 111.151 3.38253 111.027 2.84 110.802ZM11.072 111.151V109.151H13.2288C13.5852 109.151 13.9201 109.081 14.2241 108.954L14.9902 110.802C14.4476 111.027 13.8527 111.151 13.2288 111.151H11.072ZM17.8302 100.079H15.8302V97.9223C15.8302 97.5659 15.7596 97.231 15.6336 96.927L17.481 96.1609C17.706 96.7035 17.8302 97.2984 17.8302 97.9223V100.079ZM6.75821 93.3209H4.60133C3.97743 93.3209 3.38253 93.4451 2.84 93.6701L3.60611 95.5175C3.91005 95.3915 4.24493 95.3209 4.60133 95.3209H6.75821V93.3209ZM0 104.393H2V106.55C2 106.906 2.07056 107.241 2.1966 107.545L0.349152 108.311C0.124172 107.769 0 107.174 0 106.55V104.393ZM0 100.079H2V97.9223C2 97.5659 2.07056 97.231 2.1966 96.927L0.349152 96.1609C0.124172 96.7035 0 97.2984 0 97.9223V100.079ZM11.072 93.3209V95.3209H13.2288C13.5852 95.3209 13.9201 95.3915 14.2241 95.5175L14.9902 93.6701C14.4476 93.4451 13.8527 93.3209 13.2288 93.3209H11.072ZM17.8302 104.393H15.8302V106.55C15.8302 106.906 15.7596 107.241 15.6336 107.545L17.481 108.311C17.706 107.769 17.8302 107.174 17.8302 106.55V104.393Z"
|
||||
fill="#657D99" id="path20" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M114.745 202.969L115.511 201.122C115.815 201.248 116.149 201.318 116.506 201.318H118.663V203.318H116.506C115.882 203.318 115.287 203.194 114.745 202.969ZM122.977 203.318V201.318H125.133C125.49 201.318 125.825 201.248 126.129 201.122L126.895 202.969C126.352 203.194 125.757 203.318 125.133 203.318H122.977ZM129.735 192.246H127.735V190.09C127.735 189.733 127.664 189.398 127.538 189.094L129.386 188.328C129.611 188.871 129.735 189.466 129.735 190.09V192.246ZM118.663 185.488H116.506C115.882 185.488 115.287 185.612 114.745 185.837L115.511 187.685C115.815 187.559 116.149 187.488 116.506 187.488H118.663V185.488ZM111.905 196.56H113.905V198.717C113.905 199.074 113.975 199.408 114.101 199.712L112.254 200.478C112.029 199.936 111.905 199.341 111.905 198.717V196.56ZM111.905 192.246H113.905V190.09C113.905 189.733 113.975 189.398 114.101 189.094L112.254 188.328C112.029 188.871 111.905 189.466 111.905 190.09V192.246ZM122.977 185.488V187.488H125.133C125.49 187.488 125.825 187.559 126.129 187.685L126.895 185.837C126.352 185.612 125.757 185.488 125.133 185.488H122.977ZM129.735 196.56H127.735V198.717C127.735 199.074 127.664 199.408 127.538 199.712L129.386 200.478C129.611 199.936 129.735 199.341 129.735 198.717V196.56Z"
|
||||
fill="#657D99" id="path22" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M240.444 110.802L241.21 108.954C241.514 109.081 241.849 109.151 242.205 109.151H244.362V111.151H242.205C241.581 111.151 240.987 111.027 240.444 110.802ZM248.676 111.151V109.151H250.833C251.189 109.151 251.524 109.081 251.828 108.954L252.594 110.802C252.052 111.027 251.457 111.151 250.833 111.151H248.676ZM255.434 100.079H253.434V97.9223C253.434 97.5659 253.364 97.231 253.238 96.927L255.085 96.1609C255.31 96.7035 255.434 97.2984 255.434 97.9223V100.079ZM244.362 93.3209H242.205C241.581 93.3209 240.987 93.4451 240.444 93.6701L241.21 95.5175C241.514 95.3915 241.849 95.3209 242.205 95.3209H244.362V93.3209ZM237.604 104.393H239.604V106.55C239.604 106.906 239.675 107.241 239.801 107.545L237.953 108.311C237.728 107.769 237.604 107.174 237.604 106.55V104.393ZM237.604 100.079H239.604V97.9223C239.604 97.5659 239.675 97.231 239.801 96.927L237.953 96.1609C237.728 96.7035 237.604 97.2984 237.604 97.9223V100.079ZM248.676 93.3209V95.3209H250.833C251.189 95.3209 251.524 95.3915 251.828 95.5175L252.594 93.6701C252.052 93.4451 251.457 93.3209 250.833 93.3209H248.676ZM255.434 104.393H253.434V106.55C253.434 106.906 253.364 107.241 253.238 107.545L255.085 108.311C255.31 107.769 255.434 107.174 255.434 106.55V104.393Z"
|
||||
fill="#657D99" id="path24" />
|
||||
<path
|
||||
d="M108.75 109.808V129.511C108.75 131.11 110.052 132.429 111.668 132.429H113.036C114.636 132.429 115.955 131.11 115.955 129.511V109.808H108.75V109.808Z"
|
||||
fill="#87C214" id="path26" />
|
||||
<path
|
||||
d="M115.938 100.312V96.6023C115.938 95.003 114.636 93.684 113.036 93.684H111.668C110.069 93.684 108.75 95.003 108.75 96.6023V100.312H115.938V100.312Z"
|
||||
fill="#87C214" id="path28" />
|
||||
<path
|
||||
d="M131.931 116.305V96.6023C131.931 95.003 130.628 93.684 129.029 93.684H127.66C126.061 93.684 124.742 95.003 124.742 96.6023V116.305H131.931V116.305Z"
|
||||
fill="#87C214" id="path30" />
|
||||
<path
|
||||
d="M124.742 125.801V129.511C124.742 131.11 126.061 132.429 127.66 132.429H129.029C130.628 132.429 131.947 131.11 131.947 129.511V125.801H124.742Z"
|
||||
fill="#87C214" id="path32" />
|
||||
<path
|
||||
d="M107.595 117.459H103.886C102.286 117.459 100.967 118.761 100.967 120.377V121.746C100.967 123.345 102.27 124.664 103.886 124.664H107.595V117.459Z"
|
||||
fill="#95D220" id="path34" />
|
||||
<path
|
||||
d="M136.795 117.459H117.092V124.664H136.795C138.394 124.664 139.713 123.345 139.713 121.746V120.377C139.713 118.761 138.394 117.459 136.795 117.459Z"
|
||||
fill="#95D220" id="path36" />
|
||||
<path
|
||||
d="M123.588 101.466H103.886C102.286 101.466 100.967 102.769 100.967 104.385V105.753C100.967 107.352 102.27 108.671 103.886 108.671H123.588V101.466Z"
|
||||
fill="#95D220" id="path38" />
|
||||
<path
|
||||
d="M136.795 101.466H133.085V108.671H136.795C138.394 108.671 139.713 107.369 139.713 105.753V104.384C139.713 102.769 138.394 101.466 136.795 101.466Z"
|
||||
fill="#95D220" id="path40" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
@@ -26,8 +26,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
versionCode 10308
|
||||
versionName "1.3.8"
|
||||
versionCode 10403
|
||||
versionName "1.4.3"
|
||||
applicationId "org.briarproject.briar.android"
|
||||
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
@@ -18,7 +18,9 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||
import org.briarproject.bramble.api.plugin.PluginConfig;
|
||||
import org.briarproject.bramble.api.plugin.TorControlPort;
|
||||
import org.briarproject.bramble.api.plugin.TorDirectory;
|
||||
import org.briarproject.bramble.api.plugin.TorSocksPort;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
|
||||
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
|
||||
@@ -41,6 +43,7 @@ import org.briarproject.briar.android.hotspot.HotspotModule;
|
||||
import org.briarproject.briar.android.introduction.IntroductionModule;
|
||||
import org.briarproject.briar.android.logging.LoggingModule;
|
||||
import org.briarproject.briar.android.login.LoginModule;
|
||||
import org.briarproject.briar.android.mailbox.MailboxModule;
|
||||
import org.briarproject.briar.android.navdrawer.NavDrawerModule;
|
||||
import org.briarproject.briar.android.privategroup.conversation.GroupConversationModule;
|
||||
import org.briarproject.briar.android.privategroup.list.GroupListModule;
|
||||
@@ -53,6 +56,7 @@ import org.briarproject.briar.android.viewmodel.ViewModelModule;
|
||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.briar.api.android.DozeWatchdog;
|
||||
import org.briarproject.briar.api.android.LockManager;
|
||||
import org.briarproject.briar.api.android.NetworkUsageMetrics;
|
||||
import org.briarproject.briar.api.android.ScreenFilterMonitor;
|
||||
import org.briarproject.briar.api.test.TestAvatarCreator;
|
||||
|
||||
@@ -74,6 +78,8 @@ import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_CONTROL_PORT;
|
||||
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_SOCKS_PORT;
|
||||
import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_ONION_ADDRESS;
|
||||
import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_PUBLIC_KEY_HEX;
|
||||
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
||||
@@ -99,6 +105,7 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
||||
SharingModule.class,
|
||||
HotspotModule.class,
|
||||
TransferDataModule.class,
|
||||
MailboxModule.class,
|
||||
})
|
||||
public class AppModule {
|
||||
|
||||
@@ -108,7 +115,7 @@ public class AppModule {
|
||||
@Inject
|
||||
ScreenFilterMonitor screenFilterMonitor;
|
||||
@Inject
|
||||
NetworkUsageLogger networkUsageLogger;
|
||||
NetworkUsageMetrics networkUsageMetrics;
|
||||
@Inject
|
||||
DozeWatchdog dozeWatchdog;
|
||||
@Inject
|
||||
@@ -155,6 +162,28 @@ public class AppModule {
|
||||
return app.getDir("tor", MODE_PRIVATE);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@TorSocksPort
|
||||
int provideTorSocksPort() {
|
||||
if (!IS_DEBUG_BUILD) {
|
||||
return DEFAULT_SOCKS_PORT;
|
||||
} else {
|
||||
return DEFAULT_SOCKS_PORT + 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@TorControlPort
|
||||
int provideTorControlPort() {
|
||||
if (!IS_DEBUG_BUILD) {
|
||||
return DEFAULT_CONTROL_PORT;
|
||||
} else {
|
||||
return DEFAULT_CONTROL_PORT + 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
PluginConfig providePluginConfig(AndroidBluetoothPluginFactory bluetooth,
|
||||
@@ -171,11 +200,8 @@ public class AppModule {
|
||||
|
||||
@Override
|
||||
public Collection<SimplexPluginFactory> getSimplexFactories() {
|
||||
if (SDK_INT >= 19 && featureFlags.shouldEnableTransferData()) {
|
||||
return singletonList(drive);
|
||||
} else {
|
||||
return emptyList();
|
||||
}
|
||||
if (SDK_INT >= 19) return singletonList(drive);
|
||||
else return emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -262,11 +288,12 @@ public class AppModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
NetworkUsageLogger provideNetworkUsageLogger(
|
||||
@Singleton
|
||||
NetworkUsageMetrics provideNetworkUsageMetrics(
|
||||
LifecycleManager lifecycleManager) {
|
||||
NetworkUsageLogger networkUsageLogger = new NetworkUsageLogger();
|
||||
lifecycleManager.registerService(networkUsageLogger);
|
||||
return networkUsageLogger;
|
||||
NetworkUsageMetrics networkUsageMetrics = new NetworkUsageMetricsImpl();
|
||||
lifecycleManager.registerService(networkUsageMetrics);
|
||||
return networkUsageMetrics;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -312,16 +339,6 @@ public class AppModule {
|
||||
public boolean shouldEnableDisappearingMessages() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldEnableTransferData() {
|
||||
return IS_DEBUG_BUILD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldEnableShareAppViaOfflineHotspot() {
|
||||
return IS_DEBUG_BUILD;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package org.briarproject.briar.android;
|
||||
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Process;
|
||||
|
||||
import org.briarproject.bramble.api.lifecycle.Service;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
|
||||
class NetworkUsageLogger implements Service {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(NetworkUsageLogger.class.getName());
|
||||
|
||||
private volatile long startTime, rxBytes, txBytes;
|
||||
|
||||
@Override
|
||||
public void startService() {
|
||||
startTime = now();
|
||||
int uid = Process.myUid();
|
||||
rxBytes = TrafficStats.getUidRxBytes(uid);
|
||||
txBytes = TrafficStats.getUidTxBytes(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopService() {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
long sessionDuration = now() - startTime;
|
||||
int uid = Process.myUid();
|
||||
long rx = TrafficStats.getUidRxBytes(uid) - rxBytes;
|
||||
long tx = TrafficStats.getUidTxBytes(uid) - txBytes;
|
||||
LOG.info("Duration " + (sessionDuration / 1000) + " seconds");
|
||||
LOG.info("Received " + rx + " bytes");
|
||||
LOG.info("Sent " + tx + " bytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.briarproject.briar.android;
|
||||
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Process;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.android.NetworkUsageMetrics;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
|
||||
@NotNullByDefault
|
||||
class NetworkUsageMetricsImpl implements NetworkUsageMetrics {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(NetworkUsageMetricsImpl.class.getName());
|
||||
|
||||
private volatile long startTime, rxBytes, txBytes;
|
||||
|
||||
@Override
|
||||
public void startService() {
|
||||
startTime = now();
|
||||
int uid = Process.myUid();
|
||||
rxBytes = TrafficStats.getUidRxBytes(uid);
|
||||
txBytes = TrafficStats.getUidTxBytes(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopService() {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
Metrics metrics = getMetrics();
|
||||
LOG.info("Duration " + (metrics.getSessionDurationMs() / 1000)
|
||||
+ " seconds");
|
||||
LOG.info("Received " + metrics.getRxBytes() + " bytes");
|
||||
LOG.info("Sent " + metrics.getTxBytes() + " bytes");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics getMetrics() {
|
||||
long sessionDurationMs = now() - startTime;
|
||||
int uid = Process.myUid();
|
||||
long rx = TrafficStats.getUidRxBytes(uid) - rxBytes;
|
||||
long tx = TrafficStats.getUidTxBytes(uid) - txBytes;
|
||||
return new Metrics(sessionDurationMs, rx, tx);
|
||||
}
|
||||
}
|
||||
@@ -40,10 +40,10 @@ public class ContactListItem extends ContactItem
|
||||
item.unread, item.timestamp);
|
||||
}
|
||||
|
||||
ContactListItem(ContactListItem item, ConversationMessageHeader h) {
|
||||
ContactListItem(ContactListItem item, long timestamp, boolean read) {
|
||||
this(item.getContact(), item.getAuthorInfo(), item.isConnected(), false,
|
||||
h.isRead() ? item.unread : item.unread + 1,
|
||||
Math.max(h.getTimestamp(), item.timestamp));
|
||||
read ? item.unread : item.unread + 1,
|
||||
Math.max(timestamp, item.timestamp));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.briarproject.briar.api.client.MessageTracker;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||
import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.conversation.event.ConversationMessageTrackedEvent;
|
||||
import org.briarproject.briar.api.identity.AuthorInfo;
|
||||
import org.briarproject.briar.api.identity.AuthorManager;
|
||||
|
||||
@@ -131,13 +132,14 @@ public class ContactsViewModel extends DbViewModel implements EventListener {
|
||||
} else if (e instanceof ContactRemovedEvent) {
|
||||
LOG.info("Contact removed, removing item");
|
||||
removeItem(((ContactRemovedEvent) e).getContactId());
|
||||
} else if (e instanceof ConversationMessageReceivedEvent) {
|
||||
LOG.info("Conversation message received, updating item");
|
||||
ConversationMessageReceivedEvent<?> p =
|
||||
(ConversationMessageReceivedEvent<?>) e;
|
||||
ConversationMessageHeader h = p.getMessageHeader();
|
||||
updateItem(p.getContactId(), item -> new ContactListItem(item, h),
|
||||
true);
|
||||
} else if (e instanceof ConversationMessageTrackedEvent) {
|
||||
LOG.info("Conversation message tracked, updating item");
|
||||
ConversationMessageTrackedEvent p =
|
||||
(ConversationMessageTrackedEvent) e;
|
||||
long timestamp = p.getTimestamp();
|
||||
boolean read = p.getRead();
|
||||
updateItem(p.getContactId(),
|
||||
item -> new ContactListItem(item, timestamp, read), true);
|
||||
} else if (e instanceof AvatarUpdatedEvent) {
|
||||
AvatarUpdatedEvent a = (AvatarUpdatedEvent) e;
|
||||
updateItem(a.getContactId(), item -> new ContactListItem(item,
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgre
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.QrCodeScanned;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.qrcode.CameraException;
|
||||
import org.briarproject.briar.android.qrcode.CameraView;
|
||||
import org.briarproject.briar.android.view.QrCodeView;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -53,7 +53,8 @@ import org.briarproject.briar.android.contact.add.nearby.AddContactState.Contact
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementListening;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
||||
import org.briarproject.briar.android.util.QrCodeUtils;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeUtils;
|
||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||
|
||||
|
||||
@@ -380,7 +380,7 @@ public class ConversationActivity extends BriarActivity
|
||||
}
|
||||
});
|
||||
// Transfer Data feature only supported on API 19+
|
||||
if (SDK_INT >= 19 && featureFlags.shouldEnableTransferData()) {
|
||||
if (SDK_INT >= 19) {
|
||||
menu.findItem(R.id.action_transfer_data).setVisible(true);
|
||||
}
|
||||
// enable alias and bluetooth action once available
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.briarproject.bramble.api.settings.SettingsManager;
|
||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.hotspot.HotspotState.NetworkConfig;
|
||||
import org.briarproject.briar.android.util.QrCodeUtils;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeUtils;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -52,7 +52,7 @@ import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.briar.android.util.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
||||
import static org.briarproject.briar.android.qrcode.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
||||
import static org.briarproject.briar.android.util.UiUtils.handleException;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -312,12 +312,19 @@ class HotspotManager {
|
||||
}
|
||||
GroupInfoListener groupListener = group -> {
|
||||
boolean valid = isGroupValid(group);
|
||||
// If the group is valid, set the hotspot to started. If we don't
|
||||
// have any attempts left, we try what we got
|
||||
if (valid || attempt >= MAX_GROUP_INFO_ATTEMPTS) {
|
||||
if (valid) {
|
||||
// the group is valid, set the hotspot to started.
|
||||
onHotspotStarted(group);
|
||||
} else if (attempt < MAX_GROUP_INFO_ATTEMPTS) {
|
||||
// we have attempts left, try again
|
||||
retryRequestingGroupInfo(attempt);
|
||||
} else if (group != null) {
|
||||
// no attempts left, but group is not null, try what we got
|
||||
onHotspotStarted(group);
|
||||
} else {
|
||||
retryRequestingGroupInfo(attempt);
|
||||
// no attempts left and group is null, fail
|
||||
releaseHotspotWithError(ctx.getString(
|
||||
R.string.hotspot_error_start_callback_no_group_info));
|
||||
}
|
||||
};
|
||||
try {
|
||||
@@ -366,13 +373,8 @@ class HotspotManager {
|
||||
private void retryRequestingGroupInfo(int attempt) {
|
||||
LOG.info("retrying to request group info");
|
||||
// On some devices we need to wait for the group info to become available
|
||||
if (attempt < MAX_GROUP_INFO_ATTEMPTS) {
|
||||
handler.postDelayed(() -> requestGroupInfo(attempt + 1),
|
||||
RETRY_DELAY_MILLIS);
|
||||
} else {
|
||||
releaseHotspotWithError(ctx.getString(
|
||||
R.string.hotspot_error_start_callback_no_group_info));
|
||||
}
|
||||
handler.postDelayed(() -> requestGroupInfo(attempt + 1),
|
||||
RETRY_DELAY_MILLIS);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.android.hotspot.HotspotState.WebsiteConfig;
|
||||
import org.briarproject.briar.android.util.QrCodeUtils;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
@@ -27,7 +27,7 @@ import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.NetworkUtils.getNetworkInterfaces;
|
||||
import static org.briarproject.briar.android.hotspot.WebServer.PORT;
|
||||
import static org.briarproject.briar.android.util.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
||||
import static org.briarproject.briar.android.qrcode.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.briarproject.briar.android.mailbox;
|
||||
|
||||
import org.briarproject.briar.android.viewmodel.ViewModelKey;
|
||||
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.multibindings.IntoMap;
|
||||
|
||||
@Module
|
||||
public interface MailboxModule {
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(MailboxPairViewModel.class)
|
||||
ViewModel bindMailboxViewModel(
|
||||
MailboxPairViewModel mailboxPairViewModel);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.briarproject.briar.android.mailbox;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.google.zxing.Result;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.TransactionManager;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||
import org.briarproject.briar.android.viewmodel.DbViewModel;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
class MailboxPairViewModel extends DbViewModel
|
||||
implements QrCodeDecoder.ResultCallback {
|
||||
private static final Logger LOG =
|
||||
getLogger(MailboxPairViewModel.class.getName());
|
||||
|
||||
private static final int VERSION_REQUIRED = 32;
|
||||
|
||||
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
||||
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final QrCodeDecoder qrCodeDecoder;
|
||||
|
||||
@Nullable
|
||||
private String onionAddress = null;
|
||||
@Nullable
|
||||
private String setupToken = null;
|
||||
|
||||
@Inject
|
||||
MailboxPairViewModel(
|
||||
Application app,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
LifecycleManager lifecycleManager,
|
||||
TransactionManager db,
|
||||
AndroidExecutor androidExecutor,
|
||||
@IoExecutor Executor ioExecutor,
|
||||
CryptoComponent crypto) {
|
||||
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
||||
this.crypto = crypto;
|
||||
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQrCodeDecoded(Result result) {
|
||||
LOG.info("Got result from decoder");
|
||||
byte[] bytes = result.getText().getBytes(ISO_8859_1);
|
||||
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("QR code length in bytes: " + bytes.length);
|
||||
if (bytes.length != 65) {
|
||||
LOG.info("QR code has wrong length");
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("QR code version: " + bytes[0]);
|
||||
if (bytes[0] != VERSION_REQUIRED) {
|
||||
LOG.info("QR code has wrong version");
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33);
|
||||
onionAddress = crypto.encodeOnionAddress(onionPubKey);
|
||||
setupToken = StringUtils.toHexString(Arrays.copyOfRange(bytes, 33, 65))
|
||||
.toLowerCase();
|
||||
LOG.info("QR code is valid");
|
||||
}
|
||||
|
||||
QrCodeDecoder getQrCodeDecoder() {
|
||||
return qrCodeDecoder;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
package org.briarproject.briar.android.qrcode;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class CameraException extends IOException {
|
||||
public class CameraException extends IOException {
|
||||
|
||||
CameraException(String message) {
|
||||
super(message);
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
package org.briarproject.briar.android.qrcode;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Camera;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
package org.briarproject.briar.android.qrcode;
|
||||
|
||||
import android.hardware.Camera;
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
@NotNullByDefault
|
||||
interface PreviewConsumer {
|
||||
public interface PreviewConsumer {
|
||||
|
||||
@UiThread
|
||||
void start(Camera camera, int cameraIndex);
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
package org.briarproject.briar.android.qrcode;
|
||||
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.CameraInfo;
|
||||
@@ -32,7 +32,7 @@ import static java.util.logging.Logger.getLogger;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
|
||||
private static final Logger LOG = getLogger(QrCodeDecoder.class.getName());
|
||||
|
||||
@@ -44,7 +44,7 @@ class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
private Camera camera = null;
|
||||
private int cameraIndex = 0;
|
||||
|
||||
QrCodeDecoder(AndroidExecutor androidExecutor,
|
||||
public QrCodeDecoder(AndroidExecutor androidExecutor,
|
||||
@IoExecutor Executor ioExecutor, ResultCallback callback) {
|
||||
this.androidExecutor = androidExecutor;
|
||||
this.ioExecutor = ioExecutor;
|
||||
@@ -127,7 +127,7 @@ class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
}
|
||||
|
||||
@NotNullByDefault
|
||||
interface ResultCallback {
|
||||
public interface ResultCallback {
|
||||
@IoExecutor
|
||||
void onQrCodeDecoded(Result result);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.briarproject.briar.android.util;
|
||||
package org.briarproject.briar.android.qrcode;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.DisplayMetrics;
|
||||
@@ -23,11 +23,10 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@NotNullByDefault
|
||||
public class QrCodeUtils {
|
||||
public static final double HOTSPOT_QRCODE_FACTOR = 0.35;
|
||||
|
||||
private static final Logger LOG = getLogger(QrCodeUtils.class.getName());
|
||||
|
||||
public static final double HOTSPOT_QRCODE_FACTOR = 0.35;
|
||||
|
||||
@Nullable
|
||||
public static Bitmap createQrCode(DisplayMetrics dm, String input) {
|
||||
return createQrCode(Math.min(dm.widthPixels, dm.heightPixels), input);
|
||||
@@ -28,6 +28,8 @@ import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
|
||||
import org.briarproject.briar.android.reporting.ReportData.ReportItem;
|
||||
import org.briarproject.briar.android.reporting.ReportData.SingleReportInfo;
|
||||
import org.briarproject.briar.api.android.NetworkUsageMetrics;
|
||||
import org.briarproject.briar.api.android.NetworkUsageMetrics.Metrics;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
@@ -65,9 +67,11 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||
class BriarReportCollector {
|
||||
|
||||
private final Context ctx;
|
||||
private final NetworkUsageMetrics networkUsageMetrics;
|
||||
|
||||
BriarReportCollector(Context ctx) {
|
||||
BriarReportCollector(Context ctx, NetworkUsageMetrics networkUsageMetrics) {
|
||||
this.ctx = ctx;
|
||||
this.networkUsageMetrics = networkUsageMetrics;
|
||||
}
|
||||
|
||||
ReportData collectReportData(@Nullable Throwable t, long appStartTime,
|
||||
@@ -81,6 +85,7 @@ class BriarReportCollector {
|
||||
.add(getMemory())
|
||||
.add(getStorage())
|
||||
.add(getConnectivity())
|
||||
.add(getNetworkUsage())
|
||||
.add(getBuildConfig())
|
||||
.add(getLogcat(logs))
|
||||
.add(getDeviceFeatures());
|
||||
@@ -298,6 +303,16 @@ class BriarReportCollector {
|
||||
connectivityInfo);
|
||||
}
|
||||
|
||||
private ReportItem getNetworkUsage() {
|
||||
Metrics metrics = networkUsageMetrics.getMetrics();
|
||||
MultiReportInfo networkUsage = new MultiReportInfo()
|
||||
.add("SessionDuration", metrics.getSessionDurationMs())
|
||||
.add("BytesReceived", metrics.getRxBytes())
|
||||
.add("BytesSent", metrics.getTxBytes());
|
||||
return new ReportItem("NetworkUsage", R.string.dev_report_network_usage,
|
||||
networkUsage);
|
||||
}
|
||||
|
||||
private ReportItem getBuildConfig() {
|
||||
MultiReportInfo buildConfig = new MultiReportInfo()
|
||||
.add("GitHash", BuildConfig.GitHash)
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
|
||||
import org.briarproject.briar.android.reporting.ReportData.ReportItem;
|
||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||
import org.briarproject.briar.api.android.NetworkUsageMetrics;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.File;
|
||||
@@ -69,12 +70,13 @@ class ReportViewModel extends AndroidViewModel {
|
||||
|
||||
@Inject
|
||||
ReportViewModel(@NonNull Application application,
|
||||
NetworkUsageMetrics networkUsageMetrics,
|
||||
CachingLogHandler logHandler,
|
||||
LogDecrypter logDecrypter,
|
||||
DevReporter reporter,
|
||||
PluginManager pluginManager) {
|
||||
super(application);
|
||||
collector = new BriarReportCollector(application);
|
||||
collector = new BriarReportCollector(application, networkUsageMetrics);
|
||||
this.logHandler = logHandler;
|
||||
this.logDecrypter = logDecrypter;
|
||||
this.reporter = reporter;
|
||||
|
||||
@@ -86,12 +86,6 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
||||
PreferenceGroup dev = requireNonNull(findPreference(PREF_KEY_DEV));
|
||||
dev.setVisible(false);
|
||||
}
|
||||
|
||||
if (!viewModel.shouldEnableShareAppViaOfflineHotspot()) {
|
||||
Preference shareApp =
|
||||
requireNonNull(findPreference(PREF_KEY_SHARE_APP));
|
||||
shareApp.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -262,8 +262,4 @@ class SettingsViewModel extends DbViewModel implements EventListener {
|
||||
return screenLockTimeout;
|
||||
}
|
||||
|
||||
boolean shouldEnableShareAppViaOfflineHotspot() {
|
||||
return featureFlags.shouldEnableShareAppViaOfflineHotspot();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class AuthorView extends ConstraintLayout {
|
||||
if (authorInfo.getStatus() == OURSELVES) {
|
||||
authorName.setTypeface(authorNameTypeface, BOLD);
|
||||
} else {
|
||||
authorName.setTypeface(authorNameTypeface, NORMAL);
|
||||
authorName.setTypeface(authorNameTypeface, Typeface.NORMAL);
|
||||
}
|
||||
|
||||
invalidate();
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.briarproject.briar.api.android;
|
||||
|
||||
import org.briarproject.bramble.api.lifecycle.Service;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface NetworkUsageMetrics extends Service {
|
||||
|
||||
Metrics getMetrics();
|
||||
|
||||
class Metrics {
|
||||
|
||||
private final long sessionDurationMs, rxBytes, txBytes;
|
||||
|
||||
public Metrics(long sessionDurationMs, long rxBytes,
|
||||
long txBytes) {
|
||||
this.sessionDurationMs = sessionDurationMs;
|
||||
this.rxBytes = rxBytes;
|
||||
this.txBytes = txBytes;
|
||||
}
|
||||
|
||||
public long getSessionDurationMs() {
|
||||
return sessionDurationMs;
|
||||
}
|
||||
|
||||
public long getRxBytes() {
|
||||
return rxBytes;
|
||||
}
|
||||
|
||||
public long getTxBytes() {
|
||||
return txBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
briar-android/src/main/res/drawable/ic_share_app.xml
Normal file
66
briar-android/src/main/res/drawable/ic_share_app.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="256dp"
|
||||
android:height="204dp"
|
||||
android:viewportWidth="256"
|
||||
android:viewportHeight="204">
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M41.583,100.841H22.181V102.841H52.75V136.663H54.75V102.841H68.034C70.924,102.841 73.267,105.184 73.267,108.074C73.267,112.068 76.505,115.307 80.5,115.307H92.727V113.307H80.5C77.61,113.307 75.267,110.964 75.267,108.074C75.267,104.079 72.029,100.841 68.034,100.841H43.583V63.659H41.583V100.841Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M122.611,86.06V46.253H124.611V86.06H122.611Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M119.754,179.928L119.754,142.682L121.754,142.682L121.754,179.928L119.754,179.928Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M195.251,100.841V86.596H193.251V113.826H148.362V115.826H194.251C198.125,115.826 201.301,118.969 201.301,122.826V127.044H203.301V122.826C203.301,118.186 199.75,114.378 195.251,113.881V102.841H233.052V100.841H195.251Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M32.121,57.411L32.888,55.564C33.596,55.858 34.375,56.021 35.197,56.021H37.079V58.021H35.197C34.107,58.021 33.069,57.804 32.121,57.411ZM48.377,58.021V56.021H50.26C51.082,56.021 51.86,55.858 52.569,55.564L53.335,57.411C52.388,57.804 51.349,58.021 50.26,58.021H48.377ZM58.293,36.807H56.293V34.924C56.293,34.102 56.13,33.323 55.836,32.615L57.684,31.849C58.077,32.796 58.293,33.834 58.293,34.924V36.807ZM37.079,26.89H35.197C34.107,26.89 33.069,27.107 32.121,27.5L32.888,29.347C33.596,29.053 34.375,28.89 35.197,28.89H37.079V26.89ZM27.163,48.104H29.163V49.987C29.163,50.809 29.326,51.588 29.62,52.296L27.772,53.062C27.38,52.115 27.163,51.076 27.163,49.987V48.104ZM27.163,44.338H29.163V40.572H27.163V44.338ZM27.163,36.807H29.163V34.924C29.163,34.102 29.326,33.323 29.62,32.615L27.772,31.849C27.38,32.796 27.163,33.834 27.163,34.924V36.807ZM40.845,26.89V28.89H44.611V26.89H40.845ZM48.377,26.89V28.89H50.26C51.082,28.89 51.86,29.053 52.569,29.347L53.335,27.5C52.388,27.107 51.349,26.89 50.26,26.89H48.377ZM58.293,40.572H56.293V44.338H58.293V40.572ZM58.293,48.104H56.293V49.987C56.293,50.809 56.13,51.588 55.836,52.296L57.684,53.062C58.077,52.115 58.293,51.076 58.293,49.987V48.104ZM44.611,58.021V56.021H40.845V58.021H44.611Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M112.487,40.426L112.875,38.464C113.41,38.569 113.964,38.625 114.533,38.625H116.99V40.625H114.533C113.833,40.625 113.149,40.556 112.487,40.426ZM131.733,40.625V38.625H134.191C134.76,38.625 135.314,38.569 135.848,38.464L136.237,40.426C135.575,40.556 134.891,40.625 134.191,40.625H131.733ZM140.016,38.859L138.903,37.197C139.829,36.577 140.627,35.78 141.247,34.854L142.909,35.966C142.143,37.11 141.159,38.094 140.016,38.859ZM144.674,12.941H142.674V10.484C142.674,9.915 142.619,9.361 142.513,8.826L144.475,8.438C144.606,9.1 144.674,9.784 144.674,10.484V12.941ZM142.909,4.659L141.247,5.772C140.627,4.845 139.829,4.048 138.903,3.428L140.016,1.766C141.159,2.531 142.143,3.516 142.909,4.659ZM116.99,0H114.533C113.833,0 113.149,0.069 112.487,0.2L112.875,2.162C113.41,2.056 113.964,2 114.533,2H116.99V0ZM108.708,1.766L109.821,3.428C108.895,4.048 108.097,4.845 107.477,5.772L105.815,4.659C106.581,3.516 107.565,2.531 108.708,1.766ZM104.049,27.684H106.049V30.141C106.049,30.71 106.105,31.264 106.211,31.799L104.249,32.187C104.118,31.525 104.049,30.841 104.049,30.141V27.684ZM105.815,35.966L107.477,34.854C108.097,35.78 108.895,36.577 109.821,37.197L108.708,38.859C107.565,38.094 106.581,37.11 105.815,35.966ZM104.049,22.77H106.049V17.855H104.049V22.77ZM104.049,12.941H106.049V10.484C106.049,9.915 106.105,9.361 106.211,8.826L104.249,8.438C104.118,9.1 104.049,9.784 104.049,10.484V12.941ZM121.905,0V2H126.819V0H121.905ZM131.733,0V2H134.191C134.76,2 135.314,2.056 135.848,2.162L136.237,0.2C135.575,0.069 134.891,0 134.191,0H131.733ZM144.674,17.855H142.674V22.77H144.674V17.855ZM144.674,27.684H142.674V30.141C142.674,30.71 142.619,31.264 142.513,31.799L144.475,32.187C144.606,31.525 144.674,30.841 144.674,30.141V27.684ZM126.819,40.625V38.625H121.905V40.625H126.819Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M183.397,81.99L184.163,80.143C184.902,80.449 185.714,80.619 186.57,80.619H188.513V82.619H186.57C185.446,82.619 184.375,82.396 183.397,81.99ZM200.171,82.619V80.619H202.114C202.97,80.619 203.782,80.449 204.521,80.143L205.287,81.99C204.309,82.396 203.238,82.619 202.114,82.619H200.171ZM210.403,60.729H208.403V58.787C208.403,57.93 208.233,57.118 207.927,56.38L209.774,55.613C210.18,56.591 210.403,57.663 210.403,58.787V60.729ZM188.513,50.497H186.57C185.446,50.497 184.375,50.721 183.397,51.126L184.163,52.973C184.902,52.667 185.714,52.497 186.57,52.497H188.513V50.497ZM178.281,72.387H180.281V74.33C180.281,75.186 180.451,75.998 180.757,76.737L178.91,77.503C178.504,76.525 178.281,75.454 178.281,74.33V72.387ZM178.281,68.501H180.281V64.615H178.281V68.501ZM178.281,60.729H180.281V58.787C180.281,57.93 180.451,57.118 180.757,56.38L178.91,55.613C178.504,56.591 178.281,57.663 178.281,58.787V60.729ZM192.399,50.497V52.497H196.285V50.497H192.399ZM200.171,50.497V52.497H202.114C202.97,52.497 203.782,52.667 204.521,52.973L205.287,51.126C204.309,50.721 203.238,50.497 202.114,50.497H200.171ZM210.403,64.615H208.403V68.501H210.403V64.615ZM210.403,72.387H208.403V74.33C208.403,75.186 208.233,75.998 207.927,76.737L209.774,77.503C210.18,76.525 210.403,75.454 210.403,74.33V72.387ZM196.285,82.619V80.619H192.399V82.619H196.285Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M188.271,180.562L188.659,178.6C189.316,178.73 189.996,178.798 190.694,178.798H192.633V180.798H190.694C189.865,180.798 189.055,180.717 188.271,180.562ZM212.029,180.798V178.798H213.968C214.666,178.798 215.346,178.73 216.003,178.6L216.391,180.562C215.607,180.717 214.797,180.798 213.968,180.798H212.029ZM220.865,178.708L219.753,177.046C220.889,176.285 221.868,175.306 222.629,174.17L224.291,175.282C223.384,176.636 222.219,177.801 220.865,178.708ZM226.381,147.05H224.381V145.111C224.381,144.413 224.313,143.733 224.183,143.077L226.145,142.688C226.3,143.472 226.381,144.282 226.381,145.111V147.05ZM224.291,138.214L222.629,139.327C221.868,138.19 220.889,137.211 219.753,136.451L220.865,134.789C222.219,135.695 223.384,136.86 224.291,138.214ZM192.633,132.698H190.694C189.865,132.698 189.055,132.779 188.271,132.934L188.659,134.896C189.316,134.766 189.996,134.698 190.694,134.698H192.633V132.698ZM183.797,134.789L184.91,136.451C183.773,137.211 182.794,138.19 182.033,139.327L180.372,138.214C181.278,136.86 182.443,135.695 183.797,134.789ZM178.281,166.446H180.281V168.385C180.281,169.083 180.349,169.763 180.479,170.42L178.517,170.808C178.362,170.024 178.281,169.214 178.281,168.385V166.446ZM180.372,175.282L182.033,174.17C182.794,175.306 183.773,176.285 184.91,177.046L183.797,178.708C182.443,177.801 181.278,176.636 180.372,175.282ZM178.281,162.567H180.281V158.688H178.281V162.567ZM178.281,154.809H180.281V150.93H178.281V154.809ZM178.281,147.05H180.281V145.111C180.281,144.413 180.349,143.733 180.479,143.077L178.517,142.688C178.362,143.472 178.281,144.282 178.281,145.111V147.05ZM196.512,132.698V134.698H200.392V132.698H196.512ZM204.271,132.698V134.698H208.15V132.698H204.271ZM212.029,132.698V134.698H213.968C214.666,134.698 215.346,134.766 216.003,134.896L216.391,132.934C215.607,132.779 214.797,132.698 213.968,132.698H212.029ZM226.381,150.93H224.381V154.809H226.381V150.93ZM226.381,158.688H224.381V162.567H226.381V158.688ZM226.381,166.446H224.381V168.385C224.381,169.083 224.313,169.763 224.183,170.42L226.145,170.808C226.3,170.024 226.381,169.214 226.381,168.385V166.446ZM208.15,180.798V178.798H204.271V180.798H208.15ZM200.392,180.798V178.798H196.512V180.798H200.392Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M40.389,175.457L41.155,173.609C41.934,173.932 42.789,174.111 43.692,174.111H45.713V176.111H43.692C42.522,176.111 41.406,175.878 40.389,175.457ZM57.845,176.111V174.111H59.867C60.769,174.111 61.625,173.932 62.403,173.609L63.169,175.457C62.152,175.878 61.037,176.111 59.867,176.111H57.845ZM68.494,153.33H66.494V151.309C66.494,150.406 66.315,149.551 65.992,148.772L67.84,148.006C68.261,149.023 68.494,150.139 68.494,151.309V153.33ZM45.713,142.682H43.692C42.522,142.682 41.406,142.914 40.389,143.336L41.155,145.184C41.934,144.861 42.789,144.682 43.692,144.682H45.713V142.682ZM35.064,165.462H37.064V167.484C37.064,168.386 37.244,169.242 37.567,170.02L35.719,170.786C35.297,169.769 35.064,168.654 35.064,167.484V165.462ZM35.064,161.418H37.064V157.374H35.064V161.418ZM35.064,153.33H37.064V151.309C37.064,150.406 37.244,149.551 37.567,148.772L35.719,148.006C35.297,149.023 35.064,150.139 35.064,151.309V153.33ZM49.757,142.682V144.682H53.801V142.682H49.757ZM57.845,142.682V144.682H59.867C60.769,144.682 61.625,144.861 62.403,145.184L63.169,143.336C62.152,142.914 61.037,142.682 59.867,142.682H57.845ZM68.494,157.374H66.494V161.418H68.494V157.374ZM68.494,165.462H66.494V167.484C66.494,168.386 66.315,169.242 65.992,170.02L67.84,170.786C68.261,169.769 68.494,168.654 68.494,167.484V165.462ZM53.801,176.111V174.111H49.757V176.111H53.801Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M2.84,110.802L3.606,108.954C3.91,109.081 4.245,109.151 4.601,109.151H6.758V111.151H4.601C3.977,111.151 3.383,111.027 2.84,110.802ZM11.072,111.151V109.151H13.229C13.585,109.151 13.92,109.081 14.224,108.954L14.99,110.802C14.448,111.027 13.853,111.151 13.229,111.151H11.072ZM17.83,100.079H15.83V97.922C15.83,97.566 15.76,97.231 15.634,96.927L17.481,96.161C17.706,96.703 17.83,97.298 17.83,97.922V100.079ZM6.758,93.321H4.601C3.977,93.321 3.383,93.445 2.84,93.67L3.606,95.518C3.91,95.392 4.245,95.321 4.601,95.321H6.758V93.321ZM0,104.393H2V106.55C2,106.906 2.071,107.241 2.197,107.545L0.349,108.311C0.124,107.769 0,107.174 0,106.55V104.393ZM0,100.079H2V97.922C2,97.566 2.071,97.231 2.197,96.927L0.349,96.161C0.124,96.703 0,97.298 0,97.922V100.079ZM11.072,93.321V95.321H13.229C13.585,95.321 13.92,95.392 14.224,95.518L14.99,93.67C14.448,93.445 13.853,93.321 13.229,93.321H11.072ZM17.83,104.393H15.83V106.55C15.83,106.906 15.76,107.241 15.634,107.545L17.481,108.311C17.706,107.769 17.83,107.174 17.83,106.55V104.393Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M114.745,202.969L115.511,201.122C115.815,201.248 116.149,201.318 116.506,201.318H118.663V203.318H116.506C115.882,203.318 115.287,203.194 114.745,202.969ZM122.977,203.318V201.318H125.133C125.49,201.318 125.825,201.248 126.129,201.122L126.895,202.969C126.352,203.194 125.757,203.318 125.133,203.318H122.977ZM129.735,192.246H127.735V190.09C127.735,189.733 127.664,189.398 127.538,189.094L129.386,188.328C129.611,188.871 129.735,189.466 129.735,190.09V192.246ZM118.663,185.488H116.506C115.882,185.488 115.287,185.612 114.745,185.837L115.511,187.685C115.815,187.559 116.149,187.488 116.506,187.488H118.663V185.488ZM111.905,196.56H113.905V198.717C113.905,199.074 113.975,199.408 114.101,199.712L112.254,200.478C112.029,199.936 111.905,199.341 111.905,198.717V196.56ZM111.905,192.246H113.905V190.09C113.905,189.733 113.975,189.398 114.101,189.094L112.254,188.328C112.029,188.871 111.905,189.466 111.905,190.09V192.246ZM122.977,185.488V187.488H125.133C125.49,187.488 125.825,187.559 126.129,187.685L126.895,185.837C126.352,185.612 125.757,185.488 125.133,185.488H122.977ZM129.735,196.56H127.735V198.717C127.735,199.074 127.664,199.408 127.538,199.712L129.386,200.478C129.611,199.936 129.735,199.341 129.735,198.717V196.56Z" />
|
||||
<path
|
||||
android:fillColor="#657D99"
|
||||
android:pathData="M240.444,110.802L241.21,108.954C241.514,109.081 241.849,109.151 242.205,109.151H244.362V111.151H242.205C241.581,111.151 240.987,111.027 240.444,110.802ZM248.676,111.151V109.151H250.833C251.189,109.151 251.524,109.081 251.828,108.954L252.594,110.802C252.052,111.027 251.457,111.151 250.833,111.151H248.676ZM255.434,100.079H253.434V97.922C253.434,97.566 253.364,97.231 253.238,96.927L255.085,96.161C255.31,96.703 255.434,97.298 255.434,97.922V100.079ZM244.362,93.321H242.205C241.581,93.321 240.987,93.445 240.444,93.67L241.21,95.518C241.514,95.392 241.849,95.321 242.205,95.321H244.362V93.321ZM237.604,104.393H239.604V106.55C239.604,106.906 239.675,107.241 239.801,107.545L237.953,108.311C237.728,107.769 237.604,107.174 237.604,106.55V104.393ZM237.604,100.079H239.604V97.922C239.604,97.566 239.675,97.231 239.801,96.927L237.953,96.161C237.728,96.703 237.604,97.298 237.604,97.922V100.079ZM248.676,93.321V95.321H250.833C251.189,95.321 251.524,95.392 251.828,95.518L252.594,93.67C252.052,93.445 251.457,93.321 250.833,93.321H248.676ZM255.434,104.393H253.434V106.55C253.434,106.906 253.364,107.241 253.238,107.545L255.085,108.311C255.31,107.769 255.434,107.174 255.434,106.55V104.393Z" />
|
||||
<path
|
||||
android:fillColor="#87C214"
|
||||
android:pathData="M108.75,109.808V129.511C108.75,131.11 110.052,132.429 111.668,132.429H113.036C114.636,132.429 115.955,131.11 115.955,129.511V109.808H108.75V109.808Z" />
|
||||
<path
|
||||
android:fillColor="#87C214"
|
||||
android:pathData="M115.938,100.312V96.602C115.938,95.003 114.636,93.684 113.036,93.684H111.668C110.069,93.684 108.75,95.003 108.75,96.602V100.312H115.938V100.312Z" />
|
||||
<path
|
||||
android:fillColor="#87C214"
|
||||
android:pathData="M131.931,116.305V96.602C131.931,95.003 130.628,93.684 129.029,93.684H127.66C126.061,93.684 124.742,95.003 124.742,96.602V116.305H131.931V116.305Z" />
|
||||
<path
|
||||
android:fillColor="#87C214"
|
||||
android:pathData="M124.742,125.801V129.511C124.742,131.11 126.061,132.429 127.66,132.429H129.029C130.628,132.429 131.947,131.11 131.947,129.511V125.801H124.742Z" />
|
||||
<path
|
||||
android:fillColor="#95D220"
|
||||
android:pathData="M107.595,117.459H103.886C102.286,117.459 100.967,118.761 100.967,120.377V121.746C100.967,123.345 102.27,124.664 103.886,124.664H107.595V117.459Z" />
|
||||
<path
|
||||
android:fillColor="#95D220"
|
||||
android:pathData="M136.795,117.459H117.092V124.664H136.795C138.394,124.664 139.713,123.345 139.713,121.746V120.377C139.713,118.761 138.394,117.459 136.795,117.459Z" />
|
||||
<path
|
||||
android:fillColor="#95D220"
|
||||
android:pathData="M123.588,101.466H103.886C102.286,101.466 100.967,102.769 100.967,104.385V105.753C100.967,107.352 102.27,108.671 103.886,108.671H123.588V101.466Z" />
|
||||
<path
|
||||
android:fillColor="#95D220"
|
||||
android:pathData="M136.795,101.466H133.085V108.671H136.795C138.394,108.671 139.713,107.369 139.713,105.753V104.384C139.713,102.769 138.394,101.466 136.795,101.466Z" />
|
||||
</vector>
|
||||
@@ -47,6 +47,19 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/wifi1View" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/wifi3View"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:drawablePadding="6dp"
|
||||
android:text="@string/hotspot_help_wifi_3"
|
||||
app:drawableLeftCompat="@drawable/ic_circle_small"
|
||||
app:drawableStartCompat="@drawable/ic_circle_small"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/wifi2View" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/siteTitleView"
|
||||
android:layout_width="0dp"
|
||||
@@ -57,7 +70,7 @@
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/wifi2View" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/wifi3View" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/site1View"
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="@dimen/hero_square"
|
||||
android:layout_height="@dimen/hero_square"
|
||||
android:layout_width="@dimen/hero_rect_width"
|
||||
android:layout_height="@dimen/hero_rect_width"
|
||||
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||
android:layout_marginTop="@dimen/margin_xlarge"
|
||||
app:layout_constraintBottom_toTopOf="@+id/introView"
|
||||
@@ -24,7 +24,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.25"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:srcCompat="@drawable/ic_wifi_tethering"
|
||||
app:srcCompat="@drawable/ic_share_app"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true">
|
||||
|
||||
<org.briarproject.briar.android.contact.add.nearby.CameraView
|
||||
<org.briarproject.briar.android.qrcode.CameraView
|
||||
android:id="@+id/camera_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
<string name="ok">Добре</string>
|
||||
<string name="cancel">Отказ</string>
|
||||
<string name="got_it">Разбрах</string>
|
||||
<string name="delete">Изтриване</string>
|
||||
<string name="delete">Премахване</string>
|
||||
<string name="accept">Приемане</string>
|
||||
<string name="decline">Отказване</string>
|
||||
<string name="online">На линия</string>
|
||||
@@ -190,7 +190,7 @@
|
||||
<string name="auto_delete_changed_warning_message_enabled">Откакто съставяте съобщението е бил включен механизмът за изчезващи съобщения.</string>
|
||||
<string name="auto_delete_changed_warning_message_disabled">Откакто съставяте съобщението е бил изключен механизмът за изчезващи съобщения.</string>
|
||||
<string name="auto_delete_changed_warning_send">Изпращане въпреки това</string>
|
||||
<string name="delete_all_messages">Изтриване на всички</string>
|
||||
<string name="delete_all_messages">Премахване на всички</string>
|
||||
<string name="dialog_title_delete_all_messages">Потвърждение на премахване на съобщение</string>
|
||||
<string name="dialog_message_delete_all_messages">Сигурни ли сте, че желаете всички съобщения да бъдат премахнати?</string>
|
||||
<string name="dialog_title_not_all_messages_deleted">Не премахнати съобщения</string>
|
||||
@@ -238,7 +238,7 @@
|
||||
<string name="add_contact_remotely_title_case">Добавяне на контакт отдалечено</string>
|
||||
<string name="add_contact_nearby_title">Добавяне на контакт на живо</string>
|
||||
<string name="add_contact_remotely_title">Добавяне на контакт отдалечено</string>
|
||||
<string name="contact_link_intro">Въведете препратката от вашия контакт</string>
|
||||
<string name="contact_link_intro">Въведете препратката на контакта, когото добавяте</string>
|
||||
<string name="contact_link_hint">Препратка от контакт</string>
|
||||
<string name="paste_button">Поставяне</string>
|
||||
<string name="add_contact_button">Добавяне на контакт</string>
|
||||
@@ -277,8 +277,8 @@
|
||||
</plurals>
|
||||
<string name="offline_state">Няма връзка с интернет.</string>
|
||||
<string name="duplicate_link_dialog_title">Дублираща се препратка</string>
|
||||
<string name="duplicate_link_dialog_text_1">Вече имате чакаща заявка за контакт с тази препратка: %s</string>
|
||||
<string name="duplicate_link_dialog_text_1_contact">Вече имате контакт с тази препратка: %s</string>
|
||||
<string name="duplicate_link_dialog_text_1">Вече има чакаща заявка за контакт с тази препратка: %s</string>
|
||||
<string name="duplicate_link_dialog_text_1_contact">Вече има контакт с тази препратка: %s</string>
|
||||
<!--This is a question asking whether two nicknames refer to the same person-->
|
||||
<string name="duplicate_link_dialog_text_2">%s и %s един и същи човек ли са?</string>
|
||||
<!--This is a button for answering that two nicknames do indeed refer to the same person. This
|
||||
@@ -316,9 +316,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Свързване чрез Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_title">Свързване чрез Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_intro">В случай, че връзка чрез Bluetooth не се установява автоматично можете да използвате този екран, за да се свържете ръчно.\n\nВие и контакта трябва да бъдете близо един до друг.\n\nДвамата трябва да докоснете бутона „Старт“ едновременно.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Осъществява св връзка през Bluetooth. По-късно опитайте отново.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Не може да продължи без разрешение за местоположение</string>
|
||||
<string name="connect_via_bluetooth_start">Свързване чрез Bluetooth…</string>
|
||||
<string name="connect_via_bluetooth_success">Успешно свързване чрез Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_success">Успешно е създaдена връзка чрез Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">Не може да бъде установена връзка чрез Bluetooth.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Bluetooth не се поддържа от устройството.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">Няма групи</string>
|
||||
<string name="groups_list_empty_action">Докоснете иконата с +, за да създадете своя или поискайте от контактите си да споделят група с вас</string>
|
||||
@@ -434,7 +438,7 @@
|
||||
<string name="blogs_blog_post_received">Получена е нова публикация в блога</string>
|
||||
<string name="blogs_blog_post_scroll_to">Плъзване до нея</string>
|
||||
<string name="blogs_feed_empty_state">Няма публикации</string>
|
||||
<string name="blogs_feed_empty_state_action">Публикации от вашите контакти и абонираните блогове се показват тук.\n\nДокоснете иконата на писалка, за да направите публикация.</string>
|
||||
<string name="blogs_feed_empty_state_action">Тук се показват публикациите от вашите контакти и блоговете, за които имате абонамент.\n\nЗа да направите вие публикация, докоснете иконата на писалка.</string>
|
||||
<string name="blogs_remove_blog">Премахване на блог</string>
|
||||
<string name="blogs_remove_blog_dialog_message">Сигурни ли сте, че желаете да премахнете блога?\n\nПубликациите ще бъдат премахнати от устройството ви, но не и от устройствата на другите хора.\n\nКонтактите, с които сте споделили този блог може да спрат да получават обновявания.</string>
|
||||
<string name="blogs_remove_blog_ok">Премахване</string>
|
||||
@@ -510,7 +514,7 @@
|
||||
<string name="pref_lock_disabled_summary">За да се възползвате от тази възможност, настройте заключване на екрана</string>
|
||||
<string name="pref_lock_timeout_title">Заключване при бездействие</string>
|
||||
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
|
||||
<string name="pref_lock_timeout_summary">Briar се изключва автоматично при неактивност от %s</string>
|
||||
<string name="pref_lock_timeout_summary">При неактивност Briar автоматично се заключав след %s</string>
|
||||
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
|
||||
<string name="pref_lock_timeout_1">1 минута</string>
|
||||
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
|
||||
@@ -539,9 +543,9 @@
|
||||
<string name="dialog_message_connect_panic_app">Сигурни ли сте, че желаете да позволите на %1$s да задейства разрушителните действия на бутона за паника?</string>
|
||||
<string name="panic_setting_destructive_action">Разрушителни действия</string>
|
||||
<string name="panic_setting_signout_title">Отписване</string>
|
||||
<string name="panic_setting_signout_summary">Отписване от Briar при натиснат бутон за паника</string>
|
||||
<string name="purge_setting_title">Изтриване на профил</string>
|
||||
<string name="purge_setting_summary">Профила на Briar се изтрива при натиснат бутон за паника. Внимание: Изтрива безвъзвратно профила, контактите и съобщенията</string>
|
||||
<string name="panic_setting_signout_summary">Отписване от Briar при задействан бутон за паника</string>
|
||||
<string name="purge_setting_title">Премахване на профил</string>
|
||||
<string name="purge_setting_summary">Профилът на Briar се изтрива при задействане на бутона за паника. Внимание: Изтрива безвъзвратно профила, контактите и съобщенията</string>
|
||||
<!--Settings Notifications-->
|
||||
<string name="notification_settings_title">Известия</string>
|
||||
<string name="notify_sign_in_title">Напомняне за вписване</string>
|
||||
@@ -555,8 +559,8 @@
|
||||
<string name="notify_forum_posts_setting_title">Публикации във форуми</string>
|
||||
<string name="notify_forum_posts_setting_summary">Известия за публикации във форуми</string>
|
||||
<string name="notify_forum_posts_setting_summary_26">Настройки на известия за публикации във форуми</string>
|
||||
<string name="notify_blog_posts_setting_title">Публикации в блог</string>
|
||||
<string name="notify_blog_posts_setting_summary">Известия за публикации в блог</string>
|
||||
<string name="notify_blog_posts_setting_title">Публикации в блогове</string>
|
||||
<string name="notify_blog_posts_setting_summary">Известия за публикации в блогове</string>
|
||||
<string name="notify_blog_posts_setting_summary_26">Настройки на известия за публикации в блог</string>
|
||||
<string name="notify_vibration_setting">Вибрация</string>
|
||||
<string name="notify_sound_setting">Звук</string>
|
||||
@@ -575,7 +579,7 @@
|
||||
<string name="disappearing_messages_summary">Бъдещите съобщения в разговора изчезват след 7\u00A0дни</string>
|
||||
<!--Settings Actions-->
|
||||
<string name="pref_category_actions">Действия</string>
|
||||
<string name="send_feedback">Изпращане на отзив</string>
|
||||
<string name="send_feedback">Изпращане на обратна връзка</string>
|
||||
<!--Link Warning-->
|
||||
<string name="link_warning_title">Предупреждение за препратка</string>
|
||||
<string name="link_warning_intro">Препратката ще бъде отворена от външно приложение.</string>
|
||||
@@ -583,6 +587,7 @@
|
||||
<string name="link_warning_open_link">Отваряне</string>
|
||||
<!--Crash Reporter-->
|
||||
<string name="crash_report_title">Доклад на срив</string>
|
||||
<string name="briar_crashed">Съжаляваме, Briar се срина</string>
|
||||
<string name="not_your_fault">Не е по ваша вина.</string>
|
||||
<string name="please_send_report">Помогнете да направим Briar по-добър като ни изпратите доклад.</string>
|
||||
<string name="report_is_encrypted">Обещаваме, че докладът е ще бъде изпратен шифрован и добре защитен.</string>
|
||||
@@ -641,16 +646,42 @@
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar може да се свърже с контактите ви през интернет, Wi-Fi или Bluetooth.\n\nЗа повече поверителност цялата връзка към интернет се пренасочва през мрежата на Tor.\n\nАко даден контакт може да бъде достъпен чрез няколко метода Briar ги използва успоредно.</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">Споделяне на приложението извън мрежа</string>
|
||||
<string name="hotspot_button_start_sharing">Включване на безжична точка</string>
|
||||
<string name="hotspot_button_stop_sharing">Спиране на безжична точка</string>
|
||||
<string name="hotspot_progress_text_start">Настройване на безжична точка…</string>
|
||||
<string name="hotspot_notification_channel_title">Безжична точка за достъп</string>
|
||||
<string name="hotspot_notification_title">Споделяне на Briar извън мрежа</string>
|
||||
<string name="hotspot_button_connected">Напред</string>
|
||||
<string name="permission_hotspot_location_request_body">За да създаде безжична точка за достъп, на Briar му е необходимо разрешение за достъп до местоположението.\n\nBriar не го пази и не го споделя с никого.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Отказахте достъп до местоположението, но то е необходимо за създаване на безжична точка за достъп.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||
<string name="wifi_settings_title">Настройки на Wi-Fi</string>
|
||||
<string name="wifi_settings_request_enable_body">За създаване на безжична точка за достъп Briar се нуждае от Wi-Fi. Включете го.</string>
|
||||
<string name="hotspot_tab_manual">Ръчно</string>
|
||||
<!--The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s-->
|
||||
<string name="hotspot_scanning_a_qr_code">като сканират код за QR</string>
|
||||
<!--Wi-Fi setup-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_wifi">Устройството ви създава безжична точка за достъп. Хората, които желаят да изтеглят Briar могат да се свържат към нея като добавят в настройките за Wi-Fi на техните устройства параметрите по-долу или %s. Когато те се свържат към точката за достъп натиснете „Напред“.</string>
|
||||
<string name="hotspot_manual_wifi_ssid">Наименование на мрежата</string>
|
||||
<string name="hotspot_qr_wifi">Устройството ви създава безжична точка за достъп. Хората, които желаят да изтеглят Briar могат да се свържат към нея като сканират този код за QR. Когато те се свържат към точката за достъп натиснете „Напред“.</string>
|
||||
<string name="hotspot_no_peers_connected">Няма свързани устройства</string>
|
||||
<plurals name="hotspot_peers_connected">
|
||||
<item quantity="one">%s свързано устройства</item>
|
||||
<item quantity="other">%s свързани устройства</item>
|
||||
</plurals>
|
||||
<!--Download link-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_site">Устройството ви създава безжична точка за достъп. Хората, които са свързани към нея могат да изтеглят Briar от следния адрес или %s.</string>
|
||||
<string name="hotspot_manual_site_address">Адрес (URL)</string>
|
||||
<string name="hotspot_qr_site">Устройството ви създава безжична точка за достъп. Хората, които са свързани към нея могат да изтеглят Briar като сканират този код за QR.</string>
|
||||
<!--e.g. Download Briar 1.2.20-->
|
||||
<string name="website_download_title">Изтеглете %s</string>
|
||||
<string name="website_download_intro">Някой наблизо споделя с вас %s.</string>
|
||||
<string name="website_download_outro">След като файлът се изтегли, отворете го и го инсталирайте.</string>
|
||||
<string name="website_troubleshooting_title">Отстраняване на неизправности</string>
|
||||
<string name="website_troubleshooting_1">Ако не можете да изтеглите приложението пробвайте с друг мрежов четец.</string>
|
||||
<string name="hotspot_help_fallback_title">Нищо не става?</string>
|
||||
<!--error handling-->
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_title_send">Изпращане на сведения</string>
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
<string name="hotspot_help_wifi_title">Probleme bei der WLAN-Verbindung:</string>
|
||||
<string name="hotspot_help_wifi_1">Versuche, WLAN auf beiden Telefonen zu deaktivieren und wieder zu aktivieren, und versuche es dann erneut.</string>
|
||||
<string name="hotspot_help_wifi_2">Wenn dein Telefon meldet, dass das WLAN kein Internet hat, sag ihm, dass du trotzdem verbunden bleiben willst.</string>
|
||||
<string name="hotspot_help_wifi_3">Telefon neu starten, auf dem der WLAN-Hotspot läuft, danach Briar starten und erneut teilen.</string>
|
||||
<string name="hotspot_help_site_title">Probleme beim Besuch der lokalen Webseite:</string>
|
||||
<string name="hotspot_help_site_1">Überprüfe unbedingt, ob du die Adresse genau so wie angezeigt eingegeben hast. Ein kleiner Fehler kann dazu führen, dass der Versuch fehlschlägt.</string>
|
||||
<string name="hotspot_help_site_2">Vergewissere dich, dass dein Telefon immer noch mit dem richtigen WLAN verbunden ist (siehe oben), wenn du die Webseite aufrufen willst.</string>
|
||||
@@ -712,6 +713,9 @@
|
||||
<string name="hotspot_flag_test">Warnung: Diese App wurde mit Android Studio installiert und kann NICHT auf einem anderen Gerät installiert werden.</string>
|
||||
<string name="hotspot_error_framework_busy">Hotspot kann nicht gestartet werden.\n\nWenn du einen anderen Hotspot betreibst oder deine Internetverbindung über WLAN teilst, beende dies und versuche es danach erneut.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Über Wechseldatenträger verbinden</string>
|
||||
<string name="removable_drive_intro">Wenn du keine Verbindung zu deinem Kontakt über das Internet, WLAN oder Bluetooth herstellen kannst, kann Briar auch Nachrichten auf einem Wechseldatenträger wie einem USB-Stick oder einer SD-Karte übertragen.</string>
|
||||
<string name="removable_drive_explanation">Wenn du keine Verbindung zu deinem Kontakt über das Internet, WLAN oder Bluetooth herstellen kannst, kann Briar auch Nachrichten auf einem Wechseldatenträger wie einem USB-Stick oder einer SD-Karte übertragen.n\nWenn du die Schaltfläche \"Daten senden\" verwendest, werden alle Daten, die darauf warten, an den Kontakt gesendet zu werden, auf den Wechseldatenträger geschrieben. Dazu gehören private Nachrichten, Anhänge, Blogs, Foren und private Gruppen.\n\nAlles wird verschlüsselt, bevor es auf den Wechseldatenträger geschrieben wird.\n\nWenn dein Kontakt den Wechseldatenträger erhält, kann er die Schaltfläche \"Daten empfangen\" verwenden, um die Nachrichten in Briar zu importieren.</string>
|
||||
<string name="removable_drive_title_send">Daten senden</string>
|
||||
<string name="removable_drive_title_receive">Daten empfangen</string>
|
||||
<string name="removable_drive_send_intro">Tippe auf die Schaltfläche unten, um eine neue Datei mit den verschlüsselten Nachrichten zu erstellen. Du kannst wählen, wo die Datei gespeichert werden soll.\n\nWenn du die Datei auf einem Wechsellaufwerk speichern möchtest, lege das Laufwerk jetzt ein.</string>
|
||||
|
||||
@@ -316,9 +316,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Conectar mediante Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_title">Conectar mediante Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_intro">En el caso que las conexiones Bluetooth no funcionen automáticamente, puedes usar esta pantalla para conectarte manualmente.\n\nTu contacto necesita estar cerca para que esto funcione.\n\nAmbos deberían presionar \"Inicio\" al mismo tiempo.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Ya se está intentando conectar vía Bluetooth. Por favor inténtalo de nuevo en unos segundos.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">No se puede continuar sin permiso de ubicación</string>
|
||||
<string name="connect_via_bluetooth_start">Conectar mediante Bluetooth...</string>
|
||||
<string name="connect_via_bluetooth_success">Conectado exitosamente mediante Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">No se pudo conectar mediante Bluetooth.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Este dispositivo no soporta Bluetooth.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">No hay grupos para mostrar</string>
|
||||
<string name="groups_list_empty_action">Golpea el icono + para crear un grupo, o pregunta a tus contactos si quieren compartir grupos contigo</string>
|
||||
@@ -605,6 +609,7 @@
|
||||
<string name="dev_report_memory">Memoria</string>
|
||||
<string name="dev_report_storage">Almacenamiento</string>
|
||||
<string name="dev_report_connectivity">Conectividad</string>
|
||||
<string name="dev_report_network_usage">Uso de red</string>
|
||||
<string name="dev_report_build_config">Configuración de compilación</string>
|
||||
<string name="dev_report_logcat">Registro de la aplicación</string>
|
||||
<string name="dev_report_device_features">Características del dispositivo</string>
|
||||
@@ -647,7 +652,7 @@
|
||||
<string name="transports_help_text">Briar puede conectar a tus contactos vía Internet, Wi-Fi o Bluetooth.\n\nTodas las conexiones a Internet van a través de la red Tor por privacidad.\n\nSi un contacto puede ser alcanzado por múltiples métodos, Briar los usa en paralelo.</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">Comparte esta aplicación fuera de línea</string>
|
||||
<string name="hotspot_intro">Comparte esta aplicación con alguien que esté cerca tuyo sin conexión a Internet, usando el Wi-Fi de tu teléfono.
|
||||
<string name="hotspot_intro">Comparte esta aplicación con alguien que esté cerca tuyo sin una conexión a Internet, usando el Wi-Fi de tu teléfono.
|
||||
\n\nTu teléfono iniciará un punto de acceso Wi-Fi. Las personas cercanas a tí pueden conectarse al punto de acceso y descargar la aplicación Briar desde tu teléfono.</string>
|
||||
<string name="hotspot_button_start_sharing">Iniciar punto de acceso</string>
|
||||
<string name="hotspot_button_stop_sharing">Detener punto de acceso</string>
|
||||
@@ -658,19 +663,77 @@
|
||||
<string name="permission_hotspot_location_request_body">Para crear un punto de acceso Wi-Fi, Briar necesita permiso para acceder tu ubicación.\n\nBriar no la almacena o la comparte con nadie.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Has denegado el acceso a tu ubicación, pero Briar necesita este permiso para crear un punto de acceso Wi-Fi.\n\nPor favor considera la posibilidad de conceder el acceso.</string>
|
||||
<string name="wifi_settings_title">Configuración de Wi-Fi</string>
|
||||
<string name="wifi_settings_request_enable_body">Para crear un punto de acceso Wi-Fi, Briar necesita usar Wi-Fi. Por favor habilítalo.</string>
|
||||
<string name="hotspot_tab_manual">Manual</string>
|
||||
<!--The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s-->
|
||||
<string name="hotspot_scanning_a_qr_code">escaneando un código QR</string>
|
||||
<!--Wi-Fi setup-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_wifi">Tu teléfono está proporcionando un punto de acceso Wi-Fi. Las personas que quieran descargar Briar pueden conectarse al punto de acceso agregándolo en la configuración de Wi-Fi de sus dispositivos, usando los detalles de abajo o mediante %s. Una vez que se hayan conectado al punto de acceso, presiona \'Siguiente\'.</string>
|
||||
<string name="hotspot_manual_wifi_ssid">Nombre de red</string>
|
||||
<string name="hotspot_qr_wifi">Tu teléfono está proporcionando un punto de acceso Wi-Fi. Las personas que quieran descargar Briar pueden conectarse al punto de acceso escaneando este código QR. Una vez que se hayan conectado al punto de acceso, presiona \'Siguiente\'.</string>
|
||||
<string name="hotspot_no_peers_connected">No hay dispositivos conectados</string>
|
||||
<plurals name="hotspot_peers_connected">
|
||||
<item quantity="one">%s dispositivo conectado</item>
|
||||
<item quantity="other">%s dispositivos conectados</item>
|
||||
</plurals>
|
||||
<!--Download link-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_site">Tu teléfono está proporcionando un punto de acceso Wi-Fi. Las personas que están conectadas al mismo pueden descargar Briar tipeando el siguiente vínculo en un navegador web o %s.</string>
|
||||
<string name="hotspot_manual_site_address">Dirección (URL)</string>
|
||||
<string name="hotspot_qr_site">Tu teléfono está proporcionando un punto de acceso Wi-Fi. Las personas que están conectadas al mismo pueden descargar Briar escaneando este código QR.</string>
|
||||
<!--e.g. Download Briar 1.2.20-->
|
||||
<string name="website_download_title">Descargar %s</string>
|
||||
<string name="website_download_intro">Alguien en las cercanías compartió %s contigo.</string>
|
||||
<string name="website_download_outro">Luego de que la descarga se complete, abre el archivo descargado e instálalo.</string>
|
||||
<string name="website_troubleshooting_title">Resolución de problemas</string>
|
||||
<string name="website_troubleshooting_1">Si no puedes descargar la aplicación, inténtalo con una aplicación de navegación web diferente.</string>
|
||||
<string name="website_troubleshooting_2_old">Para instalar la aplicación descargada, podrías necesitar permitir la instalación de aplicaciones desde \"Fuentes desconocidas\" en la configuración del sistema. Con posterioridad, podrías necesitar descargar la aplicación de nuevo. Te recomendamos deshabilitar el ajuste \"Fuentes desconocidas\" después de instalar la aplicación.</string>
|
||||
<string name="website_troubleshooting_2_new">Para instalar la aplicación descargada, podrías necesitar permitirle a tu navegador instalar aplicaciones desconocidas. Luego de instalar la aplicación, recomendamos remover el permiso del navegador para este tipo de instalaciones.</string>
|
||||
<string name="hotspot_help_wifi_title">Problemas para conectar al Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Intenta deshabilitar y rehabilitar el Wi-Fi en ambos teléfonos, e intenta de nuevo.</string>
|
||||
<string name="hotspot_help_wifi_2">Si tu teléfono se queja de que el Wi-Fi no tiene Internet, dile que quieres permanecer conectado de todos modos.</string>
|
||||
<string name="hotspot_help_wifi_3">Reinicia el teléfono que está ejecutando el punto de acceso Wi-Fi, luego inicia Briar e intenta compartir de nuevo.</string>
|
||||
<string name="hotspot_help_site_title">Problemas visitando al sitio web local:</string>
|
||||
<string name="hotspot_help_site_1">Comprueba doblemente que hayas entrado la dirección exactamente como se muestra. Un pequeño error puede hacer que falle.</string>
|
||||
<string name="hotspot_help_site_2">Asegúrate de que tu teléfono aún esté conectado al Wi-Fi correcto (ver arriba) cuando intentes acceder al sitio.</string>
|
||||
<string name="hotspot_help_site_3">Si tienes una aplicación de cortafuegos, comprueba que no esté bloqueando el acceso.</string>
|
||||
<string name="hotspot_help_site_4">Si puedes visitar el sitio, pero no descargar la aplicación Briar, inténtalo con una aplicación de navegación web diferente.</string>
|
||||
<string name="hotspot_help_fallback_title">¿Nada funciona?</string>
|
||||
<string name="hotspot_help_fallback_intro">Puedes intentar guardar la aplicación como archivo .apk para compartir de cualquier otra manera. Una vez que el archivo ha sido transferido al otro dispositivo, puede ser usado para instalar Briar.
|
||||
\n\nConsejo: Para compartir vía Bluetooth, primero podrías necesitar renombrar al archivo para que finalice con .zip.</string>
|
||||
<string name="hotspot_help_fallback_button">Guardar aplicación</string>
|
||||
<!--error handling-->
|
||||
<string name="hotspot_error_intro">Algo salió mal mientras se intentaba compartir la aplicación vía Wi-Fi:</string>
|
||||
<string name="hotspot_error_no_wifi_direct">El dispositivo no soporta Wi-Fi Direct</string>
|
||||
<string name="hotspot_error_start_callback_failed">Fallo al iniciar punto de acceso: error %s</string>
|
||||
<string name="hotspot_error_start_callback_failed_unknown">El punto de acceso falló al iniciar con un error desconocido, la razón es %d</string>
|
||||
<string name="hotspot_error_start_callback_no_group_info">Fallo al iniciar punto de acceso: no hay información de grupo</string>
|
||||
<string name="hotspot_error_web_server_start">Error al iniciar el servidor web</string>
|
||||
<string name="hotspot_error_web_server_serve">Error al presentar el sitio web.\n\nPor favor, envía tus comentarios (con datos anónimos) a través de la aplicación Briar si la dificultad persiste.</string>
|
||||
<string name="hotspot_flag_test">Advertencia: Esta aplicación fue instalada con Android Studio, y NO puede ser instalada en otro dispositivo.</string>
|
||||
<string name="hotspot_error_framework_busy">Incapaz de iniciar el punto de acceso.\n\nSi tienes otro punto de acceso ejecutándose o estás compartiendo tu conexión de Internet vía Wi-Fi, intenta detener eso e intentar de nuevo luego.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Conectar a través de Discos Removibles</string>
|
||||
<string name="removable_drive_intro">Si no puedes conectarte con tu contacto vía Internet, Wi-Fi o Bluetooth, Briar también puede transferir mensajes en un disco removible, tal como una memoria USB o tarjeta SD.</string>
|
||||
<string name="removable_drive_explanation">Si no puedes conectarte con tu contacto vía Internet, Wi-Fi o Bluetooth, Briar también puede transferir mensajes en un disco removible, tal como una memoria USB o tarjeta SD.\n\nCuando usas el botón \"Enviar Datos\", cualesquiera datos que estén esperando ser enviados al contacto serán escritos al disco removible. Esto incluye mensajes privados, adjuntos, blogs, foros y grupos privados.\n\nTodo será cifrado antes de que sea escrito al disco removible.\n\nCuando tu contacto reciba el disco removible, puede usar el botón \"Recibir Datos\" para importar los mensajes dentro de Briar.</string>
|
||||
<string name="removable_drive_title_send">Enviar Datos</string>
|
||||
<string name="removable_drive_title_receive">Recibir Datos</string>
|
||||
<string name="removable_drive_send_intro">Pulsa el botón de abajo para crear un nuevo archivo conteniendo los mensajes cifrados. Puedes elegir dónde será guardado el archivo.\n\nSi quieres guardarlo en un disco removible, insértalo ahora.</string>
|
||||
<string name="removable_drive_send_no_data">Actualmente no hay mensajes esperando ser enviados a este contacto.</string>
|
||||
<string name="removable_drive_send_not_supported">Este contacto está usando una versión vieja de Briar, o un dispositivo viejo que no soporta esta característica.</string>
|
||||
<string name="removable_drive_send_button">Selecciona el archivo a exportar</string>
|
||||
<string name="removable_drive_ongoing">Por favor espera hasta que la tarea en curso se complete</string>
|
||||
<string name="removable_drive_receive_intro">Pulsa el botón de abajo para elegir el archivo que envió tu contacto.\n\nSi el archivo está en un disco removible, insértalo ahora.</string>
|
||||
<string name="removable_drive_receive_button">Selecciona el archivo a importar</string>
|
||||
<string name="removable_drive_success_send_title">Exportado con éxito</string>
|
||||
<string name="removable_drive_success_send_text">Datos exportados exitosamente. Ahora tienes 28 días para transportar el archivo hasta tu contacto.\n\nSi el archivo está en un disco removible, usa la notificación en la barra de estado para expulsar el disco antes de desconectarlo.</string>
|
||||
<string name="removable_drive_success_receive_title">Importado con éxito</string>
|
||||
<string name="removable_drive_success_receive_text">Todos los mensajes cifrados contenidos en este archivo han sido recibidos.</string>
|
||||
<string name="removable_drive_error_send_title">Error al exportar datos</string>
|
||||
<string name="removable_drive_error_send_text">Hubo un error escribiendo los datos al archivo.\n\nSi estás usando un disco removible, asegúrate de que esté apropiadamente insertado e inténtalo de nuevo.\n\nSi el error persiste, por favor envía tus comentarios para que el equipo de Briar conozca acerca de esta dificultad.</string>
|
||||
<string name="removable_drive_error_receive_title">Error al importar datos</string>
|
||||
<string name="removable_drive_error_receive_text">El archivo seleccionado no contenía nada que Briar pudiera reconocer.\n\nPor favor comprueba que hayas elegido el archivo correcto.\n\nSi tu contacto creó el archivo más de 28 días atrás, Briar no será capaz de reconocerlo.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alicia</string>
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
|
||||
اخطار: هویت های شما، مخاطبان شما و پیام های شما برای همیشه از بین خواهند رفت.</string>
|
||||
<string name="startup_failed_activity_title">خطا در شروع Briar (برایر)</string>
|
||||
<string name="startup_failed_clock_error">Briar به دلیل این که ساعت دستگاه شما غلط است، اجرا نشد.\n\n لطفا ساعت دستگاه خود را تنظیم کرده و دوباره تلاش کنید.</string>
|
||||
<string name="startup_failed_db_error">Briar قادر به باز کردن پایگاه داده حاوی حساب کاربری، مخاطبین و پیامهای شما نشد.\n\n لطفا برنامه را به آخرین نسخه ارتقا داده، و یا هنگام وارد کردن رمز عبور، با انتخاب گزینه «رمز خود را فراموش کردهام» حساب جدیدی ایجاد کنید.</string>
|
||||
<string name="startup_failed_data_too_old_error">حساب کاربری شما با نسخه قدیمی این برنامه ساخته شده و در این نسخه قابل باز شدن نیست.\n\n شما یا باید نسخه قبلی را دوباره نصب کنید و یا هنگام وارد کردن رمز عبور، با انتخاب «رمز خود را فراموش کردهام» حساب جدیدی ایجاد کنید.</string>
|
||||
<string name="startup_failed_data_too_new_error">حساب کاربری شما با نسخه جدیدتر این برنامه ساخته شده و در این نسخه قابل باز شدن نیست.\n\n لطفا به آخرین نسخه ارتقا داده و دوباره امتحان کنید.</string>
|
||||
<string name="startup_failed_service_error">Briar قادر به آغاز اجزای مورد نیاز نیست.\n\n لطفا به آخرین نسخه برنامه ارتقا داده و دوباره امتحان کنید.</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="one">این یک نسخه آزمایشی از Briar (برایر) می باشد. حساب کاربری شما در %d روز آینده به پایان می رسد و امکان تمدید آن وجود نخواهد داشت.</item>
|
||||
<item quantity="other">این یک نسخه آزمایشی از Briar (برایر) می باشد. حساب کاربری شما در %d روز آینده به پایان می رسد و امکان تمدید آن وجود نخواهد داشت.</item>
|
||||
@@ -329,9 +334,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">اتصال از طریق بلوتوث</string>
|
||||
<string name="connect_via_bluetooth_title">اتصال از طریق بلوتوث</string>
|
||||
<string name="connect_via_bluetooth_intro">در صورتی که ارتباطات بلوتوث به صورت خودکار کار نکرد، میتوانید از این صفحه برای ارتباط دستی استفاده کنید.\n\n برای کار کردن این امکان، مخاطب شما باید نزدیک باشد.\n\n شما و مخاطبتان باید هر دو گزینه «آغاز» را همزمان بفشارید.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">در حال تلاش برای اتصال با بلوتوث. لطفا به زودی دوباره امتحان کنید.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">امکان ادامه بدون اجازه مکانیابی وجود ندارد</string>
|
||||
<string name="connect_via_bluetooth_start">در حال اتصال از طریق بلوتوث</string>
|
||||
<string name="connect_via_bluetooth_success">ارتباط از طریق بلوتوث با موفقیت انجام شد</string>
|
||||
<string name="connect_via_bluetooth_error">اتصال از طریق بلوتوث امکان پذیر نیست.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">بلوتوث توسط دستگاه پشتیبانی نمیشود.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">هیچ گروهی برای نمایش وجود ندارد</string>
|
||||
<string name="groups_list_empty_action">برای ایجاد یک گروه روی آیکون + کلیک کنید، یا از مخاطبان خود بخواهید تا گروه های خود را با شما به اشتراک بگذارند</string>
|
||||
@@ -622,6 +631,7 @@
|
||||
<string name="link_warning_open_link">باز کردن پیوند</string>
|
||||
<!--Crash Reporter-->
|
||||
<string name="crash_report_title">گزارش خطای Briar (برایر)</string>
|
||||
<string name="briar_crashed">متاسفانه Briar از کار افتاد</string>
|
||||
<string name="not_your_fault">این تقصیر شما نیست.</string>
|
||||
<string name="please_send_report">لطفا با فرستادن گزارش خطا به ما کمک کنید تا Briar (برایر) را بهتر کنیم.</string>
|
||||
<string name="report_is_encrypted">به شما اطمینان می دهیم که گزارش شما رمزنگاری شده و به صورت امن فرستاده می شود.</string>
|
||||
@@ -639,6 +649,7 @@
|
||||
<string name="dev_report_memory">حافظه</string>
|
||||
<string name="dev_report_storage">حافظه</string>
|
||||
<string name="dev_report_connectivity">اتصال</string>
|
||||
<string name="dev_report_network_usage">استفاده از شبکه</string>
|
||||
<string name="dev_report_build_config">پیکربندی ساخت</string>
|
||||
<string name="dev_report_logcat">لاگ برنامه</string>
|
||||
<string name="dev_report_device_features">ویژگیهای دستگاه</string>
|
||||
@@ -692,18 +703,89 @@ Briar (برایر) موقعیت شما را ذخیره نمیکند و آن
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar (برایر) میتواند از طریق اینترنت، Wi-Fi و یا بلوتوث به مخاطبین شما متصل گردد.\n\nارتباط با اینترنت از طریق شبکهی تور صورت میپذیرد.\n\nاگر دسترسی به مخاطب شما از روشهای مختلفی ممکن باشد، Briar (برایر) به صورت موازی از آنها استفاده خواهد کرد.</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">این برنامه را به صورت آفلاین به اشتراک بگذارید</string>
|
||||
<string name="hotspot_intro">این برنامه را بدو ارتباط با اینترنت و فقط با Wi-Fi تلفن خود با فردی در نزدیکی خود به اشتراک بگذارید.
|
||||
\n\n تلفن شما با Wi-Fi hotspot آغاز میشود. افراد در نزدیکی شما میتوانند به hotspot متصل شده و برنامه Briar را از تلفن شما دانلود کنند.</string>
|
||||
<string name="hotspot_button_start_sharing">آغاز hotspot</string>
|
||||
<string name="hotspot_button_stop_sharing">توقف hotspot</string>
|
||||
<string name="hotspot_progress_text_start">در حال راه اندازی hotspot...</string>
|
||||
<string name="hotspot_notification_channel_title">Wi-Fi hotspot</string>
|
||||
<string name="hotspot_notification_title">اشتراکگذاری آفلاین Briar</string>
|
||||
<string name="hotspot_button_connected">بعد</string>
|
||||
<string name="permission_hotspot_location_request_body">برای ایجاد Wi-Fi hotspot، Briar به مجوز دسترسی مکانی شما نیاز دارد.\n\n Briar اطلاعات مکانی شما را ذخیره نکرده و با کسی به اشتراک نمیگذارد.</string>
|
||||
<string name="permission_hotspot_location_denied_body">شما دسترسی به مکان خود را رد کردهاید، در صورتی که Briar برای ایجاد Wi-Fi hotspot به این مجوز نیاز دارد.\n\n لطفا اجازه دسترسی را در نظر بگیرید.</string>
|
||||
<string name="wifi_settings_title">تنظیمات Wi-Fi</string>
|
||||
<string name="wifi_settings_request_enable_body">برای ایجاد Wi-Fi hotspot، Briar نیاز به استفاده از Wi-Fi دارد. لطفا آن را فعال کنید.</string>
|
||||
<string name="hotspot_tab_manual">دستی</string>
|
||||
<!--The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s-->
|
||||
<string name="hotspot_scanning_a_qr_code">کد QR را اسکن کنید</string>
|
||||
<!--Wi-Fi setup-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_wifi">تلفن شما Wi-Fi hotspot ارائه میکند. کسانی که قصد دانلود Briar را دارند، میتوانند با افزودن hotspot در تنظیمات Wi-Fi دستگاه خود، به آن متصل شده و یا %s. هنگامی که به hotspot متصل شدند، دکمه «بعد» را بفشارند.</string>
|
||||
<string name="hotspot_manual_wifi_ssid">نام شبکه</string>
|
||||
<string name="hotspot_qr_wifi">تلفن شما Wi-Fi hotspot ارائه میکند. کسانی که قصد دانلود Briar را دارند، میتوانند با اسکن این کد QR به hotspot متصل شوند. هنگامی که به hotspot متصل شدند، دکمه «بعد» را بفشارند.</string>
|
||||
<string name="hotspot_no_peers_connected">هیچ دستگاهی متصل نیست</string>
|
||||
<plurals name="hotspot_peers_connected">
|
||||
<item quantity="one">%s دستگاه متصل است</item>
|
||||
<item quantity="other">%s دستگاه متصل است</item>
|
||||
</plurals>
|
||||
<!--Download link-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_site">تلفن شما Wi-Fi hotspot ارائه میکند. کسانی که به hotspot متصل هستند، میتوانند Briar را با تایپ لینک زیر در مرورگر خود دانلود کنند و یا %s.</string>
|
||||
<string name="hotspot_manual_site_address">آدرس (URL)</string>
|
||||
<string name="hotspot_qr_site">تلفن شما Wi-Fi hotspot ارائه میکند. کسانی که به hotspot متصل هستند، میتوانند Briar را با اسکن این کد QR دانلود کنند.</string>
|
||||
<!--e.g. Download Briar 1.2.20-->
|
||||
<string name="website_download_title">دانلود %s</string>
|
||||
<string name="website_download_intro">فردی در نزدیکی %s را با شما به اشتراک گذاشته است.</string>
|
||||
<string name="website_download_outro">پس از تکمیل دانلود، فایل دانلود شده را باز کرده و نصب کنید.</string>
|
||||
<string name="website_troubleshooting_title">◾️ عیب یابی</string>
|
||||
<string name="website_troubleshooting_1">اگر قادر به دانلود کردن برنامه نیستید، با مرورگر دیگری امتحان کنید.</string>
|
||||
<string name="website_troubleshooting_2_old">برای نصب برنامه دانلود شده، باید اجازه نصب برنامه از «منابع ناشناخته» را در تنظیمات سیستم بدهید. سپس ممکن است نیاز به دانلود دوباره برنامه داشته باشید. ما توصیه میکنیم که پس از نصب این برنامه، اجازه «منابع ناشناخته» را لغو کنید.</string>
|
||||
<string name="website_troubleshooting_2_new">برای نصب برنامه دانلود شده، ممکن است نیاز به ایجاد مجوز نصب برنامههای ناشناخته در مرورگر را داشته باشید. پس از نصب این برنامه، توصیه میکنیم مجوز نصب برنامههای ناشناخته را لغو کنید.</string>
|
||||
<string name="hotspot_help_wifi_title">مشکلات اتصال به Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Wi-Fi را در هر دو تلفن غیرفعال و دوباره فعال کنید.</string>
|
||||
<string name="hotspot_help_wifi_2">اگر تلفن پیامی مبنی بر عدم دسترسی Wi-Fi به اینترنت داد، از گزینه مربوط به متصل ماندن استفاده کنید.</string>
|
||||
<string name="hotspot_help_wifi_3">تلفنی که میزبان Wi-Fi hotspot است را دوباره راهاندازی کنید، سپس Briar را باز کرده و دوباره به اشتراک بگذارید.</string>
|
||||
<string name="hotspot_help_site_title">مشکلات بازدید از وبسایت محلی:</string>
|
||||
<string name="hotspot_help_site_1">مطمئن شوید که آدرسی که وارد میکنید، دقیقا آدرسی باشد که نمایش یافته. خطای کوچک منجر به ناموفق بودن پروسه خواهد شد.</string>
|
||||
<string name="hotspot_help_site_2">مطمئن شوید هنگامی که قصد دسترسی به سایت را دارید، تلفن شما هنوز به Wi-Fi صحیح متصل باشد (بالا را ببینید).</string>
|
||||
<string name="hotspot_help_site_3">اگر از برنامه فایروال استفاده میکنید، مطمئن باشید که دسترسی را مسدود نکرده است.</string>
|
||||
<string name="hotspot_help_site_4">اگر میتوانید سایت را باز کنید، ولی نمیتوانید برنامه Briar را دانلود کنید، از یک مرورگر دیگر استفاده کنید.</string>
|
||||
<string name="hotspot_help_fallback_title">هیچ چیز کار نمیکند؟</string>
|
||||
<string name="hotspot_help_fallback_intro">شما میتوانید با راههایی، برنامه را به صورت فایل .apk ذخیره و به اشتراک بگذارید. هنگامی که فایل به دستگاه دیگری انتقال یافت، میتواند برای نصب Briar مورد استفاده قرار گیرد.
|
||||
\n\nنکته: برای اشتراکگذاری از طریق بلوتوث، ممکن است نیاز به تغییر انتهای نام فایل به .zip داشته باشید.</string>
|
||||
<string name="hotspot_help_fallback_button">ذخیره برنامه</string>
|
||||
<!--error handling-->
|
||||
<string name="hotspot_error_intro">هنگام تلاش برای اشتراکگذاری برنامه از طریق Wi-Fi مشکلی رخ داد:</string>
|
||||
<string name="hotspot_error_no_wifi_direct">دستگاه از Wi-Fi Direct پشتیبانی نمیکند</string>
|
||||
<string name="hotspot_error_start_callback_failed">Hotspot قادر به راهاندازی نبود: خطای %s</string>
|
||||
<string name="hotspot_error_start_callback_failed_unknown">Hotspot با خطایی ناشناخته قادر به راهاندازی نبود، علت %d</string>
|
||||
<string name="hotspot_error_start_callback_no_group_info">Hotspot قادر به راهاندازی نبود: بدون اطلاعات گروه</string>
|
||||
<string name="hotspot_error_web_server_start">خطا در راهاندازی سرور وب</string>
|
||||
<string name="hotspot_error_web_server_serve">خطا در ارائه وبسایت.\n\n لطفا در صورت ادامه مشکل، بازخورد خود را (به همراه دادههای ناشناس) به برنامه Briar ارسال کنید.</string>
|
||||
<string name="hotspot_flag_test">هشدار: این برنامه با Android Studio نصب شده و قادر به نصب بر روی دستگاه دیگری نیست.</string>
|
||||
<string name="hotspot_error_framework_busy">مشکل در راهاندازی hotspot.\n\n اگر hotspot دیگری در دستگاه شما فعال است و اینترنت شما را با اتصال Wi-Fi به اشتراک میگذارد، لطفا آن را متوقف کرده و دوباره امتحان کنید.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">اتصال ار طریق حافظه قابل جابجایی</string>
|
||||
<string name="removable_drive_intro">اگر از طریق اینترنت، Wi-Fi و یا بلوتوث قادر به ارتباط با مخاطب خود نیستید، Briar قادر به جابجایی پیامها از طریق درایو قابل جابجایی مانند حافظه قلش و یا کارت SD است.</string>
|
||||
<string name="removable_drive_explanation">اگر از طریق اینترنت، Wi-Fi و یا بلوتوث قادر به ارتباط با مخاطب خود نیستید، Briar قادر به جابجایی پیامها از طریق درایو قابل جابجایی مانند حافظه قلش و یا کارت SD است.\n\nهنگامی که از گزینه «ارسال داده» استفاده میکنید، هر دادهای که منتظر ارسال به مخاطب شماست، بر روی حافظه قابل جابجایی ذخیره خواهد شد. این دادهها شامل پیامها، ضمائم، بلاگها، تالارها و گروههای خصوصی است.\n\nهمه دادهها قبل از ذخیره در حافظه قابل جابجایی، رمزگذاری خواهند شد.\n\nهنگامی که مخاطب شما حافظه قابل جابجایی را دریافت میکند، میتواند با استفاده از دکمه «دریافت داده» تمامی پیامها را به Briar وارد کند.</string>
|
||||
<string name="removable_drive_title_send">ارسال داده</string>
|
||||
<string name="removable_drive_title_receive">دریافت داده</string>
|
||||
<string name="removable_drive_send_intro">دکمه زیر را برای ایجاد فایل جدید حاوی پیامهای رمزگذاری شده بفشارید. شما میتوانید محل ذخیره فایل را تعیین کنید.\n\n اگر تمایل به ذخیره فایل بر روی حافظه قابل جابجایی دارید، آن را الآن متصل کنید.</string>
|
||||
<string name="removable_drive_send_no_data">در حال حاظر هیچ پیامی در انتظار ارسال به مخاطب نیست.</string>
|
||||
<string name="removable_drive_send_not_supported">این مخاطب از نسخه قدیمی Briar و یا از دستگاه قدیمی که این قابلیت را پشتیبانی نمیکند، استفاده میکند.</string>
|
||||
<string name="removable_drive_send_button">فایل را برای گرفتن خروجی انتخاب کنید</string>
|
||||
<string name="removable_drive_ongoing">لطفا تا تکمیل کار فعلی منتظر بمانید</string>
|
||||
<string name="removable_drive_receive_intro">برای انتخاب فایلی که مخاطب شما ارسال کرده است، دکمه زیر را بفشارید.\n\nاگر فایل بر روی حافظه قابل جابجایی است، آن را الآن متصل کنید.</string>
|
||||
<string name="removable_drive_receive_button">فایل را برای وارد کردن انتخاب کنید</string>
|
||||
<string name="removable_drive_success_send_title">خروجی با موفقیت گرفته شد</string>
|
||||
<string name="removable_drive_success_send_text">از دادهها با موفقیت خروجی گرفته شد. شما الآن ۲۸ روز تا انتقال فایل به مخاطب خود فرصت دارید.\n\nاگر فایل بر روی حافظه قابل جابجایی است، از پیام در نوار اعلانات برای خارج کردن آن استفاده کنید.</string>
|
||||
<string name="removable_drive_success_receive_title">درون برد موفق بود</string>
|
||||
<string name="removable_drive_success_receive_text">تمامی پیامهای رمزگذاریشده در این فایل دریافت شدند.</string>
|
||||
<string name="removable_drive_error_send_title">خطا حین گرفتن خروجی از داده</string>
|
||||
<string name="removable_drive_error_send_text">خطایی هنگام نوشتن دادهها در فایل رخ داد.\n\nاگر از حافظه قابل جابجایی استفاده میکنید، از اتصال صحیح آن مطمئن شوید.\n\nاگر خطا ادامه یافت، لطفا بازخورد خود را برای اطلاع تیم Briar از مشکل، به ما ارسال کنید.</string>
|
||||
<string name="removable_drive_error_receive_title">خطا حین وارد کردن داده</string>
|
||||
<string name="removable_drive_error_receive_text">فایل انتخاب شده چیز قابل شناسایی توسط Briar نداشت.\n\nلطفا از انتخاب فایل صحبح مطمئن شوید.\n\nاگر مخاطب شما فایل را بیش از ۲۸ روز قبل ساخته است، Briar قادر به شناسایی آن نخواهد بود.</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">آلیس</string>
|
||||
|
||||
@@ -41,6 +41,11 @@
|
||||
<string name="dialog_title_lost_password">Mot de passe oublié</string>
|
||||
<string name="dialog_message_lost_password">Votre compte Briar est enregistré chiffré sur votre appareil, pas dans le nuage, et nous ne pouvons donc pas réinitialiser votre mot de passe. Voulez-vous supprimer votre compte et recommencer ?\n\nAttention : vos identités, contacts et messages seront perdus irrémédiablement.</string>
|
||||
<string name="startup_failed_activity_title">Échec de démarrage de Briar</string>
|
||||
<string name="startup_failed_clock_error">Briar n’a pas pu démarrer, car l’horloge de votre appareil n’est pas à l’heure.\n\nVeuillez mettre l’horloge de votre appareil à l’heure et réessayer.</string>
|
||||
<string name="startup_failed_db_error">Briar n’a pas pu ouvrir la base de données qui comprend votre compte, vos contacts et messages.\n\nVeuillez mettre l’appli à jour vers la version la plus récente et réessayer, ou créer un nouveau compte en choisissant « J’ai oublié mon mot de passe » à l’invite de mot de passe.</string>
|
||||
<string name="startup_failed_data_too_old_error">Votre compte a été créé avec une ancienne version de cette appli et ne peut pas être ouvert avec cette version.\n\nVous devez soit réinstaller l’ancienne version, soit créer un nouveau compte en choisissant « J’ai oublié mon mot de passe » à l’invite de mot de passe.</string>
|
||||
<string name="startup_failed_data_too_new_error">Votre compte a été créé avec une version plus récente de cette appli et ne peut être ouvert avec cette version.\n\nVeuillez mettre l’appli à jour vers la version la plus récente et réessayer.</string>
|
||||
<string name="startup_failed_service_error">Briar n\'a pas pu lancer un composant essentiel.\n\nVeuillez mettre l’appli à jour vers la version la plus récente et réessayer.</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="one">Ceci est une version de test de Briar. Votre compte arrivera à expiration dans %d jour et ne peut pas être renouvelé.</item>
|
||||
<item quantity="other">Ceci est une version de test de Briar. Votre compte arrivera à expiration dans %d jours et ne pourra pas être renouvelé.</item>
|
||||
@@ -311,9 +316,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Se connecter par Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_title">Se connecter par Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Impossible de poursuivre sans la permission de position</string>
|
||||
<string name="connect_via_bluetooth_intro">Au cas où les connexions Bluetooth ne fonctionneraient pas automatiquement, vous pouvez utiliser cet écran pour vous connecter manuellement.\n\nPour que cela fonctionne, votre contact doit être à proximité.\n\nVotre contact et vous devriez appuyer sur « Commencer » en même temps.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Une tentative de connexion par Bluetooth est en cours. Veuillez réessayer dans un moment.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Impossible de poursuivre sans autoriser la position.</string>
|
||||
<string name="connect_via_bluetooth_start">Connexion par Bluetooth…</string>
|
||||
<string name="connect_via_bluetooth_success">Connectée par Bluetooth avec succès</string>
|
||||
<string name="connect_via_bluetooth_success">La connexion par Bluetooth est réussie</string>
|
||||
<string name="connect_via_bluetooth_error">Impossible de se connecter par Bluetooth.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Bluetooth n’est pas pris en charge par l’appareil.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">Aucun groupe à afficher</string>
|
||||
<string name="groups_list_empty_action">Touchez l’icône + pour créer un groupe ou pour demander à vos contacts de partager des groupes avec vous</string>
|
||||
@@ -584,6 +593,7 @@ copies des messages que vous envoyez.
|
||||
<string name="link_warning_open_link">Ouvrir le lien</string>
|
||||
<!--Crash Reporter-->
|
||||
<string name="crash_report_title">Rapport de plantage de Briar</string>
|
||||
<string name="briar_crashed">Désolé, Briar a planté</string>
|
||||
<string name="not_your_fault">Vous n’y êtes pour rien.</string>
|
||||
<string name="please_send_report">Veuillez nous aider à améliorer Briar en nous envoyant un rapport de plantage.</string>
|
||||
<string name="report_is_encrypted">Nous promettons que le rapport est chiffré et envoyé en toute sécurité. </string>
|
||||
@@ -642,10 +652,22 @@ copies des messages que vous envoyez.
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar peut se connecter à vos contacts par Internet, Wi-Fi ou Bluetooth.\n\nToutes les connections Internet passent par le réseau Tor afin de protéger les données.\n\nSi un contact peut être joint par plusieurs moyens, Briar les utilisera simultanément.</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">Partager cette appli hors ligne.</string>
|
||||
<string name="hotspot_intro">Partagez cette appli avec une personne à proximité sans connexion Internet en utilisant le Wi-Fi de votre téléphone.
|
||||
\n\nVotre téléphone démarrera un point d’accès Wi-Fi. Les personnes à proximité peuvent se connecter au point d’accès sans fil et télécharger l’appli Briar de votre téléphone.</string>
|
||||
<string name="hotspot_button_start_sharing">Démarrer le point d’accès sans fil</string>
|
||||
<string name="hotspot_button_stop_sharing">Arrêter le point d’accès sans fil</string>
|
||||
<string name="hotspot_progress_text_start">Configuration du point d’accès sans fil…</string>
|
||||
<string name="hotspot_notification_channel_title">Point d’accès Wi-Fi</string>
|
||||
<string name="hotspot_notification_title">Partage hors ligne de Briar</string>
|
||||
<string name="hotspot_button_connected">Suivant</string>
|
||||
<string name="permission_hotspot_location_request_body">Pour créer un point d’accès Wi-Fi, Briar a besoin de l’autorisation Position.\n\nBriar ne stocke pas votre position et ne la partage avec personne.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Vous avez refusé l’accès à votre position, mais Briar en a besoin pour créer un point d’accès Wi-Fi.\n\nNous vous invitons à y accorder l’accès.</string>
|
||||
<string name="wifi_settings_title">Paramètre Wi-Fi</string>
|
||||
<string name="wifi_settings_request_enable_body">Pour créer un point d’accès Wi-Fi, Briar a besoin d’utiliser le Wi-Fi. Veuillez l’activer.</string>
|
||||
<string name="hotspot_tab_manual">Manuel</string>
|
||||
<!--The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s-->
|
||||
<string name="hotspot_scanning_a_qr_code">balayant un code QR</string>
|
||||
<!--Wi-Fi setup-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<!--Download link-->
|
||||
|
||||
@@ -20,12 +20,16 @@
|
||||
<string name="more_info">Nánari upplýsingar</string>
|
||||
<string name="don_t_ask_again">Ekki spyrja aftur</string>
|
||||
<string name="setup_huawei_text">Ýttu á hnappinn hér fyrir neðan og gakktu úr skugga um að Briar sé varið á skjánum \"Varin forrit\".</string>
|
||||
<string name="setup_huawei_button">Verja Briar</string>
|
||||
<string name="setup_huawei_button">Vernda Briar</string>
|
||||
<string name="setup_huawei_help">Ef Briar er ekki bætt á listann yfir varin forrit, getur það ekki keyrt í bakgrunni.</string>
|
||||
<string name="setup_huawei_app_launch_text">Ýttu á hnappinn hér fyrir neðan, opnaðu \"Ræsing forrits\" skjáinn og gakktu úr skugga um að Briar sé stillt á \"Stýra handvirkt\".</string>
|
||||
<string name="setup_huawei_app_launch_button">Opna rafhlöðustillingar</string>
|
||||
<string name="setup_huawei_app_launch_help">Ef Briar er ekki stillt á \"Stýra handvirkt\" í \"Ræsing forrits\" skjánum, mun það ekki geta keyrt í bakgrunni.</string>
|
||||
<string name="setup_xiaomi_button">Verja Briar</string>
|
||||
<string name="setup_xiaomi_text">Til að keyra í bakgrunni þarf Briar að vera læst við listann yfir nýleg forrit.</string>
|
||||
<string name="setup_xiaomi_button">Vernda Briar</string>
|
||||
<string name="setup_xiaomi_help">Ef Briar er ekki læst við listann yfir nýleg forrit, mun það ekki geta keyrt í bakgrunni.</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">1. Opnaðu listann yfir nýleg forrit (einnig kallað forritaskiptir)\n\n2. Strjúktu niður myndina af Briar til að birta hengilástáknið\n\n3. Ef hengilásinn er ekki læstur, ýttu á hann til að læsa</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">1. Opnaðu listann yfir nýleg forrit (einnig kallað forritaskiptir)\n\n2. Ýttu og haltu niðri á myndina af Briar til að birta hengiláshnappinn\n\n3. Ef hengilásinn er ekki læstur, ýttu á hann til að læsa</string>
|
||||
<string name="warning_dozed">%s gat ekki keyrt í bakgrunni</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">Lykilorð</string>
|
||||
@@ -37,6 +41,9 @@
|
||||
<string name="dialog_title_lost_password">Týnt lykilorð</string>
|
||||
<string name="dialog_message_lost_password">Notandaaðgangur þinn í Briar er geymdur dulritaður á tækinu þínu, ekki í tölvuskýi, þannig að við getum ekki endurstillt lykilorðið þitt. Myndirðu vilja eyða notandaaðgangnum þínum og byrja aftur?\n\nVarúð: Auðkennin þín, tengiliðir og skilaboð munu tapast óendurkræft.</string>
|
||||
<string name="startup_failed_activity_title">Bilun í ræsingu Briar</string>
|
||||
<string name="startup_failed_clock_error">Briar gat ekki farið af stað því klukka tækisins þíns er ekki rétt stillt.\n\nLeiðréttu klukku tækisins og prófaðu síðan aftur.</string>
|
||||
<string name="startup_failed_data_too_old_error">Notandaaðgangurinn þinn var útbúinn með eldri útgáfu forritsins og er ekki hægt að opna hann með þessari útgáfu.\n\Þú þarft annað hvort að setja gömlu útgáfuna upp aftur, eða setja upp nýjan notandaaðgang með því að velja \'Ég hef gleymt lykilorðinu mínu\' þegar beðið er um lykilorð.</string>
|
||||
<string name="startup_failed_data_too_new_error">Notandaaðgangurinn þinn var útbúinn með nýrri útgáfu forritsins og er ekki hægt að opna hann með þessari útgáfu.\n\Þú þarft að setja upp nýjustu útgáfuna og prófa svo aftur.</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="one">Þetta er prufuútgáfa af Briar. Notandaaðgangurinn þinn mun renna út eftir %d dag og er ekki hægt að endurnýja hann.</item>
|
||||
<item quantity="other">Þetta er prufuútgáfa af Briar. Notandaaðgangurinn þinn mun renna út eftir %d daga og er ekki hægt að endurnýja hann.</item>
|
||||
@@ -307,9 +314,12 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Tengjast í gegnum Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_title">Tengjast í gegnum Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Er þegar að reyna að tengjast með Bluetooth. Prófaðu aftur eftir dálitla stund.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Get ekki haldið áfram án heimildar til að nota staðsetningu</string>
|
||||
<string name="connect_via_bluetooth_start">Tengist í gegnum Bluetooth…</string>
|
||||
<string name="connect_via_bluetooth_success">Tókst að tengjast í gegnum Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">Gat ekki tengst í gegnum Bluetooth.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Bluetooth er ekki stutt af tækinu.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">Engir hópar sem hægt er að birta</string>
|
||||
<string name="groups_list_empty_action">Ýttu á + táknið til að útbúa hóp, eða biddu tengiliðina þína um að deila hópi með þér</string>
|
||||
@@ -569,6 +579,7 @@
|
||||
<string name="learn_more">Fræðast frekar</string>
|
||||
<string name="disappearing_messages_summary">Láta öll frekari skilaboð í þessu samtali hverfa sjálfkrafa eftir 7\u00A0daga.</string>
|
||||
<!--Settings Actions-->
|
||||
<string name="pref_category_actions">Aðgerðir</string>
|
||||
<string name="send_feedback">Senda umsögn</string>
|
||||
<!--Link Warning-->
|
||||
<string name="link_warning_title">Aðvörun vegna tengils</string>
|
||||
@@ -577,6 +588,7 @@
|
||||
<string name="link_warning_open_link">Opna tengil</string>
|
||||
<!--Crash Reporter-->
|
||||
<string name="crash_report_title">Hrunskýrsla fyrir Briar</string>
|
||||
<string name="briar_crashed">Því miður, Briar hefur hrunið</string>
|
||||
<string name="not_your_fault">Það er ekki þér að kenna.</string>
|
||||
<string name="please_send_report">Hjálpaðu okkur við að bæta Briar með því að senda okkur hrunskýrslu.</string>
|
||||
<string name="report_is_encrypted">Við lofum að skýrslan sé dulrituð og send á öruggan máta.</string>
|
||||
@@ -635,16 +647,64 @@
|
||||
<!--Connections Screen-->
|
||||
<string name="transports_help_text">Briar getur tengst við tengiliðina þína í gegnum internet, Wi-Fi eða Bluetooth.\n\nAllar internettengingar fara í gegnum Tor-netkerfið til að gæta gagnaleyndar.\n\nEf hægt er að nálgast tengilið með mörgum leiðum, notar Briar þær samhliða.</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">Deila þessu forriti án nettengingar</string>
|
||||
<string name="hotspot_button_start_sharing">Ræsa tengipunkt</string>
|
||||
<string name="hotspot_button_stop_sharing">Stöðva tengipunkt</string>
|
||||
<string name="hotspot_progress_text_start">Set upp tengipunkt…</string>
|
||||
<string name="hotspot_notification_channel_title">Þráðlaus Wi-Fi tengipunktur</string>
|
||||
<string name="hotspot_notification_title">Deiling Briar án nettengingar</string>
|
||||
<string name="hotspot_button_connected">Næsta</string>
|
||||
<string name="permission_hotspot_location_request_body">Til að útbúa Wi-Fi-aðgangsstað, þarf Briar heimild til að nota staðsetningu þína.\n\nBriar geymir ekki staðsetningar eða deilir þeim með neinum.</string>
|
||||
<string name="permission_hotspot_location_denied_body">Þú hefur hafnað aðgangi að staðsetningu, en Briar þarf þessa heimild til að geta útbúið Wi-Fi-aðgangsstað.\n\nÍhugaðu að veita þennan aðgang.</string>
|
||||
<string name="wifi_settings_title">Wi-Fi-stillingar</string>
|
||||
<string name="wifi_settings_request_enable_body">Til að útbúa Wi-Fi aðgangsstað þarf Briar að nota Wi-Fi. Virkjaðu það.</string>
|
||||
<string name="hotspot_tab_manual">Handvirk</string>
|
||||
<!--The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s-->
|
||||
<string name="hotspot_scanning_a_qr_code">skönnun QR-kóða</string>
|
||||
<!--Wi-Fi setup-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_wifi_ssid">Heiti netkerfis</string>
|
||||
<string name="hotspot_no_peers_connected">Engin tæki tengd</string>
|
||||
<plurals name="hotspot_peers_connected">
|
||||
<item quantity="one">%s tæki tengt</item>
|
||||
<item quantity="other">%s tæki tengd</item>
|
||||
</plurals>
|
||||
<!--Download link-->
|
||||
<!--The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code'-->
|
||||
<string name="hotspot_manual_site_address">Vistfang (URL)</string>
|
||||
<!--e.g. Download Briar 1.2.20-->
|
||||
<string name="website_download_title">Sækja %s</string>
|
||||
<string name="website_download_intro">Einhver í nágrenninu hefur deilt %s með þér.</string>
|
||||
<string name="website_download_outro">Eftir að niðurhalinu er lokið, skaltu opna sóttu skrána og setja hana upp.</string>
|
||||
<string name="website_troubleshooting_title">Lausn á vandamálum</string>
|
||||
<string name="website_troubleshooting_1">Ef þú getur ekki sótt forritið, ættirðu að prófa það með öðrum vafra.</string>
|
||||
<string name="hotspot_help_wifi_title">Vandamál við að tengjast við Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Prófaðu að gera Wi-Fi óvirkt og virkja það aftur á báðum símunum og reyndu svo aftur.</string>
|
||||
<string name="hotspot_help_site_title">Vandamál við að skoða staðvært vefsvæði:</string>
|
||||
<string name="hotspot_help_site_3">Ef þú ert með eldveggjarhugbúnað í gangi, skaltu vera viss um að það sé ekki að loka fyrir aðgang.</string>
|
||||
<string name="hotspot_help_site_4">Ef þú getur skoðað vefsvæðið en ekki sótt Briar-forritið, ættirðu að prófa það með öðrum vafra.</string>
|
||||
<string name="hotspot_help_fallback_title">Virkar ekkert?</string>
|
||||
<string name="hotspot_help_fallback_button">Vista forrit</string>
|
||||
<!--error handling-->
|
||||
<string name="hotspot_error_intro">Eitthvað fór úrskeiðis þegar reynt var að deila forritinu með Wi-Fi:</string>
|
||||
<string name="hotspot_error_no_wifi_direct">Þetta tæki styður ekki beint Wi-Fi samband.</string>
|
||||
<string name="hotspot_error_start_callback_failed">Tengipunktur ræstist ekki: villa %s</string>
|
||||
<string name="hotspot_error_start_callback_failed_unknown">Tengipunktur ræstist ekki vegna óþekktrar villu, ástæðan er %d</string>
|
||||
<string name="hotspot_error_start_callback_no_group_info">Tengipunktur ræstist ekki: engar hópupplýsingar</string>
|
||||
<string name="hotspot_error_web_server_start">Villa við að ræsa vefþjón</string>
|
||||
<string name="hotspot_flag_test">Aðvörun: Þetta forrit var sett upp með Android Studio og er EKKI hægt að setja upp á öðru tæki.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Tengjast í gegnum útskiptanlegt drif</string>
|
||||
<string name="removable_drive_title_send">Senda gögn</string>
|
||||
<string name="removable_drive_title_receive">Taka við gögnum</string>
|
||||
<string name="removable_drive_send_button">Veldu skrá til að flytja út</string>
|
||||
<string name="removable_drive_ongoing">Bíddu eftir að verk sem er í gangi klárist</string>
|
||||
<string name="removable_drive_receive_intro">Ýttu á hnappinn hér fyrir neðan til að velja skrána sem tengiliðurinn sendi þér.\n\nEf skráin er á útskiptanlegu drifi, skaltu tengja það núna.</string>
|
||||
<string name="removable_drive_receive_button">Veldu skrá til að flytja inn</string>
|
||||
<string name="removable_drive_success_send_title">Útflutningur tókst</string>
|
||||
<string name="removable_drive_success_receive_title">Innflutningur tókst</string>
|
||||
<string name="removable_drive_error_send_title">Villa við útflutning gagna</string>
|
||||
<string name="removable_drive_error_receive_title">Villa í innflutningi gagna</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Lísa</string>
|
||||
|
||||
@@ -609,6 +609,7 @@
|
||||
<string name="dev_report_memory">Memoria</string>
|
||||
<string name="dev_report_storage">Spazio</string>
|
||||
<string name="dev_report_connectivity">Connettività</string>
|
||||
<string name="dev_report_network_usage">Utilizzo della rete</string>
|
||||
<string name="dev_report_build_config">Configurazione build</string>
|
||||
<string name="dev_report_logcat">Registro app</string>
|
||||
<string name="dev_report_device_features">Caratteristiche dispositivo</string>
|
||||
@@ -692,6 +693,7 @@
|
||||
<string name="hotspot_help_wifi_title">Problemi di connessione al Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Prova a disattivare e riattivare il Wi-Fi su entrambi i telefoni e riprova.</string>
|
||||
<string name="hotspot_help_wifi_2">Se il telefono ti segnala che il Wi-Fi non ha internet, digli che vuoi restare comunque connesso.</string>
|
||||
<string name="hotspot_help_wifi_3">Riavvia il telefono su cui è in esecuzione l\'hotspot Wi-Fi, poi avvia Briar e riprova a condividere.</string>
|
||||
<string name="hotspot_help_site_title">Problemi visitando il sito web locale:</string>
|
||||
<string name="hotspot_help_site_1">Controlla di avere inserito l\'indirizzo esattamente come mostrato. Un piccolo errore può impedire il funzionamento.</string>
|
||||
<string name="hotspot_help_site_2">Assicurati che il telefono sia ancora connesso al Wi-Fi giusto (vedi sopra) quando provi ad accedere al sito.</string>
|
||||
@@ -712,6 +714,9 @@
|
||||
<string name="hotspot_flag_test">Attenzione: questa app è stata installata con Android Studio e NON può essere installata su un altro dispositivo.</string>
|
||||
<string name="hotspot_error_framework_busy">Impossibile avviare l\'hotspot.\n\nSe ne hai un altro in esecuzione o se stai condividendo la connessione internet via Wi-Fi, fermalo e poi riprova.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Connessione tramite unità rimovibile</string>
|
||||
<string name="removable_drive_intro">Se non riesci a connetterti al tuo contatto tramite Internet, Wi-Fi o Bluetooth, Briar può anche trasferire i messaggi su un\'unità rimovibile come una chiavetta USB o una scheda SD.</string>
|
||||
<string name="removable_drive_explanation">Se non riesci a connetterti al tuo contatto tramite Internet, Wi-Fi o Bluetooth, Briar può anche trasferire i messaggi su un\'unità rimovibile come una chiavetta USB o una scheda SD.\n\nQuando usi il pulsante \"Invia dati\" , tutti i dati in attesa di essere inviati al contatto verranno scritti sull\'unità rimovibile. Ciò include messaggi privati, allegati, blog, forum e gruppi privati.\n\nTutto sarà crittografato prima di essere scritto sull\'unità rimovibile.\n\nQuando il tuo contatto riceve l\'unità rimovibile, può utilizzare il pulsante \"Ricevi dati\" per importare i messaggi in Briar.</string>
|
||||
<string name="removable_drive_title_send">Invia dati</string>
|
||||
<string name="removable_drive_title_receive">Ricevi dati</string>
|
||||
<string name="removable_drive_send_intro">Tocca il pulsante sottostante per creare un nuovo file contenente i messaggi cifrati. Puoi scegliere dove verrà salvato il file.\n\nSe vuoi salvarlo in un supporto rimovibile, inseriscilo ora.</string>
|
||||
|
||||
@@ -31,10 +31,15 @@
|
||||
<string name="dialog_title_cannot_check_password">パスワードを確認できません</string>
|
||||
<string name="dialog_message_cannot_check_password">Briarはあなたのパスワードを確認できません。この問題を解決するため、デバイスの再起動を試してください。</string>
|
||||
<string name="sign_in_button">サインイン</string>
|
||||
<string name="forgotten_password">パスワードを忘れました。</string>
|
||||
<string name="forgotten_password">パスワードを忘れました</string>
|
||||
<string name="dialog_title_lost_password">パスワードを紛失</string>
|
||||
<string name="dialog_message_lost_password">あなたのBriarアカウントはクラウド上ではなく、暗号化さた上であなたのデバイスに保存さています。したがってBriarはパスワードをリセットできません。アカウントを削除しはじめからやりなおしますか?\n\n注意:あなたのID、連絡先、メッセージは永久に復元できません。</string>
|
||||
<string name="startup_failed_activity_title">起動に失敗しました</string>
|
||||
<string name="startup_failed_clock_error">デバイスの時計が不正なので、Briarは起動できませんでした。\n\nデバイスの時計を正しい時刻に設定して、再試行してください。</string>
|
||||
<string name="startup_failed_db_error">Briarは、あなたのアカウント、連絡先、メッセージを含むデータベースを開くことができませんでした。\n\nアプリを最新版にアップグレードして再度お試しいただくか、パスワード入力画面で\'パスワードを忘れました\'を選択して新しいアカウントを設定してください。</string>
|
||||
<string name="startup_failed_data_too_old_error">あなたのアカウントは古いバージョンのアプリで作成されたもので、このバージョンでは開くことができません。\n\n古いバージョンを再インストールするか、パスワード入力画面で\'パスワードを忘れました\'を選択して新しいアカウントを設定する必要があります。</string>
|
||||
<string name="startup_failed_data_too_new_error">あなたのアカウントは、このアプリの新しいバージョンで作成されたもので、このバージョンでは開くことができません。\n\n最新のバージョンにアップグレードしてから再度お試しください。</string>
|
||||
<string name="startup_failed_service_error">Briarは、必要なコンポーネントを起動できませんでした。\n\n最新版のアプリにアップグレードしてから再度お試しください。</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="other">これは、Briarのテストバージョンです。 アカウントは%d日で期限切れになり、更新できません。</item>
|
||||
</plurals>
|
||||
@@ -289,9 +294,12 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Bluetooth経由で接続する</string>
|
||||
<string name="connect_via_bluetooth_title">Bluetooth経由で接続する</string>
|
||||
<string name="connect_via_bluetooth_intro">Bluetooth接続が自動的に行われない場合は、この画面を使って手動で接続することができます。\n\nこの機能を利用するには、あなたの連絡先が近くにある必要があります。\n\nあなたと連絡先が同時に\"開始\"を押してください。</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">位置情報の権限なくして続行不可能</string>
|
||||
<string name="connect_via_bluetooth_start">Bluetooth経由で接続中…</string>
|
||||
<string name="connect_via_bluetooth_success">Bluetooth経由で接続に成功</string>
|
||||
<string name="connect_via_bluetooth_error">Bluetooth経由で接続不可能。</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Bluetoothはデバイスによってサポートされていません。</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">表示するグループがありません</string>
|
||||
<string name="groups_list_empty_action">「+」アイコンをタップしてグループを作成するか、連絡先に登録している誰かにグループを共有してもらう</string>
|
||||
@@ -534,6 +542,7 @@
|
||||
<string name="choose_ringtone_title">着信音を選択</string>
|
||||
<string name="cannot_load_ringtone">着信音を読み込めません</string>
|
||||
<!--Conversation Settings-->
|
||||
<string name="disappearing_messages_title">消えたメッセージ</string>
|
||||
<string name="learn_more">詳細情報</string>
|
||||
<!--Settings Actions-->
|
||||
<string name="pref_category_actions">操作</string>
|
||||
@@ -578,6 +587,7 @@
|
||||
<string name="screen_filter_body">別のアプリがBriarの画面上に描画しています。 セキュリティを保護するために、Briarは、別のアプリがBriarの画面上に描画している場合、タッチに応答しません。\n\n次のアプリが上に描画されている可能性があります:\n\n%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_review_apps">アプリを確認</string>
|
||||
<!--Permission Requests-->
|
||||
<string name="permission_camera_title">カメラへのアクセス許可</string>
|
||||
<string name="permission_camera_request_body">QRコードをスキャンするには、Briarはカメラにアクセスする必要があります。</string>
|
||||
@@ -603,8 +613,6 @@
|
||||
<string name="transports_help_text">Briarは、インターネット、Wi-Fi、Bluetoothを介して連絡先に接続することができます。\n\nすべてのインターネット接続は、プライバシー保護のためにTorネットワークを経由します。\n\n複数の方法で連絡が取れる場合、Briarはそれらを並行して使用します。</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">このアプリをオフラインで共有</string>
|
||||
<string name="hotspot_intro">あなたの電話機のWi-Fiを使用して、インターネット接続なしで、近くの誰かとこのアプリを共有します。
|
||||
\n\nあなたの電話機はWi-Fiホットスポットになります。近くの人はホットスポットへ接続し、あなたの電話機からBriarアプリをダウンロードできます。</string>
|
||||
<string name="hotspot_button_start_sharing">ホットスポットを開始</string>
|
||||
<string name="hotspot_button_stop_sharing">ホットスポットを停止</string>
|
||||
<string name="hotspot_progress_text_start">ホットスポットを設定する…</string>
|
||||
@@ -637,7 +645,31 @@
|
||||
<string name="website_download_intro">近くの誰かが、あなたと %s を共有しました。</string>
|
||||
<string name="website_download_outro">ダウンロードが完了した後に、ダウンロードしたファイルを開いて、インストールしてください。</string>
|
||||
<string name="website_troubleshooting_title">トラブルシューティング</string>
|
||||
<string name="website_troubleshooting_1">アプリをインストールできない場合、別のブラウザアプリで試してください。</string>
|
||||
<string name="website_troubleshooting_2_old">ダウンロードしたアプリをインストールするには、システム設定で\"提供元不明\"のアプリのインストールを許可する必要がある場合があります。その後、再度アプリのダウンロードが必要になる場合があります。アプリをインストールした後は、\"提供元不明\"の設定を解除することをお勧めします。</string>
|
||||
<string name="website_troubleshooting_2_new">ダウンロードしたアプリをインストールするには、ブラウザに不明なアプリのインストールを許可する必要がある場合があります。アプリをインストールした後は、ブラウザの不明なアプリのインストール許可を解除することをお勧めします。</string>
|
||||
<string name="hotspot_help_wifi_title">W-Fi接続の問題:</string>
|
||||
<string name="hotspot_help_wifi_1">双方の電話機でWi-Fiを無効にして、再び有効にするのを試してください。</string>
|
||||
<string name="hotspot_help_wifi_2">もし電話機が「Wi-Fiにはインターネットがない」と不満を訴えてきたら、「とにかく接続していたい」と伝えてください。</string>
|
||||
<string name="hotspot_help_wifi_3">Wi-Fiホットスポットが実行中の電話機を再起動して、Briarの起動と共有を再び試してください。</string>
|
||||
<string name="hotspot_help_site_title">ローカルのウェブサイト訪問の問題:</string>
|
||||
<string name="hotspot_help_site_1">表示されている通りにアドレスを入力したかどうかを再確認してください。小さなミスで失敗することがあります。</string>
|
||||
<string name="hotspot_help_site_2">サイトにアクセスする際に、電話機が正しいWi-Fi(上記を参照)に接続されていることを確認してください。</string>
|
||||
<string name="hotspot_help_site_3">ファイアウォールアプリを使用している場合は、それがアクセスをブロックしていないか確認してください。</string>
|
||||
<string name="hotspot_help_site_4">サイトにはアクセスできるが、Briarアプリがダウンロードできない場合は、別のウェブブラウザアプリで試してみてください。</string>
|
||||
<string name="hotspot_help_fallback_title">どれもうまくいきませんか?</string>
|
||||
<string name="hotspot_help_fallback_intro">他の方法で共有するために、アプリを.apkファイルとして保存してみてください。そのファイルをもう一方のデバイスに転送すれば、Briarをインストールすることができます。
|
||||
\n\nヒント: Bluetoothで共有する場合は、まずファイル名を.zipで終わるように名前変更する必要があるかもしれません。</string>
|
||||
<string name="hotspot_help_fallback_button">アプリを保存する</string>
|
||||
<!--error handling-->
|
||||
<string name="hotspot_error_intro">Wi-Fiでアプリを共有しようとしたときに、何か問題が発生しました。</string>
|
||||
<string name="hotspot_error_no_wifi_direct">デバイスはWi-Fiダイレクトをサポートしていません</string>
|
||||
<string name="hotspot_error_start_callback_failed">ホットスポットの開始に失敗しました: エラー %s</string>
|
||||
<string name="hotspot_error_start_callback_no_group_info">ホットスポットの開始に失敗しました: グループ情報なし</string>
|
||||
<string name="hotspot_error_web_server_start">ウェブサーバー起動エラー</string>
|
||||
<string name="hotspot_error_web_server_serve">ウェブサイトの表示にエラーが発生しました。\n\n問題が解決しない場合は、Briarアプリから(匿名のデータで)フィードバックを送ってください。</string>
|
||||
<string name="hotspot_flag_test">警告: このアプリはAndroid Studioでインストールされたものであり、他の端末にインストールすることはできません。</string>
|
||||
<string name="hotspot_error_framework_busy">ホットスポットの起動ができません。\n\n他のホットスポットを起動している場合や、Wi-Fiでインターネット接続を共有している場合は、そのホットスポットを停止してから再度試してみてください。</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_success_receive_title">インポート成功</string>
|
||||
<!--Screenshots-->
|
||||
|
||||
@@ -334,9 +334,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Prisijungti per Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_title">Prisijungti per Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_intro">Tuo atveju, jei Bluetooth ryšiai neveikia automatiškai, galite naudoti šį langą, kad prisijungtumėte rankiniu būdu.\n\nTam, kad tai suveiktų, jūsų adresatas turi būti šalia jūsų.\n\nJūs ir jūsų adresatas vienu metu turėtumėte paspausti „Pradėti“.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Jau bandoma jungtis per Bluetooth. Netrukus bandykite dar kartą.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Nepavyksta tęsti be įrenginio vietovės leidimo</string>
|
||||
<string name="connect_via_bluetooth_start">Jungiamasi per Bluetooth…</string>
|
||||
<string name="connect_via_bluetooth_success">Sėkmingai prisijungta per Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">Nepavyko prisijungti per Bluetooth.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Įrenginys nepalaiko Bluetooth.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">Nėra rodytinų grupių</string>
|
||||
<string name="groups_list_empty_action">Norėdami sukurti grupę ar paprašyti savo adresatų pradėti su jumis bendrinti grupes, bakstelėkite + piktogramą</string>
|
||||
@@ -631,6 +635,7 @@
|
||||
<string name="dev_report_memory">Atmintis</string>
|
||||
<string name="dev_report_storage">Saugykla</string>
|
||||
<string name="dev_report_connectivity">Jungiamumas</string>
|
||||
<string name="dev_report_network_usage">Tinklo naudojimas</string>
|
||||
<string name="dev_report_build_config">Darinio konfigūracija</string>
|
||||
<string name="dev_report_logcat">Programėlės žurnalas</string>
|
||||
<string name="dev_report_device_features">Įrenginio ypatybės</string>
|
||||
@@ -716,6 +721,7 @@
|
||||
<string name="hotspot_help_wifi_title">Problemos jungiantis prie belaidžio (Wi-Fi):</string>
|
||||
<string name="hotspot_help_wifi_1">Pabandykite abiejuose telefonuose išjungti ir vėl įjungti belaidį (Wi-Fi) ryšį ir bandykite dar kartą.</string>
|
||||
<string name="hotspot_help_wifi_2">Jeigu jūsų telefonas skundžiasi, jog belaidžiame (Wi-Fi) tinkle nėra interneto ryšio, nurodykite jam, kad norite likti prisijungę.</string>
|
||||
<string name="hotspot_help_wifi_3">Paleiskite telefoną, kuriame įjungtas belaidis (Wi-Fi) prieigos taškas, iš naujo, o tuomet paleiskite Briar ir bandykite bendrinti dar kartą.</string>
|
||||
<string name="hotspot_help_site_title">Iškilo problemų apsilankant vietinėje svetainėje:</string>
|
||||
<string name="hotspot_help_site_1">Dar kartą įsitikinkite, kad tiksliai įvedėte nurodytą adresą. Maža klaida gali sukelti nesėkmę.</string>
|
||||
<string name="hotspot_help_site_2">Bandydami pasiekti šią svetainę, įsitikinkite, kad jūsų telefonas vis dar yra prisijungęs prie teisingo belaidžio (Wi-Fi) ryšio (žiūrėkite aukščiau).</string>
|
||||
@@ -736,6 +742,9 @@
|
||||
<string name="hotspot_flag_test">Įspėjimas: Ši programėlė buvo įdiegta naudojant „Android Studio“ ir NEGALI būti įdiegta kitame įrenginyje.</string>
|
||||
<string name="hotspot_error_framework_busy">Nepavyko įjungti prieigos taško.\n\nJei turite veikiantį kitą prieigos tašką arba, jei bendrinate interneto ryšį per belaidį (Wi-Fi) ryšį, pabandykite to nebedaryti ir po to, bandykite dar kartą.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Prisijungti per keičiamąjį diską</string>
|
||||
<string name="removable_drive_intro">Jei negalite prisijungti prie savo adresato per internetą, belaidį (Wi-Fi) ar Bluetooth, Briar taip pat gali perkelti žinutes į keičiamąjį diską, pavyzdžiui, USB atmintuką ar SD kortelę.</string>
|
||||
<string name="removable_drive_explanation">Jei negalite prisijungti prie savo adresato per internetą, belaidį (Wi-Fi) ar Bluetooth, Briar taip pat gali perkelti žinutes į keičiamąjį diską, pavyzdžiui, USB atmintuką ar SD kortelę.\n\nKai naudojate mygtuką „Siųsti duomenis“, bet kokie duomenys, laukiantys, kad būtų išsiųsti adresatui, bus įrašyti į keičiamąjį diską. Į juos įeina privačios žinutės, priedai, tinklaraščiai, forumai ir privačios grupės.\n\nVisa tai, prieš įrašant į keičiamąjį diską, bus užšifruota.\n\nJūsų adresatas, gavęs keičiamąjį diską, galės naudoti mygtuką „Gauti duomenis“, kad importuotų žinutes į Briar.</string>
|
||||
<string name="removable_drive_title_send">Siųsti duomenis</string>
|
||||
<string name="removable_drive_title_receive">Gauti duomenis</string>
|
||||
<string name="removable_drive_send_intro">Bakstelėkite mygtuką žemiau, kad sukurtumėte naują failą su šifruotomis žinutėmis. Galite pasirinkti, kur failą įrašyti.\n\nJei norite įrašyti failą į keičiamąjį diską, tuomet įdėkite diską dabar.</string>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!--Setup-->
|
||||
<string name="setup_title">Briar မှ ကြိုဆိုပါသည်</string>
|
||||
<string name="setup_name_explanation">သင့်နာမည်ပြောင်သည် သင်တင်ထားသမျှအရာ၏ဘေးတွင် ပေါ်နေပါလိမ့်မည်။ သို့ပါ၍ သင့်နာမည်ပြောင်အား အကောင့်ဖွင့်ပြီးနောက် ပြောင်း၍မရတော့ပါ။</string>
|
||||
<string name="setup_name_explanation">သင့်နာမည်ပြောင်သည် သင်တင်ထားသမျှ၏ဘေးတွင် ပေါ်နေပါလိမ့်မည်။ သို့ပါ၍ သင့်နာမည်ပြောင်အား အကောင့်ဖွင့်ပြီးနောက် ပြောင်း၍မရတော့ပါ။</string>
|
||||
<string name="setup_next">ရှေ့သို့</string>
|
||||
<string name="setup_password_intro">စကားဝှက်တစ်ခု ရွေးပါ</string>
|
||||
<string name="setup_password_explanation">သင့် Briar အကောင့်ကို ကလောက်တွင်မဟုတ်ဘဲ သင့်ကိရိယာတွင်သာ လျှို့ဝှက်ကုဒ်ပြောင်းသိမ်းဆည်းထားပါသည်။ သင့်စကားဝှက်ကို မေ့သွားလျှင် (သို့) Briar ကို ဖြုတ်လိုက်လျှင် သင့်အကောင့်ကို မည်သည့်နည်းနှင့်မှ ပြန်မရယူနိုင်တော့ပါ။\n\nကြုံရာစကားလုံးလေးလုံး (သို့) ကြုံရာအက္ခရာဆယ်လုံး၊ နံပါတ်များနှင့် သင်္ကေတများကဲ့သို့ ခန့်မှန်းရခက်သည့် ရှည်လျားသောစကားဝှက်ကို ရွေးချယ်ပါ။</string>
|
||||
<string name="setup_password_explanation">သင့် Briar အကောင့်ကို ကလောက်တွင်မဟုတ်ဘဲ သင့်ကိရိယာတွင်သာ လျှို့ဝှက်ကုဒ်ပြောင်းသိမ်းဆည်းထားပါသည်။ သင့်စကားဝှက်ကို မေ့သွားလျှင် (သို့) Briar ကို ဖြုတ်လိုက်လျှင် သင့်အကောင့်ကို မည်သည့်နည်းနှင့်မျှ ပြန်မရယူနိုင်ပါ။\n\nကြုံရာစကားလုံးလေးလုံး (သို့) ကြုံရာအက္ခရာဆယ်လုံး၊ နံပါတ်များနှင့် သင်္ကေတများကဲ့သို့ ခန့်မှန်းရခက်သည့် ရှည်လျားသောစကားဝှက်ကို ရွေးချယ်ပါ။</string>
|
||||
<string name="setup_doze_title">နောက်ခံချိတ်ဆက်မှုများ</string>
|
||||
<string name="setup_doze_intro">မက်ဆေ့ချ်များလက်ခံရယူနိုင်ရန် Briar သည် နောက်ခံချိတ်ဆက်နေရန် လိုအပ်သည်။</string>
|
||||
<string name="setup_doze_explanation">မက်ဆေ့ချ်များလက်ခံရယူနိုင်ရန် Briar သည် နောက်ခံချိတ်ဆက်နေရန် လိုအပ်သည်။ Briar အနေဖြင့် ချိတ်ဆက်မှုမပြတ်ရှိနေစေရန် ဘတ္ထရီအားအကောင်းဆုံးထိန်းညှိခြင်းကို ကျေးဇူးပြု၍ ပိတ်ထားပေးပါ။</string>
|
||||
@@ -22,30 +22,35 @@
|
||||
<string name="setup_huawei_text">အောက်ပါခလုတ်ကိုနှိပ်၍ \"ကာကွယ်မှုပေးထားသောအက်ပ်များ\" စခရင်တွင် Briar ကို ကာကွယ်ထားကြောင်း သေချာစေပါ။</string>
|
||||
<string name="setup_huawei_button">Briar ကို ကာကွယ်မည်</string>
|
||||
<string name="setup_huawei_help">ကာကွယ်မှုပေးထားသောအက်ပ်များစာရင်းတွင် ထည့်မထားလျှင် Briar ကို နောက်ကွယ်တွင် ဖွင့်ထားနိုင်မည်မဟုတ်ပါ။</string>
|
||||
<string name="setup_huawei_app_launch_text">အောက်က ခလုတ်ကို နှိပ်၍ \"အပ္ပလီကေးရှင်း ဖွင့်ရန်\" စကင်ရင်ကို ဖွင့်ပါ၊ ပြီးလျှင် Briar ကို \"ကိုယ်တိုင်စီမံမယ်\" လို့ သတ်မှတ်ပါ။</string>
|
||||
<string name="setup_huawei_app_launch_button">ဘက်ထရီအပြင်အဆင်များကို ဖွင့်ပါ</string>
|
||||
<string name="setup_huawei_app_launch_help">Briar ကို \"အပ္ပလီကေးရှင်း ဖွင့်ရန်\" စကင်ရင်ပေါ်တွင် \"ကိုယ်တိုင်စီမံမယ်\" လို့မသတ်မှတ်ထားလျှင် နောက်ခံတွင် ၎င်းကို လည်ပတ်၍ မရနိုင်ပါ။</string>
|
||||
<string name="setup_xiaomi_text">နောက်ခံတွင်အလုပ်လုပ်စေရန် လတ်တလောအက်ပလီကေးရှင်းများစာရင်းတွင် Briar အား သော့ခတ်ထားရန် လိုအပ်သည်။</string>
|
||||
<string name="setup_xiaomi_button">Briar ကို ကာကွယ်ပါ</string>
|
||||
<string name="setup_xiaomi_help">အကယ်၍ Briar ကို သော့မခတ်ထားပါက၊ ထိုအက်ပလီကေးရှင်းသည် နောက်ခံတွင် အလုပ်လုပ်နေနိုင်မည် မဟုတ်ပါ။</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">၁။ လတ်တလောအက်ပ်များစာရင်းကိုဖွင့်ပါ (ဒါ့အပြင် app switcher လို့လည်းခေါ်ပါသည်) \n\n2. သော့ခလောက်အိုင်ကွန်ကို \n\n3. ပြသရန် Briar ၏ပုံကို အောက်ကိုတွန်းပါ။ </string>
|
||||
<string name="setup_xiaomi_dialog_body_new">၁။ လတ်တလော အက်ပလီကေးရှင်းများစာရင်း (ဒါ့အပြင် အက်ပလီကေးရှင်းခလုတ်ဟုလည်းခေါ်သည်) ကိုလည်းဖွင့်ပါ \n\n2 ။ အဆိုပါသော့ခလောက်ခလုတ်မှ \n\n3 ပေါ်လာသည်အထိ Briar ၏ ပုံကို နှိပ်၍ ဖိထားပါ။ အကယ်၍ သော့ခလောက်သည် သော့ခတ်ထားခြင်းမရှိပါက ၎င်းကိုသော့ခတ်ရန် ပွတ်ဆွဲပါ။ </string>
|
||||
<string name="warning_dozed">%s ကို နောက်ကွယ်တွင် မဖွင့်ထားနိုင်ပါ</string>
|
||||
<string name="setup_huawei_app_launch_text">အောက်ပါခလုတ်ကိုနှိပ်ပြီး \"အက်ပ်စတင်ခြင်း\" စခရင်ကို ဖွင့်၍ Briar ကို \"ကိုယ်တိုင်စီမံမည်\" ဟု သတ်မှတ်ပါ။</string>
|
||||
<string name="setup_huawei_app_launch_button">ဘတ္ထရီဆက်တင်များကို ဖွင့်မည်</string>
|
||||
<string name="setup_huawei_app_launch_help">\"အက်ပ်စတင်ခြင်း\" စခရင်တွင် \"ကိုယ်တိုင်စီမံမည်\" ဟု သတ်မှတ်မထားလျှင် Briar ကို နောက်ကွယ်တွင် ဖွင့်ထားနိုင်မည်မဟုတ်ပါ။</string>
|
||||
<string name="setup_xiaomi_text">ဖွင့်ထားသောအက်ပ်များစာရင်းတွင် Briar ကို လော့ခ်ချထားမှ နောက်ကွယ်တွင် ဖွင့်ထားနိုင်မည်။</string>
|
||||
<string name="setup_xiaomi_button">Briar ကို ကာကွယ်ထားမည်</string>
|
||||
<string name="setup_xiaomi_help">ဖွင့်ထားသောအက်ပ်များစာရင်းတွင် လော့ခ်ချမထားပါက Briar ကို နောက်ကွယ်တွင် ဖွင့်ထားနိုင်မည်မဟုတ်ပါ။</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">၁။ ဖွင့်ထားသောအက်ပ်များစာရင်း (တစ်နည်းအားဖြင့် အက်ပ်ပြောင်းရာ) ကို ဖွင့်ပါ\n\n၂။ သော့ခလောက်အိုင်ကွန်ပေါ်လာရန် Briar ပုံပေါ်မှ ပွတ်ဆွဲချပါ\n\n၃။ သော့ခတ်မထားပါက သော့ခတ်ရန်နှိပ်လိုက်ပါ</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">၁။ ဖွင့်ထားသောအက်ပ်များစာရင်း (တစ်နည်းအားဖြင့် အက်ပ်ပြောင်းရာ) ကို ဖွင့်ပါ\n\n၂။ သော့ခလောက်ခလုတ်ပေါ်လာသည်အထိ Briar ပုံကို နှိပ်ထားပါ\n\n၃။ သော့ခတ်မထားပါက သော့ခတ်ရန်နှိပ်လိုက်ပါ</string>
|
||||
<string name="warning_dozed">%s ကို နောက်ကွယ်တွင် ဖွင့်မထားနိုင်ပါ</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">စကားဝှက်</string>
|
||||
<string name="try_again">စကားဝှက်မှားနေသည်၊ ထပ်စမ်းကြည့်ပါ</string>
|
||||
<string name="dialog_title_cannot_check_password">စကားဝှက်ကို စစ်ဆေး၍မရပါ</string>
|
||||
<string name="dialog_message_cannot_check_password">Briar က သင့်စကားဝှက်ကို မစစ်ဆေးနိုင်ပါ။ ဤပြဿနာကို ဖြေရှင်းရန် သင့်ကိရိယာကို ပိတ်ပြီးပြန်ဖွင့်ကြည့်ပါ။</string>
|
||||
<string name="dialog_message_cannot_check_password">Briar က သင့်စကားဝှက်ကို မစစ်ဆေးနိုင်ပါ။ ဤပြဿနာကို ဖြေရှင်းရန် သင့်ကိရိယာကို ပိတ်၍ပြန်ဖွင့်ကြည့်ပါ။</string>
|
||||
<string name="sign_in_button">အကောင့်ဝင်မည်</string>
|
||||
<string name="forgotten_password">ကျွန်ုပ်၏စကားဝှက်ကို မေ့သွားပါသည်</string>
|
||||
<string name="dialog_title_lost_password">စကားဝှက်ပျောက်ဆုံး</string>
|
||||
<string name="dialog_message_lost_password">သင့် Briar အကောင့်ကို ကလောက်တွင်မဟုတ်ဘဲ သင့်ကိရိယာတွင်သာ လျှို့ဝှက်ကုဒ်ပြောင်းသိမ်းဆည်းထားသောကြောင့် သင့်စကားဝှက်ကို ပြန်လည်သတ်မှတ်မပေးနိုင်ပါ။ သင့်အကောင့်ကို ဖျက်ပစ်ပြီး အသစ်ပြန်ဖွင့်ချင်ပါသလား။\n\nသတိ - သင့်ကိုယ်ပိုင်အချက်အလက်များ၊ အဆက်အသွယ်များနှင့် မက်ဆေ့ချ်များအားလုံး အပြီးပျက်သွားပါလိမ့်မည်။</string>
|
||||
<string name="startup_failed_activity_title">Briar မစတင်နိုင်ပါ</string>
|
||||
<string name="startup_failed_clock_error">သင့်ကိရိယာ၏နာရီသည် မှားနေပါသဖြင့် Briar မစတင်နိုင်ပါ။\n\nသင့်ကိရိယာ၏နာရီကို အချိန်မှန်အောင်တိုက်ပြီး ပြန်စမ်းကြည့်ပါ။</string>
|
||||
<string name="startup_failed_db_error">Briar သည် သင့်အကောင့်၊ သင့်အဆက်အသွယ်များနှင့် သင့်မက်ဆေ့ချ်များပါရှိသော အချက်အလက်အစုကို မဖွင့်နိုင်ပါ။\n\nအက်ပ်နောက်ဆုံးဗားရှင်းသို့ အဆင့်မြှင့်ပြီး ထပ်စမ်းကြည့်ပါ (သို့) စကားဝှက်တောင်းသည့်နေရာတွင် \'ကျွန်ုပ်၏စကားဝှက်ကို မေ့သွားပါသည်\' ကို ရွေးချယ်ပြီး အကောင့်အသစ်တစ်ခု ဖွင့်နိုင်ပါသည်။</string>
|
||||
<string name="startup_failed_data_too_old_error">သင့်အကောင့်ကို ဤအက်ပ်၏ဗားရှင်းအဟောင်းတစ်ခုဖြင့် ဖွင့်ခဲ့သောကြောင့် ယခုဗားရှင်းဖြင့် ဖွင့်၍မရပါ။\n\nဗားရှင်းအဟောင်းကို ပြန်ထည့်သွင်းရပါမည် (သို့) စကားဝှက်တောင်းသည့်နေရာတွင် \'ကျွန်ုပ်၏စကားဝှက်ကို မေ့သွားပါသည်\' ကို ရွေးချယ်ပြီး အကောင့်အသစ်တစ်ခု ဖွင့်နိုင်ပါသည်။</string>
|
||||
<string name="startup_failed_data_too_new_error">သင့်အကောင့်ကို ဤအက်ပ်ဗားရှင်းထက်နောက်ကျသောဗားရှင်းတစ်ခုဖြင့် ဖွင့်ခဲ့သောကြောင့် ယခုဗားရှင်းဖြင့် ဖွင့်၍မရပါ။\n\nနောက်ဆုံးဗားရှင်းသို့ အဆင့်မြှင့်ပြီး ထပ်စမ်းကြည့်ပါ။</string>
|
||||
<string name="startup_failed_service_error">Briar သည် လိုအပ်သည့် အစိတ်အပိုင်းတစ်ခုကို မဖွင့်နိုင်ပါ။\n\nအက်ပ်နောက်ဆုံးဗားရှင်းသို့ အဆင့်မြှင့်ပြီး ထပ်စမ်းကြည့်ပါ။</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="other">ဤအရာသည် Briar ၏ စမ်းသပ်ဆဲဗားရှင်းဖြစ်ပါသည်။ သင့်အကောင့်သည် %d ရက်နေ့တွင် သက်တမ်းကုန်ဆုံးမည်ဖြစ်ပြီး သက်တမ်းတိုး၍မရနိုင်ပါ။</item>
|
||||
<item quantity="other">ဤအရာသည် Briar ၏ စမ်းသပ်ဆဲဗားရှင်းဖြစ်ပါသည်။ သင့်အကောင့်သည် %d ရက်ကြာလျှင် သက်တမ်းကုန်ဆုံးမည်ဖြစ်ပြီး သက်တမ်းတိုး၍မရနိုင်ပါ။</item>
|
||||
</plurals>
|
||||
<string name="expiry_date_reached">ဤဆော့ဖ်ဝဲသည် သက်တမ်းကုန်သွားပါပြီ။\nစမ်းသပ်အသုံးပြုခြင်းအတွက် ကျေးဇူးတင်ပါသည်။</string>
|
||||
<string name="download_briar">Briar ကို ဆက်လက်အသုံးပြုလိုပါက နောက်ဆုံးထွက်ထားသည်ကို ဒေါင်းလုဒ်လုပ်ပါ။</string>
|
||||
<string name="download_briar">Briar ကို ဆက်လက်အသုံးပြုရန် နောက်ဆုံးထွက်ထားသည်ကို ဒေါင်းလုဒ်လုပ်ပါ။</string>
|
||||
<string name="create_new_account">အကောင့်အသစ်ဖွင့်ရန် လိုအပ်သော်လည်း သုံးလက်စနာမည်ပြောင်ကို ဆက်သုံးနိုင်ပါသည်။</string>
|
||||
<string name="download_briar_button">နောက်ဆုံးထွက်ထားသည်ကို ဒေါင်းလုဒ်လုပ်မည်</string>
|
||||
<string name="startup_open_database">အချက်အလက်အစုကို ပြန်ဖြည်နေသည်…</string>
|
||||
@@ -637,6 +642,7 @@
|
||||
<string name="website_troubleshooting_title">အကူအညီ</string>
|
||||
<!--error handling-->
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_success_receive_text">ဤဖိုင်တွင်ပါဝင်သည့် လျှို့ဝှက်ကုဒ်ပြောင်းမက်ဆေ့ချ်အားလုံးကို လက်ခံရရှိပါပြီ။</string>
|
||||
<!--Screenshots-->
|
||||
<!--This is a name to be used in screenshots. Feel free to change it to a local name.-->
|
||||
<string name="screenshot_alice">Alice</string>
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
<string name="setup_huawei_text">Vă rugăm să apăsați butonul de mai jos și să vă asigurați că Briar este marcat ca protejat în fereastra de \"Aplicații protejate\".</string>
|
||||
<string name="setup_huawei_button">Protejează Briar</string>
|
||||
<string name="setup_huawei_help">Dacă Briar nu este adăugat în lista de aplicații protejate, nu va fi capabil să ruleze în fundal.</string>
|
||||
<string name="setup_huawei_app_launch_text">Vă rugăm să atingeți butonul de mai jos, să deschideți ecranul \"Lansare app\" și să vă asigurați că Briar este setat la \"Gestionare manuală\".</string>
|
||||
<string name="setup_huawei_app_launch_text">Vă rugăm să atingeți butonul de mai jos, să deschideți ecranul \"Lansare aplicație\" și să vă asigurați că Briar este setat la \"Gestionare manuală\".</string>
|
||||
<string name="setup_huawei_app_launch_button">Deschide setările de baterie</string>
|
||||
<string name="setup_huawei_app_launch_help">Dacă Briar nu este setat la \" Gestionare manuală\" în ecranul \"Lansare app\", nu va putea rula în fundal.</string>
|
||||
<string name="setup_huawei_app_launch_help">Dacă Briar nu este setat la \" Gestionare manuală\" în ecranul \"Lansare aplicație\", nu va putea rula în fundal.</string>
|
||||
<string name="setup_xiaomi_text">Pentru a funcționa în fundal, Briar trebuie să fie blocat în lista de aplicații recente.</string>
|
||||
<string name="setup_xiaomi_button">Protejează Briar</string>
|
||||
<string name="setup_xiaomi_help">Dacă Briar nu este blocat în lista de aplicații recente, acesta nu va putea rula în fundal.</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">1. Deschideți lista de aplicații recente (denumită și comutatorul de app-uri)\n\n2. Trageți cu degetul în jos pe imaginea lui Briar pentru a afișa pictograma lacătului\n\n\n3. Dacă lacătul nu este blocat, atingeți pentru a-l bloca</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">1. Deschideți lista de aplicații recente (denumită și comutatorul de app-uri)\n\n2. Țineți apăsată imaginea lui Briar până când apare butonul cu lacăt\n\n3. Dacă lacătul nu este blocat, apăsați pentru a-l bloca</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">1. Deschideți lista de aplicații recente (denumită și comutatorul de aplicații)\n\n2. Trageți cu degetul în jos pe imaginea lui Briar pentru a afișa pictograma lacătului\n\n3. Dacă lacătul nu este blocat, atingeți pentru a-l bloca</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">1. Deschideți lista de aplicații recente (denumită și comutatorul de aplicatii)\n\n2. Țineți apăsată imaginea lui Briar până când apare butonul cu lacăt\n\n3. Dacă lacătul nu este blocat, apăsați pentru a-l bloca</string>
|
||||
<string name="warning_dozed">%s nu poate rula în fundal</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">Parola</string>
|
||||
@@ -42,10 +42,10 @@
|
||||
<string name="dialog_message_lost_password">Contul dvs. Briar este stocat criptat pe dispozitiv, nu în cloud. Dacă vă uitați parola sau ștergeți Briar, nu veți putea să vă recuperați contul. Doriți să vă ștergeți contul și să începeți din nou?\n\nAtenție: identitățile, contactele și mesajele dvs. vor fi pierdute definitiv.</string>
|
||||
<string name="startup_failed_activity_title">Eroare de pornire Briar</string>
|
||||
<string name="startup_failed_clock_error">Briar nu a putut porni deoarece ceasul dispozitivului dvs. este greșit.\n\nVă rugăm să setați ceasul dispozitivului dvs. la ora corectă și să încercați din nou.</string>
|
||||
<string name="startup_failed_db_error">Briar nu a reușit să deschidă baza de date care conține contul dvs., contactele și mesajele dvs.\n\nVă rugăm să faceți upgrade la cea mai recentă versiune a app-ului și să încercați din nou, sau să configurați un cont nou alegând \"Mi-am uitat parola\" la solicitarea parolei.</string>
|
||||
<string name="startup_failed_data_too_old_error">Contul dvs. a fost creat cu o versiune veche a acestui app și nu poate fi deschis cu această versiune.\n\nTrebuie fie să reinstalați versiunea veche, fie să creați un cont nou alegând \"Mi-am uitat parola\" la solicitarea de parolă.</string>
|
||||
<string name="startup_failed_data_too_new_error">Contul dvs. a fost creat cu o versiune mai nouă a acestui app și nu poate fi deschis cu această versiune.\n\nVă rugăm să faceți upgrade la cea mai recentă versiune și să încercați din nou.</string>
|
||||
<string name="startup_failed_service_error">Briar nu a reușit să pornească o componentă necesară.\n\nVă rugăm să faceți upgrade la cea mai recentă versiune a acestui app și să încercați din nou.</string>
|
||||
<string name="startup_failed_db_error">Briar nu a reușit să deschidă baza de date care conține contul dvs., contactele și mesajele dvs.\n\nVă rugăm să faceți upgrade la cea mai recentă versiune a aplicației și să încercați din nou, sau să configurați un cont nou alegând \"Mi-am uitat parola\" la solicitarea parolei.</string>
|
||||
<string name="startup_failed_data_too_old_error">Contul dvs. a fost creat cu o versiune veche a acestei aplicații și nu poate fi deschis cu această versiune.\n\nTrebuie fie să reinstalați versiunea veche, fie să creați un cont nou alegând \"Mi-am uitat parola\" la solicitarea de parolă.</string>
|
||||
<string name="startup_failed_data_too_new_error">Contul dvs. a fost creat cu o versiune mai nouă a acestei aplicații și nu poate fi deschis cu această versiune.\n\nVă rugăm să faceți upgrade la cea mai recentă versiune și să încercați din nou.</string>
|
||||
<string name="startup_failed_service_error">Briar nu a reușit să pornească o componentă necesară.\n\nVă rugăm să faceți upgrade la cea mai recentă versiune a acestei aplicații și să încercați din nou.</string>
|
||||
<plurals name="expiry_warning">
|
||||
<item quantity="one">Aceasta este o versiune de test pentru Briar. Contul dumneavoastră va expira în %d zi și nu se poate reînnoi</item>
|
||||
<item quantity="few">Aceasta este o versiune de test pentru Briar. Contul dumneavoastră va expira în %d zile și nu se poate reînnoi.</item>
|
||||
@@ -325,9 +325,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Conectare prin Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_title">Conectare prin Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_intro">În cazul în care conexiunile Bluetooth nu funcționează automat, puteți utiliza acest ecran pentru a vă conecta manual.\n\nPersoana de contact trebuie să fie în apropiere pentru ca acest lucru să funcționeze.\n\nDumneavoastră și persoana de contact trebuie să apăsați \"Start\" în același timp.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Încercați deja să vă conectați prin Bluetooth. Vă rugăm să încercați din nou în scurt timp.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Nu se poate continua fără permisiunea locației</string>
|
||||
<string name="connect_via_bluetooth_start">Conectarea prin Bluetooth...</string>
|
||||
<string name="connect_via_bluetooth_success">Conectat cu succes prin Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">Nu s-a putut conecta prin Bluetooth.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Dispozitivul nu suportă Bluetooth.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">Nici un grup de arătat</string>
|
||||
<string name="groups_list_empty_action">Atingeți iconița + pentru a crea un grup sau rugați-vă contactele să partajele grupuri cu dumneavoastră</string>
|
||||
@@ -660,8 +664,8 @@ De asemenea, contactul dvs. poate modifica această setare pentru amândoi.</str
|
||||
<string name="transports_help_text">Briar se poate conecta la contactele dumneavoastră prin Internet, Wi-Fi sau Bluetooth.\n\nToate conexiunile la internet trec prin rețeaua Tor din motive de confidențialitate.\n\nDacă un contact poate fi accesat prin metode multiple, Briar le va folosi în mod paralel.</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">Partajează această aplicație fără Internet</string>
|
||||
<string name="hotspot_intro">Partajați această aplicație cu cineva din apropiere fără Internet folosind conexiunea Wi-Fi a dispozitivului.
|
||||
\n\nDispozitivul dumneavoastră va porni un hotspot Wi-Fi. Persoanele din apropiere se pot conecta la hotspot și pot descărca aplicația Briar de pe dispozitivul dumneavoastră.</string>
|
||||
<string name="hotspot_intro">Împărtășiți acest app cu o persoană din apropiere fără conexiune la internet, utilizând Wi-Fi-ul telefonului dumneavoastră.
|
||||
\n\nTelefonul dumneavoastră va porni un hotspot Wi-Fi. Persoanele din apropiere se pot conecta la hotspot și pot descărca aplicația Briar de pe telefonul vostru.</string>
|
||||
<string name="hotspot_button_start_sharing">Pornește hotspot</string>
|
||||
<string name="hotspot_button_stop_sharing">Oprește hotspot</string>
|
||||
<string name="hotspot_progress_text_start">Configurare hotspot...</string>
|
||||
@@ -702,6 +706,7 @@ De asemenea, contactul dvs. poate modifica această setare pentru amândoi.</str
|
||||
<string name="hotspot_help_wifi_title">Probleme la conectarea Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Încercați să dezactivați și să reactivați Wi-Fi pe ambele dispozitive și reîncercați.</string>
|
||||
<string name="hotspot_help_wifi_2">Dacă dispozitivul se plânge că nu este accesibil Internetul prin Wi-Fi, spuneți-i că doriți să rămână conectat oricum.</string>
|
||||
<string name="hotspot_help_wifi_3">Reporniți telefonul pe care rulează hotspotul Wi-Fi, apoi porniți Briar și încercați din nou distribuirea.</string>
|
||||
<string name="hotspot_help_site_title">Problemă la vizitarea siteului local:</string>
|
||||
<string name="hotspot_help_site_1">Verificați că ați introdus adresa exact cum este afișată. O mică eroare poate să o facă să eșueze.</string>
|
||||
<string name="hotspot_help_site_2">Asigurați-vă că dispozitivul este încă conectat la Wi-Fi-ul corect (vedeți mai sus) când încercați să accesați siteul.</string>
|
||||
@@ -722,6 +727,9 @@ De asemenea, contactul dvs. poate modifica această setare pentru amândoi.</str
|
||||
<string name="hotspot_flag_test">Atenție: Această aplicație a fost instalată din Android Studio și NU poate fi instalată pe un alt dispozitiv.</string>
|
||||
<string name="hotspot_error_framework_busy">Nu s-a putut porni hotspotul.\n\nDacă aveți alt hotspot pornit sau dacă partajați conexiunea la Internet prin Wi-Fi, încercați să opriți asta și să reîncercați apoi.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Conectare prin intermediul unei unități detașabile</string>
|
||||
<string name="removable_drive_intro">Dacă nu vă puteți conecta la persoana de contact prin intermediul Internetului, Wi-Fi sau Bluetooth, Briar poate, de asemenea, transfera mesaje pe o unitate detașabilă, cum ar fi un stick USB sau un card SD.</string>
|
||||
<string name="removable_drive_explanation">Dacă nu vă puteți conecta la persoana de contact prin Internet, Wi-Fi sau Bluetooth, Briar poate transfera mesaje și pe o unitate detașabilă, cum ar fi un stick USB sau un card SD.\n\nCând folosiți butonul \"Trimite date\", orice date care așteaptă să fie trimise contactului vor fi scrise pe unitatea detașabilă. Aceasta include mesaje private, atașamente, bloguri, forumuri și grupuri private.\n\nToate vor fi criptate înainte de a fi scrise pe unitatea detașabilă.\n\nCând persoana de contact primește unitatea detașabilă, poate folosi butonul \"Primește date\" pentru a importa mesajele în Briar.</string>
|
||||
<string name="removable_drive_title_send">Trimiteți date</string>
|
||||
<string name="removable_drive_title_receive">Primiți date</string>
|
||||
<string name="removable_drive_send_intro">Atingeți butonul de mai jos pentru a crea un nou fișier care conține mesajele criptate. Puteți alege unde va fi salvat fișierul.\n\nDacă doriți să salvați fișierul pe o unitate detașabilă, introduceți unitatea acum.</string>
|
||||
@@ -736,7 +744,7 @@ De asemenea, contactul dvs. poate modifica această setare pentru amândoi.</str
|
||||
<string name="removable_drive_success_receive_title">Importat cu succes</string>
|
||||
<string name="removable_drive_success_receive_text">Toate mesajele criptate conținute în acest fișier au fost primite.</string>
|
||||
<string name="removable_drive_error_send_title">Eroare la exportul de date</string>
|
||||
<string name="removable_drive_error_send_text">A avut loc o eroare de scriere a datelor în fișier.\n\nDacă utilizați o unitate detașabilă, asigurați-vă că aceasta este introdusă corect și încercați din nou.\n\n\nDacă eroarea persistă, vă rugăm să trimiteți feedback pentru a informa echipa Briar despre problemă.</string>
|
||||
<string name="removable_drive_error_send_text">A avut loc o eroare de scriere a datelor în fișier.\n\nDacă utilizați o unitate detașabilă, asigurați-vă că aceasta este introdusă corect și încercați din nou.\n\nDacă eroarea persistă, vă rugăm să trimiteți feedback pentru a informa echipa Briar despre problemă.</string>
|
||||
<string name="removable_drive_error_receive_title">Eroare la importul de date</string>
|
||||
<string name="removable_drive_error_receive_text">Fișierul selectat nu conține nimic care să poată fi recunoscut de Briar.\n\nVă rugăm să verificați dacă ați ales fișierul corect.\n\nDacă persoana de contact a creat fișierul cu mai mult de 28 de zile în urmă, Briar nu îl va putea recunoaște.</string>
|
||||
<!--Screenshots-->
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
<string name="setup_huawei_app_launch_text">Пожалуйста, нажмите кнопку ниже, откройте экран \"Запуск приложения\" и убедитесь, что для Briar установлено значение \"Управлять вручную\".</string>
|
||||
<string name="setup_huawei_app_launch_button">Открыть настройки батареи</string>
|
||||
<string name="setup_huawei_app_launch_help">Если для Briar не установлено значение \"Управлять вручную\" на экране \"Запуск приложения\", он не сможет работать в фоновом режиме.</string>
|
||||
<string name="setup_xiaomi_text">Для работы в фоновом режиме Briar должен быть заблокирован в списке недавних приложений.</string>
|
||||
<string name="setup_xiaomi_text">Для работы в фоновом режиме Briar должен быть закреплен в списке недавних приложений.</string>
|
||||
<string name="setup_xiaomi_button">Защитить Briar</string>
|
||||
<string name="setup_xiaomi_help">Если Briar не заблокирован в списке последних приложений, он не сможет работать в фоновом режиме.</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">1. Откройте список недавних приложений (также называемый переключателем приложений)\n\n2. Смахните вниз изображение Briar, чтобы появился значок замка\n\n3. Если замок не заблокирован, нажмите на него для блокировки.</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">1. Откройте список недавних приложений (также называемый переключателем приложений)\n\n2. Нажмите и удерживайте изображение Briar, пока не появится кнопка с замком\n\n3. Если замок не заблокирован, нажмите на него для блокировки.</string>
|
||||
<string name="setup_xiaomi_help">Если Briar не закреплен в списке последних приложений, он не сможет работать в фоновом режиме.</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">1. Откройте список недавних приложений (иначе называемый переключателем приложений)\n\n2. Смахните вниз изображение Briar, чтобы появился значок замка\n\n3. Если замок не закреплен, нажмите на него для закрепления.</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">1. Откройте список недавних приложений (иначе называемый переключателем приложений)\n\n2. Нажмите и удерживайте изображение Briar, пока не появится кнопка с замком\n\n3. Если замок не закреплен, нажмите на него для закрепления.</string>
|
||||
<string name="warning_dozed">%s не удалось выполнить в фоновом режиме</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">Пароль</string>
|
||||
@@ -334,9 +334,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Подключение через Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_title">Подключение через Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_intro">Если соединение Bluetooth не устанавливается автоматически, вы можете использовать этот экран для подключения вручную.\n\nДля этого ваш собеседник должен находиться рядом.\n\nВы и ваш собеседник должны одновременно нажать кнопку \'Начать\'.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Пытаемся подключиться через Bluetooth. Пожалуйста, повторите попытку в ближайшее время.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Невозможно продолжить без доступа к местоположению</string>
|
||||
<string name="connect_via_bluetooth_start">Подключение через Bluetooth...</string>
|
||||
<string name="connect_via_bluetooth_success">Успешное подключение через Bluetooth</string>
|
||||
<string name="connect_via_bluetooth_error">Не удалось подключиться через Bluetooth.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Bluetooth не поддерживается устройством.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">Нет групп для отображения</string>
|
||||
<string name="groups_list_empty_action">Для создания группы нажмите значок + или попросите ваши контакты поделиться с вами группами</string>
|
||||
@@ -716,6 +720,7 @@
|
||||
<string name="hotspot_help_wifi_title">Проблемы с подключением к Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Попробуйте отключить и снова включить Wi-Fi на обоих телефонах и повторить попытку.</string>
|
||||
<string name="hotspot_help_wifi_2">Если ваш телефон сообщит, что в сети Wi-Fi нет доступа к интернету, подтвердите, что вы все равно хотите подключиться к этой сети.</string>
|
||||
<string name="hotspot_help_wifi_3">Перезагрузите телефон, на котором работает точка доступа Wi-Fi, затем запустите Briar и повторите попытку обмена.</string>
|
||||
<string name="hotspot_help_site_title">Проблемы с доступом к локальному веб-сайту:</string>
|
||||
<string name="hotspot_help_site_1">Дважды убедитесь, что вы ввели адрес точно так, как показано. Небольшая ошибка может привести к сбою.</string>
|
||||
<string name="hotspot_help_site_2">Убедитесь, что ваш телефон все еще подключен к правильной сети Wi-Fi (см. выше), прежде чем попытаться зайти на этот сайт.</string>
|
||||
@@ -736,6 +741,9 @@
|
||||
<string name="hotspot_flag_test">Предупреждение: Это приложение было установлено с помощью Android Studio и НЕ может быть установлено на другое устройство.</string>
|
||||
<string name="hotspot_error_framework_busy">Невозможно запустить точку доступа.\n\nЕсли у вас запущена другая точка доступа или вы используете подключение к интернету через Wi-Fi, попробуйте отключить его, а затем повторить попытку.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Подключиться через съемный носитель</string>
|
||||
<string name="removable_drive_intro">Если вы не можете подключиться к контакту через интернет, Wi-Fi или Bluetooth, Briar также может передавать сообщения на съемном носителе, таком как USB-накопитель или SD-карта.</string>
|
||||
<string name="removable_drive_explanation">Если вы не можете подключиться к контакту через интернет, Wi-Fi или Bluetooth, Briar также может передавать сообщения на съемном носителе, таком как USB-накопитель или SD-карта.\n\n\nКогда вы используете кнопку \"Отправить данные\", все данные, которые ожидают отправки контакту, будут записаны на съемный носитель. Сюда входят личные сообщения, вложения, блоги, форумы и личные группы.\n\n\nВсе данные будут зашифрованы перед записью.\n\n\nКогда ваш собеседник получит съемный носитель, он может воспользоваться кнопкой \"Получить данные\", чтобы импортировать сообщения в Briar.</string>
|
||||
<string name="removable_drive_title_send">Отправить данные</string>
|
||||
<string name="removable_drive_title_receive">Принять данные</string>
|
||||
<string name="removable_drive_send_intro">Нажмите кнопку ниже, чтобы создать новый файл, содержащий зашифрованные сообщения. Вы сможете выбрать, где будет сохранен этот файл.\n\nЕсли вы хотите сохранить файл на съемном диске, вставьте диск сейчас.</string>
|
||||
|
||||
@@ -610,6 +610,7 @@ Këtë rregullim mund ta ndryshojë edhe kontakti juaj, për të dy ju.</string>
|
||||
<string name="dev_report_memory">Kujtesë</string>
|
||||
<string name="dev_report_storage">Depozitim</string>
|
||||
<string name="dev_report_connectivity">Aftësi lidhjeje</string>
|
||||
<string name="dev_report_network_usage">Përdorim rrjeti</string>
|
||||
<string name="dev_report_build_config">Formësim montimi</string>
|
||||
<string name="dev_report_logcat">Regjistër aplikacioni</string>
|
||||
<string name="dev_report_device_features">Veçori Pajisjeje</string>
|
||||
@@ -696,6 +697,7 @@ Briar-i i përdor ato paralelisht.</string>
|
||||
<string name="hotspot_help_wifi_title">Probleme me lidhjen me Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Provoni çaktivizimin dhe riaktivizimin e Wi-Fi-it në të dy telefonat dhe riprovoni.</string>
|
||||
<string name="hotspot_help_wifi_2">Nëse telefoni juaj ankohet se Wi-Fi s’ka internet, i thoni se dëshironi të jeni i lidhur sido qoftë.</string>
|
||||
<string name="hotspot_help_wifi_3">Rinisni telefonin që xhiron hotspot-in Wi-Fi, mandej rinisni Briar-in dhe riprovoni ta jepni lidhjen.</string>
|
||||
<string name="hotspot_help_site_title">Probleme në vizita të sajtit vendor:</string>
|
||||
<string name="hotspot_help_site_1">Rikontrolloni se e keni dhënë adresën saktësisht siç shfaqet. Një gabim i vockël mund të bëjë të dështojë.</string>
|
||||
<string name="hotspot_help_site_2">Sigurohuni se telefoni juaj është ende i lidhur me Wi-Fi e duhur (shihni më sipër), kur provoni të hyni te sajti.</string>
|
||||
@@ -716,6 +718,9 @@ Briar-i i përdor ato paralelisht.</string>
|
||||
<string name="hotspot_flag_test">Kujdes: Ky aplikacion qe instaluar me Android Studio dhe NUK mund të instalohet në një pajisje tjetër.</string>
|
||||
<string name="hotspot_error_framework_busy">S’arrihet të niset hotspot-i.\n\nNëse keni një tjetër hotspot në punë, ose e jepni lidhjen tuaj Internet përmes Wi-Fi, provoni ta ndalni dhe të riprovoni pas kësaj.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Lidhu përmes Disku të Heqshëm</string>
|
||||
<string name="removable_drive_intro">Nëse s’lidheni dot me kontaktin tuaj përmes Interneti, Wi-Fi apo Bluetooth-i, Briar-i mund të shpërngulë mesazhe edhe përmes disqesh të heqshëm, bie fjala një diskth USB, ose një kartë SD.</string>
|
||||
<string name="removable_drive_explanation">Nëse s’lidheni dot me kontaktin tuaj përmes Interneti, Wi-Fi apo Bluetooth-i, Briar-i mund të shpërngulë mesazhe edhe përmes disqesh të heqshëm, bie fjala një diskth USB, ose një kartë SD.\n\nKur përdorni butonin “Dërgo të Dhëna”, çfarëdo të dhënash që po presin të dërgohen te kontakti, do të shkruhen te disku i heqshëm. Kjo përfshin mesazhe privates, bashkëngjitje, blogje, forume dhe grupe private.\n\nPara se të shkruhet te disku i heqshëm, gjithçka do të fshehtëzohet.\n\nKur kontakti juaj merr diskun e heqshëm, ai mund të përdorë butonin “Merr të Dhëna” që të importoni mesazhet në Briar.</string>
|
||||
<string name="removable_drive_title_send">Dërgoni të dhëna</string>
|
||||
<string name="removable_drive_title_receive">Merrni të dhëna</string>
|
||||
<string name="removable_drive_send_intro">Prekni butonin më poshtë që të krijoni një kartelë të re që përmban mesazhe të fshehtëzuar. Mund të zgjidhni ku të ruhen kartelat.\n\nNëse doni të ruhet kartela në një disk të heqshëm, futeni diskun tani.</string>
|
||||
|
||||
@@ -316,9 +316,13 @@
|
||||
<!--Connect via Bluetooth-->
|
||||
<string name="menu_item_connect_via_bluetooth">Bluetooth ile Bağlan</string>
|
||||
<string name="connect_via_bluetooth_title">Bluetooth ile Bağlan</string>
|
||||
<string name="connect_via_bluetooth_intro">Bluetooth bağlantıları otomatik olarak çalışmadığında, elle bağlanmak için bu ekranı kullanabilirsiniz.\n\nBunun çalışması için kişinin yakınınızda olması gerekiyor.\n\nSizin ve kişinin aynı anda \"Başlat\" seçeneğine basması gerekiyor.</string>
|
||||
<string name="connect_via_bluetooth_already_discovering">Bluetooth ile zaten bağlanmaya çalışıyor. Lütfen daha sonra tekrar deneyin.</string>
|
||||
<string name="connect_via_bluetooth_no_location_permission">Konum izni olmadan devam edilemez</string>
|
||||
<string name="connect_via_bluetooth_start">Bluetooth ile bağlanılıyor…</string>
|
||||
<string name="connect_via_bluetooth_success">Bluetooth ile başarılı bir şekilde bağlandı</string>
|
||||
<string name="connect_via_bluetooth_error">Bluetooth ile bağlanamıyor.</string>
|
||||
<string name="connect_via_bluetooth_error_not_supported">Bluetooth aygıt tarafından desteklemiyor.</string>
|
||||
<!--Private Groups-->
|
||||
<string name="groups_list_empty">Gösterilecek grup yok</string>
|
||||
<string name="groups_list_empty_action">Bir grup oluşturmak için + simgesine dokunun veya kişilerinizden grupları sizinle paylaşmasını isteyin</string>
|
||||
@@ -605,6 +609,7 @@
|
||||
<string name="dev_report_memory">Bellek</string>
|
||||
<string name="dev_report_storage">Depo</string>
|
||||
<string name="dev_report_connectivity">Bağlanabilirlik</string>
|
||||
<string name="dev_report_network_usage">Ağ Kullanımı</string>
|
||||
<string name="dev_report_build_config">Derleme yapılandırması</string>
|
||||
<string name="dev_report_logcat">Uygulama günlüğü</string>
|
||||
<string name="dev_report_device_features">Aygıt Seçenekleri</string>
|
||||
@@ -688,6 +693,7 @@
|
||||
<string name="hotspot_help_wifi_title">Kablosuz ağa bağlanma sorunları:</string>
|
||||
<string name="hotspot_help_wifi_1">Her iki telefonda da kablosuz ağı devre dışı bırakıp tekrar etkinleştirin ve yeniden deneyin.</string>
|
||||
<string name="hotspot_help_wifi_2">Eğer telefonunuz kablosuz ağda İnternet olmadığını söylüyorsa yine de bağlı kalmasını söyleyin.</string>
|
||||
<string name="hotspot_help_wifi_3">Wi-Fi bağlantı noktasını sağlayan telefonu yeniden başlatın, daha sonra Briar\'ı başlatın ve paylaşmayı yeniden deneyin.</string>
|
||||
<string name="hotspot_help_site_title">Yerel web sitesini ziyaret etme sorunları:</string>
|
||||
<string name="hotspot_help_site_1">Adresi tam gösterildiği şekilde girdiğinizden emin olun. Çok küçük bir hata sorun olabilir.</string>
|
||||
<string name="hotspot_help_site_2">Siteye erişmeye çalışırken telefonunuzun doğru kablosuz ağa bağlı olduğundan emin olun (Bkz. önceki kısım).</string>
|
||||
@@ -708,6 +714,9 @@
|
||||
<string name="hotspot_flag_test">Uyarı: Bu uygulama Android Studio ile kurulduğu için başka bir aygıta kurulamaz.</string>
|
||||
<string name="hotspot_error_framework_busy">Erişim noktası başlatılamıyor.\n\nEğer başka bir erişim noktası çalışıyorsa veya İnternet bağlantınızı kablosuz üzerinden paylaşıyorsanız, lütfen önce onu durdurun ve sonra yeniden deneyin.</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">Çıkarılabilir Sürücü ile Bağlan</string>
|
||||
<string name="removable_drive_intro">Eğer İnternet, Wi-Fi veya Bluetooth ile bağlanamıyorsanız, Briar iletileri USB bellek veya hafıza kart gibi çıkarılabilir sürücüyle de aktarabilir.</string>
|
||||
<string name="removable_drive_explanation">Eğer İnternet, Wi-Fi veya Bluetooth ile bağlanamıyorsanız, Briar iletileri USB bellek veya hafıza kart gibi çıkarılabilir sürücüyle de aktarabilir.\n\n\"Veri Gönder\" düğmesini kullandığınızda, kişilere gönderilmeyi bekleyen herhangi bir veri çıkarılabilir sürücüye yazılacaktır. Bu özel iletileri, ekleri, blogları, forumları ve özel grupları içerir.\n\nÇıkarılabilir sürücüye kaydedilmeden önce her şey şifrelenecektir.\n\nKişiler çıkarılabilir sürücüyü aldığında, \"Veri Al\" düğmesini kullanarak iletileri Briar\'a aktarabilir.</string>
|
||||
<string name="removable_drive_title_send">Veri gönder</string>
|
||||
<string name="removable_drive_title_receive">Veri al</string>
|
||||
<string name="removable_drive_send_intro">Şifreli iletileri içeren yeni bir dosya oluşturmak için aşağıdaki düğmeye dokunun. Dosyanın kaydedileceği yeri seçebilirsiniz.\n\nEğer dosyayı taşınabilir bir sürücüye saklamak istiyorsanız, sürücüyü şimdi takın.</string>
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
<string name="setup_xiaomi_text">要在后台运行,需将 Briar 锁定在最近的应用列表中。</string>
|
||||
<string name="setup_xiaomi_button">保护 Briar</string>
|
||||
<string name="setup_xiaomi_help">如果未将 Briar 锁定到最近的应用列表,它将无法在后台运行。</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">1. 打开最近的应用列表(也称为应用切换器)\n\n2. 向下滑动Briar的图像,显示挂锁图标\n\n3.如果挂锁没有被锁上,轻敲以锁定它</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">1. 打开最近的应用列表(也称为应用切换器)\n\n2. 按住Briar的图像,直到挂锁按钮出现\n\n3. 如果挂锁没有被锁上,轻敲以锁定它</string>
|
||||
<string name="setup_xiaomi_dialog_body_old">1. 打开最近的应用列表(也称为应用切换器)\n\n2. 向下滑动 Briar 的图像,显示挂锁图标\n\n3.如果挂锁没有被锁上,轻按锁定它</string>
|
||||
<string name="setup_xiaomi_dialog_body_new">1. 打开最近的应用列表(也称为应用切换器)\n\n2. 按住 Briar 的图像,直到挂锁按钮出现\n\n3. 如果挂锁没有被锁上,轻按锁定它</string>
|
||||
<string name="warning_dozed">%s 无法在后台运行</string>
|
||||
<!--Login-->
|
||||
<string name="enter_password">密码</string>
|
||||
@@ -170,7 +170,7 @@
|
||||
<item quantity="other">%d分钟</item>
|
||||
</plurals>
|
||||
<plurals name="duration_hours">
|
||||
<item quantity="other">%d小时消</item>
|
||||
<item quantity="other">%d小时</item>
|
||||
</plurals>
|
||||
<plurals name="duration_days">
|
||||
<item quantity="other">%d天</item>
|
||||
@@ -596,6 +596,7 @@
|
||||
<string name="dev_report_memory">内存</string>
|
||||
<string name="dev_report_storage">存储</string>
|
||||
<string name="dev_report_connectivity">连通性</string>
|
||||
<string name="dev_report_network_usage">网络使用</string>
|
||||
<string name="dev_report_build_config">编译配置</string>
|
||||
<string name="dev_report_logcat">应用程序日志</string>
|
||||
<string name="dev_report_device_features">设备特性</string>
|
||||
@@ -638,8 +639,8 @@
|
||||
<string name="transports_help_text">Briar 可以通过互联网、Wi-Fi 或蓝牙来连接到您的联系人。\n\n为了保护隐私,本应用会通过 Tor 网络进行所有的互联网连接。\n\n如果一个联系人可以通过多种方法联系到,Briar 会并行地使用它们。</string>
|
||||
<!--Share app offline-->
|
||||
<string name="hotspot_title">离线分享此应用</string>
|
||||
<string name="hotspot_intro">使用手机的Wi-Fi与附近没有网络的人分享这款应用。
|
||||
\n\n你的手机会启动一个 Wi-Fi 热点。附近的人可以连接热点,从你的手机下载 Briar 应用。</string>
|
||||
<string name="hotspot_intro">使用手机的 Wi-Fi 与附近没有网络的人分享这款应用。
|
||||
\n\n你的手机将启动一个 Wi-Fi 热点。附近的人可以连接至这个热点,从你的手机下载 Briar 应用。</string>
|
||||
<string name="hotspot_button_start_sharing">启动热点</string>
|
||||
<string name="hotspot_button_stop_sharing">停止热点</string>
|
||||
<string name="hotspot_progress_text_start">设置热点中…</string>
|
||||
@@ -680,6 +681,7 @@
|
||||
<string name="hotspot_help_wifi_title">连接 Wi-Fi 出现问题:</string>
|
||||
<string name="hotspot_help_wifi_1">尝试禁用和重新启用这两部手机的 Wi-Fi,然后再试一次。</string>
|
||||
<string name="hotspot_help_wifi_2">如果你的手机抱怨 Wi-Fi 没有网络,告诉它无论如何你都想保持连接。</string>
|
||||
<string name="hotspot_help_wifi_3">重启正在运行 Wi-Fi 热点的手机,然后启动 Briar 并再次尝试共享。</string>
|
||||
<string name="hotspot_help_site_title">访问本地网站出现问题:</string>
|
||||
<string name="hotspot_help_site_1">再次检查您输入的地址是否完全和所显示的一样。一个小的错误就可能导致失败。</string>
|
||||
<string name="hotspot_help_site_2">当你尝试访问网站时,确保你的手机仍然连接到正确的 Wi-Fi (见上文)。</string>
|
||||
@@ -700,6 +702,9 @@
|
||||
<string name="hotspot_flag_test">警告:此应用程序通过 Android Studio 安装,不能安装在其他设备上</string>
|
||||
<string name="hotspot_error_framework_busy">无法启动热点。\n\n如果您有另一个热点正在运行或通过 Wi-Fi 共享您的互联网连接,尝试停止它稍后再试一次。</string>
|
||||
<!--Transfer Data via Removable Drives-->
|
||||
<string name="removable_drive_menu_title">通过可移动驱动器连接</string>
|
||||
<string name="removable_drive_intro">如果你无法通过互联网、Wi-Fi 或蓝牙连接到你的联系人,Briar 还可以通过U 盘或 SD 卡等可移动驱动器传输信息。</string>
|
||||
<string name="removable_drive_explanation">如果你无法通过互联网、Wi-Fi 或蓝牙连接到你的联系人,Briar 还可以通过U 盘或 SD 卡等可移动驱动器传输信息。\n\n当您使用“发送数据”按钮时,任何等待发送到联系人的数据将被写入可移动驱动器。这包括私人消息、附件、博客、论坛和私人群组。\n\n在写入移动驱动器之前,所有内容都将被加密。\n\n当您的联系人收到可移动驱动器时,他们可以使用“接收数据”按钮将消息导入 Briar。</string>
|
||||
<string name="removable_drive_title_send">发送数据</string>
|
||||
<string name="removable_drive_title_receive">接收数据</string>
|
||||
<string name="removable_drive_send_intro">轻按下面的按钮创建一个包含加密消息的新文件。您可以选择将文件保存在哪里。\n\n如果您想将文件保存在可移动驱动器上,请立即插入驱动器。</string>
|
||||
|
||||
@@ -649,6 +649,7 @@
|
||||
<string name="dev_report_memory">Memory</string>
|
||||
<string name="dev_report_storage">Storage</string>
|
||||
<string name="dev_report_connectivity">Connectivity</string>
|
||||
<string name="dev_report_network_usage">Network usage</string>
|
||||
<string name="dev_report_build_config">Build configuration</string>
|
||||
<string name="dev_report_logcat">App log</string>
|
||||
<string name="dev_report_device_features">Device Features</string>
|
||||
@@ -697,7 +698,7 @@
|
||||
|
||||
<!-- Share app offline -->
|
||||
<string name="hotspot_title">Share this app offline</string>
|
||||
<string name="hotspot_intro">Share this app with someone nearby without Internet connection by using your phone\'s Wi-Fi.
|
||||
<string name="hotspot_intro">Share this app with someone nearby without an Internet connection by using your phone\'s Wi-Fi.
|
||||
\n\nYour phone will start a Wi-Fi hotspot. People nearby can connect to the hotspot and download the Briar app from your phone.</string>
|
||||
<string name="hotspot_button_start_sharing">Start hotspot</string>
|
||||
<string name="hotspot_button_stop_sharing">Stop hotspot</string>
|
||||
@@ -744,6 +745,7 @@
|
||||
<string name="hotspot_help_wifi_title">Problems with connecting to Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Try disabling and re-enabling Wi-Fi on both phones and try again.</string>
|
||||
<string name="hotspot_help_wifi_2">If your phone complains that the Wi-Fi has no Internet, tell it that you want to stay connected anyway.</string>
|
||||
<string name="hotspot_help_wifi_3">Restart the phone which is running the Wi-Fi hotspot, then start Briar and try sharing again.</string>
|
||||
<string name="hotspot_help_site_title">Problems visiting the local website:</string>
|
||||
<string name="hotspot_help_site_1">Double check that you entered the address exactly as shown. A small error can make it fail.</string>
|
||||
<string name="hotspot_help_site_2">Ensure that your phone is still connected to the correct Wi-Fi (see above) when you try to access the site.</string>
|
||||
|
||||
@@ -71,41 +71,41 @@ dependencyVerification {
|
||||
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
|
||||
'classworlds:classworlds:1.1-alpha-2:classworlds-1.1-alpha-2.jar:2bf4e59f3acd106fea6145a9a88fe8956509f8b9c0fdd11eb96fee757269e3f3',
|
||||
'com.almworks.sqlite4java:sqlite4java:0.282:sqlite4java-0.282.jar:9e1d8dd83ca6003f841e3af878ce2dc7c22497493a7bb6d1b62ec1b0d0a83c05',
|
||||
'com.android.tools.analytics-library:protos:27.1.3:protos-27.1.3.jar:0d9e6cff60b318baac250b6f5bb076a8161103338bf2749cdf1db8a5a13a1f12',
|
||||
'com.android.tools.analytics-library:shared:27.1.3:shared-27.1.3.jar:10d2a51d8f89ff4ac849888e5a9c60b10e879c30d78545ec1da4d3df7bd56ae4',
|
||||
'com.android.tools.analytics-library:tracker:27.1.3:tracker-27.1.3.jar:589b355a2ba796cbc0a2b2295737de6661f078262e5f87cd6f540b8d011e5ebb',
|
||||
'com.android.tools.analytics-library:protos:30.0.3:protos-30.0.3.jar:f62b89dcd9de719c6a7b7e15fb1dd20e45b57222e675cf633607bd0ed6bca7e7',
|
||||
'com.android.tools.analytics-library:shared:30.0.3:shared-30.0.3.jar:05aa9ba3cc890354108521fdf99802565aae5dd6ca44a6ac8bb8d594d1c1cd15',
|
||||
'com.android.tools.analytics-library:tracker:30.0.3:tracker-30.0.3.jar:5d0ef35bf6733e96210b5085a2a202152921bf834d345959dce1ca3369b528df',
|
||||
'com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524:aapt2-proto-4.1.0-alpha01-6193524.jar:17e75523e1e92dd4f222c7368ee41df9e964a508232f591e265d0c499baf9dca',
|
||||
'com.android.tools.build:apksig:4.1.3:apksig-4.1.3.jar:a851980c678ff7a6785388b9a9e8cc094788ce3c4a985ad2b19c2028fd3c631a',
|
||||
'com.android.tools.build:apkzlib:4.1.3:apkzlib-4.1.3.jar:475903065e7e83a8c1ba78d267c97a54dc5a04d768b535093850423d7b11f2c8',
|
||||
'com.android.tools.build:builder-model:4.1.3:builder-model-4.1.3.jar:2624a1436c3ab39dd91d3ecf9409a594b0f89ea5cab255f2e9ff11f5ee03d274',
|
||||
'com.android.tools.build:builder-test-api:4.1.3:builder-test-api-4.1.3.jar:3d2af66726b06b53b8d6d497efcee39ff9f77eb2f8d2cce38b31502383a40d2c',
|
||||
'com.android.tools.build:builder:4.1.3:builder-4.1.3.jar:a40426cd6d68f6a722ef4950058c075e4547025e8c2fd78e732ad89f15176f84',
|
||||
'com.android.tools.build:gradle-api:4.1.3:gradle-api-4.1.3.jar:11b1fb9de658bdcf9290b1c1517060d0c4d93f2b27975934989ca4ac890bc077',
|
||||
'com.android.tools.build:manifest-merger:27.1.3:manifest-merger-27.1.3.jar:ce8d4009b1f1584777a7ffa1da3b0551dc316bc8e08112e442c352af70f46f2d',
|
||||
'com.android.tools.ddms:ddmlib:27.1.3:ddmlib-27.1.3.jar:8f76e8236d2b9eebf26378746dad025c4c7c056a02e133dae4ddef47b283c710',
|
||||
'com.android.tools.external.com-intellij:intellij-core:27.1.3:intellij-core-27.1.3.jar:652814fa099b4746fb6f10e19718e476952e8b5bac24e17d914f90650ad21808',
|
||||
'com.android.tools.external.com-intellij:kotlin-compiler:27.1.3:kotlin-compiler-27.1.3.jar:8d7a78d5efd213c5e467e42bd205582aad73ffc77ee5dc18eb1361c9af72f125',
|
||||
'com.android.tools.external.org-jetbrains:uast:27.1.3:uast-27.1.3.jar:aea53944a1ac6a05f12297b55290e8cbecfe54c4166260cfba4405823bfe1c78',
|
||||
'com.android.tools.layoutlib:layoutlib-api:27.1.3:layoutlib-api-27.1.3.jar:23875ce0a8429f33a4e86cc358f658faa0ba9c576f5f05760e544b453d67d04b',
|
||||
'com.android.tools.lint:lint-api:27.1.3:lint-api-27.1.3.jar:97666be32bcadacd944416ea334a9575ef8f4ad0c8f333151491ff4a7df43e1c',
|
||||
'com.android.tools.lint:lint-checks:27.1.3:lint-checks-27.1.3.jar:b2d71ae84a31490fe9ff26c706163fe245b2aea98e3eb747214c1085df444708',
|
||||
'com.android.tools.lint:lint-gradle-api:27.1.3:lint-gradle-api-27.1.3.jar:e54131c287a2954e6ed78a3351e5e10e35a1da2f09ac443bf44b705c71b63a4d',
|
||||
'com.android.tools.lint:lint-gradle:27.1.3:lint-gradle-27.1.3.jar:6a79e48943649d63665db7b17dbaff7af93e94ab9b15072f1a4d90486294ee9f',
|
||||
'com.android.tools.lint:lint-model:27.1.3:lint-model-27.1.3.jar:acb9e792db7000e38e3c3ca21a9b14f2de6549d7a3fc92a97ffba3d06345e5bf',
|
||||
'com.android.tools.lint:lint:27.1.3:lint-27.1.3.jar:5a2e69d0901a3a476a5b2d5001de755868113145f5f6aa557750cfad5389a44b',
|
||||
'com.android.tools:annotations:27.1.3:annotations-27.1.3.jar:904dd771883496d5dfc86619ab2555968ea4e8a29d7a5f4f7cae6fbf5429f8f5',
|
||||
'com.android.tools:common:27.1.3:common-27.1.3.jar:17ab4728e3ea50f047dd5937f0faf35f2c5416962ed74891057087ddc328bf96',
|
||||
'com.android.tools:dvlib:27.1.3:dvlib-27.1.3.jar:cead1c0c356cbe43e6855b0330fe09ef4bec2c72e22bdb4c6e7cf7e6b1dfbc37',
|
||||
'com.android.tools:repository:27.1.3:repository-27.1.3.jar:99de1a178855b56b8cd91a56296f1e0a9399c445e6acc51f1d2927947cc472cb',
|
||||
'com.android.tools:sdk-common:27.1.3:sdk-common-27.1.3.jar:b591e2aa0f1be600795f5c9e2bf81cba9b052bee452fc86c3362b5dd9e427a14',
|
||||
'com.android.tools:sdklib:27.1.3:sdklib-27.1.3.jar:ad6c08a45fe2904d05656bdddf9f623fa5c1d16bbd7b8d6a270a0734136ae02e',
|
||||
'com.android:signflinger:4.1.3:signflinger-4.1.3.jar:f3103b55ccdc8dd9ee2517eb26af93b904d41303726594372d0df59d51156e5c',
|
||||
'com.android:zipflinger:4.1.3:zipflinger-4.1.3.jar:48569896c0497268308a8014c66eb0f2bace2b9e2fc9390f3012823fb86387d5',
|
||||
'com.android.tools.build:apksig:7.0.3:apksig-7.0.3.jar:012337a2803c9a30dfc41dcbc6450686ee9e5f582549f7f126479f743a343ec9',
|
||||
'com.android.tools.build:apkzlib:7.0.3:apkzlib-7.0.3.jar:b31e53174c92db83c5cc6e7dac6734ea4e907a72e452c2bf1818dfd082c59397',
|
||||
'com.android.tools.build:builder-model:7.0.3:builder-model-7.0.3.jar:483f99d7494a5bed027e1e8d29111384cf535d4842f0be5a79805bd44bb68d4e',
|
||||
'com.android.tools.build:builder-test-api:7.0.3:builder-test-api-7.0.3.jar:f6de4bc2cef545e8367bf82d7c733829c7be3b0b3b8b09fd8c58f2150e59ab46',
|
||||
'com.android.tools.build:builder:7.0.3:builder-7.0.3.jar:c6952da0094b094c2ba0fe84c675622097c5d9b9f9beb53485b860320540cf1d',
|
||||
'com.android.tools.build:manifest-merger:30.0.3:manifest-merger-30.0.3.jar:72b346ba6318b4b6260e6e49df4bea5da2e12329ab6c2beb2269c49a9f51f178',
|
||||
'com.android.tools.ddms:ddmlib:30.0.3:ddmlib-30.0.3.jar:7a914a68ab93393657297234e2f37b22410ae9a433cba692ce8c727c9607e3bb',
|
||||
'com.android.tools.external.com-intellij:intellij-core:30.0.3:intellij-core-30.0.3.jar:1ebe858d3f58eeaa8c06507f8ac0f1c7051e6c61f35a70f3c3967d5734d3abc5',
|
||||
'com.android.tools.external.com-intellij:kotlin-compiler:30.0.3:kotlin-compiler-30.0.3.jar:ed00e441f427cb4e0d418287b9da30b12b7f735f9af32e6b5d3dc960b6a742fc',
|
||||
'com.android.tools.external.org-jetbrains:uast:30.0.3:uast-30.0.3.jar:a77801bee6ff509910e459525c9c34d7f04b066ade123547f16f1917548eadea',
|
||||
'com.android.tools.layoutlib:layoutlib-api:30.0.3:layoutlib-api-30.0.3.jar:4caa87e9ca2e11315f650d576cd59fec1793373bc3fca3f6d53c029e7534e7c4',
|
||||
'com.android.tools.lint:lint-api:30.0.3:lint-api-30.0.3.jar:bcecbd2f752a6560096a9029a47d1de6bd788a51bab505c5ebfba6a18524b983',
|
||||
'com.android.tools.lint:lint-checks:30.0.3:lint-checks-30.0.3.jar:25a7cd42dc3ad502337f131fb8b7e873c53301db0a67b1c64dd4ae7a8eb66cec',
|
||||
'com.android.tools.lint:lint-gradle:30.0.3:lint-gradle-30.0.3.jar:94544d6147a809bf2fd3440e51f28a4e42e547d74aab53eefd74938cdad42c26',
|
||||
'com.android.tools.lint:lint-model:30.0.3:lint-model-30.0.3.jar:0b940a7f575c2ff5cbd038260f41dde686a93c672213881ead3ce8af3513b396',
|
||||
'com.android.tools.lint:lint:30.0.3:lint-30.0.3.jar:ee4f11001e0c7e3b776e0d67399ad354b19b0f168822ec2b7db47c0910ed227d',
|
||||
'com.android.tools:annotations:30.0.3:annotations-30.0.3.jar:5c1944982fda8555855c4f5422fabf0dc8e2306e1f5460e9ad82dae71316bc31',
|
||||
'com.android.tools:common:30.0.3:common-30.0.3.jar:8751efaaf2c2ddd1f0a37526c794347def6a3057ca9fc510307c13a6cf0d036f',
|
||||
'com.android.tools:dvlib:30.0.3:dvlib-30.0.3.jar:5affafcec390041e5afd64cb924153f5e474db47ee8ccc2f555b495083141233',
|
||||
'com.android.tools:repository:30.0.3:repository-30.0.3.jar:0a40c6f16c506903ce2c609affd8228aceda73a69d93dfa42d4f02b8491449f6',
|
||||
'com.android.tools:sdk-common:30.0.3:sdk-common-30.0.3.jar:b45570a380360236ffee0f6bb593d66b673bad3834dfe0d6c9871fa7188ee0eb',
|
||||
'com.android.tools:sdklib:30.0.3:sdklib-30.0.3.jar:7088f20a414fab170a21e457825e14ebe099f753558e02c8acc12c67eb412162',
|
||||
'com.android:signflinger:7.0.3:signflinger-7.0.3.jar:903a4536db3e96b4e1e1dc1e400eb0b91bf7866d9b39cd7ec94d75dde158f152',
|
||||
'com.android:zipflinger:7.0.3:zipflinger-7.0.3.jar:fd209c960a3eff7a339e6fcba07d5e9ef4604d1633c69ab2df987460d9804140',
|
||||
'com.beust:jcommander:1.78:jcommander-1.78.jar:7891debb84b5f83e9bd57593ebece3399abbe0fd938cf306b3534c57913b9615',
|
||||
'com.github.bumptech.glide:annotations:4.11.0:annotations-4.11.0.jar:d219d238006d824962176229d4708abcdddcfe342c6a18a5d0fa48d6f0479b3e',
|
||||
'com.github.bumptech.glide:compiler:4.11.0:compiler-4.11.0.jar:a98cdf265c36261b1d523448b05c322ec290afa865946425eded6361980e8770',
|
||||
'com.github.bumptech.glide:gifdecoder:4.11.0:gifdecoder-4.11.0.aar:197a1cd5b76855aa02b230c13974e293229b901dc2b96fab4315201e78baa804',
|
||||
'com.github.bumptech.glide:glide:4.11.0:glide-4.11.0.aar:5c294e6a5f0f812cef876b8412954c1822da184af38e082a5b766e3c4f4fcd95',
|
||||
'com.github.chrisbanes:PhotoView:2.3.0:PhotoView-2.3.0.aar:6c8989f2945d50ab38b3e0300064f1f8d2d75bbcae1434fe535d9fb6898e9ad6',
|
||||
'com.github.javaparser:javaparser-core:3.17.0:javaparser-core-3.17.0.jar:23f5c982e1c7771423d37d52c774e8d2e80fd7ea7305ebe448797a96f67e6fca',
|
||||
'com.github.kobakei:MaterialFabSpeedDial:1.2.1:MaterialFabSpeedDial-1.2.1.aar:e86198c3c48cd832fb209a769a9f222c2a3cc045743b110ac2391d9737e3ea02',
|
||||
'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.0:accessibility-test-framework-2.0.jar:cdf16ef8f5b8023d003ce3cc1b0d51bda737762e2dab2fedf43d1c4292353f7f',
|
||||
'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1:accessibility-test-framework-2.1.jar:7b0aa6ed7553597ce0610684a9f7eca8021eee218f2e2f427c04a7fbf5f920bd',
|
||||
@@ -114,19 +114,19 @@ dependencyVerification {
|
||||
'com.google.auto:auto-common:0.8:auto-common-0.8.jar:97db1709f57b91b32edacb596ef4641872f227b7d99ad90e467f0d77f5ba134a',
|
||||
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.code.gson:gson:2.8.5:gson-2.8.5.jar:233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81',
|
||||
'com.google.code.gson:gson:2.8.6:gson-2.8.6.jar:c8fb4839054d280b3033f800d1f5a97de2f028eb8ba2eb458ad287e536f3f25f',
|
||||
'com.google.dagger:dagger-compiler:2.33:dagger-compiler-2.33.jar:aa8a0d8370c578fd6999802d0d90b9829377a46d2c1141e11b8f737970e7155e',
|
||||
'com.google.dagger:dagger-producers:2.33:dagger-producers-2.33.jar:5897f0b6eef799c2adfe3ccacc58c0fb374d58acb063c3ebe5366c38a8bce5c8',
|
||||
'com.google.dagger:dagger-spi:2.33:dagger-spi-2.33.jar:e2dcab2221b8afb9556ef0a1c83b0bd5f42552e254322a257330f754cdbbb9d4',
|
||||
'com.google.dagger:dagger:2.33:dagger-2.33.jar:d8798c5b8cf6b125234e33af5c6293bb9f2208ce29b57924c35b8c0be7b6bdcb',
|
||||
'com.google.errorprone:error_prone_annotations:2.2.0:error_prone_annotations-2.2.0.jar:6ebd22ca1b9d8ec06d41de8d64e0596981d9607b42035f9ed374f9de271a481a',
|
||||
'com.google.errorprone:error_prone_annotations:2.3.2:error_prone_annotations-2.3.2.jar:357cd6cfb067c969226c442451502aee13800a24e950fdfde77bcdb4565a668d',
|
||||
'com.google.errorprone:error_prone_annotations:2.3.4:error_prone_annotations-2.3.4.jar:baf7d6ea97ce606c53e11b6854ba5f2ce7ef5c24dddf0afa18d1260bd25b002c',
|
||||
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
|
||||
'com.google.guava:guava:27.0.1-jre:guava-27.0.1-jre.jar:e1c814fd04492a27c38e0317eabeaa1b3e950ec8010239e400fe90ad6c9107b4',
|
||||
'com.google.guava:guava:27.1-jre:guava-27.1-jre.jar:4a5aa70cc968a4d137e599ad37553e5cfeed2265e8c193476d7119036c536fe7',
|
||||
'com.google.guava:guava:28.1-jre:guava-28.1-jre.jar:30beb8b8527bd07c6e747e77f1a92122c2f29d57ce347461a4a55eb26e382da4',
|
||||
'com.google.guava:guava:30.1-jre:guava-30.1-jre.jar:e6dd072f9d3fe02a4600688380bd422bdac184caf6fe2418cfdd0934f09432aa',
|
||||
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
|
||||
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6',
|
||||
'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
|
||||
@@ -141,34 +141,45 @@ dependencyVerification {
|
||||
'com.squareup:javawriter:2.1.1:javawriter-2.1.1.jar:f699823d0081f69cbb676c1845ea222e0ada79bc88a53e5d22d8bd02d328f57e',
|
||||
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
|
||||
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
|
||||
'com.sun.istack:istack-commons-runtime:3.0.7:istack-commons-runtime-3.0.7.jar:6443e10ba2e259fb821d9b6becf10db5316285fc30c53cec9d7b19a3877e7fdf',
|
||||
'com.sun.xml.fastinfoset:FastInfoset:1.2.15:FastInfoset-1.2.15.jar:785861db11ca1bd0d1956682b974ad73eb19cd3e01a4b3fa82d62eca97210aec',
|
||||
'com.sun.istack:istack-commons-runtime:3.0.8:istack-commons-runtime-3.0.8.jar:4ffabb06be454a05e4398e20c77fa2b6308d4b88dfbef7ca30a76b5b7d5505ef',
|
||||
'com.sun.xml.fastinfoset:FastInfoset:1.2.16:FastInfoset-1.2.16.jar:056f3a1e144409f21ed16afc26805f58e9a21f3fce1543c42d400719d250c511',
|
||||
'com.thoughtworks.qdox:qdox:1.12.1:qdox-1.12.1.jar:21fba22f830e9268f07cf4ab2d99e8181abbdcb0cb91ee0228eb3cb918dcdd1d',
|
||||
'com.vanniktech:emoji-google:0.6.0:emoji-google-0.6.0.aar:029d6a954cebfe3f0a5bac0c9539a054fa7db2e1272d006a8f0e850f3794d44b',
|
||||
'com.vanniktech:emoji:0.6.0:emoji-0.6.0.aar:a5fcde58902305c004f03c6dc2241e718400ac4162226079791d87fac83ef639',
|
||||
'commons-codec:commons-codec:1.10:commons-codec-1.10.jar:4241dfa94e711d435f29a4604a3e2de5c4aa3c165e23bd066be6fc1fc4309569',
|
||||
'commons-io:commons-io:2.4:commons-io-2.4.jar:cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581',
|
||||
'commons-logging:commons-logging:1.2:commons-logging-1.2.jar:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636',
|
||||
'de.hdodenhof:circleimageview:3.1.0:circleimageview-3.1.0.aar:8e9965b54072ee159074a55df216e17d5a622c94ce915ef311b1a1f32660c7fb',
|
||||
'info.guardianproject.panic:panic:1.0:panic-1.0.jar:35116ab95212e67f94577faf67b88c11a6b21cbf9178b3f5b51d3dff45203ffd',
|
||||
'info.guardianproject.trustedintents:trustedintents:0.2:trustedintents-0.2.jar:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e',
|
||||
'it.unimi.dsi:fastutil:7.2.0:fastutil-7.2.0.jar:74fa208043740642f7e6eb09faba15965218ad2f50ce3020efb100136e4b591c',
|
||||
'javax.activation:javax.activation-api:1.2.0:javax.activation-api-1.2.0.jar:43fdef0b5b6ceb31b0424b208b930c74ab58fac2ceeb7b3f6fd3aeb8b5ca4393',
|
||||
'info.picocli:picocli:4.5.2:picocli-4.5.2.jar:b4395e9a67932616efd2245d984bf5fcd453c2c5049558c3ce959ac2af4d3fac',
|
||||
'it.unimi.dsi:fastutil:8.4.0:fastutil-8.4.0.jar:2ad2824a4a0a0eb836b52ee2fc84ba2134f44bce7bfa54015ae3f31c710a3071',
|
||||
'jakarta.activation:jakarta.activation-api:1.2.1:jakarta.activation-api-1.2.1.jar:8b0a0f52fa8b05c5431921a063ed866efaa41dadf2e3a7ee3e1961f2b0d9645b',
|
||||
'jakarta.xml.bind:jakarta.xml.bind-api:2.3.2:jakarta.xml.bind-api-2.3.2.jar:69156304079bdeed9fc0ae3b39389f19b3cc4ba4443bc80508995394ead742ea',
|
||||
'javax.annotation:javax.annotation-api:1.3.2:javax.annotation-api-1.3.2.jar:e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'javax.xml.bind:jaxb-api:2.3.1:jaxb-api-2.3.1.jar:88b955a0df57880a26a74708bc34f74dcaf8ebf4e78843a28b50eae945732b06',
|
||||
'jline:jline:2.14.6:jline-2.14.6.jar:97d1acaac82409be42e622d7a54d3ae9d08517e8aefdea3d2ba9791150c2f02d',
|
||||
'junit:junit:4.13.1:junit-4.13.1.jar:c30719db974d6452793fe191b3638a5777005485bae145924044530ffa5f6122',
|
||||
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
|
||||
'nekohtml:nekohtml:1.9.6.2:nekohtml-1.9.6.2.jar:fdff6cfa9ed9cc911c842a5d2395f209ec621ef1239d46810e9e495809d3ae09',
|
||||
'nekohtml:xercesMinimal:1.9.6.2:xercesMinimal-1.9.6.2.jar:95b8b357d19f63797dd7d67622fd3f18374d64acbc6584faba1c7759a31e8438',
|
||||
'net.bytebuddy:byte-buddy-agent:1.10.20:byte-buddy-agent-1.10.20.jar:b592a6c43e752bf41659717956c57fbb790394d2ee5f8941876659f9c5c0e7e8',
|
||||
'net.bytebuddy:byte-buddy:1.10.20:byte-buddy-1.10.20.jar:5fcad05da791e9a22811c255a4a74b7ea094b7243d9dbf3e6fc578c8c94290ac',
|
||||
'net.java.dev.jna:jna-platform:5.6.0:jna-platform-5.6.0.jar:9ecea8bf2b1b39963939d18b70464eef60c508fed8820f9dcaba0c35518eabf7',
|
||||
'net.java.dev.jna:jna:5.6.0:jna-5.6.0.jar:5557e235a8aa2f9766d5dc609d67948f2a8832c2d796cea9ef1d6cbe0b3b7eaf',
|
||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||
'net.sf.jopt-simple:jopt-simple:4.9:jopt-simple-4.9.jar:26c5856e954b5f864db76f13b86919b59c6eecf9fd930b96baa8884626baf2f5',
|
||||
'net.sf.kxml:kxml2:2.3.0:kxml2-2.3.0.jar:f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2',
|
||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||
'org.apache.ant:ant-antlr:1.10.9:ant-antlr-1.10.9.jar:7623dc9d0f20ea713290c6bf1a23f4c059447aef7ff9f5b2be75960f3f028d2e',
|
||||
'org.apache.ant:ant-junit:1.10.9:ant-junit-1.10.9.jar:960bdc8827954d62206ba42d0a68a7ee4476175ba47bb113e17e77cce7394630',
|
||||
'org.apache.ant:ant-launcher:1.10.9:ant-launcher-1.10.9.jar:fcce891f57f3be72149ff96ac2a80574165b3e0839866b95d24528f3027d50c1',
|
||||
'org.apache.ant:ant-launcher:1.8.0:ant-launcher-1.8.0.jar:da9fd92eacdf63daf0be52eb71accc10ff7943a85d7aac9ea96cf7e03ee3d3cc',
|
||||
'org.apache.ant:ant:1.10.9:ant-1.10.9.jar:0715478af585ea80a18985613ebecdc7922122d45b2c3c970ff9b352cddb75fc',
|
||||
'org.apache.ant:ant:1.8.0:ant-1.8.0.jar:0251dbb938740ace07a53675113eee753ba389db65aebc814b175af50321620e',
|
||||
'org.apache.commons:commons-compress:1.12:commons-compress-1.12.jar:2c1542faf343185b7cab9c3d55c8ae5471d6d095d3887a4adefdbdf2984dc0b6',
|
||||
'org.apache.commons:commons-compress:1.20:commons-compress-1.20.jar:0aeb625c948c697ea7b205156e112363b59ed5e2551212cd4e460bdb72c7c06e',
|
||||
'org.apache.httpcomponents:httpclient:4.5.6:httpclient-4.5.6.jar:c03f813195e7a80e3608d0ddd8da80b21696a4c92a6a2298865bf149071551c7',
|
||||
'org.apache.httpcomponents:httpcore:4.4.10:httpcore-4.4.10.jar:78ba1096561957db1b55200a159b648876430342d15d461277e62360da19f6fd',
|
||||
'org.apache.httpcomponents:httpmime:4.5.6:httpmime-4.5.6.jar:0b2b1102c18d3c7e05a77214b9b7501a6f6056174ae5604e0e256776eda7553e',
|
||||
@@ -191,42 +202,72 @@ dependencyVerification {
|
||||
'org.bouncycastle:bcprov-jdk15on:1.69:bcprov-jdk15on-1.69.jar:e469bd39f936999f256002631003ff022a22951da9d5bd9789c7abfa9763a292',
|
||||
'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.8.1:checker-qual-2.8.1.jar:9103499008bcecd4e948da29b17864abb64304e15706444ae209d17ebe0575df',
|
||||
'org.codehaus.groovy:groovy-all:2.4.15:groovy-all-2.4.15.jar:51d6c4e71782e85674239189499854359d380fb75e1a703756e3aaa5b98a5af0',
|
||||
'org.checkerframework:checker-qual:3.5.0:checker-qual-3.5.0.jar:729990b3f18a95606fc2573836b6958bcdb44cb52bfbd1b7aa9c339cff35a5a4',
|
||||
'org.codehaus.groovy:groovy-ant:3.0.7:groovy-ant-3.0.7.jar:6ed2ba82813d128f7050c24142e87b3dc2ad8b504786280eb03e81f0cf6a5793',
|
||||
'org.codehaus.groovy:groovy-astbuilder:3.0.7:groovy-astbuilder-3.0.7.jar:b290451eb1583666e906c41f7d14747b4cc96363c99c478b244634fd5dfc9013',
|
||||
'org.codehaus.groovy:groovy-cli-picocli:3.0.7:groovy-cli-picocli-3.0.7.jar:71b4bd11fb30a9c7b5618e22122c9c5141958fb27f4dcf0068b6f715088f6916',
|
||||
'org.codehaus.groovy:groovy-console:3.0.7:groovy-console-3.0.7.jar:0541b358b6b8e5363215026736168fccfec1d91bac678d066fa77349eeeaa5dd',
|
||||
'org.codehaus.groovy:groovy-datetime:3.0.7:groovy-datetime-3.0.7.jar:b9823d14b1a4f94236ae2f8a471701aab17e093e1b33402b91550b5c8dd88f04',
|
||||
'org.codehaus.groovy:groovy-docgenerator:3.0.7:groovy-docgenerator-3.0.7.jar:bf53f7a11c9eb1e278e1b8ed2714c741bcf781235c803ad3ba1555f2614573f3',
|
||||
'org.codehaus.groovy:groovy-groovydoc:3.0.7:groovy-groovydoc-3.0.7.jar:86b24dfc23c005066ab83927cdb54177f06c9531773f2e2d2ecc9a131f7c2677',
|
||||
'org.codehaus.groovy:groovy-groovysh:3.0.7:groovy-groovysh-3.0.7.jar:5c40e78cbc09726aedd1c75fab112d245d665d6294870f9119e6cd3013ed14ab',
|
||||
'org.codehaus.groovy:groovy-jmx:3.0.7:groovy-jmx-3.0.7.jar:0a89f3007884eb156751937d93382038b83d39c7c2f0ab156ebf251a7251f2ab',
|
||||
'org.codehaus.groovy:groovy-json:3.0.7:groovy-json-3.0.7.jar:df1f0ee475e3fc93a6a0d17548294e160cca5de6d9d36817a7be1fbe650de03b',
|
||||
'org.codehaus.groovy:groovy-jsr223:3.0.7:groovy-jsr223-3.0.7.jar:1dbd969595332416193baa660fbb45743d19696eaa25fe98e591a2739e13517e',
|
||||
'org.codehaus.groovy:groovy-macro:3.0.7:groovy-macro-3.0.7.jar:c6cc06df526b39e2c359e2435f0071594c5a1c7babafaa6c184fdd8fa931531f',
|
||||
'org.codehaus.groovy:groovy-nio:3.0.7:groovy-nio-3.0.7.jar:db54c577882b294cd8c975ec5451596441baf54781319c61627dca0e0c2361ef',
|
||||
'org.codehaus.groovy:groovy-servlet:3.0.7:groovy-servlet-3.0.7.jar:5b6a909bf501c209adfb6205b9e740649609074455fd979bf9da4853e6ff9a39',
|
||||
'org.codehaus.groovy:groovy-sql:3.0.7:groovy-sql-3.0.7.jar:252bb6c74e1a9f41756ad4fbd3b0d2eddc93bb61109961dd1952a37bf2d57a64',
|
||||
'org.codehaus.groovy:groovy-swing:3.0.7:groovy-swing-3.0.7.jar:bd942032d9328d54c6679c49a41f6caa0d4a0039ebe598493b8a647730d98cff',
|
||||
'org.codehaus.groovy:groovy-templates:3.0.7:groovy-templates-3.0.7.jar:f119e07f650ef186ae5a4b944f9e30915b14311bad47c94a6b32de8d4f69bc80',
|
||||
'org.codehaus.groovy:groovy-test-junit5:3.0.7:groovy-test-junit5-3.0.7.jar:c16eeea07b8e396891e266d7ba9388b24ac804237ffdd9a792b0d08969bad014',
|
||||
'org.codehaus.groovy:groovy-test:3.0.7:groovy-test-3.0.7.jar:f71afd7c25d43017f89ea47e6de6daec971d159047dae083c1513a8422d44b90',
|
||||
'org.codehaus.groovy:groovy-testng:3.0.7:groovy-testng-3.0.7.jar:713d5f2231bbb5712aefd362151b9ffd884aeb7ef2e773315cc54259cbdd063d',
|
||||
'org.codehaus.groovy:groovy-xml:3.0.7:groovy-xml-3.0.7.jar:8a62e7c9ddece3e82676c4bef2f2c100f459602cd1fb6a14e94187bf863e97ff',
|
||||
'org.codehaus.groovy:groovy:3.0.7:groovy-3.0.7.jar:51d1777e8dd1f00e60ea56e00d8a354ff5aab1f00fc8464ae8d39d71867e401f',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',
|
||||
'org.codehaus.mojo:animal-sniffer-annotations:1.18:animal-sniffer-annotations-1.18.jar:47f05852b48ee9baefef80fa3d8cea60efa4753c0013121dd7fe5eef2e5c729d',
|
||||
'org.codehaus.plexus:plexus-container-default:1.0-alpha-9-stable-1:plexus-container-default-1.0-alpha-9-stable-1.jar:7c758612888782ccfe376823aee7cdcc7e0cdafb097f7ef50295a0b0c3a16edf',
|
||||
'org.codehaus.plexus:plexus-interpolation:1.11:plexus-interpolation-1.11.jar:fd9507feb858fa620d1b4aa4b7039fdea1a77e09d3fd28cfbddfff468d9d8c28',
|
||||
'org.codehaus.plexus:plexus-utils:1.5.15:plexus-utils-1.5.15.jar:2ca121831e597b4d8f2cb22d17c5c041fc23a7777ceb6bfbdd4dfb34bbe7d997',
|
||||
'org.glassfish.jaxb:jaxb-runtime:2.3.1:jaxb-runtime-2.3.1.jar:45fecfa5c8217ce1f3652ab95179790ec8cc0dec0384bca51cbeb94a293d9f2f',
|
||||
'org.glassfish.jaxb:txw2:2.3.1:txw2-2.3.1.jar:34975dde1c6920f1a39791142235689bc3cd357e24d05edd8ff93b885bd68d60',
|
||||
'org.glassfish.jaxb:jaxb-runtime:2.3.2:jaxb-runtime-2.3.2.jar:e6e0a1e89fb6ff786279e6a0082d5cef52dc2ebe67053d041800737652b4fd1b',
|
||||
'org.glassfish.jaxb:txw2:2.3.2:txw2-2.3.2.jar:4a6a9f483388d461b81aa9a28c685b8b74c0597993bf1884b04eddbca95f48fe',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||
'org.hamcrest:hamcrest-integration:1.3:hamcrest-integration-1.3.jar:70f418efbb506c5155da5f9a5a33262ea08a9e4d7fea186aa9015c41a7224ac2',
|
||||
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
||||
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
|
||||
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
|
||||
'org.jetbrains.kotlin:kotlin-reflect:1.3.72:kotlin-reflect-1.3.72.jar:a188d9367de1c4ee9479db630985c0597b20709c83161b1430d24edb27e38c40',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.72:kotlin-stdlib-common-1.3.72.jar:5e7d1552863e480c1628b1cc39ce230ef829f5b7230106215a05acda5172203a',
|
||||
'org.jacoco:org.jacoco.agent:0.8.3:org.jacoco.agent-0.8.3.jar:522deb254ee16a04cc8341cc8f335f5cb7232982994d961b9cf3a0454709209f',
|
||||
'org.jacoco:org.jacoco.ant:0.8.3:org.jacoco.ant-0.8.3.jar:735844e1ae15f9b875b42a27ac5cb61cc26e106d9e839e5d1c6756709b424ce0',
|
||||
'org.jacoco:org.jacoco.core:0.8.3:org.jacoco.core-0.8.3.jar:0818437bc060a0c7cc798148f22b713702aae2771aba104444407697d578f1ea',
|
||||
'org.jacoco:org.jacoco.report:0.8.3:org.jacoco.report-0.8.3.jar:aae08fa4ff043c807b8876cdb2d8705eb8449a55efce461baa6c09da245088c1',
|
||||
'org.jetbrains.intellij.deps:trove4j:1.0.20181211:trove4j-1.0.20181211.jar:affb7c85a3c87bdcf69ff1dbb84de11f63dc931293934bc08cd7ab18de083601',
|
||||
'org.jetbrains.kotlin:kotlin-reflect:1.4.32:kotlin-reflect-1.4.32.jar:dbf19e9cdaa9c3c170f3f6f6ce3922f38dfc1d7fa1cab5b7c23a19da8b5eec5b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20:kotlin-stdlib-common-1.4.20.jar:a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72:kotlin-stdlib-jdk7-1.3.72.jar:40566c0c08d414b9413ba556ff7f8a0b04b98b9f0f424d122dd2088510efccc4',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72:kotlin-stdlib-jdk8-1.3.72.jar:133da70cfc07b56094282eac5c59bccd59f167ee2ead22e5282876d8bc10bf95',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.3.72:kotlin-stdlib-1.3.72.jar:3856a7349ebacd6d1be6802b2fed9c4dc2c5a564ea92b6b945ac988243d4b16b',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32:kotlin-stdlib-common-1.4.32.jar:e1ff6f55ee9e7591dcc633f7757bac25a7edb1cc7f738b37ec652f10f66a4145',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32:kotlin-stdlib-jdk7-1.4.32.jar:5f801e75ca27d8791c14b07943c608da27620d910a8093022af57f543d5d98b6',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32:kotlin-stdlib-jdk8-1.4.32.jar:adc43e54757b106e0cd7b3b7aa257dff471b61efdabe067fc02b2f57e2396262',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.4.20:kotlin-stdlib-1.4.20.jar:b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656',
|
||||
'org.jetbrains.kotlin:kotlin-stdlib:1.4.32:kotlin-stdlib-1.4.32.jar:13e9fd3e69dc7230ce0fc873a92a4e5d521d179bcf1bef75a6705baac3bfecba',
|
||||
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1:kotlinx-coroutines-android-1.4.1.jar:d4cadb673b2101f1ee5fbc147956ac78b1cfd9cc255fb53d3aeb88dff11d99ca',
|
||||
'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.4.1:kotlinx-coroutines-core-jvm-1.4.1.jar:6d2f87764b6638f27aff12ed380db4b63c9d46ba55dc32683a650598fa5a3e22',
|
||||
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0:kotlinx-metadata-jvm-0.1.0.jar:9753bb39efef35957c5c15df9a3cb769aabf2cdfa74b47afcb7760e5146be3b5',
|
||||
'org.jetbrains.trove4j:trove4j:20160824:trove4j-20160824.jar:1917871c8deb468307a584680c87a44572f5a8b0b98c6d397fc0f5f86596dbe7',
|
||||
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
|
||||
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
|
||||
'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd',
|
||||
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
|
||||
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
|
||||
'org.jvnet.staxex:stax-ex:1.8:stax-ex-1.8.jar:95b05d9590af4154c6513b9c5dc1fb2e55b539972ba0a9ef28e9a0c01d83ad77',
|
||||
'org.junit.jupiter:junit-jupiter-api:5.7.0:junit-jupiter-api-5.7.0.jar:b03f78e0daeed2d77a0af9bcd662b4cdb9693f7ee72e01a539b508b84c63d182',
|
||||
'org.junit.jupiter:junit-jupiter-engine:5.7.0:junit-jupiter-engine-5.7.0.jar:dfa26af94644ac2612dde6625852fcb550a0d21caa243257de54cba738ba87af',
|
||||
'org.junit.platform:junit-platform-commons:1.7.0:junit-platform-commons-1.7.0.jar:5330ee87cc7586e6e25175a34e9251624ff12ff525269d3415d0b4ca519b6fea',
|
||||
'org.junit.platform:junit-platform-engine:1.7.0:junit-platform-engine-1.7.0.jar:75f21a20dc594afdc875736725b408cec6d0344874d29f34b2dd3075500236f2',
|
||||
'org.junit.platform:junit-platform-launcher:1.7.0:junit-platform-launcher-1.7.0.jar:fbdc748fde4c4279fe1d3c607447cb3b7ccd45d7338fc574f8a894ddf2d16818',
|
||||
'org.jvnet.staxex:stax-ex:1.8.1:stax-ex-1.8.1.jar:20522549056e9e50aa35ef0b445a2e47a53d06be0b0a9467d704e2483ffb049a',
|
||||
'org.mockito:mockito-core:3.9.0:mockito-core-3.9.0.jar:a1f64211407b8dc4cf80b16e07cc11aa9e5228d53dc4a5357326d66825f6a4ac',
|
||||
'org.nanohttpd:nanohttpd:2.3.1:nanohttpd-2.3.1.jar:de864c47818157141a24c9acb36df0c47d7bf15b7ff48c90610f3eb4e5df0e58',
|
||||
'org.objenesis:objenesis:3.2:objenesis-3.2.jar:03d960bd5aef03c653eb000413ada15eb77cdd2b8e4448886edf5692805e35f3',
|
||||
'org.opentest4j:opentest4j:1.2.0:opentest4j-1.2.0.jar:58812de60898d976fb81ef3b62da05c6604c18fd4a249f5044282479fc286af2',
|
||||
'org.ow2.asm:asm-analysis:7.0:asm-analysis-7.0.jar:e981f8f650c4d900bb033650b18e122fa6b161eadd5f88978d08751f72ee8474',
|
||||
'org.ow2.asm:asm-commons:7.0:asm-commons-7.0.jar:fed348ef05958e3e846a3ac074a12af5f7936ef3d21ce44a62c4fa08a771927d',
|
||||
'org.ow2.asm:asm-tree:7.0:asm-tree-7.0.jar:cfd7a0874f9de36a999c127feeadfbfe6e04d4a71ee954d7af3d853f0be48a6c',
|
||||
@@ -244,7 +285,10 @@ dependencyVerification {
|
||||
'org.robolectric:shadows-framework:4.3.1:shadows-framework-4.3.1.jar:9c69db134cdd79be751856a148020fd9b32b086bb491846eedc0a1106fcadd5e',
|
||||
'org.robolectric:utils-reflector:4.3.1:utils-reflector-4.3.1.jar:9d7bf2557947d44d6f3ed76ec5231e8b72e33eb61c65ac9e149ad307b0eb936c',
|
||||
'org.robolectric:utils:4.3.1:utils-4.3.1.jar:6f9e406cd667019a5450e473c4e2d372bff9c9ab6ef55aafcbc9843109cb1519',
|
||||
'org.testng:testng:7.3.0:testng-7.3.0.jar:63727488f9717d57f0d0a0fee5a1fc10a2be9cfcff2ec3a7187656d663c0774e',
|
||||
'tools.fastlane:screengrab:2.0.0:screengrab-2.0.0.aar:15ac15eb7c371db05e721be8d466567c2b7274b767d91478e781b6d89ee5d3d0',
|
||||
'uk.co.samuelwall:material-tap-target-prompt:3.3.0:material-tap-target-prompt-3.3.0.aar:00f16e8d7e55d01e3b41cf66e09eee8588870ca7285ba3c72267ca0482f1606e',
|
||||
'xerces:xercesImpl:2.12.0:xercesImpl-2.12.0.jar:b50d3a4ca502faa4d1c838acb8aa9480446953421f7327e338c5dda3da5e76d0',
|
||||
'xml-apis:xml-apis:1.4.01:xml-apis-1.4.01.jar:a840968176645684bb01aed376e067ab39614885f9eee44abe35a5f20ebe7fad',
|
||||
]
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user