Compare commits

..

3 Commits

Author SHA1 Message Date
akwizgran
3cbc67c3cd Upgrade H2 to 2.2.220.
Columns called "key" and "value" are no longer allowed. MVCC is mandatory.
2023-09-07 15:12:41 +01:00
akwizgran
da186abced Fix database URLs in tests. 2023-08-29 18:14:49 +01:00
akwizgran
98d1fc4ce2 Enable library desugaring, upgrade H2. 2023-08-29 17:49:52 +01:00
199 changed files with 1742 additions and 5783 deletions

View File

@@ -7,7 +7,6 @@ stages:
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
workflow: workflow:
# when to create a CI pipeline # when to create a CI pipeline

View File

@@ -4,7 +4,6 @@
<option name="ANNOTATION_PARAMETER_WRAP" value="1" /> <option name="ANNOTATION_PARAMETER_WRAP" value="1" />
<option name="IMPORT_LAYOUT_TABLE"> <option name="IMPORT_LAYOUT_TABLE">
<value> <value>
<package name="" withSubpackages="true" static="false" module="true" />
<package name="android" withSubpackages="true" static="false" /> <package name="android" withSubpackages="true" static="false" />
<emptyLine /> <emptyLine />
<package name="com" withSubpackages="true" static="false" /> <package name="com" withSubpackages="true" static="false" />
@@ -29,11 +28,15 @@
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" /> <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
</JavaCodeStyleSettings> </JavaCodeStyleSettings>
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value />
</option>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
<codeStyleSettings language="Groovy"> <codeStyleSettings language="Groovy">
<indentOptions> <indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="true" /> <option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" /> <option name="SMART_TABS" value="true" />
</indentOptions> </indentOptions>

View File

@@ -3,18 +3,18 @@ apply plugin: 'witness'
apply from: 'witness.gradle' apply from: 'witness.gradle'
android { android {
compileSdkVersion 35 compileSdkVersion 33
buildToolsVersion '35.0.0' buildToolsVersion '33.0.0'
packagingOptions {
jniLibs {
keepDebugSymbols += ['**/*.so']
}
}
packagingOptions {
doNotStrip '**/*.so'
}
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 35 targetSdkVersion 33
versionCode 10506
versionName "1.5.6"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -25,11 +25,14 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
namespace 'org.briarproject.bramble'
lint {
warning 'LintError', 'InvalidPackage', 'MissingPermission', 'InlinedApi', 'ObsoleteSdkInt', 'Override', 'NewApi', 'UnusedAttribute'
}
lintOptions {
// FIXME
warning "LintError"
warning "InvalidPackage"
warning "MissingPermission"
warning "InlinedApi", "ObsoleteSdkInt", "Override", "NewApi", "UnusedAttribute"
}
} }
configurations { configurations {
@@ -37,7 +40,7 @@ configurations {
} }
dependencies { dependencies {
api 'org.briarproject:dont-kill-me-lib:0.2.8' api 'org.briarproject:dont-kill-me-lib:0.2.7'
// In theory this dependency shouldn't be needed, but without it Android Studio's linter will // In theory this dependency shouldn't be needed, but without it Android Studio's linter will
// complain about unresolved symbols for bramble-api test classes in bramble-android tests, // complain about unresolved symbols for bramble-api test classes in bramble-android tests,
@@ -51,7 +54,8 @@ dependencies {
implementation "org.briarproject:onionwrapper-android:$onionwrapper_version" implementation "org.briarproject:onionwrapper-android:$onionwrapper_version"
tor "org.briarproject:tor-android:$tor_version" tor "org.briarproject:tor-android:$tor_version"
tor "org.briarproject:lyrebird-android:$lyrebird_version" tor "org.briarproject:obfs4proxy-android:$obfs4proxy_version"
tor "org.briarproject:snowflake-android:$snowflake_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version" annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"

View File

@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
package="org.briarproject.bramble">
<uses-feature <uses-feature
android:name="android.hardware.bluetooth" android:name="android.hardware.bluetooth"
@@ -7,8 +8,10 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- The BLUETOOTH permission was supposed to be removed in API 31 but is still needed on some Xiaomi/Redmi/POCO devices running API 31 and Nubia devices running API 32/33 --> <!-- The BLUETOOTH permission was supposed to be removed in API 31 but is still needed on some Xiaomi/Redmi/POCO devices running API 31 and Nubia devices running API 32 -->
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="32" />
<uses-permission <uses-permission
android:name="android.permission.BLUETOOTH_ADMIN" android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" /> android:maxSdkVersion="30" />

View File

@@ -30,7 +30,6 @@ import static android.os.PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED;
import static android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGED; import static android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGED;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.AndroidUtils.registerReceiver;
class AndroidBatteryManager implements BatteryManager, Service { class AndroidBatteryManager implements BatteryManager, Service {
@@ -53,7 +52,7 @@ class AndroidBatteryManager implements BatteryManager, Service {
public boolean isCharging() { public boolean isCharging() {
// Get the sticky intent for ACTION_BATTERY_CHANGED // Get the sticky intent for ACTION_BATTERY_CHANGED
IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED); IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
Intent i = registerReceiver(appContext, null, filter, false); Intent i = appContext.registerReceiver(null, filter);
if (i == null) return false; if (i == null) return false;
int status = i.getIntExtra(EXTRA_PLUGGED, 0); int status = i.getIntExtra(EXTRA_PLUGGED, 0);
return status != 0; return status != 0;
@@ -72,7 +71,7 @@ class AndroidBatteryManager implements BatteryManager, Service {
filter.addAction(ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED); filter.addAction(ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
filter.addAction(ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED); filter.addAction(ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED);
} }
registerReceiver(appContext, batteryReceiver, filter, false); appContext.registerReceiver(batteryReceiver, filter);
} }
@Override @Override

View File

@@ -55,7 +55,6 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.AndroidUtils.registerReceiver;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.nullsafety.NullSafety.requireNonNull; import static org.briarproject.nullsafety.NullSafety.requireNonNull;
@@ -104,7 +103,7 @@ class AndroidNetworkManager implements NetworkManager, Service {
filter.addAction(WIFI_AP_STATE_CHANGED_ACTION); filter.addAction(WIFI_AP_STATE_CHANGED_ACTION);
filter.addAction(WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); filter.addAction(WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
if (SDK_INT >= 23) filter.addAction(ACTION_DEVICE_IDLE_MODE_CHANGED); if (SDK_INT >= 23) filter.addAction(ACTION_DEVICE_IDLE_MODE_CHANGED);
registerReceiver(app, networkStateReceiver, filter, false); app.registerReceiver(networkStateReceiver, filter);
} }
@Override @Override

View File

@@ -56,7 +56,6 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.AndroidUtils.hasBtConnectPermission; import static org.briarproject.bramble.util.AndroidUtils.hasBtConnectPermission;
import static org.briarproject.bramble.util.AndroidUtils.registerReceiver;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -113,7 +112,7 @@ class AndroidBluetoothPlugin extends
filter.addAction(ACTION_STATE_CHANGED); filter.addAction(ACTION_STATE_CHANGED);
filter.addAction(ACTION_SCAN_MODE_CHANGED); filter.addAction(ACTION_SCAN_MODE_CHANGED);
receiver = new BluetoothStateReceiver(); receiver = new BluetoothStateReceiver();
registerReceiver(app, receiver, filter, true); app.registerReceiver(receiver, filter);
} }
@Override @Override
@@ -238,7 +237,7 @@ class AndroidBluetoothPlugin extends
filter.addAction(ACTION_DISCOVERY_STARTED); filter.addAction(ACTION_DISCOVERY_STARTED);
filter.addAction(ACTION_DISCOVERY_FINISHED); filter.addAction(ACTION_DISCOVERY_FINISHED);
filter.addAction(ACTION_FOUND); filter.addAction(ACTION_FOUND);
registerReceiver(app, receiver, filter, true); app.registerReceiver(receiver, filter);
try { try {
if (adapter.startDiscovery()) { if (adapter.startDiscovery()) {
long now = clock.currentTimeMillis(); long now = clock.currentTimeMillis();

View File

@@ -201,7 +201,6 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
@Nullable @Nullable
private InetAddress getIpv6AddressForInterface(InetAddress ipv4) { private InetAddress getIpv6AddressForInterface(InetAddress ipv4) {
try { try {
// We may get an NPE from getByInetAddress() on Android 11
NetworkInterface iface = NetworkInterface.getByInetAddress(ipv4); NetworkInterface iface = NetworkInterface.getByInetAddress(ipv4);
if (iface == null) return null; if (iface == null) return null;
for (InetAddress addr : list(iface.getInetAddresses())) { for (InetAddress addr : list(iface.getInetAddresses())) {
@@ -209,7 +208,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin {
} }
// No suitable address // No suitable address
return null; return null;
} catch (SocketException | NullPointerException e) { } catch (SocketException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
return null; return null;
} }

View File

@@ -31,6 +31,7 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import static android.os.Build.VERSION.SDK_INT;
import static org.briarproject.bramble.util.AndroidUtils.getSupportedArchitectures; import static org.briarproject.bramble.util.AndroidUtils.getSupportedArchitectures;
@Immutable @Immutable
@@ -85,10 +86,15 @@ public class AndroidTorPluginFactory extends TorPluginFactory {
TorWrapper tor = new AndroidTorWrapper(app, wakeLockManager, TorWrapper tor = new AndroidTorWrapper(app, wakeLockManager,
ioExecutor, eventExecutor, architecture, torDirectory, ioExecutor, eventExecutor, architecture, torDirectory,
torSocksPort, torControlPort); torSocksPort, torControlPort);
// Android versions 7.1 and newer can verify Let's Encrypt TLS certs
// signed with the IdentTrust DST Root X3 certificate. Older versions
// of Android consider the certificate to have expired at the end of
// September 2021.
boolean canVerifyLetsEncryptCerts = SDK_INT >= 25;
return new TorPlugin(ioExecutor, wakefulIoExecutor, return new TorPlugin(ioExecutor, wakefulIoExecutor,
networkManager, locationUtils, torSocketFactory, networkManager, locationUtils, torSocketFactory,
circumventionProvider, batteryManager, backoff, circumventionProvider, batteryManager, backoff,
torRendezvousCrypto, tor, callback, MAX_LATENCY, torRendezvousCrypto, tor, callback, MAX_LATENCY,
MAX_IDLE_TIME); MAX_IDLE_TIME, canVerifyLetsEncryptCerts);
} }
} }

View File

@@ -2,10 +2,7 @@ package org.briarproject.bramble.util;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build; import android.os.Build;
import android.os.Looper; import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
@@ -18,30 +15,22 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.content.Context.MODE_PRIVATE; import static android.content.Context.MODE_PRIVATE;
import static android.content.Context.RECEIVER_EXPORTED;
import static android.content.Context.RECEIVER_NOT_EXPORTED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.os.Process.myPid; import static android.os.Process.myPid;
import static android.os.Process.myUid; import static android.os.Process.myUid;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.nullsafety.NullSafety.requireNonNull; import static org.briarproject.nullsafety.NullSafety.requireNonNull;
@NotNullByDefault @NotNullByDefault
public class AndroidUtils { public class AndroidUtils {
private static final Logger LOG =
getLogger(AndroidUtils.class.getName());
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later // Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00"; private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
@@ -67,32 +56,18 @@ public class AndroidUtils {
// If we don't have permission to access the adapter's address, let // If we don't have permission to access the adapter's address, let
// the caller know we can't find it // the caller know we can't find it
if (!hasBtConnectPermission(ctx)) return new Pair<>("", ""); if (!hasBtConnectPermission(ctx)) return new Pair<>("", "");
@SuppressLint("HardwareIds")
String address;
// Return the adapter's address if it's valid and not fake // Return the adapter's address if it's valid and not fake
try { @SuppressLint("HardwareIds")
address = adapter.getAddress(); String address = adapter.getAddress();
if (isValidBluetoothAddress(address)) { if (isValidBluetoothAddress(address)) {
return new Pair<>(address, "adapter"); return new Pair<>(address, "adapter");
}
} catch (SecurityException e) {
if (LOG.isLoggable(INFO)) {
LOG.info("Security exception when getting BT address: " +
e.getMessage());
}
} }
// Return the address from settings if it's valid and not fake // Return the address from settings if it's valid and not fake
if (SDK_INT < 33) { if (SDK_INT < 33) {
try { address = Settings.Secure.getString(ctx.getContentResolver(),
address = Settings.Secure.getString(ctx.getContentResolver(), "bluetooth_address");
"bluetooth_address"); if (isValidBluetoothAddress(address)) {
if (isValidBluetoothAddress(address)) { return new Pair<>(address, "settings");
return new Pair<>(address, "settings");
}
} catch (SecurityException e) {
// Some custom ROMs throw this exception on SDK_INT < 33.
// Fall through
} }
} }
// Try to get the address via reflection // Try to get the address via reflection
@@ -161,21 +136,4 @@ public class AndroidUtils {
} }
return flags; return flags;
} }
/**
* Could be replaced to a similar call in ContextCompat once we
* use and upgrade to version 1.9.0 or higher of the AndroidX Core library.
*/
@Nullable
@SuppressLint("UnspecifiedRegisterReceiverFlag") // we specify where needed
public static Intent registerReceiver(Context ctx,
@Nullable BroadcastReceiver receiver, IntentFilter filter,
boolean export) {
if (SDK_INT >= 33) {
return ctx.registerReceiver(receiver, filter,
export ? RECEIVER_EXPORTED : RECEIVER_NOT_EXPORTED);
} else {
return ctx.registerReceiver(receiver, filter);
}
}
} }

View File

@@ -1,171 +1,67 @@
dependencyVerification { dependencyVerification {
verify = [ verify = [
'androidx.annotation:annotation:1.5.0:annotation-1.5.0.jar:261fb7c0210858500bab66d34354972a75166ab4182add283780b05513d6ec4a', 'androidx.annotation:annotation:1.5.0:annotation-1.5.0.jar:261fb7c0210858500bab66d34354972a75166ab4182add283780b05513d6ec4a',
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db', 'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.android.tools.ddms:ddmlib:31.13.0:ddmlib-31.13.0.jar:839957f961100713ea0eed628a8684cc39aa479631c36249793e6df7e0cd63d8', 'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79',
'com.android.tools.emulator:proto:31.13.0:proto-31.13.0.jar:b77f81cc0751d79393ec4b2eb046f910d21abcd7608b5b0f5a1efea1b3243b48', 'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.android.tools.utp:android-device-provider-ddmlib-proto:31.13.0:android-device-provider-ddmlib-proto-31.13.0.jar:047aecdd66e106137f77a52c442f1b83db7d6e8496899800251f206c7f39de65', 'com.google.dagger:dagger-compiler:2.45:dagger-compiler-2.45.jar:5617dfb994537dba5b41f3744a6dd13ec3cd99789c065e0d5c6fa9f21cf7ca25',
'com.android.tools.utp:android-device-provider-ddmlib:31.13.0:android-device-provider-ddmlib-31.13.0.jar:e6c2d4674077610e165524df6e0617b6af0f91358075854d57c1072f5fb0c245', 'com.google.dagger:dagger-producers:2.45:dagger-producers-2.45.jar:a05abb4c3ccf6bb0f056bdcb5ef973898ecf172952ab5948a824aeea6c86ecaa',
'com.android.tools.utp:android-device-provider-profile-proto:31.13.0:android-device-provider-profile-proto-31.13.0.jar:3e7b098f6e3ecae31b6f7909c343b4ec09aa18d8a89f41bf92077ba4b056f453', 'com.google.dagger:dagger-spi:2.45:dagger-spi-2.45.jar:7cd6f0b09d88e64a9c97bc80e544ab8ac8fdee9301754413585a74cf64222b27',
'com.android.tools.utp:android-device-provider-profile:31.13.0:android-device-provider-profile-31.13.0.jar:1aae6909dd10cf15d100f24871a5b9310fff6d2556d67c3808a1e1663ef471ca', 'com.google.dagger:dagger:2.45:dagger-2.45.jar:f011cae7d2c0fb7ea17c34e05bc10e768b1081a5892ad019cf1fdb0e125c49c1',
'com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.13.0:android-test-plugin-host-additional-test-output-proto-31.13.0.jar:6ba7e6ac2208d74c1bb5f1d1464abafc6a45d8710b20455a2dc02adf8726bc83', 'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
'com.android.tools.utp:android-test-plugin-host-additional-test-output:31.13.0:android-test-plugin-host-additional-test-output-31.13.0.jar:fc5f224db1b1d21642339dff08e3bcc9bb3b6753c4e6a7d5e750769a7cbbbeb4', 'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
'com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.13.0:android-test-plugin-host-apk-installer-proto-31.13.0.jar:4f2b610542e91a35a396b04368a784036e42b8787021460550b9a3495bb8245b', 'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
'com.android.tools.utp:android-test-plugin-host-apk-installer:31.13.0:android-test-plugin-host-apk-installer-31.13.0.jar:ad4a65f53ed841253b875b3f4232826ca83e92d2f8df2c757944824d9f9bb1e2', 'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.android.tools.utp:android-test-plugin-host-coverage-proto:31.13.0:android-test-plugin-host-coverage-proto-31.13.0.jar:fa86719a3dc5de465f7e0c023184414c27f8fd53a34fd557289c0bf6df340244', 'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
'com.android.tools.utp:android-test-plugin-host-coverage:31.13.0:android-test-plugin-host-coverage-31.13.0.jar:6ef641e612a91dcf5c11eeec7e183ae616bccf18db968f8593c32c215ba45e6b', 'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
'com.android.tools.utp:android-test-plugin-host-device-info-proto:31.13.0:android-test-plugin-host-device-info-proto-31.13.0.jar:9683ac7648a7a41be9a1349f6981592944f627164898c3c8925a0beede8bb8bb', 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
'com.android.tools.utp:android-test-plugin-host-device-info:31.13.0:android-test-plugin-host-device-info-31.13.0.jar:bbf196a617d5f501f2696bfeabbee4b687b4e809d8d56d9c74610094f8a007cb', 'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
'com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.13.0:android-test-plugin-host-emulator-control-proto-31.13.0.jar:a4f34aae0f9ffa026dbf7151436dd7ae53becb72622b40f2c479cac8943d9319', 'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
'com.android.tools.utp:android-test-plugin-host-emulator-control:31.13.0:android-test-plugin-host-emulator-control-31.13.0.jar:43f5a73b559758c1d3a119277a109ea552a3e4f75368842fb79af7308ad22465', 'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
'com.android.tools.utp:android-test-plugin-host-logcat-proto:31.13.0:android-test-plugin-host-logcat-proto-31.13.0.jar:c1f6ebbacdad559b6efe4eaa29561552b33156395f069cd9703fda09c462dea6', 'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'com.android.tools.utp:android-test-plugin-host-logcat:31.13.0:android-test-plugin-host-logcat-31.13.0.jar:be7ccad0a7b8d062782b769030e17d573e96d302196b2f9985ec51cb42b6b76b', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.13.0:android-test-plugin-result-listener-gradle-proto-31.13.0.jar:d429b9312dffa0503381d1ee1b18a999bd901e7456612b2fb48c6a5d5a2caf88', 'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'com.android.tools.utp:android-test-plugin-result-listener-gradle:31.13.0:android-test-plugin-result-listener-gradle-31.13.0.jar:a1b95cbed5fd4b8c6a44e7db4642f1acc87f5bff956350e8ae644b505029c120', 'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
'com.android.tools.utp:utp-common:31.13.0:utp-common-31.13.0.jar:cde678a64b13041cdd2cc9dad1685990a1d090fb04ff5da2261ff75a83598106', 'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'com.android.tools:annotations:31.13.0:annotations-31.13.0.jar:3b4bb9620c17d19e5bd91ac1988080553573b4c3b739fdd92416f42f2daf3e78', 'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'com.android.tools:common:31.13.0:common-31.13.0.jar:b4b6f4ba94843c86e1365f294d9085b5f4f14f63fccd0f0e10da7fdbfa4c3d04', 'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'com.google.android:annotations:4.1.1.4:annotations-4.1.1.4.jar:ba734e1e84c09d615af6a09d33034b4f0442f8772dec120efb376d86a565ae15', 'org.briarproject:dont-kill-me-lib:0.2.7:dont-kill-me-lib-0.2.7.aar:8a9540941fd927e1c127096a7a9b4aa61ce2f2965d2e24f849be92f9e57213c4',
'com.google.api.grpc:proto-google-common-protos:2.17.0:proto-google-common-protos-2.17.0.jar:4ef1fe0c327fc1521d1d753b0b1c4a875a54bd14ebded3afff0ca395320b6ea9', 'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b',
'com.google.api.grpc:proto-google-common-protos:2.48.0:proto-google-common-protos-2.48.0.jar:43ec7807459aaa4012e838a1be4ef2d590cf233305da60af5b54f08ec8cf2302', 'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011',
'com.google.auto.service:auto-service-annotations:1.1.1:auto-service-annotations-1.1.1.jar:16a76dd00a2650568447f5d6e3a9e2c809d9a42367d56b45215cfb89731f4d24', 'org.briarproject:obfs4proxy-android:0.0.14-tor2:obfs4proxy-android-0.0.14-tor2.jar:a0a93770d6760ce57d9dbd31cc7177687374e00c3361dac22ab75e3b6e0f289e',
'com.google.auto.service:auto-service:1.1.1:auto-service-1.1.1.jar:1f48f451503e623daba7d9ed368cca0f81e1e3815653a4560113e12c0129ebd5', 'org.briarproject:onionwrapper-android:0.0.5:onionwrapper-android-0.0.5.aar:d761854dac454616b3e0ca099b2cd17060365ce4316afe495cc7ae86b6c81d15',
'com.google.auto:auto-common:1.2.1:auto-common-1.2.1.jar:f43f29fe2a6ebaf04b2598cdeec32a4e346d49a9404e990f5fc19c19f3a28d0e', 'org.briarproject:onionwrapper-core:0.0.5:onionwrapper-core-0.0.5.jar:9071678323535cb3dfe0f3add96066037db43ea024333eba0117c759bcbd8d63',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79', 'org.briarproject:snowflake-android:2.5.1:snowflake-android-2.5.1.jar:88ec81c17b1b6fa884d06839dec0330e328b45c89f88c970a213ce91ca8eac87',
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7', 'org.briarproject:tor-android:0.4.7.14:tor-android-0.4.7.14.jar:d39faa3a8abb116136c191c6ebadf8ea0e1f3e4785076d2c66a7b3b0f26988a2',
'com.google.code.gson:gson:2.10.1:gson-2.10.1.jar:4241c14a7727c34feea6507ec801318a3d4a90f070e4525681079fb94ee4c593', 'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'com.google.code.gson:gson:2.11.0:gson-2.11.0.jar:57928d6e5a6edeb2abd3770a8f95ba44dce45f3b23b7a9dc2b309c581552a78b', 'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
'com.google.code.gson:gson:2.8.9:gson-2.8.9.jar:d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e', 'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
'com.google.crypto.tink:tink:1.7.0:tink-1.7.0.jar:88970a456a08ba4c66b01b23e5846ca1095cc14e54cb48363e5d2e15a1307308', 'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
'com.google.dagger:dagger-compiler:2.51.1:dagger-compiler-2.51.1.jar:14cf2def1c4c8cd3b977840e297b463191d537cd1c8330992ca5c0b341a641ad', 'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
'com.google.dagger:dagger-spi:2.51.1:dagger-spi-2.51.1.jar:deb52030b92b27c5dcd76b2c0747f1cf105b60939f6073b43eb06cfe7c9ba601', 'org.jacoco:org.jacoco.agent:0.8.8:org.jacoco.agent-0.8.8.jar:072ecbd496896623899a696fff12c01c1615f737616d2792e6d0e10cdf8a610d',
'com.google.dagger:dagger:2.48:dagger-2.48.jar:1fa226d2b4a02cc80950fa4d49a4a235cc8eced499b581fc358a55446a83f579', 'org.jacoco:org.jacoco.ant:0.8.8:org.jacoco.ant-0.8.8.jar:02e33bd2c48dc0be67c2fea84d43beececfd400da6797c58153253d4c30aca15',
'com.google.dagger:dagger:2.51.1:dagger-2.51.1.jar:c3891a4c4a4e48682888ca321eaf8497004b286e1d9a2936867373219f7dd86d', 'org.jacoco:org.jacoco.core:0.8.8:org.jacoco.core-0.8.8.jar:474c782f809d88924713dfdbf0acb79d330f904be576484803463d0465611643',
'com.google.devtools.ksp:symbol-processing-api:1.9.20-1.0.14:symbol-processing-api-1.9.20-1.0.14.jar:d0339396f40dc9eb3b3f7bc86257f93869ee23448fa31ec4a1de900c6b7ae6d7', 'org.jacoco:org.jacoco.report:0.8.8:org.jacoco.report-0.8.8.jar:2c129110f3e3fcaa1f8179578ea3894586199cb0826be5c7790278084c9622a9',
'com.google.errorprone:error_prone_annotations:2.23.0:error_prone_annotations-2.23.0.jar:ec6f39f068b6ff9ac323c68e28b9299f8c0a80ca512dccb1d4a70f40ac3ec054', 'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
'com.google.errorprone:error_prone_annotations:2.28.0:error_prone_annotations-2.28.0.jar:f3fc8a3a0a4020706a373b00e7f57c2512dd26d1f83d28c7d38768f8682b231e', 'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
'com.google.errorprone:error_prone_annotations:2.30.0:error_prone_annotations-2.30.0.jar:144f3aefbd6e27daec55d3753b2c6b13c1afdaf0cf04816cdb564588ed92f1bd', 'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0:kotlin-stdlib-common-1.8.0.jar:78ef93b59e603cc0fe51def9bd4c037b07cbace3b3b7806d1a490a42bc1f4cb2',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30', 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e', 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0:kotlin-stdlib-jdk7-1.8.0.jar:4c889d1d9803f5f2eb6c1592a6b7e62369ac7660c9eee15aba16fec059163666',
'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
'com.google.guava:failureaccess:1.0.2:failureaccess-1.0.2.jar:8a8f81cf9b359e3f6dfa691a1e776985c061ef2f223c9b2c80753e1b458e8064', 'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
'com.google.guava:guava:32.0.1-jre:guava-32.0.1-jre.jar:bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5', 'org.jetbrains.kotlin:kotlin-stdlib:1.8.0:kotlin-stdlib-1.8.0.jar:c77bef8774640b9fb9d6e217459ff220dae59878beb7d2e4b430506feffc654e',
'com.google.guava:guava:33.0.0-jre:guava-33.0.0-jre.jar:f4d85c3e4d411694337cb873abea09b242b664bb013320be6105327c45991537', 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
'com.google.guava:guava:33.3.1-jre:guava-33.3.1-jre.jar:4bf0e2c5af8e4525c96e8fde17a4f7307f97f8478f11c4c8e35a0e3298ae4e90', 'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99', 'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
'com.google.j2objc:j2objc-annotations:2.8:j2objc-annotations-2.8.jar:f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed', 'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
'com.google.j2objc:j2objc-annotations:3.0.0:j2objc-annotations-3.0.0.jar:88241573467ddca44ffd4d74aa04c2bbfd11bf7c17e0c342c94c9de7a70a7c64', 'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd',
'com.google.protobuf:protobuf-java-util:3.22.3:protobuf-java-util-3.22.3.jar:c615f76879dc5c303e4df5b94a6afa39534058c7545db2d483fd95d9f63c8bfe', 'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
'com.google.protobuf:protobuf-java-util:3.24.4:protobuf-java-util-3.24.4.jar:133c929e2cfe3990a105d18eaccc49122b2d2fb492b420ef02d5d9f937eaebb8', 'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
'com.google.protobuf:protobuf-java:3.24.4:protobuf-java-3.24.4.jar:e5655522be1aa5cc1f2f092aa036b0445157f294928eedf1332ac938c7b69686', 'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
'com.google.protobuf:protobuf-java:3.25.5:protobuf-java-3.25.5.jar:8540247fad9e06baefa8fb45eb313802d019f485f14300e0f9d6b556ed88e753', 'org.ow2.asm:asm-analysis:9.2:asm-analysis-9.2.jar:878fbe521731c072d14d2d65b983b1beae6ad06fda0007b6a8bae81f73f433c4',
'com.google.protobuf:protobuf-kotlin:3.24.4:protobuf-kotlin-3.24.4.jar:508ca13d97b50f5404eaa37eb4493cb07884162eb7971bf924d8f803d4c21bb4', 'org.ow2.asm:asm-commons:9.2:asm-commons-9.2.jar:be4ce53138a238bb522cd781cf91f3ba5ce2f6ca93ec62d46a162a127225e0a6',
'com.google.testing.platform:android-device-provider-local:0.0.9-alpha03:android-device-provider-local-0.0.9-alpha03.jar:667a4d35bbba87d3c86f5180dfa521fdbd7a4ef5c60d949154b0301f3e232e1b', 'org.ow2.asm:asm-tree:9.2:asm-tree-9.2.jar:aabf9bd23091a4ebfc109c1f3ee7cf3e4b89f6ba2d3f51c5243f16b3cffae011',
'com.google.testing.platform:android-driver-instrumentation:0.0.9-alpha03:android-driver-instrumentation-0.0.9-alpha03.jar:507c632ec7db77bcb299b5519d59b14cc6243aac541767c632fdbeddc6226b07', 'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
'com.google.testing.platform:android-test-plugin:0.0.9-alpha03:android-test-plugin-0.0.9-alpha03.jar:d6cb7e126f433037190bcd3c3b904b19ba842d46b17b0fd27c38cc4ccecbec90', 'org.ow2.asm:asm:9.2:asm-9.2.jar:b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5',
'com.google.testing.platform:core-proto:0.0.9-alpha03:core-proto-0.0.9-alpha03.jar:d001eb0ccbbfc8cb9eaa193a358e63712974639775647be949ab232c2b29b407', ]
'com.google.testing.platform:core:0.0.9-alpha03:core-0.0.9-alpha03.jar:6e1806d015c416596f53a45a3100e25743c313a6e3fc4f52f24e8b257f2c82ce',
'com.google.testing.platform:launcher:0.0.9-alpha03:launcher-0.0.9-alpha03.jar:0012f980a059a0c4c216d0f1d0016867ab31eb8079e3f8f879f1f02b7be3a6e7',
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
'commons-io:commons-io:2.16.1:commons-io-2.16.1.jar:f41f7baacd716896447ace9758621f62c1c6b0a91d89acee488da26fc477c84f',
'io.grpc:grpc-api:1.57.2:grpc-api-1.57.2.jar:42b72e6572c084055ac3ce03e6efe433eb05ef620b3daf5136a4359fc72cc3e1',
'io.grpc:grpc-api:1.69.1:grpc-api-1.69.1.jar:a8d3d6dcc71f3ab613d668842282b488bdd93d3e99a0ef5dca7eee6fa734c283',
'io.grpc:grpc-context:1.57.2:grpc-context-1.57.2.jar:9b8ac88d9cef2819daffed7bdbd2f22680237d482c6c671fe02d36da3f08cf00',
'io.grpc:grpc-context:1.69.1:grpc-context-1.69.1.jar:45ef95b8c158a8b5bdd3acb67b9e682ef25414bb148f488ec847438ab64715d4',
'io.grpc:grpc-core:1.57.2:grpc-core-1.57.2.jar:5a10070abfeb4966ec4d580961dcc4e7f69fa83ab25242f92c1765efb07b8606',
'io.grpc:grpc-core:1.69.1:grpc-core-1.69.1.jar:51352cadaecbf9a4a4aa42d93f6f1fc728f1fd01b051680383ed09e5631ffbd0',
'io.grpc:grpc-inprocess:1.69.1:grpc-inprocess-1.69.1.jar:b7c6ac0e3abf4b8d582610d632d79417bc3da81254e1a4bcf7f01e8db7bd55ef',
'io.grpc:grpc-netty:1.57.2:grpc-netty-1.57.2.jar:9809d4c10c94d11e7b2946cdeb5b2884be20a09510289544f37569f02c877a21',
'io.grpc:grpc-netty:1.69.1:grpc-netty-1.69.1.jar:52a86ed66f78933e83d1a3fb7162ad1667489564c4556366b7a3579c7024a447',
'io.grpc:grpc-protobuf-lite:1.57.2:grpc-protobuf-lite-1.57.2.jar:fc4917dc5d419ac810fb3f27523c14e75e1fe50372154fab29324215ee6a955a',
'io.grpc:grpc-protobuf-lite:1.69.1:grpc-protobuf-lite-1.69.1.jar:c29f90fadf3c7620f9359a243c067dd85b73bd765b28f3d95df910ac2d331555',
'io.grpc:grpc-protobuf:1.57.2:grpc-protobuf-1.57.2.jar:31630d8a9e9f08a959862015e30a4863908be3680c3a686f4c1f08d2ffeaf706',
'io.grpc:grpc-protobuf:1.69.1:grpc-protobuf-1.69.1.jar:4c52ef948fb8987a3baa7d46ba362b7bf307dd3c51f29241cd5c598398a010df',
'io.grpc:grpc-services:1.57.2:grpc-services-1.57.2.jar:057a43ba647833756ab2f851bac80a3b9f8dce026fc1ac1f17d4f315648f4172',
'io.grpc:grpc-stub:1.57.2:grpc-stub-1.57.2.jar:84d2af12719168f76375f2afdfd6eb5133a865edba9244d40e6b968e3adde1d3',
'io.grpc:grpc-stub:1.69.1:grpc-stub-1.69.1.jar:e39c63273d53052ebe9f638d8ae98176735ec567328d9a17092cddb6f239b8c2',
'io.grpc:grpc-util:1.69.1:grpc-util-1.69.1.jar:dd597bd675eaa042f3e3578648d9050c813c4595c5de6869ef9ddbb449006031',
'io.netty:netty-buffer:4.1.110.Final:netty-buffer-4.1.110.Final.jar:46d74e79125aacc055c31f18152fdc5d4a569aa8d60091203d0baa833973ac3c',
'io.netty:netty-buffer:4.1.93.Final:netty-buffer-4.1.93.Final.jar:007c7d9c378df02d390567d0d7ddf542ffddb021b7313dbf502392113ffabb08',
'io.netty:netty-codec-http2:4.1.110.Final:netty-codec-http2-4.1.110.Final.jar:b546c75445a487bb7bcd5a94779caecce33582cf7be31b8b39fc0e65b1ee26fc',
'io.netty:netty-codec-http2:4.1.93.Final:netty-codec-http2-4.1.93.Final.jar:d96cc09045a1341c6d47494352aa263b87b72fb1d2ea9eca161aa73820bfe8bb',
'io.netty:netty-codec-http:4.1.110.Final:netty-codec-http-4.1.110.Final.jar:dc0d6af5054630a70ff0ef354f20aa7a6e46738c9fc5636ed3d4fe77e38bd48d',
'io.netty:netty-codec-http:4.1.93.Final:netty-codec-http-4.1.93.Final.jar:dacf78ce78ab2d29570325db4cd2451ea589639807de95881a0fa7155a9e6b55',
'io.netty:netty-codec-socks:4.1.110.Final:netty-codec-socks-4.1.110.Final.jar:976052a3c9bb280bc6d99f3a29e6404677cf958c3de05b205093d38c006b880c',
'io.netty:netty-codec-socks:4.1.93.Final:netty-codec-socks-4.1.93.Final.jar:0ea47b5ba23ca1da8eb9146c8fc755c1271414633b1e2be2ce1df764ba0fff2a',
'io.netty:netty-codec:4.1.110.Final:netty-codec-4.1.110.Final.jar:9eccce9a8d827bb8ce84f9c3183fec58bd1c96a51010cf711297746034af3701',
'io.netty:netty-codec:4.1.93.Final:netty-codec-4.1.93.Final.jar:990c378168dc6364c6ff569701f4f2f122fffe8998b3e189eba4c4d868ed1084',
'io.netty:netty-common:4.1.110.Final:netty-common-4.1.110.Final.jar:9851ec66548b9e0d41164ce98943cdd4bbe305f68ddbd24eae52e4501a0d7b1a',
'io.netty:netty-common:4.1.93.Final:netty-common-4.1.93.Final.jar:443bb316599fb16e3baeba2fb58881814d7ff0b7af176fe76e38071a6e86f8c0',
'io.netty:netty-handler-proxy:4.1.110.Final:netty-handler-proxy-4.1.110.Final.jar:ad54ab4fe9c47ef3e723d71251126db53e8db543871adb9eafc94446539eff52',
'io.netty:netty-handler-proxy:4.1.93.Final:netty-handler-proxy-4.1.93.Final.jar:2ac5f7fbefa0b73ef783889069344d5515505a14b2303be693c5002c486df2b4',
'io.netty:netty-handler:4.1.110.Final:netty-handler-4.1.110.Final.jar:d5a08d7de364912e4285968de4d4cce3f01da4bb048d5c6937e5f2af1f8e148a',
'io.netty:netty-handler:4.1.93.Final:netty-handler-4.1.93.Final.jar:4e5f563ae14ed713381816d582f5fcfd0615aefb29203486cdfb782d8a00a02b',
'io.netty:netty-resolver:4.1.110.Final:netty-resolver-4.1.110.Final.jar:a2e9b4ae7caa92fc5bd747e11d1dec20d81b18fc00959554302244ac5c56ce70',
'io.netty:netty-resolver:4.1.93.Final:netty-resolver-4.1.93.Final.jar:e59770b66e81822e5d111ac4e544d7eb0c543e0a285f52628e53941acd8ed759',
'io.netty:netty-transport-native-unix-common:4.1.110.Final:netty-transport-native-unix-common-4.1.110.Final.jar:51717bb7471141950390c6713a449fdb1054d07e60737ee7dda7083796cdee48',
'io.netty:netty-transport-native-unix-common:4.1.93.Final:netty-transport-native-unix-common-4.1.93.Final.jar:774165a1c4dbaacb17f9c1ad666b3569a6a59715ae828e7c3d47703f479a53e7',
'io.netty:netty-transport:4.1.110.Final:netty-transport-4.1.110.Final.jar:a42dd68390ca14b4ff2d40628a096c76485b4adb7c19602d5289321a0669e704',
'io.netty:netty-transport:4.1.93.Final:netty-transport-4.1.93.Final.jar:a5a78019bc1cd43dbc3c7b7cdd3801912ca26d1f498fb560514fee497864ba96',
'io.opencensus:opencensus-api:0.31.0:opencensus-api-0.31.0.jar:702ba55d78f39d55195dcf041fdfaab7a7490a9ac45013542487ed9e4d3a4d23',
'io.opencensus:opencensus-proto:0.2.0:opencensus-proto-0.2.0.jar:0c192d451e9dd74e98721b27d02f0e2b6bca44b51563b5dabf2e211f7a3ebf13',
'io.perfmark:perfmark-api:0.26.0:perfmark-api-0.26.0.jar:b7d23e93a34537ce332708269a0d1404788a5b5e1949e82f5535fce51b3ea95b',
'io.perfmark:perfmark-api:0.27.0:perfmark-api-0.27.0.jar:c7b478503ec524e55df19b424d46d27c8a68aeb801664fadd4f069b71f52d0f6',
'javax.annotation:javax.annotation-api:1.3.2:javax.annotation-api-1.3.2.jar:e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b',
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.bytebuddy:byte-buddy: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.kxml:kxml2:2.3.0:kxml2-2.3.0.jar:f264dd9f79a1fde10ce5ecc53221eff24be4c9331c830b7d52f2f08a7b633de2',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.briarproject:dont-kill-me-lib:0.2.8:dont-kill-me-lib-0.2.8.aar:e21173e480ee3f2364c142cc14db8dc6447be91bde9e62e4985c485ea0af9126',
'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b',
'org.briarproject:lyrebird-android:0.6.2:lyrebird-android-0.6.2.jar:2d70a38393ee6f1760a65a33dd971210efa06b5a355ebea829196b61fd9fd11a',
'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011',
'org.briarproject:onionwrapper-android:0.1.4:onionwrapper-android-0.1.4.aar:15231f0b2ad44df8eb1dd362a989ba3f88ebdc9b02a9128daa72a8da83651bf0',
'org.briarproject:onionwrapper-core:0.1.4:onionwrapper-core-0.1.4.jar:d0a48de7198d48eb0182a25d109bc06811484d1da799c6dfa5e2581285880a49',
'org.briarproject:tor-android:0.4.8.21:tor-android-0.4.8.21.jar:0b797b2a4f07430b4465f784ee579c8c19b5def921a655caba4622b232ae2118',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.checkerframework:checker-qual:3.33.0:checker-qual-3.33.0.jar:e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1',
'org.checkerframework:checker-qual:3.41.0:checker-qual-3.41.0.jar:2f9f245bf68e4259d610894f2406dc1f6363dc639302bd566e8272e4f4541172',
'org.checkerframework:checker-qual:3.43.0:checker-qual-3.43.0.jar:3fbc2e98f05854c3df16df9abaa955b91b15b3ecac33623208ed6424640ef0f6',
'org.codehaus.mojo:animal-sniffer-annotations:1.23:animal-sniffer-annotations-1.23.jar:9ffe526bf43a6348e9d8b33b9cd6f580a7f5eed0cf055913007eda263de974d0',
'org.codehaus.mojo:animal-sniffer-annotations:1.24:animal-sniffer-annotations-1.24.jar:c720e6e5bcbe6b2f48ded75a47bccdb763eede79d14330102e0d352e3d89ed92',
'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.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
'org.jetbrains.kotlin:kotlin-reflect:1.8.21:kotlin-reflect-1.8.21.jar:8a6cd5a3cf092acee274ce2c444dc36eefdb631579859dd4d857b3309a529c91',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21:kotlin-stdlib-common-1.8.21.jar:6a44c9ecc9d7754d9e943fb1e3588c74d4a3f1785be51074f49d6c5723682a73',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0:kotlin-stdlib-common-1.9.0.jar:283274204bd7c020789ec46f8f8e72af4244d7f550b3392a57e5ca006ad7aa2c',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10:kotlin-stdlib-common-1.9.10.jar:cde3341ba18a2ba262b0b7cf6c55b20c90e8d434e42c9a13e6a3f770db965a88',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20:kotlin-stdlib-jdk7-1.8.20.jar:af1ec40c3b951afdcc0c2a0173c7b81763c5281c2d5bafbf0a8544a24c5dcc0c',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0:kotlin-stdlib-jdk7-1.9.0.jar:b7979a7aac94055f0d9f1fd3b47ce5ffe1cb6032a842ba9fbe7186f085289178',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10:kotlin-stdlib-jdk7-1.9.10.jar:ac6361bf9ad1ed382c2103d9712c47cdec166232b4903ed596e8876b0681c9b7',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.0:kotlin-stdlib-jdk7-2.2.0.jar:0d10bc0d42b8605f23629a3f31ea27c19cdbca9dcdf4f53f6d22cd6366836d18',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20:kotlin-stdlib-jdk8-1.8.20.jar:e398b67977622718bf18ff99b739c7d9da060f33fb458a2e25203221c16af010',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0:kotlin-stdlib-jdk8-1.9.0.jar:a59fa24fdf1ffb594baecdbf0fd10010f977cea10236d487fe3464977a7377fa',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.0:kotlin-stdlib-jdk8-2.2.0.jar:adc16648dbbcf35b0d10e7ec301c35d746d1c2fe460c606aba59f12b117cf9b0',
'org.jetbrains.kotlin:kotlin-stdlib:1.8.21:kotlin-stdlib-1.8.21.jar:042a1cd1ac976cdcfe5eb63f1d8e0b0b892c9248e15a69c8cfba495d546ea52a',
'org.jetbrains.kotlin:kotlin-stdlib:1.9.0:kotlin-stdlib-1.9.0.jar:35aeffbe2db5aa446072cee50fcee48b7fa9e2fc51ca37c0cc7d7d0bc39d952e',
'org.jetbrains.kotlin:kotlin-stdlib:1.9.10:kotlin-stdlib-1.9.10.jar:55e989c512b80907799f854309f3bc7782c5b3d13932442d0379d5c472711504',
'org.jetbrains.kotlin:kotlin-stdlib:1.9.20:kotlin-stdlib-1.9.20.jar:28a35bcdff46d864f80f346a617e486284b208d17378c41900dfb1de95a90e6c',
'org.jetbrains.kotlin:kotlin-stdlib:2.2.0:kotlin-stdlib-2.2.0.jar:65d12d85a3b865c160db9147851712a64b10dadd68b22eea22a95bf8a8670dca',
'org.jetbrains.kotlinx:atomicfu-jvm:0.22.0:atomicfu-jvm-0.22.0.jar:2da073727f3ab5e5584e74c12e11519c908ae2dfaf6aeb25ded42b6682297882',
'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3:kotlinx-coroutines-core-jvm-1.7.3.jar:1ab3acc38f3e7355c4f9d1ec62107a46fa73c899f3070d055e5d4373dfe67e12',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.jetbrains:annotations:23.0.0:annotations-23.0.0.jar:7b0f19724082cbfcbc66e5abea2b9bc92cf08a1ea11e191933ed43801eb3cd05',
'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.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
]
} }

View File

@@ -27,8 +27,8 @@ configurations {
} }
task jarTest(type: Jar, dependsOn: testClasses) { task jarTest(type: Jar, dependsOn: testClasses) {
from sourceSets.test.output, sourceSets.main.output from sourceSets.test.output, sourceSets.main.output
archiveClassifier = 'test' classifier = 'test'
} }
artifacts { artifacts {
testOutput jarTest testOutput jarTest
} }

View File

@@ -46,7 +46,6 @@ public interface TorConstants {
/** /**
* Reason flag returned by {@link Plugin#getReasonsDisabled()}. * Reason flag returned by {@link Plugin#getReasonsDisabled()}.
* Currently unused, but may be worth keeping for future use.
*/ */
int REASON_COUNTRY_BLOCKED = 8; int REASON_COUNTRY_BLOCKED = 8;
} }

View File

@@ -1,29 +1,29 @@
dependencyVerification { dependencyVerification {
verify = [ verify = [
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db', 'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.fasterxml.jackson.core:jackson-annotations:2.13.4:jackson-annotations-2.13.4.jar:ac5b27a634942391ca113850ee7db01df1499a240174021263501c05fc653b44', 'com.fasterxml.jackson.core:jackson-annotations:2.13.4:jackson-annotations-2.13.4.jar:ac5b27a634942391ca113850ee7db01df1499a240174021263501c05fc653b44',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79', '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.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger:2.51.1:dagger-2.51.1.jar:c3891a4c4a4e48682888ca321eaf8497004b286e1d9a2936867373219f7dd86d', 'com.google.dagger:dagger:2.45:dagger-2.45.jar:f011cae7d2c0fb7ea17c34e05bc10e768b1081a5892ad019cf1fdb0e125c49c1',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3', '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.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', 'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047', 'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011', 'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011',
'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619', 'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619',
'org.codehaus.mojo:animal-sniffer-annotations:1.24:animal-sniffer-annotations-1.24.jar:c720e6e5bcbe6b2f48ded75a47bccdb763eede79d14330102e0d352e3d89ed92', 'org.codehaus.mojo:animal-sniffer-ant-tasks:1.22:animal-sniffer-ant-tasks-1.22.jar:3f6afeb3e09301d2d7179ed1db21e3ad8846c1e38415ad832a395138ae3f4218',
'org.codehaus.mojo:animal-sniffer:1.24:animal-sniffer-1.24.jar:65d028de87134f0955e3a964fe438fc3e99e77b237a77e5e165869a8ff59db5f', 'org.codehaus.mojo:animal-sniffer:1.22:animal-sniffer-1.22.jar:f18c11a25bdd8b520b9c6a28cbb6f33007c812ab0051b6be3f0778e660aa501c',
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9', 'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21', 'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050', 'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09', '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-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-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-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04',
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be', 'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be',
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984', 'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de', 'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
'org.ow2.asm:asm:9.7:asm-9.7.jar:adf46d5e34940bdf148ecdd26a9ee8eea94496a72034ff7141066b3eea5c4e9d', 'org.ow2.asm:asm:9.3:asm-9.3.jar:1263369b59e29c943918de11d6d6152e2ec6085ce63e5710516f8c67d368e4bc',
] ]
} }

View File

@@ -14,8 +14,9 @@ dependencies {
api "org.briarproject:onionwrapper-core:$onionwrapper_version" api "org.briarproject:onionwrapper-core:$onionwrapper_version"
implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version" implementation "org.bouncycastle:bcprov-jdk15to18:$bouncy_castle_version"
//noinspection GradleDependency // 2.2.222 includes a precompiled Java 21 class that breaks the jetifier, so it will require
implementation 'com.h2database:h2:1.4.192' // The last version that supports Java 1.6 // a Gradle/AGP upgrade
implementation 'com.h2database:h2:2.2.220'
implementation 'org.bitlet:weupnp:0.1.4' implementation 'org.bitlet:weupnp:0.1.4'
implementation 'net.i2p.crypto:eddsa:0.2.0' implementation 'net.i2p.crypto:eddsa:0.2.0'
implementation 'org.whispersystems:curve25519-java:0.5.0' implementation 'org.whispersystems:curve25519-java:0.5.0'
@@ -54,8 +55,8 @@ configurations {
} }
task jarTest(type: Jar, dependsOn: testClasses) { task jarTest(type: Jar, dependsOn: testClasses) {
from sourceSets.test.output, sourceSets.main.output from sourceSets.test.output, sourceSets.main.output
archiveClassifier = 'test' classifier = 'test'
} }
artifacts { artifacts {
testOutput jarTest testOutput jarTest
} }

View File

@@ -107,8 +107,6 @@ class CryptoComponentImpl implements CryptoComponent {
} }
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html // Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
// "Applications which run exclusively on Android KitKat (4.4) or above do
// not need to take any special action to work around this bug."
private void installSecureRandomProvider(Provider provider) { private void installSecureRandomProvider(Provider provider) {
Provider[] providers = Security.getProviders("SecureRandom.SHA1PRNG"); Provider[] providers = Security.getProviders("SecureRandom.SHA1PRNG");
if (providers == null || providers.length == 0 if (providers == null || providers.length == 0

View File

@@ -38,7 +38,7 @@ class H2Database extends JdbcDatabase {
private static final String HASH_TYPE = "BINARY(32)"; private static final String HASH_TYPE = "BINARY(32)";
private static final String SECRET_TYPE = "BINARY(32)"; private static final String SECRET_TYPE = "BINARY(32)";
private static final String BINARY_TYPE = "BINARY"; private static final String BINARY_TYPE = "BINARY VARYING";
private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT"; private static final String COUNTER_TYPE = "INT NOT NULL AUTO_INCREMENT";
private static final String STRING_TYPE = "VARCHAR"; private static final String STRING_TYPE = "VARCHAR";
private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE, private static final DatabaseTypes dbTypes = new DatabaseTypes(HASH_TYPE,
@@ -57,8 +57,7 @@ class H2Database extends JdbcDatabase {
this.config = config; this.config = config;
File dir = config.getDatabaseDirectory(); File dir = config.getDatabaseDirectory();
String path = new File(dir, "db").getAbsolutePath(); String path = new File(dir, "db").getAbsolutePath();
url = "jdbc:h2:split:" + path + ";CIPHER=AES;MULTI_THREADED=1" url = "jdbc:h2:split:" + path + ";CIPHER=AES;WRITE_DELAY=0";
+ ";WRITE_DELAY=0";
} }
@Override @Override
@@ -89,17 +88,11 @@ class H2Database extends JdbcDatabase {
try { try {
c = createConnection(); c = createConnection();
closeAllConnections(); closeAllConnections();
LOG.info("Compacting DB"); setDirty(c, false);
s = c.createStatement(); s = c.createStatement();
s.execute("SHUTDOWN COMPACT"); s.execute("SHUTDOWN COMPACT");
LOG.info("Finished compacting DB");
s.close(); s.close();
c.close(); c.close();
// Reopen the DB to mark it as clean after compacting
c = createConnection();
setDirty(c, false);
LOG.info("Marked DB as clean");
c.close();
} catch (SQLException e) { } catch (SQLException e) {
tryToClose(s, LOG, WARNING); tryToClose(s, LOG, WARNING);
tryToClose(c, LOG, WARNING); tryToClose(c, LOG, WARNING);
@@ -132,7 +125,6 @@ class H2Database extends JdbcDatabase {
closeAllConnections(); closeAllConnections();
s = c.createStatement(); s = c.createStatement();
s.execute("SHUTDOWN COMPACT"); s.execute("SHUTDOWN COMPACT");
LOG.info("Finished compacting DB");
s.close(); s.close();
c.close(); c.close();
} catch (SQLException e) { } catch (SQLException e) {

View File

@@ -117,7 +117,7 @@ abstract class JdbcDatabase implements Database<Connection> {
"CREATE TABLE settings" "CREATE TABLE settings"
+ " (namespace _STRING NOT NULL," + " (namespace _STRING NOT NULL,"
+ " settingKey _STRING NOT NULL," + " settingKey _STRING NOT NULL,"
+ " value _STRING NOT NULL," + " settingValue _STRING NOT NULL,"
+ " PRIMARY KEY (namespace, settingKey))"; + " PRIMARY KEY (namespace, settingKey))";
private static final String CREATE_LOCAL_AUTHORS = private static final String CREATE_LOCAL_AUTHORS =
@@ -143,7 +143,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " handshakePublicKey _BINARY," // Null if key is unknown + " handshakePublicKey _BINARY," // Null if key is unknown
+ " localAuthorId _HASH NOT NULL," + " localAuthorId _HASH NOT NULL,"
+ " verified BOOLEAN NOT NULL," + " verified BOOLEAN NOT NULL,"
+ " syncVersions _BINARY DEFAULT '00' NOT NULL," + " syncVersions _BINARY DEFAULT X'00' NOT NULL,"
+ " PRIMARY KEY (contactId)," + " PRIMARY KEY (contactId),"
+ " FOREIGN KEY (localAuthorId)" + " FOREIGN KEY (localAuthorId)"
+ " REFERENCES localAuthors (authorId)" + " REFERENCES localAuthors (authorId)"
@@ -161,7 +161,7 @@ abstract class JdbcDatabase implements Database<Connection> {
"CREATE TABLE groupMetadata" "CREATE TABLE groupMetadata"
+ " (groupId _HASH NOT NULL," + " (groupId _HASH NOT NULL,"
+ " metaKey _STRING NOT NULL," + " metaKey _STRING NOT NULL,"
+ " value _BINARY NOT NULL," + " metaValue _BINARY NOT NULL,"
+ " PRIMARY KEY (groupId, metaKey)," + " PRIMARY KEY (groupId, metaKey),"
+ " FOREIGN KEY (groupId)" + " FOREIGN KEY (groupId)"
+ " REFERENCES groups (groupId)" + " REFERENCES groups (groupId)"
@@ -206,7 +206,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " groupId _HASH NOT NULL," // Denormalised + " groupId _HASH NOT NULL," // Denormalised
+ " state INT NOT NULL," // Denormalised + " state INT NOT NULL," // Denormalised
+ " metaKey _STRING NOT NULL," + " metaKey _STRING NOT NULL,"
+ " value _BINARY NOT NULL," + " metaValue _BINARY NOT NULL,"
+ " PRIMARY KEY (messageId, metaKey)," + " PRIMARY KEY (messageId, metaKey),"
+ " FOREIGN KEY (messageId)" + " FOREIGN KEY (messageId)"
+ " REFERENCES messages (messageId)" + " REFERENCES messages (messageId)"
@@ -1926,7 +1926,7 @@ abstract class JdbcDatabase implements Database<Connection> {
Set<MessageId> intersection = null; Set<MessageId> intersection = null;
String sql = "SELECT messageId FROM messageMetadata" String sql = "SELECT messageId FROM messageMetadata"
+ " WHERE groupId = ? AND state = ?" + " WHERE groupId = ? AND state = ?"
+ " AND metaKey = ? AND value = ?"; + " AND metaKey = ? AND metaValue = ?";
for (Entry<String, byte[]> e : query.entrySet()) { for (Entry<String, byte[]> e : query.entrySet()) {
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getBytes()); ps.setBytes(1, g.getBytes());
@@ -1982,7 +1982,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT messageId, metaKey, value" String sql = "SELECT messageId, metaKey, metaValue"
+ " FROM messageMetadata" + " FROM messageMetadata"
+ " WHERE groupId = ? AND state = ?"; + " WHERE groupId = ? AND state = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
@@ -2027,7 +2027,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT metaKey, value FROM groupMetadata" String sql = "SELECT metaKey, metaValue FROM groupMetadata"
+ " WHERE groupId = ?"; + " WHERE groupId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getBytes()); ps.setBytes(1, g.getBytes());
@@ -2050,7 +2050,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT metaKey, value FROM messageMetadata" String sql = "SELECT metaKey, metaValue FROM messageMetadata"
+ " WHERE state = ? AND messageId = ?"; + " WHERE state = ? AND messageId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setInt(1, DELIVERED.getValue()); ps.setInt(1, DELIVERED.getValue());
@@ -2074,7 +2074,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT metaKey, value FROM messageMetadata" String sql = "SELECT metaKey, metaValue FROM messageMetadata"
+ " WHERE (state = ? OR state = ?)" + " WHERE (state = ? OR state = ?)"
+ " AND messageId = ?"; + " AND messageId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
@@ -2678,7 +2678,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT settingKey, value FROM settings" String sql = "SELECT settingKey, settingValue FROM settings"
+ " WHERE namespace = ?"; + " WHERE namespace = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setString(1, namespace); ps.setString(1, namespace);
@@ -2914,7 +2914,8 @@ abstract class JdbcDatabase implements Database<Connection> {
g.getBytes(), meta, "groupMetadata", "groupId"); g.getBytes(), meta, "groupMetadata", "groupId");
if (added.isEmpty()) return; if (added.isEmpty()) return;
// Insert any keys that don't already exist // Insert any keys that don't already exist
String sql = "INSERT INTO groupMetadata (groupId, metaKey, value)" String sql = "INSERT INTO groupMetadata"
+ " (groupId, metaKey, metaValue)"
+ " VALUES (?, ?, ?)"; + " VALUES (?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getBytes()); ps.setBytes(1, g.getBytes());
@@ -2957,7 +2958,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.close(); ps.close();
// Insert any keys that don't already exist // Insert any keys that don't already exist
sql = "INSERT INTO messageMetadata" sql = "INSERT INTO messageMetadata"
+ " (messageId, groupId, state, metaKey, value)" + " (messageId, groupId, state, metaKey, metaValue)"
+ " VALUES (?, ?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getBytes()); ps.setBytes(1, m.getBytes());
@@ -3016,7 +3017,7 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
if (notRemoved.isEmpty()) return Collections.emptyMap(); if (notRemoved.isEmpty()) return Collections.emptyMap();
// Update any keys that already exist // Update any keys that already exist
String sql = "UPDATE " + tableName + " SET value = ?" String sql = "UPDATE " + tableName + " SET metaValue = ?"
+ " WHERE " + columnName + " = ? AND metaKey = ?"; + " WHERE " + columnName + " = ? AND metaKey = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(2, id); ps.setBytes(2, id);
@@ -3053,7 +3054,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
// Update any settings that already exist // Update any settings that already exist
String sql = "UPDATE settings SET value = ?" String sql = "UPDATE settings SET settingValue = ?"
+ " WHERE namespace = ? AND settingKey = ?"; + " WHERE namespace = ? AND settingKey = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
for (Entry<String, String> e : s.entrySet()) { for (Entry<String, String> e : s.entrySet()) {
@@ -3069,7 +3070,7 @@ abstract class JdbcDatabase implements Database<Connection> {
if (rows > 1) throw new DbStateException(); if (rows > 1) throw new DbStateException();
} }
// Insert any settings that don't already exist // Insert any settings that don't already exist
sql = "INSERT INTO settings (namespace, settingKey, value)" sql = "INSERT INTO settings (namespace, settingKey, settingValue)"
+ " VALUES (?, ?, ?)"; + " VALUES (?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
int updateIndex = 0, inserted = 0; int updateIndex = 0, inserted = 0;

View File

@@ -388,6 +388,7 @@ abstract class AbstractBluetoothPlugin<S, SS> implements BluetoothPlugin,
} }
// Validate the UUID // Validate the UUID
try { try {
//noinspection ResultOfMethodCallIgnored
UUID.fromString(uuid); UUID.fromString(uuid);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
if (LOG.isLoggable(WARNING)) LOG.warning("Invalid UUID " + uuid); if (LOG.isLoggable(WARNING)) LOG.warning("Invalid UUID " + uuid);

View File

@@ -75,6 +75,7 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ONLY_WHE
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3; 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_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.REASON_MOBILE_DATA;
import static org.briarproject.bramble.plugin.tor.TorRendezvousCrypto.SEED_BYTES; import static org.briarproject.bramble.plugin.tor.TorRendezvousCrypto.SEED_BYTES;
import static org.briarproject.bramble.util.IoUtils.tryToClose; import static org.briarproject.bramble.util.IoUtils.tryToClose;
@@ -105,6 +106,7 @@ class TorPlugin implements DuplexPlugin, EventListener {
private final PluginCallback callback; private final PluginCallback callback;
private final long maxLatency; private final long maxLatency;
private final int maxIdleTime; private final int maxIdleTime;
private final boolean canVerifyLetsEncryptCerts;
private final int socketTimeout; private final int socketTimeout;
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
@@ -124,7 +126,8 @@ class TorPlugin implements DuplexPlugin, EventListener {
TorWrapper tor, TorWrapper tor,
PluginCallback callback, PluginCallback callback,
long maxLatency, long maxLatency,
int maxIdleTime) { int maxIdleTime,
boolean canVerifyLetsEncryptCerts) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.wakefulIoExecutor = wakefulIoExecutor; this.wakefulIoExecutor = wakefulIoExecutor;
this.networkManager = networkManager; this.networkManager = networkManager;
@@ -138,6 +141,7 @@ class TorPlugin implements DuplexPlugin, EventListener {
this.callback = callback; this.callback = callback;
this.maxLatency = maxLatency; this.maxLatency = maxLatency;
this.maxIdleTime = maxIdleTime; this.maxIdleTime = maxIdleTime;
this.canVerifyLetsEncryptCerts = canVerifyLetsEncryptCerts;
if (maxIdleTime > Integer.MAX_VALUE / 2) { if (maxIdleTime > Integer.MAX_VALUE / 2) {
socketTimeout = Integer.MAX_VALUE; socketTimeout = Integer.MAX_VALUE;
} else { } else {
@@ -293,7 +297,7 @@ class TorPlugin implements DuplexPlugin, EventListener {
List<String> bridges = new ArrayList<>(); List<String> bridges = new ArrayList<>();
for (BridgeType bridgeType : bridgeTypes) { for (BridgeType bridgeType : bridgeTypes) {
bridges.addAll(circumventionProvider.getBridges(bridgeType, bridges.addAll(circumventionProvider.getBridges(bridgeType,
countryCode)); countryCode, canVerifyLetsEncryptCerts));
} }
tor.enableBridges(bridges); tor.enableBridges(bridges);
} }
@@ -487,8 +491,8 @@ class TorPlugin implements DuplexPlugin, EventListener {
boolean wifi = status.isWifi(); boolean wifi = status.isWifi();
boolean ipv6Only = status.isIpv6Only(); boolean ipv6Only = status.isIpv6Only();
String country = locationUtils.getCurrentCountry(); String country = locationUtils.getCurrentCountry();
boolean bridgesByDefault = boolean blocked =
circumventionProvider.shouldUseBridges(country); circumventionProvider.isTorProbablyBlocked(country);
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE,
DEFAULT_PREF_PLUGIN_ENABLE); DEFAULT_PREF_PLUGIN_ENABLE);
int network = settings.getInt(PREF_TOR_NETWORK, int network = settings.getInt(PREF_TOR_NETWORK,
@@ -498,6 +502,7 @@ class TorPlugin implements DuplexPlugin, EventListener {
boolean onlyWhenCharging = boolean onlyWhenCharging =
settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING,
DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING); DEFAULT_PREF_TOR_ONLY_WHEN_CHARGING);
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC; boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
@@ -527,6 +532,10 @@ class TorPlugin implements DuplexPlugin, EventListener {
LOG.info("Configured not to use mobile data"); LOG.info("Configured not to use mobile data");
reasonsDisabled |= REASON_MOBILE_DATA; reasonsDisabled |= REASON_MOBILE_DATA;
} }
if (automatic && blocked && !bridgesWork) {
LOG.info("Country is blocked");
reasonsDisabled |= REASON_COUNTRY_BLOCKED;
}
if (reasonsDisabled != 0) { if (reasonsDisabled != 0) {
LOG.info("Disabling network due to settings"); LOG.info("Disabling network due to settings");
@@ -534,7 +543,7 @@ class TorPlugin implements DuplexPlugin, EventListener {
LOG.info("Enabling network"); LOG.info("Enabling network");
enableNetwork = true; enableNetwork = true;
if (network == PREF_TOR_NETWORK_WITH_BRIDGES || if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
(automatic && bridgesByDefault)) { (automatic && bridgesWork)) {
if (ipv6Only) { if (ipv6Only) {
bridgeTypes = asList(MEEK, SNOWFLAKE); bridgeTypes = asList(MEEK, SNOWFLAKE);
} else { } else {

View File

@@ -1,45 +0,0 @@
package org.briarproject.bramble.crypto;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
import static java.util.Arrays.fill;
/**
* A fake SecureRandom implementation for testing, which returns all zeroes.
*/
public class NeitherSecureNorRandom extends SecureRandom {
private static final Provider PROVIDER =
new NeitherSecureNorRandomProvider();
public NeitherSecureNorRandom() {
super(new NeitherSecureNorRandomSpi(), PROVIDER);
}
private static class NeitherSecureNorRandomSpi extends SecureRandomSpi {
@Override
protected byte[] engineGenerateSeed(int length) {
return new byte[length];
}
@Override
protected void engineNextBytes(byte[] b) {
fill(b, (byte) 0);
}
@Override
protected void engineSetSeed(byte[] seed) {
// Thank you for your input
}
}
private static class NeitherSecureNorRandomProvider extends Provider {
private NeitherSecureNorRandomProvider() {
super("NeitherSecureNorRandom", 1.0, "Only for testing");
}
}
}

View File

@@ -0,0 +1,34 @@
package org.briarproject.bramble.crypto;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.Blake2bDigest;
import org.bouncycastle.crypto.engines.Salsa20Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.briarproject.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe
@NotNullByDefault
class PseudoRandom {
private final Salsa20Engine cipher = new Salsa20Engine();
PseudoRandom(byte[] seed) {
// Hash the seed to produce a 32-byte key
byte[] key = new byte[32];
Digest digest = new Blake2bDigest(256);
digest.update(seed, 0, seed.length);
digest.doFinal(key, 0);
// Initialise the stream cipher with an all-zero nonce
byte[] nonce = new byte[8];
cipher.init(true, new ParametersWithIV(new KeyParameter(key), nonce));
}
byte[] nextBytes(int length) {
byte[] in = new byte[length], out = new byte[length];
cipher.processBytes(in, 0, length, out, 0);
return out;
}
}

View File

@@ -0,0 +1,46 @@
package org.briarproject.bramble.crypto;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
class PseudoSecureRandom extends SecureRandom {
private static final Provider PROVIDER = new PseudoSecureRandomProvider();
PseudoSecureRandom(byte[] seed) {
super(new PseudoSecureRandomSpi(seed), PROVIDER);
}
private static class PseudoSecureRandomSpi extends SecureRandomSpi {
private final PseudoRandom pseudoRandom;
private PseudoSecureRandomSpi(byte[] seed) {
pseudoRandom = new PseudoRandom(seed);
}
@Override
protected byte[] engineGenerateSeed(int length) {
return pseudoRandom.nextBytes(length);
}
@Override
protected void engineNextBytes(byte[] b) {
byte[] random = pseudoRandom.nextBytes(b.length);
System.arraycopy(random, 0, b, 0, b.length);
}
@Override
protected void engineSetSeed(byte[] seed) {
// Thank you for your input
}
}
private static class PseudoSecureRandomProvider extends Provider {
private PseudoSecureRandomProvider() {
super("PseudoSecureRandom", 1.0, "Only for testing");
}
}
}

View File

@@ -23,21 +23,18 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
private static final String DROP_TABLE = "DROP TABLE foo IF EXISTS"; private static final String DROP_TABLE = "DROP TABLE foo IF EXISTS";
private static final String CREATE_TABLE = "CREATE TABLE foo" private static final String CREATE_TABLE = "CREATE TABLE foo"
+ " (key INT NOT NULL," + " (_key INT NOT NULL,"
+ " counter INT NOT NULL)"; + " counter INT NOT NULL)";
private static final String INSERT_ROW = private static final String INSERT_ROW =
"INSERT INTO foo (key, counter) VALUES (1, 123)"; "INSERT INTO foo (_key, counter) VALUES (1, 123)";
private static final String GET_COUNTER = private static final String GET_COUNTER =
"SELECT counter FROM foo WHERE key = 1"; "SELECT counter FROM foo WHERE _key = 1";
private static final String SET_COUNTER = private static final String SET_COUNTER =
"UPDATE foo SET counter = ? WHERE key = 1"; "UPDATE foo SET counter = ? WHERE _key = 1";
private final File testDir = TestUtils.getTestDirectory(); private final File testDir = TestUtils.getTestDirectory();
private final File db = new File(testDir, "db"); private final File db = new File(testDir, "db");
private final String withMvcc = "jdbc:h2:split:" + db.getAbsolutePath() private final String url = "jdbc:h2:split:" + db.getAbsolutePath();
+ ";MV_STORE=TRUE;MVCC=TRUE";
private final String withoutMvcc = "jdbc:h2:split:" + db.getAbsolutePath()
+ ";MV_STORE=FALSE;MVCC=FALSE;LOCK_MODE=1";
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@@ -52,14 +49,14 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
@Test @Test
public void testDoesNotReadUncommittedWritesWithMvcc() throws Exception { public void testDoesNotReadUncommittedWritesWithMvcc() throws Exception {
Connection connection = openConnection(true); Connection connection = openConnection();
try { try {
createTableAndInsertRow(connection); createTableAndInsertRow(connection);
} finally { } finally {
connection.close(); connection.close();
} }
// Start the first transaction // Start the first transaction
Connection txn1 = openConnection(true); Connection txn1 = openConnection();
try { try {
txn1.setAutoCommit(false); txn1.setAutoCommit(false);
// The first transaction should read the initial value // The first transaction should read the initial value
@@ -67,7 +64,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
// The first transaction updates the value but doesn't commit it // The first transaction updates the value but doesn't commit it
assertEquals(1, setCounter(txn1, 234)); assertEquals(1, setCounter(txn1, 234));
// Start the second transaction // Start the second transaction
Connection txn2 = openConnection(true); Connection txn2 = openConnection();
try { try {
txn2.setAutoCommit(false); txn2.setAutoCommit(false);
// The second transaction should still read the initial value // The second transaction should still read the initial value
@@ -86,14 +83,14 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
@Test @Test
public void testLastWriterWinsWithMvcc() throws Exception { public void testLastWriterWinsWithMvcc() throws Exception {
Connection connection = openConnection(true); Connection connection = openConnection();
try { try {
createTableAndInsertRow(connection); createTableAndInsertRow(connection);
} finally { } finally {
connection.close(); connection.close();
} }
// Start the first transaction // Start the first transaction
Connection txn1 = openConnection(true); Connection txn1 = openConnection();
try { try {
txn1.setAutoCommit(false); txn1.setAutoCommit(false);
// The first transaction should read the initial value // The first transaction should read the initial value
@@ -101,7 +98,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
// The first transaction updates the value but doesn't commit it // The first transaction updates the value but doesn't commit it
assertEquals(1, setCounter(txn1, 234)); assertEquals(1, setCounter(txn1, 234));
// Start the second transaction // Start the second transaction
Connection txn2 = openConnection(true); Connection txn2 = openConnection();
try { try {
txn2.setAutoCommit(false); txn2.setAutoCommit(false);
// The second transaction should still read the initial value // The second transaction should still read the initial value
@@ -119,7 +116,7 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
txn1.close(); txn1.close();
} }
// The second transaction was the last writer, so it should win // The second transaction was the last writer, so it should win
connection = openConnection(true); connection = openConnection();
try { try {
assertEquals(345, getCounter(connection)); assertEquals(345, getCounter(connection));
} finally { } finally {
@@ -129,20 +126,20 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
@Test @Test
public void testLockTimeoutOnRowWithMvcc() throws Exception { public void testLockTimeoutOnRowWithMvcc() throws Exception {
Connection connection = openConnection(true); Connection connection = openConnection();
try { try {
createTableAndInsertRow(connection); createTableAndInsertRow(connection);
} finally { } finally {
connection.close(); connection.close();
} }
// Start the first transaction // Start the first transaction
Connection txn1 = openConnection(true); Connection txn1 = openConnection();
try { try {
txn1.setAutoCommit(false); txn1.setAutoCommit(false);
// The first transaction should read the initial value // The first transaction should read the initial value
assertEquals(123, getCounter(txn1)); assertEquals(123, getCounter(txn1));
// Start the second transaction // Start the second transaction
Connection txn2 = openConnection(true); Connection txn2 = openConnection();
try { try {
txn2.setAutoCommit(false); txn2.setAutoCommit(false);
// The second transaction should read the initial value // The second transaction should read the initial value
@@ -167,84 +164,8 @@ public class H2TransactionIsolationTest extends BrambleTestCase {
} }
} }
@Test private Connection openConnection() throws SQLException {
public void testReadLockTimeoutOnTableWithoutMvcc() throws Exception { return DriverManager.getConnection(url);
Connection connection = openConnection(false);
try {
createTableAndInsertRow(connection);
} finally {
connection.close();
}
// Start the first transaction
Connection txn1 = openConnection(false);
try {
txn1.setAutoCommit(false);
// The first transaction should read the initial value
assertEquals(123, getCounter(txn1));
// Start the second transaction
Connection txn2 = openConnection(false);
try {
txn2.setAutoCommit(false);
// The second transaction should read the initial value
assertEquals(123, getCounter(txn2));
// The first transaction tries to update the value
try {
setCounter(txn1, 345);
fail();
} catch (SQLException expected) {
// Expected: the table is locked by the second transaction
}
// Abort the transactions
txn1.rollback();
txn2.rollback();
} finally {
txn2.close();
}
} finally {
txn1.close();
}
}
@Test
public void testWriteLockTimeoutOnTableWithoutMvcc() throws Exception {
Connection connection = openConnection(false);
try {
createTableAndInsertRow(connection);
} finally {
connection.close();
}
// Start the first transaction
Connection txn1 = openConnection(false);
try {
txn1.setAutoCommit(false);
// The first transaction should read the initial value
assertEquals(123, getCounter(txn1));
// The first transaction updates the value but doesn't commit yet
assertEquals(1, setCounter(txn1, 345));
// Start the second transaction
Connection txn2 = openConnection(false);
try {
txn2.setAutoCommit(false);
// The second transaction tries to read the value
try {
getCounter(txn2);
fail();
} catch (SQLException expected) {
// Expected: the table is locked by the first transaction
}
// Abort the transactions
txn1.rollback();
txn2.rollback();
} finally {
txn2.close();
}
} finally {
txn1.close();
}
}
private Connection openConnection(boolean mvcc) throws SQLException {
return DriverManager.getConnection(mvcc ? withMvcc : withoutMvcc);
} }
private void createTableAndInsertRow(Connection c) throws SQLException { private void createTableAndInsertRow(Connection c) throws SQLException {

View File

@@ -15,10 +15,9 @@ import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.CaptureArgumentAction; import org.briarproject.bramble.test.CaptureArgumentAction;
import org.briarproject.bramble.test.PredicateMatcher; import org.briarproject.bramble.test.PredicateMatcher;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.jmock.imposters.ByteBuddyClassImposteriser;
import org.junit.Test; import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@@ -52,12 +51,17 @@ public class KeyAgreementTransportTest extends BrambleMockTestCase {
private final KeyAgreementConnection keyAgreementConnection = private final KeyAgreementConnection keyAgreementConnection =
new KeyAgreementConnection(duplexTransportConnection, transportId); new KeyAgreementConnection(duplexTransportConnection, transportId);
private final InputStream inputStream = private final InputStream inputStream;
new ByteArrayInputStream(new byte[0]); private final OutputStream outputStream;
private final OutputStream outputStream = new ByteArrayOutputStream();
private KeyAgreementTransport kat; private KeyAgreementTransport kat;
public KeyAgreementTransportTest() {
context.setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
inputStream = context.mock(InputStream.class);
outputStream = context.mock(OutputStream.class);
}
@Test @Test
public void testSendKey() throws Exception { public void testSendKey() throws Exception {
byte[] key = getRandomBytes(123); byte[] key = getRandomBytes(123);

View File

@@ -21,11 +21,11 @@ import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.properties.TransportPropertyManager;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.TaskScheduler; import org.briarproject.bramble.api.system.TaskScheduler;
import org.briarproject.bramble.crypto.NeitherSecureNorRandom;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.ImmediateExecutor; import org.briarproject.bramble.test.ImmediateExecutor;
import org.briarproject.bramble.test.RunAction; import org.briarproject.bramble.test.RunAction;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.jmock.imposters.ByteBuddyClassImposteriser;
import org.junit.Test; import org.junit.Test;
import java.security.SecureRandom; import java.security.SecureRandom;
@@ -55,6 +55,7 @@ public class PollerImplTest extends BrambleMockTestCase {
context.mock(TransportPropertyManager.class); context.mock(TransportPropertyManager.class);
private final Clock clock = context.mock(Clock.class); private final Clock clock = context.mock(Clock.class);
private final Cancellable cancellable = context.mock(Cancellable.class); private final Cancellable cancellable = context.mock(Cancellable.class);
private final SecureRandom random;
private final Executor ioExecutor = new ImmediateExecutor(); private final Executor ioExecutor = new ImmediateExecutor();
private final TransportId transportId = getTransportId(); private final TransportId transportId = getTransportId();
@@ -66,8 +67,8 @@ public class PollerImplTest extends BrambleMockTestCase {
private final PollerImpl poller; private final PollerImpl poller;
public PollerImplTest() { public PollerImplTest() {
// Use a fake SecureRandom that returns all zeroes context.setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
SecureRandom random = new NeitherSecureNorRandom(); random = context.mock(SecureRandom.class);
Executor wakefulIoExecutor = new ImmediateExecutor(); Executor wakefulIoExecutor = new ImmediateExecutor();
poller = new PollerImpl(ioExecutor, wakefulIoExecutor, scheduler, poller = new PollerImpl(ioExecutor, wakefulIoExecutor, scheduler,
connectionManager, connectionRegistry, pluginManager, connectionManager, connectionRegistry, pluginManager,
@@ -351,10 +352,12 @@ public class PollerImplTest extends BrambleMockTestCase {
// Running the polling task schedules the next polling task // Running the polling task schedules the next polling task
oneOf(plugin).getPollingInterval(); oneOf(plugin).getPollingInterval();
will(returnValue(pollingInterval)); will(returnValue(pollingInterval));
oneOf(random).nextDouble();
will(returnValue(0.5));
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(now)); will(returnValue(now));
oneOf(scheduler).schedule(with(any(Runnable.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(ioExecutor), with(0L), with(ioExecutor), with((long) (pollingInterval * 0.5)),
with(MILLISECONDS)); with(MILLISECONDS));
will(returnValue(cancellable)); will(returnValue(cancellable));
// Get the transport properties and connected contacts // Get the transport properties and connected contacts
@@ -393,10 +396,12 @@ public class PollerImplTest extends BrambleMockTestCase {
// Running the polling task schedules the next polling task // Running the polling task schedules the next polling task
oneOf(plugin).getPollingInterval(); oneOf(plugin).getPollingInterval();
will(returnValue(pollingInterval)); will(returnValue(pollingInterval));
oneOf(random).nextDouble();
will(returnValue(0.5));
oneOf(clock).currentTimeMillis(); oneOf(clock).currentTimeMillis();
will(returnValue(now)); will(returnValue(now));
oneOf(scheduler).schedule(with(any(Runnable.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(ioExecutor), with(0L), with(ioExecutor), with((long) (pollingInterval * 0.5)),
with(MILLISECONDS)); with(MILLISECONDS));
will(returnValue(cancellable)); will(returnValue(cancellable));
// Get the transport properties and connected contacts // Get the transport properties and connected contacts

View File

@@ -1,67 +1,73 @@
dependencyVerification { dependencyVerification {
verify = [ verify = [
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db', 'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.fasterxml.jackson.core:jackson-annotations:2.13.4:jackson-annotations-2.13.4.jar:ac5b27a634942391ca113850ee7db01df1499a240174021263501c05fc653b44', 'com.fasterxml.jackson.core:jackson-annotations:2.13.4:jackson-annotations-2.13.4.jar:ac5b27a634942391ca113850ee7db01df1499a240174021263501c05fc653b44',
'com.fasterxml.jackson.core:jackson-core:2.13.4:jackson-core-2.13.4.jar:4c2e043200edd9ee7ba6fc378bd5c17784a5bf2388e152d208068b51fd0839cf', 'com.fasterxml.jackson.core:jackson-core:2.13.4:jackson-core-2.13.4.jar:4c2e043200edd9ee7ba6fc378bd5c17784a5bf2388e152d208068b51fd0839cf',
'com.fasterxml.jackson.core:jackson-databind:2.13.4:jackson-databind-2.13.4.jar:c9faff420d9e2c7e1e4711dbeebec2506a32c9942027211c5c293d8d87807eb6', 'com.fasterxml.jackson.core:jackson-databind:2.13.4:jackson-databind-2.13.4.jar:c9faff420d9e2c7e1e4711dbeebec2506a32c9942027211c5c293d8d87807eb6',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79', '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.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger-compiler:2.51.1:dagger-compiler-2.51.1.jar:14cf2def1c4c8cd3b977840e297b463191d537cd1c8330992ca5c0b341a641ad', 'com.google.dagger:dagger-compiler:2.45:dagger-compiler-2.45.jar:5617dfb994537dba5b41f3744a6dd13ec3cd99789c065e0d5c6fa9f21cf7ca25',
'com.google.dagger:dagger-spi:2.51.1:dagger-spi-2.51.1.jar:deb52030b92b27c5dcd76b2c0747f1cf105b60939f6073b43eb06cfe7c9ba601', 'com.google.dagger:dagger-producers:2.45:dagger-producers-2.45.jar:a05abb4c3ccf6bb0f056bdcb5ef973898ecf172952ab5948a824aeea6c86ecaa',
'com.google.dagger:dagger:2.51.1:dagger-2.51.1.jar:c3891a4c4a4e48682888ca321eaf8497004b286e1d9a2936867373219f7dd86d', 'com.google.dagger:dagger-spi:2.45:dagger-spi-2.45.jar:7cd6f0b09d88e64a9c97bc80e544ab8ac8fdee9301754413585a74cf64222b27',
'com.google.devtools.ksp:symbol-processing-api:1.9.20-1.0.14:symbol-processing-api-1.9.20-1.0.14.jar:d0339396f40dc9eb3b3f7bc86257f93869ee23448fa31ec4a1de900c6b7ae6d7', 'com.google.dagger:dagger:2.45:dagger-2.45.jar:f011cae7d2c0fb7ea17c34e05bc10e768b1081a5892ad019cf1fdb0e125c49c1',
'com.google.errorprone:error_prone_annotations:2.23.0:error_prone_annotations-2.23.0.jar:ec6f39f068b6ff9ac323c68e28b9299f8c0a80ca512dccb1d4a70f40ac3ec054', 'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30', 'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e', 'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
'com.google.guava:failureaccess:1.0.2:failureaccess-1.0.2.jar:8a8f81cf9b359e3f6dfa691a1e776985c061ef2f223c9b2c80753e1b458e8064', 'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.google.guava:guava:33.0.0-jre:guava-33.0.0-jre.jar:f4d85c3e4d411694337cb873abea09b242b664bb013320be6105327c45991537', 'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99', 'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c', 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
'com.squareup.okhttp3:mockwebserver:4.10.0:mockwebserver-4.10.0.jar:af29da234e63159d6e0dea43bf8288eea97d71cdf1651a5ee2d6c0d0d4adbf8f', 'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
'com.squareup.okhttp3:okhttp:4.12.0:okhttp-4.12.0.jar:b1050081b14bb7a3a7e55a4d3ef01b5dcfabc453b4573a4fc019767191d5f4e0', 'com.h2database:h2:2.2.220:h2-2.2.220.jar:978ab863018d3f965e38880571c36293ea8b10a8086194159c4d5d20b50f0a57',
'com.squareup.okio:okio-jvm:3.6.0:okio-jvm-3.6.0.jar:67543f0736fc422ae927ed0e504b98bc5e269fda0d3500579337cb713da28412', 'com.squareup.okhttp3:mockwebserver:4.10.0:mockwebserver-4.10.0.jar:af29da234e63159d6e0dea43bf8288eea97d71cdf1651a5ee2d6c0d0d4adbf8f',
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291', 'com.squareup.okhttp3:okhttp:4.10.0:okhttp-4.10.0.jar:7580f14fa1691206e37081ad3f92063b1603b328da0bb316f2fef02e0562e7ec',
'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492', 'com.squareup.okio:okio-jvm:3.0.0:okio-jvm-3.0.0.jar:be64a0cc1f28ea9cd5c970dd7e7557af72c808d738c495b397bf897c9921e907',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3', 'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140', 'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', 'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
'net.jodah:concurrentunit:0.4.6:concurrentunit-0.4.6.jar:760e6d4ab7801484de09da621b61141f3b2c2432949da9eb13f076e5d9a5e0a5', 'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd', 'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047', 'net.jodah:concurrentunit:0.4.6:concurrentunit-0.4.6.jar:760e6d4ab7801484de09da621b61141f3b2c2432949da9eb13f076e5d9a5e0a5',
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb', 'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'org.bouncycastle:bcprov-jdk15to18:1.82:bcprov-jdk15to18-1.82.jar:9c9ccecb08a0b00bd2a74afa6567d81d61a02bba1364f24e33fa0c4c1e929821', 'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b', 'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011', 'org.bouncycastle:bcprov-jdk15to18:1.71:bcprov-jdk15to18-1.71.jar:143aaa4a40edd5fc2a18db7900059f6c16f4d931b94b94b20f7e2238e6662886',
'org.briarproject:onionwrapper-core:0.1.4:onionwrapper-core-0.1.4.jar:d0a48de7198d48eb0182a25d109bc06811484d1da799c6dfa5e2581285880a49', 'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b',
'org.briarproject:socks-socket:0.1:socks-socket-0.1.jar:e5898822d10f5390363c5dddb945891648c92cf93ba50709e07f0d173ec0eb4b', 'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a', 'org.briarproject:onionwrapper-core:0.0.5:onionwrapper-core-0.0.5.jar:9071678323535cb3dfe0f3add96066037db43ea024333eba0117c759bcbd8d63',
'org.checkerframework:checker-qual:3.41.0:checker-qual-3.41.0.jar:2f9f245bf68e4259d610894f2406dc1f6363dc639302bd566e8272e4f4541172', 'org.briarproject:socks-socket:0.1:socks-socket-0.1.jar:e5898822d10f5390363c5dddb945891648c92cf93ba50709e07f0d173ec0eb4b',
'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619', 'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.codehaus.mojo:animal-sniffer-annotations:1.24:animal-sniffer-annotations-1.24.jar:c720e6e5bcbe6b2f48ded75a47bccdb763eede79d14330102e0d352e3d89ed92', 'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
'org.codehaus.mojo:animal-sniffer:1.24:animal-sniffer-1.24.jar:65d028de87134f0955e3a964fe438fc3e99e77b237a77e5e165869a8ff59db5f', 'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619',
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9', 'org.codehaus.mojo:animal-sniffer-ant-tasks:1.22:animal-sniffer-ant-tasks-1.22.jar:3f6afeb3e09301d2d7179ed1db21e3ad8846c1e38415ad832a395138ae3f4218',
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21', 'org.codehaus.mojo:animal-sniffer:1.22:animal-sniffer-1.22.jar:f18c11a25bdd8b520b9c6a28cbb6f33007c812ab0051b6be3f0778e660aa501c',
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050', 'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
'org.hsqldb:hsqldb:2.3.5:hsqldb-2.3.5.jar:6676a6977ac98997a80f827ddbd3fe8ca1e0853dad1492512135fd1a222ccfad', 'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203', 'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10:kotlin-stdlib-common-1.9.10.jar:cde3341ba18a2ba262b0b7cf6c55b20c90e8d434e42c9a13e6a3f770db965a88', 'org.hsqldb:hsqldb:2.3.5:hsqldb-2.3.5.jar:6676a6977ac98997a80f827ddbd3fe8ca1e0853dad1492512135fd1a222ccfad',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0:kotlin-stdlib-jdk7-1.9.0.jar:b7979a7aac94055f0d9f1fd3b47ce5ffe1cb6032a842ba9fbe7186f085289178', 'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10:kotlin-stdlib-jdk7-1.9.10.jar:ac6361bf9ad1ed382c2103d9712c47cdec166232b4903ed596e8876b0681c9b7', 'org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20:kotlin-stdlib-common-1.6.20.jar:8da40a2520d30dcb1012176fe93d24e82d08a3e346c37e0343b0fb6f64f6be01',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0:kotlin-stdlib-jdk8-1.9.0.jar:a59fa24fdf1ffb594baecdbf0fd10010f977cea10236d487fe3464977a7377fa', 'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10:kotlin-stdlib-jdk8-1.9.10.jar:a4c74d94d64ce1abe53760fe0389dd941f6fc558d0dab35e47c085a11ec80f28', 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31:kotlin-stdlib-jdk7-1.5.31.jar:a25bf47353ce899d843cbddee516d621a73473e7fba97f8d0301e7b4aed7c15f',
'org.jetbrains.kotlin:kotlin-stdlib:1.9.10:kotlin-stdlib-1.9.10.jar:55e989c512b80907799f854309f3bc7782c5b3d13932442d0379d5c472711504', 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10:kotlin-stdlib-jdk7-1.6.10.jar:2aedcdc6b69b33bdf5cc235bcea88e7cf6601146bb6bcdffdb312bbacd7be261',
'org.jetbrains.kotlin:kotlin-stdlib:1.9.20:kotlin-stdlib-1.9.20.jar:28a35bcdff46d864f80f346a617e486284b208d17378c41900dfb1de95a90e6c', 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31:kotlin-stdlib-jdk8-1.5.31.jar:b548f7767aacf029d2417e47440742bd6d3ebede19b60386e23554ce5c4c5fdc',
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10:kotlin-stdlib-jdk8-1.6.10.jar:1456d82d039ea30d8485b032901f52bbf07e7cdbe8bb1f8708ad32a8574c41ce',
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd', 'org.jetbrains.kotlin:kotlin-stdlib:1.6.20:kotlin-stdlib-1.6.20.jar:eeb51c2b67b26233fd81d0bc4f8044ec849718890905763ceffd84a31e2cb799',
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04', 'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be', 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984', 'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de', 'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
'org.ow2.asm:asm:9.7:asm-9.7.jar:adf46d5e34940bdf148ecdd26a9ee8eea94496a72034ff7141066b3eea5c4e9d', 'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
'org.whispersystems:curve25519-java:0.5.0:curve25519-java-0.5.0.jar:0aadd43cf01d11e9b58f867b3c4f25c3194e8b0623d1953d32dfbfbee009e38d', '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.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
'org.ow2.asm:asm:9.3:asm-9.3.jar:1263369b59e29c943918de11d6d6152e2ec6085ce63e5710516f8c67d368e4bc',
'org.whispersystems:curve25519-java:0.5.0:curve25519-java-0.5.0.jar:0aadd43cf01d11e9b58f867b3c4f25c3194e8b0623d1953d32dfbfbee009e38d',
]
} }

View File

@@ -19,6 +19,7 @@ import org.briarproject.onionwrapper.CircumventionProvider;
import org.briarproject.onionwrapper.LocationUtils; import org.briarproject.onionwrapper.LocationUtils;
import org.briarproject.onionwrapper.MacTorWrapper; import org.briarproject.onionwrapper.MacTorWrapper;
import org.briarproject.onionwrapper.TorWrapper; import org.briarproject.onionwrapper.TorWrapper;
import org.briarproject.onionwrapper.UnixTorWrapper;
import java.io.File; import java.io.File;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -79,6 +80,6 @@ public class MacTorPluginFactory extends TorPluginFactory {
return new TorPlugin(ioExecutor, wakefulIoExecutor, networkManager, return new TorPlugin(ioExecutor, wakefulIoExecutor, networkManager,
locationUtils, torSocketFactory, circumventionProvider, locationUtils, torSocketFactory, circumventionProvider,
batteryManager, backoff, torRendezvousCrypto, tor, callback, batteryManager, backoff, torRendezvousCrypto, tor, callback,
MAX_LATENCY, MAX_IDLE_TIME); MAX_LATENCY, MAX_IDLE_TIME, true);
} }
} }

View File

@@ -81,6 +81,6 @@ public class UnixTorPluginFactory extends TorPluginFactory {
return new TorPlugin(ioExecutor, wakefulIoExecutor, networkManager, return new TorPlugin(ioExecutor, wakefulIoExecutor, networkManager,
locationUtils, torSocketFactory, circumventionProvider, locationUtils, torSocketFactory, circumventionProvider,
batteryManager, backoff, torRendezvousCrypto, tor, callback, batteryManager, backoff, torRendezvousCrypto, tor, callback,
MAX_LATENCY, MAX_IDLE_TIME); MAX_LATENCY, MAX_IDLE_TIME, true);
} }
} }

View File

@@ -78,6 +78,6 @@ public class WindowsTorPluginFactory extends TorPluginFactory {
return new TorPlugin(ioExecutor, wakefulIoExecutor, networkManager, return new TorPlugin(ioExecutor, wakefulIoExecutor, networkManager,
locationUtils, torSocketFactory, circumventionProvider, locationUtils, torSocketFactory, circumventionProvider,
batteryManager, backoff, torRendezvousCrypto, tor, callback, batteryManager, backoff, torRendezvousCrypto, tor, callback,
MAX_LATENCY, MAX_IDLE_TIME); MAX_LATENCY, MAX_IDLE_TIME, true);
} }
} }

View File

@@ -1,48 +1,52 @@
dependencyVerification { dependencyVerification {
verify = [ verify = [
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db', 'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db',
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79', '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.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
'com.google.dagger:dagger-compiler:2.51.1:dagger-compiler-2.51.1.jar:14cf2def1c4c8cd3b977840e297b463191d537cd1c8330992ca5c0b341a641ad', 'com.google.dagger:dagger-compiler:2.45:dagger-compiler-2.45.jar:5617dfb994537dba5b41f3744a6dd13ec3cd99789c065e0d5c6fa9f21cf7ca25',
'com.google.dagger:dagger-spi:2.51.1:dagger-spi-2.51.1.jar:deb52030b92b27c5dcd76b2c0747f1cf105b60939f6073b43eb06cfe7c9ba601', 'com.google.dagger:dagger-producers:2.45:dagger-producers-2.45.jar:a05abb4c3ccf6bb0f056bdcb5ef973898ecf172952ab5948a824aeea6c86ecaa',
'com.google.dagger:dagger:2.51.1:dagger-2.51.1.jar:c3891a4c4a4e48682888ca321eaf8497004b286e1d9a2936867373219f7dd86d', 'com.google.dagger:dagger-spi:2.45:dagger-spi-2.45.jar:7cd6f0b09d88e64a9c97bc80e544ab8ac8fdee9301754413585a74cf64222b27',
'com.google.devtools.ksp:symbol-processing-api:1.9.20-1.0.14:symbol-processing-api-1.9.20-1.0.14.jar:d0339396f40dc9eb3b3f7bc86257f93869ee23448fa31ec4a1de900c6b7ae6d7', 'com.google.dagger:dagger:2.45:dagger-2.45.jar:f011cae7d2c0fb7ea17c34e05bc10e768b1081a5892ad019cf1fdb0e125c49c1',
'com.google.errorprone:error_prone_annotations:2.23.0:error_prone_annotations-2.23.0.jar:ec6f39f068b6ff9ac323c68e28b9299f8c0a80ca512dccb1d4a70f40ac3ec054', 'com.google.devtools.ksp:symbol-processing-api:1.7.0-1.0.6:symbol-processing-api-1.7.0-1.0.6.jar:adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941',
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30', 'com.google.errorprone:error_prone_annotations:2.7.1:error_prone_annotations-2.7.1.jar:cd5257c08a246cf8628817ae71cb822be192ef91f6881ca4a3fcff4f1de1cff3',
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e', 'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
'com.google.guava:failureaccess:1.0.2:failureaccess-1.0.2.jar:8a8f81cf9b359e3f6dfa691a1e776985c061ef2f223c9b2c80753e1b458e8064', 'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
'com.google.guava:guava:33.0.0-jre:guava-33.0.0-jre.jar:f4d85c3e4d411694337cb873abea09b242b664bb013320be6105327c45991537', 'com.google.guava:failureaccess:1.0.1:failureaccess-1.0.1.jar:a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26',
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99', 'com.google.guava:guava:31.0.1-jre:guava-31.0.1-jre.jar:d5be94d65e87bd219fb3193ad1517baa55a3b88fc91d21cf735826ab5af087b9',
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291', 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99',
'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492', 'com.google.j2objc:j2objc-annotations:1.3:j2objc-annotations-1.3.jar:21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b',
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291',
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3', 'com.squareup:kotlinpoet:1.11.0:kotlinpoet-1.11.0.jar:2887ada1ca03dd83baa2758640d87e840d1907564db0ef88d2289c868a980492',
'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11', 'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'net.java.dev.jna:jna-platform:5.13.0:jna-platform-5.13.0.jar:474d7b88f6e97009b6ec1d98c3024dd95c23187c65dabfbc35331bcac3d173dd', 'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'net.java.dev.jna:jna:5.13.0:jna-5.13.0.jar:66d4f819a062a51a1d5627bffc23fac55d1677f0e0a1feba144aabdd670a64bb', 'net.bytebuddy:byte-buddy:1.9.12:byte-buddy-1.9.12.jar:3688c3d434bebc3edc5516296a2ed0f47b65e451071b4afecad84f902f0efc11',
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0', 'net.java.dev.jna:jna-platform:5.13.0:jna-platform-5.13.0.jar:474d7b88f6e97009b6ec1d98c3024dd95c23187c65dabfbc35331bcac3d173dd',
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd', 'net.java.dev.jna:jna:5.13.0:jna-5.13.0.jar:66d4f819a062a51a1d5627bffc23fac55d1677f0e0a1feba144aabdd670a64bb',
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047', 'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b', 'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011', 'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
'org.briarproject:onionwrapper-core:0.1.4:onionwrapper-core-0.1.4.jar:d0a48de7198d48eb0182a25d109bc06811484d1da799c6dfa5e2581285880a49', 'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b',
'org.briarproject:onionwrapper-java:0.1.4:onionwrapper-java-0.1.4.jar:3efaa84bee71cc46b5a0b033080eaed323242fae88ea05f7309ee9f999cb3ac3', 'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011',
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a', 'org.briarproject:onionwrapper-core:0.0.5:onionwrapper-core-0.0.5.jar:9071678323535cb3dfe0f3add96066037db43ea024333eba0117c759bcbd8d63',
'org.checkerframework:checker-qual:3.41.0:checker-qual-3.41.0.jar:2f9f245bf68e4259d610894f2406dc1f6363dc639302bd566e8272e4f4541172', 'org.briarproject:onionwrapper-java:0.0.5:onionwrapper-java-0.0.5.jar:19503ce1dd661f7119eee8ccd2f22b667a28d746c862dc5bb3d2e476db47e27d',
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9', 'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21', 'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050', 'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203', 'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0:kotlin-stdlib-jdk7-1.9.0.jar:b7979a7aac94055f0d9f1fd3b47ce5ffe1cb6032a842ba9fbe7186f085289178', 'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0:kotlin-stdlib-jdk8-1.9.0.jar:a59fa24fdf1ffb594baecdbf0fd10010f977cea10236d487fe3464977a7377fa', 'org.jetbrains.kotlin:kotlin-reflect:1.6.10:kotlin-reflect-1.6.10.jar:3277ac102ae17aad10a55abec75ff5696c8d109790396434b496e75087854203',
'org.jetbrains.kotlin:kotlin-stdlib:1.9.20:kotlin-stdlib-1.9.20.jar:28a35bcdff46d864f80f346a617e486284b208d17378c41900dfb1de95a90e6c', 'org.jetbrains.kotlin:kotlin-stdlib-common:1.7.0:kotlin-stdlib-common-1.7.0.jar:59c6ff64fe9a6604afce03e8aaa75f83586c6030ac71fb0b34ee7cdefed3618f',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478', 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.0:kotlin-stdlib-jdk7-1.7.0.jar:07e91be9b2ca20672d2bdb7e181b766e73453a2da13492b5ddaee8fa47aea239',
'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09', 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0:kotlin-stdlib-jdk8-1.7.0.jar:cf058e11db1dfc9944680c8c61b95ac689aaaa8a3eb30bced028100f038f030b',
'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b', 'org.jetbrains.kotlin:kotlin-stdlib:1.7.0:kotlin-stdlib-1.7.0.jar:aa88e9625577957f3249a46cb6e166ee09b369e600f7a11d148d16b0a6d87f05',
'org.jmock:jmock-legacy:2.12.0:jmock-legacy-2.12.0.jar:dea3a9cca653d082e2fe7e40232e982fe03a9984c7d67ceff24f3e03fe580dcd', 'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.5.0:kotlinx-metadata-jvm-0.5.0.jar:ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4',
'org.jmock:jmock-testjar:2.12.0:jmock-testjar-2.12.0.jar:efefbcf6cd294d0e29f0c46eb2a3380d4ca4e1763ff719c69e2f2ac62f564a04', 'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.jmock:jmock:2.12.0:jmock-2.12.0.jar:266d07314c0cd343c46ff8a55601272de8cf406807caf55e6f313295f83d10be', 'org.jmock:jmock-imposters:2.12.0:jmock-imposters-2.12.0.jar:3b836269745a137c9b2347e8d7c2104845b126ef04f012d6bfd94f1a7dea7b09',
'org.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984', 'org.jmock:jmock-junit4:2.12.0:jmock-junit4-2.12.0.jar:3233062fc889637c151a24f1ee086bad04321ab7d8264fef279daff0fa27205b',
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de', '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.objenesis:objenesis:3.0.1:objenesis-3.0.1.jar:7a8ff780b9ff48415d7c705f60030b0acaa616e7f823c98eede3b63508d4e984',
'org.ow2.asm:asm:7.1:asm-7.1.jar:4ab2fa2b6d2cc9ccb1eaa05ea329c407b47b13ed2915f62f8c4b8cc96258d4de',
]
} }

View File

@@ -1,6 +1,6 @@
[main] [main]
host = https://www.transifex.com host = https://www.transifex.com
lang_map = es_CU: es-rCU, pt_BR: pt-rBR, pt_PT: pt-rPT, nb_NO: nb, zh-Hans: zh-rCN, zh-Hant: zh-rTW lang_map = pt_BR: pt-rBR, nb_NO: nb, zh-Hans: zh-rCN, zh-Hant: zh-rTW
[o:otf:p:briar:r:google-play-full-description] [o:otf:p:briar:r:google-play-full-description]
file_filter = fastlane/metadata/android/<lang>/full_description.txt file_filter = fastlane/metadata/android/<lang>/full_description.txt

View File

@@ -16,29 +16,27 @@ def getStdout = { command, defaultValue ->
} }
android { android {
compileSdk 35 compileSdkVersion 33
buildToolsVersion '35.0.0' buildToolsVersion '33.0.0'
packagingOptions {
jniLibs {
keepDebugSymbols += ['**/*.so']
}
}
packagingOptions {
doNotStrip '**/*.so'
}
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 35 targetSdkVersion 33
versionCode 10516 versionCode 10506
versionName "1.5.16" versionName "1.5.6"
applicationId "org.briarproject.briar.android" applicationId "org.briarproject.briar.android"
buildConfigField "String", "TorVersion", "\"$tor_version\"" buildConfigField "String", "TorVersion", "\"$tor_version\""
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
buildConfigField "String", "GitHash", buildConfigField "String", "GitHash",
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\"" "\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
def now = (long) (System.currentTimeMillis() / 1000) def now = (long) (System.currentTimeMillis() / 1000)
buildConfigField "Long", "BuildTimestamp", buildConfigField "Long", "BuildTimestamp",
"${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L" "${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L"
testInstrumentationRunner 'org.briarproject.briar.android.BriarTestRunner' testInstrumentationRunner 'org.briarproject.briar.android.BriarTestRunner'
testInstrumentationRunnerArguments disableAnalytics: 'true' testInstrumentationRunnerArguments disableAnalytics: 'true'
} }
@@ -78,8 +76,9 @@ android {
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_17 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
} }
testOptions { testOptions {
@@ -88,13 +87,21 @@ android {
includeAndroidResources = true includeAndroidResources = true
} }
} }
namespace 'org.briarproject.briar'
lint {
warning 'MissingTranslation', 'MissingDefaultResource', 'ImpliedQuantity', 'ExtraTranslation', 'InvalidPackage'
}
lintOptions {
warning 'MissingTranslation'
warning 'MissingDefaultResource'
warning 'ImpliedQuantity'
warning 'ExtraTranslation'
// FIXME
warning 'InvalidPackage'
}
} }
// Workaround for https://github.com/gradle/gradle/issues/20330 to make gradle-witness work
// with Android Gradle Plugin 7.4
project.evaluationDependsOn(project.getRootProject().findProject("bramble-android").getPath())
dependencies { dependencies {
// In theory this dependency shouldn't be needed, but without it Android Studio's linter will // In theory this dependency shouldn't be needed, but without it Android Studio's linter will
// complain about unresolved symbols for bramble-api test classes in briar-android tests, // complain about unresolved symbols for bramble-api test classes in briar-android tests,
@@ -106,15 +113,16 @@ dependencies {
implementation project(':bramble-android') implementation project(':bramble-android')
implementation project(':briar-core') implementation project(':briar-core')
// newer versions of the libraries below require compileSdk 34 implementation 'androidx.fragment:fragment:1.5.5'
implementation 'androidx.fragment:fragment:1.6.2' implementation 'androidx.preference:preference:1.2.0'
implementation 'androidx.preference:preference:1.2.1' implementation 'androidx.exifinterface:exifinterface:1.3.6'
implementation 'androidx.exifinterface:exifinterface:1.3.7' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' implementation 'androidx.lifecycle:lifecycle-livedata:2.5.1'
implementation 'androidx.lifecycle:lifecycle-livedata:2.6.2'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.material:material:1.9.0' // check https://github.com/material-components/material-components-android/issues/3191
// before upgrading material library
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0'
// force kotlin standard lib to latest version to prevent jetifier issues // force kotlin standard lib to latest version to prevent jetifier issues
@@ -128,7 +136,7 @@ dependencies {
implementation 'com.vanniktech:emoji-google:0.9.0' // newer versions are more work to adapt implementation 'com.vanniktech:emoji-google:0.9.0' // newer versions are more work to adapt
implementation 'com.github.kobakei:MaterialFabSpeedDial:1.2.1' implementation 'com.github.kobakei:MaterialFabSpeedDial:1.2.1'
implementation 'com.github.chrisbanes:PhotoView:2.3.0' implementation 'com.github.chrisbanes:PhotoView:2.3.0'
def glideVersion = '4.16.0' def glideVersion = '4.14.2'
implementation("com.github.bumptech.glide:glide:$glideVersion") { implementation("com.github.bumptech.glide:glide:$glideVersion") {
exclude group: 'com.android.support' exclude group: 'com.android.support'
exclude module: 'disklrucache' // when there's no disk cache, we can't accidentally use it exclude module: 'disklrucache' // when there's no disk cache, we can't accidentally use it
@@ -140,6 +148,8 @@ dependencies {
compileOnly 'javax.annotation:jsr250-api:1.0' compileOnly 'javax.annotation:jsr250-api:1.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs_nio:2.0.3'
testImplementation project(path: ':bramble-api', configuration: 'testOutput') testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation project(path: ':bramble-core', configuration: 'testOutput') testImplementation project(path: ':bramble-core', configuration: 'testOutput')
@@ -200,7 +210,7 @@ task verifyTranslations {
} }
if (translations.size() != 0) if (translations.size() != 0)
throw new GradleException("Translations\n" + translations.join("\n") throw new GradleException("Translations\n" + translations.join("\n")
+ "\nhave no matching value folder") + "\nhave no matching value folder")
// Some devices use iw instead of he for hebrew // Some devices use iw instead of he for hebrew
def hebrew_legacy = project.file("src/main/res/values-iw") def hebrew_legacy = project.file("src/main/res/values-iw")
@@ -216,8 +226,6 @@ task verifyTranslations {
} }
} }
// Force evaluation of bramble-android before briar-android
project.evaluationDependsOn(project.getRootProject().findProject("bramble-android").getPath())
project.afterEvaluate { project.afterEvaluate {
preBuild.dependsOn.add(verifyTranslations) preBuild.dependsOn.add(verifyTranslations)
} }

View File

@@ -4,7 +4,6 @@
-keepattributes SourceFile, LineNumberTable, *Annotation*, Signature, InnerClasses, EnclosingMethod -keepattributes SourceFile, LineNumberTable, *Annotation*, Signature, InnerClasses, EnclosingMethod
-keep,includedescriptorclasses class org.briarproject.briar.android.**,org.briarproject.briar.api.android.** { *; } -keep,includedescriptorclasses class org.briarproject.briar.android.**,org.briarproject.briar.api.android.** { *; }
-keep class org.briarproject.bramble.system.UnixSecureRandomSpi { *; }
# QR codes # QR codes
-keep class com.google.zxing.Result -keep class com.google.zxing.Result
@@ -43,6 +42,3 @@
# Dependency injection annotations, needed for UI tests on older API levels # Dependency injection annotations, needed for UI tests on older API levels
-keep class javax.inject.** -keep class javax.inject.**
# H2 database: keep H2 MVStore classes
-keep class org.h2.mvstore.db.MVTableEngine

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
package="org.briarproject.briar">
<uses-feature <uses-feature
android:name="android.hardware.bluetooth" android:name="android.hardware.bluetooth"
@@ -32,17 +33,11 @@
tools:ignore="ScopedStorage" /> tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission-sdk-23 <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="32" /> android:maxSdkVersion="32" />
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" /> <uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<uses-permission
android:name="android.permission.HIDE_OVERLAY_WINDOWS"
tools:targetApi="31" />
<application <application
android:name="org.briarproject.briar.android.BriarApplicationImpl" android:name="org.briarproject.briar.android.BriarApplicationImpl"
@@ -68,8 +63,7 @@
<service <service
android:name="org.briarproject.briar.android.BriarService" android:name="org.briarproject.briar.android.BriarService"
android:exported="false" android:exported="false">
android:foregroundServiceType="connectedDevice">
<intent-filter> <intent-filter>
<action android:name="org.briarproject.briar.android.BriarService" /> <action android:name="org.briarproject.briar.android.BriarService" />
</intent-filter> </intent-filter>
@@ -110,12 +104,12 @@
<activity <activity
android:name="org.briarproject.briar.android.login.StartupActivity" android:name="org.briarproject.briar.android.login.StartupActivity"
android:exported="false" android:exported="false"
android:theme="@style/BriarTheme.NoActionBar" /> android:label="@string/app_name" />
<activity <activity
android:name="org.briarproject.briar.android.account.SetupActivity" android:name="org.briarproject.briar.android.account.SetupActivity"
android:exported="false" android:exported="false"
android:theme="@style/BriarTheme.NoActionBar" /> android:label="@string/setup_title" />
<activity <activity
android:name="org.briarproject.briar.android.splash.SplashScreenActivity" android:name="org.briarproject.briar.android.splash.SplashScreenActivity"

View File

@@ -27,7 +27,7 @@ class BriarAccountManager extends AndroidAccountManager {
super.deleteAccount(); super.deleteAccount();
Localizer.reinitialize(); Localizer.reinitialize();
UiUtils.setTheme(appContext, UiUtils.setTheme(appContext,
appContext.getString(R.string.pref_theme_system_value)); appContext.getString(R.string.pref_theme_light_value));
} }
} }
} }

View File

@@ -33,7 +33,6 @@ import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD; import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
import static org.briarproject.briar.android.settings.DisplayFragment.PREF_THEME;
public class BriarApplicationImpl extends Application public class BriarApplicationImpl extends Application
implements BriarApplication { implements BriarApplication {
@@ -110,11 +109,11 @@ public class BriarApplicationImpl extends Application
} }
private void setTheme(Context ctx, SharedPreferences prefs) { private void setTheme(Context ctx, SharedPreferences prefs) {
String theme = prefs.getString(PREF_THEME, null); String theme = prefs.getString("pref_key_theme", null);
if (theme == null) { if (theme == null) {
// set default value // set default value
theme = getString(R.string.pref_theme_system_value); theme = getString(R.string.pref_theme_light_value);
prefs.edit().putString(PREF_THEME, theme).apply(); prefs.edit().putString("pref_key_theme", theme).apply();
} }
// set theme // set theme
UiUtils.setTheme(ctx, theme); UiUtils.setTheme(ctx, theme);

View File

@@ -22,7 +22,6 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult; import org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.logout.HideUiActivity; import org.briarproject.briar.android.logout.HideUiActivity;
import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.android.AndroidNotificationManager;
@@ -175,8 +174,7 @@ public class BriarService extends Service {
filter.addAction(ACTION_SHUTDOWN); filter.addAction(ACTION_SHUTDOWN);
filter.addAction("android.intent.action.QUICKBOOT_POWEROFF"); filter.addAction("android.intent.action.QUICKBOOT_POWEROFF");
filter.addAction("com.htc.intent.action.QUICKBOOT_POWEROFF"); filter.addAction("com.htc.intent.action.QUICKBOOT_POWEROFF");
AndroidUtils.registerReceiver(getApplicationContext(), receiver, registerReceiver(receiver, filter);
filter, false);
}, "LifecycleStartup"); }, "LifecycleStartup");
} }
@@ -217,14 +215,17 @@ public class BriarService extends Service {
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); // Hold a wake lock during shutdown
LOG.info("Destroyed"); wakeLockManager.runWakefully(() -> {
// Stop the lifecycle, if not already stopped super.onDestroy();
shutdown(false); LOG.info("Destroyed");
stopForeground(true); stopForeground(true);
if (receiver != null) { if (receiver != null) unregisterReceiver(receiver);
getApplicationContext().unregisterReceiver(receiver); // Stop the services in a background thread
} wakeLockManager.executeWakefully(() -> {
if (started) lifecycleManager.stopServices();
}, "LifecycleShutdown");
}, "LifecycleShutdown");
} }
@Override @Override
@@ -294,8 +295,8 @@ public class BriarService extends Service {
private void shutdownFromBackground() { private void shutdownFromBackground() {
// Hold a wake lock during shutdown // Hold a wake lock during shutdown
wakeLockManager.runWakefully(() -> { wakeLockManager.runWakefully(() -> {
// Begin lifecycle shutdown // Stop the service
shutdown(true); stopSelf();
// Hide the UI // Hide the UI
hideUi(); hideUi();
// Wait for shutdown to complete, then exit // Wait for shutdown to complete, then exit
@@ -330,18 +331,8 @@ public class BriarService extends Service {
/** /**
* Starts the shutdown process. * Starts the shutdown process.
*/ */
public void shutdown(boolean stopAndroidService) { public void shutdown() {
// Hold a wake lock during shutdown stopSelf(); // This will call onDestroy()
wakeLockManager.runWakefully(() -> {
// Stop the lifecycle services in a background thread,
// then stop this Android service if needed
wakeLockManager.executeWakefully(() -> {
if (started) lifecycleManager.stopServices();
if (stopAndroidService) {
androidExecutor.runOnUiThread(() -> stopSelf());
}
}, "LifecycleShutdown");
}, "LifecycleShutdown");
} }
public class BriarBinder extends Binder { public class BriarBinder extends Binder {

View File

@@ -21,7 +21,6 @@ import static android.os.PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED;
import static android.os.PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED; import static android.os.PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.AndroidUtils.registerReceiver;
class DozeWatchdogImpl implements DozeWatchdog, Service { class DozeWatchdogImpl implements DozeWatchdog, Service {
@@ -49,7 +48,7 @@ class DozeWatchdogImpl implements DozeWatchdog, Service {
filter.addAction(ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED); filter.addAction(ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED);
filter.addAction(ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED); filter.addAction(ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
} }
registerReceiver(appContext, receiver, filter, false); appContext.registerReceiver(receiver, filter);
} }
@Override @Override

View File

@@ -49,7 +49,6 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.GET_SIGNATURES; import static android.content.pm.PackageManager.GET_SIGNATURES;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.AndroidUtils.registerReceiver;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
@@ -208,7 +207,7 @@ class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service {
filter.addAction(ACTION_PACKAGE_REPLACED); filter.addAction(ACTION_PACKAGE_REPLACED);
filter.addDataScheme("package"); filter.addDataScheme("package");
receiver = new PackageBroadcastReceiver(); receiver = new PackageBroadcastReceiver();
registerReceiver(app, receiver, filter, false); app.registerReceiver(receiver, filter);
cachedApps = null; cachedApps = null;
}); });
} }

View File

@@ -18,9 +18,7 @@ import javax.annotation.Nullable;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8; import static org.briarproject.bramble.util.StringUtils.toUtf8;
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
import static org.briarproject.briar.android.util.UiUtils.setError; import static org.briarproject.briar.android.util.UiUtils.setError;
import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -40,27 +38,19 @@ public class AuthorNameFragment extends SetupFragment {
public View onCreateView(LayoutInflater inflater, public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
requireActivity().setTitle(getString(R.string.setup_title));
View v = inflater.inflate(R.layout.fragment_setup_author_name, View v = inflater.inflate(R.layout.fragment_setup_author_name,
container, false); container, false);
authorNameWrapper = v.findViewById(R.id.nickname_entry_wrapper); authorNameWrapper = v.findViewById(R.id.nickname_entry_wrapper);
authorNameInput = v.findViewById(R.id.nickname_entry); authorNameInput = v.findViewById(R.id.nickname_entry);
Button infoButton = v.findViewById(R.id.info_button);
nextButton = v.findViewById(R.id.next); nextButton = v.findViewById(R.id.next);
authorNameInput.addTextChangedListener(this); authorNameInput.addTextChangedListener(this);
infoButton.setOnClickListener(view ->
showOnboardingDialog(requireContext(), getHelpText()));
nextButton.setOnClickListener(this); nextButton.setOnClickListener(this);
return v; return v;
} }
@Override
public void onStart() {
super.onStart();
hideViewOnSmallScreen(requireView().findViewById(R.id.logo));
}
@Override @Override
public String getUniqueTag() { public String getUniqueTag() {
return TAG; return TAG;

View File

@@ -23,7 +23,6 @@ import static android.view.View.VISIBLE;
import static android.widget.Toast.LENGTH_LONG; import static android.widget.Toast.LENGTH_LONG;
import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent; import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING;
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog; import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -80,12 +79,6 @@ public class DozeFragment extends SetupFragment
return v; return v;
} }
@Override
public void onStart() {
super.onStart();
hideViewOnSmallScreen(requireView().findViewById(R.id.logo));
}
@Override @Override
public String getUniqueTag() { public String getUniqueTag() {
return TAG; return TAG;

View File

@@ -28,12 +28,10 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.view.View.INVISIBLE; import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
import static androidx.core.content.ContextCompat.checkSelfPermission; import static androidx.core.content.ContextCompat.checkSelfPermission;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK; import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
import static org.briarproject.briar.android.util.UiUtils.setError; import static org.briarproject.briar.android.util.UiUtils.setError;
import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -59,6 +57,7 @@ public class SetPasswordFragment extends SetupFragment {
public View onCreateView(LayoutInflater inflater, public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
requireActivity().setTitle(getString(R.string.setup_password_intro));
View v = inflater.inflate(R.layout.fragment_setup_password, container, View v = inflater.inflate(R.layout.fragment_setup_password, container,
false); false);
@@ -68,18 +67,17 @@ public class SetPasswordFragment extends SetupFragment {
passwordConfirmationWrapper = passwordConfirmationWrapper =
v.findViewById(R.id.password_confirm_wrapper); v.findViewById(R.id.password_confirm_wrapper);
passwordConfirmation = v.findViewById(R.id.password_confirm); passwordConfirmation = v.findViewById(R.id.password_confirm);
Button infoButton = v.findViewById(R.id.info_button);
nextButton = v.findViewById(R.id.next); nextButton = v.findViewById(R.id.next);
ProgressBar progressBar = v.findViewById(R.id.progress); ProgressBar progressBar = v.findViewById(R.id.progress);
passwordEntry.addTextChangedListener(this); passwordEntry.addTextChangedListener(this);
passwordConfirmation.addTextChangedListener(this); passwordConfirmation.addTextChangedListener(this);
infoButton.setOnClickListener(view ->
showOnboardingDialog(requireContext(), getHelpText()));
nextButton.setOnClickListener(this); nextButton.setOnClickListener(this);
if (!viewModel.needToShowDozeFragment()) { if (!viewModel.needToShowDozeFragment()) {
nextButton.setText(R.string.create_account_button); nextButton.setText(R.string.create_account_button);
int options = passwordConfirmation.getImeOptions();
passwordConfirmation.setImeOptions(options | IME_ACTION_DONE);
} }
viewModel.getIsCreatingAccount() viewModel.getIsCreatingAccount()
@@ -96,12 +94,6 @@ public class SetPasswordFragment extends SetupFragment {
return v; return v;
} }
@Override
public void onStart() {
super.onStart();
hideViewOnSmallScreen(requireView().findViewById(R.id.logo));
}
@Override @Override
public String getUniqueTag() { public String getUniqueTag() {
return TAG; return TAG;
@@ -118,27 +110,17 @@ public class SetPasswordFragment extends SetupFragment {
String password2 = passwordConfirmation.getText().toString(); String password2 = passwordConfirmation.getText().toString();
boolean passwordsMatch = password1.equals(password2); boolean passwordsMatch = password1.equals(password2);
strengthMeter.setVisibility(!password1.isEmpty() ? VISIBLE : INVISIBLE); strengthMeter
.setVisibility(password1.length() > 0 ? VISIBLE : INVISIBLE);
float strength = viewModel.estimatePasswordStrength(password1); float strength = viewModel.estimatePasswordStrength(password1);
strengthMeter.setStrength(strength); strengthMeter.setStrength(strength);
boolean strongEnough = strength >= QUITE_WEAK; boolean strongEnough = strength >= QUITE_WEAK;
if (!password1.isEmpty()) {
if (strength >= STRONG) {
passwordEntryWrapper.setHelperText(
getString(R.string.password_strong));
} else if (strength >= QUITE_WEAK) {
passwordEntryWrapper.setHelperText(
getString(R.string.password_quite_strong));
} else {
passwordEntryWrapper.setHelperTextEnabled(false);
}
}
setError(passwordEntryWrapper, getString(R.string.password_too_weak), setError(passwordEntryWrapper, getString(R.string.password_too_weak),
!password1.isEmpty() && !strongEnough); password1.length() > 0 && !strongEnough);
setError(passwordConfirmationWrapper, setError(passwordConfirmationWrapper,
getString(R.string.passwords_do_not_match), getString(R.string.passwords_do_not_match),
!password2.isEmpty() && !passwordsMatch); password2.length() > 0 && !passwordsMatch);
boolean enabled = passwordsMatch && strongEnough; boolean enabled = passwordsMatch && strongEnough;
nextButton.setEnabled(enabled); nextButton.setEnabled(enabled);

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.account; package org.briarproject.briar.android.account;
import android.annotation.SuppressLint;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Intent; import android.content.Intent;
@@ -114,7 +113,6 @@ public class UnlockActivity extends BaseActivity {
} }
@Override @Override
@SuppressLint("MissingSuperCall")
public void onBackPressed() { public void onBackPressed() {
moveTaskToBack(true); moveTaskToBack(true);
} }

View File

@@ -101,8 +101,6 @@ public abstract class BaseActivity extends AppCompatActivity
// unlock screen is shown. // unlock screen is shown.
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
if (SDK_INT >= 31) getWindow().setHideOverlayWindows(true);
for (ActivityLifecycleController alc : lifecycleControllers) { for (ActivityLifecycleController alc : lifecycleControllers) {
alc.onActivityCreate(this); alc.onActivityCreate(this);
} }

View File

@@ -7,8 +7,6 @@ import android.view.Window;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.android.dontkillmelib.wakelock.AndroidWakeLockManager; import org.briarproject.android.dontkillmelib.wakelock.AndroidWakeLockManager;
import org.briarproject.bramble.api.system.Wakeful; import org.briarproject.bramble.api.system.Wakeful;
import org.briarproject.briar.R; import org.briarproject.briar.R;
@@ -179,8 +177,8 @@ public abstract class BriarActivity extends BaseActivity {
} }
protected void showDozeDialog(@StringRes int message) { protected void showDozeDialog(@StringRes int message) {
MaterialAlertDialogBuilder b = AlertDialog.Builder b =
new MaterialAlertDialogBuilder(this, R.style.BriarDialogTheme); new AlertDialog.Builder(this, R.style.BriarDialogTheme);
b.setMessage(message); b.setMessage(message);
b.setView(R.layout.checkbox); b.setView(R.layout.checkbox);
b.setPositiveButton(R.string.fix, b.setPositiveButton(R.string.fix,

View File

@@ -10,8 +10,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
@@ -29,6 +27,7 @@ import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView.LayoutManager; import androidx.recyclerview.widget.RecyclerView.LayoutManager;
@@ -221,8 +220,8 @@ public class BlogFragment extends BaseFragment
} }
private void showDeleteDialog() { private void showDeleteDialog() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(requireContext(),
requireContext(), R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.blogs_remove_blog)); builder.setTitle(getString(R.string.blogs_remove_blog));
builder.setMessage( builder.setMessage(
getString(R.string.blogs_remove_blog_dialog_message)); getString(R.string.blogs_remove_blog_dialog_message));

View File

@@ -4,8 +4,6 @@ import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.BaseActivity; import org.briarproject.briar.android.activity.BaseActivity;
@@ -15,6 +13,7 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -52,8 +51,8 @@ public class RssFeedDeleteFeedDialogFragment extends DialogFragment {
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
GroupId groupId = new GroupId( GroupId groupId = new GroupId(
requireNonNull(requireArguments().getByteArray(GROUP_ID))); requireNonNull(requireArguments().getByteArray(GROUP_ID)));
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity(),
requireActivity(), R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.blogs_rss_remove_feed)); builder.setTitle(getString(R.string.blogs_rss_remove_feed));
builder.setMessage( builder.setMessage(
getString(R.string.blogs_rss_remove_feed_dialog_message)); getString(R.string.blogs_rss_remove_feed_dialog_message));

View File

@@ -4,8 +4,6 @@ import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.BaseActivity; import org.briarproject.briar.android.activity.BaseActivity;
import org.briarproject.nullsafety.MethodsNotNullByDefault; import org.briarproject.nullsafety.MethodsNotNullByDefault;
@@ -14,6 +12,7 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -48,8 +47,8 @@ public class RssFeedImportFailedDialogFragment extends DialogFragment {
@Override @Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(requireActivity(), new AlertDialog.Builder(requireActivity(),
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setMessage(R.string.blogs_rss_feeds_import_error); builder.setMessage(R.string.blogs_rss_feeds_import_error);
builder.setNegativeButton(R.string.cancel, null); builder.setNegativeButton(R.string.cancel, null);

View File

@@ -2,12 +2,9 @@ package org.briarproject.briar.android.blog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import com.google.android.material.snackbar.Snackbar;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
@@ -37,21 +34,14 @@ import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import static android.text.util.Linkify.WEB_URLS;
import static android.text.util.Linkify.addLinks;
import static android.view.View.GONE; import static android.view.View.GONE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static androidx.core.text.HtmlCompat.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL;
import static androidx.core.text.HtmlCompat.toHtml;
import static com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_SHORT;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
import static org.briarproject.briar.android.view.TextSendController.SendState; import static org.briarproject.briar.android.view.TextSendController.SendState;
import static org.briarproject.briar.android.view.TextSendController.SendState.SENT; import static org.briarproject.briar.android.view.TextSendController.SendState.SENT;
import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_TEXT_LENGTH; import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_TEXT_LENGTH;
import static org.briarproject.briar.util.HtmlUtils.cleanArticle;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -128,23 +118,12 @@ public class WriteBlogPostActivity extends BriarActivity
List<AttachmentHeader> headers, long expectedAutoDeleteTimer) { List<AttachmentHeader> headers, long expectedAutoDeleteTimer) {
if (isNullOrEmpty(text)) throw new AssertionError(); if (isNullOrEmpty(text)) throw new AssertionError();
SpannableStringBuilder ssb = SpannableStringBuilder.valueOf(text);
addLinks(ssb, WEB_URLS);
String html = cleanArticle(toHtml(ssb,
TO_HTML_PARAGRAPH_LINES_INDIVIDUAL));
int textLength = toUtf8(html).length;
if (textLength > MAX_BLOG_POST_TEXT_LENGTH) {
Snackbar.make(input, R.string.text_too_long, LENGTH_SHORT).show();
return new MutableLiveData<>(null);
}
// hide publish button, show progress bar // hide publish button, show progress bar
input.hideSoftKeyboard(); input.hideSoftKeyboard();
input.setVisibility(GONE); input.setVisibility(GONE);
progressBar.setVisibility(VISIBLE); progressBar.setVisibility(VISIBLE);
storePost(html); storePost(text);
return new MutableLiveData<>(SENT); return new MutableLiveData<>(SENT);
} }

View File

@@ -88,7 +88,6 @@ 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.DISABLED;
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; 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.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.util.AndroidUtils.registerReceiver;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1; import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactPermissionManager.areEssentialPermissionsGranted; import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactPermissionManager.areEssentialPermissionsGranted;
@@ -209,7 +208,7 @@ class AddNearbyContactViewModel extends AndroidViewModel
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this); qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
eventBus.addListener(this); eventBus.addListener(this);
IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED); IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED);
registerReceiver(getApplication(), bluetoothReceiver, filter, false); getApplication().registerReceiver(bluetoothReceiver, filter);
} }
@Override @Override

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.contact.add.remote; package org.briarproject.briar.android.contact.add.remote;
import android.content.ActivityNotFoundException;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.os.Bundle; import android.os.Bundle;
@@ -21,7 +20,6 @@ import org.briarproject.briar.android.view.InfoView;
import org.briarproject.nullsafety.MethodsNotNullByDefault; import org.briarproject.nullsafety.MethodsNotNullByDefault;
import org.briarproject.nullsafety.ParametersNotNullByDefault; import org.briarproject.nullsafety.ParametersNotNullByDefault;
import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -31,12 +29,8 @@ import androidx.core.app.ShareCompat.IntentBuilder;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import static android.content.Context.CLIPBOARD_SERVICE; import static android.content.Context.CLIPBOARD_SERVICE;
import static android.widget.Toast.LENGTH_LONG;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX; import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen; import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
import static org.briarproject.briar.android.util.UiUtils.observeOnce; import static org.briarproject.briar.android.util.UiUtils.observeOnce;
@@ -45,7 +39,6 @@ import static org.briarproject.briar.android.util.UiUtils.observeOnce;
public class LinkExchangeFragment extends BaseFragment { public class LinkExchangeFragment extends BaseFragment {
private static final String TAG = LinkExchangeFragment.class.getName(); private static final String TAG = LinkExchangeFragment.class.getName();
private static final Logger LOG = getLogger(TAG);
@Inject @Inject
ViewModelProvider.Factory viewModelFactory; ViewModelProvider.Factory viewModelFactory;
@@ -123,18 +116,11 @@ public class LinkExchangeFragment extends BaseFragment {
copyButton.setEnabled(true); copyButton.setEnabled(true);
Button shareButton = v.findViewById(R.id.shareButton); Button shareButton = v.findViewById(R.id.shareButton);
shareButton.setOnClickListener(view -> { shareButton.setOnClickListener(view ->
try {
IntentBuilder.from(requireActivity()) IntentBuilder.from(requireActivity())
.setText(link) .setText(link)
.setType("text/plain") .setType("text/plain")
.startChooser(); .startChooser());
} catch (ActivityNotFoundException e) {
logException(LOG, WARNING, e);
Toast.makeText(requireContext(),
R.string.error_start_activity, LENGTH_LONG).show();
}
});
shareButton.setEnabled(true); shareButton.setEnabled(true);
InfoView infoText = v.findViewById(R.id.infoView); InfoView infoText = v.findViewById(R.id.infoView);

View File

@@ -55,7 +55,6 @@ public class NicknameFragment extends BaseFragment {
private TextInputLayout contactNameLayout; private TextInputLayout contactNameLayout;
private TextInputEditText contactNameInput; private TextInputEditText contactNameInput;
private BriarButton addButton;
@Override @Override
public String getUniqueTag() { public String getUniqueTag() {
@@ -92,7 +91,7 @@ public class NicknameFragment extends BaseFragment {
contactNameLayout = v.findViewById(R.id.contactNameLayout); contactNameLayout = v.findViewById(R.id.contactNameLayout);
contactNameInput = v.findViewById(R.id.contactNameInput); contactNameInput = v.findViewById(R.id.contactNameInput);
addButton = v.findViewById(R.id.addButton); BriarButton addButton = v.findViewById(R.id.addButton);
addButton.setOnClickListener(view -> onAddButtonClicked()); addButton.setOnClickListener(view -> onAddButtonClicked());
return v; return v;
@@ -113,7 +112,7 @@ public class NicknameFragment extends BaseFragment {
@Nullable @Nullable
private String getNicknameOrNull() { private String getNicknameOrNull() {
Editable text = contactNameInput.getText(); Editable text = contactNameInput.getText();
if (text == null || text.toString().trim().isEmpty()) { if (text == null || text.toString().trim().length() == 0) {
contactNameLayout.setError(getString(R.string.nickname_missing)); contactNameLayout.setError(getString(R.string.nickname_missing));
contactNameInput.requestFocus(); contactNameInput.requestFocus();
return null; return null;
@@ -130,10 +129,7 @@ public class NicknameFragment extends BaseFragment {
private void onAddButtonClicked() { private void onAddButtonClicked() {
String name = getNicknameOrNull(); String name = getNicknameOrNull();
if (name == null) { // invalid nickname if (name == null) return; // invalid nickname
addButton.reset();
return;
}
LifecycleOwner owner = getViewLifecycleOwner(); LifecycleOwner owner = getViewLifecycleOwner();
viewModel.getAddContactResult().observe(owner, result -> { viewModel.getAddContactResult().observe(owner, result -> {

View File

@@ -4,7 +4,6 @@ import android.content.DialogInterface.OnClickListener;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactId;
@@ -22,6 +21,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
@@ -110,7 +110,7 @@ public class PendingContactListActivity extends BriarActivity
// show warning dialog // show warning dialog
OnClickListener removeListener = (dialog, which) -> OnClickListener removeListener = (dialog, which) ->
removePendingContact(item.getPendingContact().getId()); removePendingContact(item.getPendingContact().getId());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(
PendingContactListActivity.this, R.style.BriarDialogTheme); PendingContactListActivity.this, R.style.BriarDialogTheme);
builder.setTitle( builder.setTitle(
getString(R.string.dialog_title_remove_pending_contact)); getString(R.string.dialog_title_remove_pending_contact));

View File

@@ -147,7 +147,7 @@ public class BriarControllerImpl implements BriarController {
service.waitForStartup(); service.waitForStartup();
// Shut down the service and wait for it to shut down // Shut down the service and wait for it to shut down
LOG.info("Shutting down service"); LOG.info("Shutting down service");
service.shutdown(true); service.shutdown();
service.waitForShutdown(); service.waitForShutdown();
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.warning("Interrupted while waiting for service"); LOG.warning("Interrupted while waiting for service");

View File

@@ -19,7 +19,6 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import org.briarproject.bramble.api.FeatureFlags; import org.briarproject.bramble.api.FeatureFlags;
@@ -102,6 +101,7 @@ import javax.inject.Inject;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.ActionMenuView; import androidx.appcompat.widget.ActionMenuView;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
@@ -812,8 +812,8 @@ public class ConversationActivity extends BriarActivity
} }
private void askToDeleteAllMessages() { private void askToDeleteAllMessages() {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(this, R.style.BriarDialogTheme); new AlertDialog.Builder(this, R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.dialog_title_delete_all_messages)); builder.setTitle(getString(R.string.dialog_title_delete_all_messages));
builder.setMessage( builder.setMessage(
getString(R.string.dialog_message_delete_all_messages)); getString(R.string.dialog_message_delete_all_messages));
@@ -892,8 +892,8 @@ public class ConversationActivity extends BriarActivity
} }
String msg = join(fails, "\n\n"); String msg = join(fails, "\n\n");
// show dialog // show dialog
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(this, R.style.BriarDialogTheme); new AlertDialog.Builder(this, R.style.BriarDialogTheme);
builder.setTitle( builder.setTitle(
getString(R.string.dialog_title_not_all_messages_deleted)); getString(R.string.dialog_title_not_all_messages_deleted));
builder.setMessage(msg); builder.setMessage(msg);
@@ -904,8 +904,8 @@ public class ConversationActivity extends BriarActivity
private void askToRemoveContact() { private void askToRemoveContact() {
DialogInterface.OnClickListener okListener = DialogInterface.OnClickListener okListener =
(dialog, which) -> removeContact(); (dialog, which) -> removeContact();
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(ConversationActivity.this, new AlertDialog.Builder(ConversationActivity.this,
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.dialog_title_delete_contact)); builder.setTitle(getString(R.string.dialog_title_delete_contact));
builder.setMessage( builder.setMessage(

View File

@@ -7,8 +7,6 @@ import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.sharing.ForumSharingStatusActivity; import org.briarproject.briar.android.sharing.ForumSharingStatusActivity;
@@ -22,6 +20,7 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -129,7 +128,7 @@ public class ForumActivity extends
private void showUnsubscribeDialog() { private void showUnsubscribeDialog() {
OnClickListener okListener = (dialog, which) -> viewModel.deleteForum(); OnClickListener okListener = (dialog, which) -> viewModel.deleteForum();
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, AlertDialog.Builder builder = new AlertDialog.Builder(this,
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.dialog_title_leave_forum)); builder.setTitle(getString(R.string.dialog_title_leave_forum));
builder.setMessage(getString(R.string.dialog_message_leave_forum)); builder.setMessage(getString(R.string.dialog_message_leave_forum));

View File

@@ -13,18 +13,15 @@ import androidx.recyclerview.widget.ListAdapter;
@NotNullByDefault @NotNullByDefault
class ForumListAdapter extends ListAdapter<ForumListItem, ForumViewHolder> { class ForumListAdapter extends ListAdapter<ForumListItem, ForumViewHolder> {
private final ForumListViewModel viewModel; ForumListAdapter() {
ForumListAdapter(ForumListViewModel viewModel) {
super(new ForumListCallback()); super(new ForumListCallback());
this.viewModel = viewModel;
} }
@Override @Override
public ForumViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public ForumViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate( View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_item_forum, parent, false); R.layout.list_item_forum, parent, false);
return new ForumViewHolder(v, viewModel); return new ForumViewHolder(v);
} }
@Override @Override

View File

@@ -40,7 +40,7 @@ public class ForumListFragment extends BaseFragment implements
private ForumListViewModel viewModel; private ForumListViewModel viewModel;
private BriarRecyclerView list; private BriarRecyclerView list;
private Snackbar snackbar; private Snackbar snackbar;
private ForumListAdapter adapter; private final ForumListAdapter adapter = new ForumListAdapter();
@Inject @Inject
ViewModelProvider.Factory viewModelFactory; ViewModelProvider.Factory viewModelFactory;
@@ -54,7 +54,6 @@ public class ForumListFragment extends BaseFragment implements
component.inject(this); component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory) viewModel = new ViewModelProvider(this, viewModelFactory)
.get(ForumListViewModel.class); .get(ForumListViewModel.class);
adapter = new ForumListAdapter(viewModel);
} }
@Nullable @Nullable

View File

@@ -1,7 +1,6 @@
package org.briarproject.briar.android.forum; package org.briarproject.briar.android.forum;
import android.app.Application; import android.app.Application;
import android.widget.Toast;
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent; import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DatabaseExecutor;
@@ -16,7 +15,6 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.event.GroupAddedEvent; import org.briarproject.bramble.api.sync.event.GroupAddedEvent;
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent; import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.briar.R;
import org.briarproject.briar.android.viewmodel.DbViewModel; import org.briarproject.briar.android.viewmodel.DbViewModel;
import org.briarproject.briar.android.viewmodel.LiveResult; import org.briarproject.briar.android.viewmodel.LiveResult;
import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.android.AndroidNotificationManager;
@@ -42,7 +40,6 @@ import androidx.annotation.UiThread;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import static android.widget.Toast.LENGTH_SHORT;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.bramble.util.LogUtils.now;
@@ -183,17 +180,4 @@ class ForumListViewModel extends DbViewModel implements EventListener {
return numInvitations; return numInvitations;
} }
void deleteForum(GroupId groupId) {
runOnDbThread(() -> {
try {
Forum f = forumManager.getForum(groupId);
forumManager.removeForum(f);
androidExecutor.runOnUiThread(() -> Toast
.makeText(getApplication(), R.string.forum_left_toast,
LENGTH_SHORT).show());
} catch (DbException e) {
handleException(e);
}
});
}
} }

View File

@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.PopupMenu;
import android.widget.TextView; import android.widget.TextView;
import org.briarproject.briar.R; import org.briarproject.briar.R;
@@ -21,7 +20,6 @@ import static org.briarproject.briar.android.activity.BriarActivity.GROUP_NAME;
class ForumViewHolder extends RecyclerView.ViewHolder { class ForumViewHolder extends RecyclerView.ViewHolder {
private final ForumListViewModel viewModel;
private final Context ctx; private final Context ctx;
private final ViewGroup layout; private final ViewGroup layout;
private final TextAvatarView avatar; private final TextAvatarView avatar;
@@ -29,9 +27,8 @@ class ForumViewHolder extends RecyclerView.ViewHolder {
private final TextView postCount; private final TextView postCount;
private final TextView date; private final TextView date;
ForumViewHolder(View v, ForumListViewModel viewModel) { ForumViewHolder(View v) {
super(v); super(v);
this.viewModel = viewModel;
ctx = v.getContext(); ctx = v.getContext();
layout = (ViewGroup) v; layout = (ViewGroup) v;
avatar = v.findViewById(R.id.avatarView); avatar = v.findViewById(R.id.avatarView);
@@ -67,21 +64,6 @@ class ForumViewHolder extends RecyclerView.ViewHolder {
date.setVisibility(VISIBLE); date.setVisibility(VISIBLE);
} }
// Open popup menu on long click
layout.setOnLongClickListener(v -> {
PopupMenu pm = new PopupMenu(ctx, v);
pm.getMenuInflater().inflate(R.menu.forum_list_item_actions,
pm.getMenu());
pm.setOnMenuItemClickListener(it -> {
if (it.getItemId() == R.id.action_forum_delete) {
viewModel.deleteForum(item.getForum().getId());
}
return true;
});
pm.show();
return true;
});
// Open Forum on Click // Open Forum on Click
layout.setOnClickListener(v -> { layout.setOnClickListener(v -> {
Intent i = new Intent(ctx, ForumActivity.class); Intent i = new Intent(ctx, ForumActivity.class);

View File

@@ -13,8 +13,6 @@ import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.BaseActivity; import org.briarproject.briar.android.activity.BaseActivity;
import org.briarproject.briar.api.android.ScreenFilterMonitor; import org.briarproject.briar.api.android.ScreenFilterMonitor;
@@ -29,6 +27,7 @@ import java.util.Collection;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
@@ -76,8 +75,8 @@ public class ScreenFilterDialogFragment extends DialogFragment {
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity == null) throw new IllegalStateException(); if (activity == null) throw new IllegalStateException();
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(activity,
activity, R.style.BriarDialogThemeNoFilter); R.style.BriarDialogThemeNoFilter);
builder.setTitle(R.string.screen_filter_title); builder.setTitle(R.string.screen_filter_title);
Bundle args = getArguments(); Bundle args = getArguments();
if (args == null) throw new IllegalStateException(); if (args == null) throw new IllegalStateException();

View File

@@ -6,13 +6,12 @@ import android.content.Intent;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.core.util.Consumer; import androidx.core.util.Consumer;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
@@ -74,8 +73,7 @@ abstract class AbstractConditionManager {
void showRationale(Context ctx, @StringRes int title, void showRationale(Context ctx, @StringRes int title,
@StringRes int body, Runnable onContinueClicked, @StringRes int body, Runnable onContinueClicked,
Runnable onDismiss) { Runnable onDismiss) {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
new MaterialAlertDialogBuilder(ctx);
builder.setTitle(title); builder.setTitle(title);
builder.setMessage(body); builder.setMessage(body);
builder.setNeutralButton(R.string.continue_button, builder.setNeutralButton(R.string.continue_button,

View File

@@ -61,7 +61,6 @@ public class HotspotIntroFragment extends Fragment {
getAndroidComponent(activity).inject(this); getAndroidComponent(activity).inject(this);
viewModel = new ViewModelProvider(activity, viewModelFactory) viewModel = new ViewModelProvider(activity, viewModelFactory)
.get(HotspotViewModel.class); .get(HotspotViewModel.class);
conditionManager.init(requireActivity());
} }
@Override @Override
@@ -77,6 +76,8 @@ public class HotspotIntroFragment extends Fragment {
startButton.setOnClickListener(this::onButtonClick); startButton.setOnClickListener(this::onButtonClick);
conditionManager.init(requireActivity());
return v; return v;
} }

View File

@@ -432,8 +432,7 @@ class HotspotManager {
@RequiresApi(29) @RequiresApi(29)
private String getPassword() { private String getPassword() {
return getRandomString(4) + "-" + getRandomString(4) + "-" + return getRandomString(8);
getRandomString(4) + "-" + getRandomString(4);
} }
private static String createWifiLoginString(String ssid, String password) { private static String createWifiLoginString(String ssid, String password) {

View File

@@ -32,7 +32,6 @@ import static android.widget.Toast.LENGTH_LONG;
import static org.briarproject.bramble.api.crypto.DecryptionResult.KEY_STRENGTHENER_ERROR; import static org.briarproject.bramble.api.crypto.DecryptionResult.KEY_STRENGTHENER_ERROR;
import static org.briarproject.bramble.api.crypto.DecryptionResult.SUCCESS; import static org.briarproject.bramble.api.crypto.DecryptionResult.SUCCESS;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK; import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
import static org.briarproject.briar.android.login.LoginUtils.createKeyStrengthenerErrorDialog; import static org.briarproject.briar.android.login.LoginUtils.createKeyStrengthenerErrorDialog;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard; import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.android.util.UiUtils.setError; import static org.briarproject.briar.android.util.UiUtils.setError;
@@ -124,25 +123,12 @@ public class ChangePasswordActivity extends BriarActivity
boolean passwordsMatch = firstPassword.equals(secondPassword); boolean passwordsMatch = firstPassword.equals(secondPassword);
float strength = viewModel.estimatePasswordStrength(firstPassword); float strength = viewModel.estimatePasswordStrength(firstPassword);
strengthMeter.setStrength(strength); strengthMeter.setStrength(strength);
if (!firstPassword.isEmpty()) {
if (strength >= STRONG) {
newPasswordEntryWrapper.setHelperText(
getString(R.string.password_strong));
} else if (strength >= QUITE_WEAK) {
newPasswordEntryWrapper.setHelperText(
getString(R.string.password_quite_strong));
} else {
newPasswordEntryWrapper.setHelperTextEnabled(false);
}
}
setError(newPasswordEntryWrapper, setError(newPasswordEntryWrapper,
getString(R.string.password_too_weak), getString(R.string.password_too_weak),
!firstPassword.isEmpty() && strength < QUITE_WEAK); firstPassword.length() > 0 && strength < QUITE_WEAK);
setError(newPasswordConfirmationWrapper, setError(newPasswordConfirmationWrapper,
getString(R.string.passwords_do_not_match), getString(R.string.passwords_do_not_match),
!secondPassword.isEmpty() && !passwordsMatch); secondPassword.length() > 0 && !passwordsMatch);
changePasswordButton.setEnabled( changePasswordButton.setEnabled(
!currentPassword.getText().toString().isEmpty() && !currentPassword.getText().toString().isEmpty() &&
passwordsMatch && strength >= QUITE_WEAK); passwordsMatch && strength >= QUITE_WEAK);

View File

@@ -2,8 +2,6 @@ package org.briarproject.briar.android.login;
import android.content.Context; import android.content.Context;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.nullsafety.NotNullByDefault; import org.briarproject.nullsafety.NotNullByDefault;
@@ -15,8 +13,8 @@ import static org.briarproject.briar.android.util.UiUtils.getDialogIcon;
class LoginUtils { class LoginUtils {
static AlertDialog createKeyStrengthenerErrorDialog(Context ctx) { static AlertDialog createKeyStrengthenerErrorDialog(Context ctx) {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(ctx, R.style.BriarDialogTheme); new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
builder.setIcon(getDialogIcon(ctx, R.drawable.alerts_and_states_error)); builder.setIcon(getDialogIcon(ctx, R.drawable.alerts_and_states_error));
builder.setTitle(R.string.dialog_title_cannot_check_password); builder.setTitle(R.string.dialog_title_cannot_check_password);
builder.setMessage(R.string.dialog_message_cannot_check_password); builder.setMessage(R.string.dialog_message_cannot_check_password);

View File

@@ -9,7 +9,6 @@ import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
@@ -41,7 +40,6 @@ import static org.briarproject.bramble.api.crypto.DecryptionResult.SUCCESS;
import static org.briarproject.briar.android.login.LoginUtils.createKeyStrengthenerErrorDialog; import static org.briarproject.briar.android.login.LoginUtils.createKeyStrengthenerErrorDialog;
import static org.briarproject.briar.android.util.UiUtils.enterPressed; import static org.briarproject.briar.android.util.UiUtils.enterPressed;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard; import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.android.util.UiUtils.hideViewOnSmallScreen;
import static org.briarproject.briar.android.util.UiUtils.setError; import static org.briarproject.briar.android.util.UiUtils.setError;
import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard; import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard;
@@ -102,12 +100,6 @@ public class PasswordFragment extends BaseFragment implements TextWatcher {
return v; return v;
} }
@Override
public void onStart() {
super.onStart();
hideViewOnSmallScreen(requireView().findViewById(R.id.logo));
}
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, public void beforeTextChanged(CharSequence s, int start, int count,
int after) { int after) {
@@ -155,11 +147,9 @@ public class PasswordFragment extends BaseFragment implements TextWatcher {
} }
private void onForgottenPasswordClick() { private void onForgottenPasswordClick() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(requireContext(),
requireContext(), R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(R.string.dialog_title_lost_password); builder.setTitle(R.string.dialog_title_lost_password);
builder.setBackgroundInsetStart(25);
builder.setBackgroundInsetEnd(25);
builder.setMessage(R.string.dialog_message_lost_password); builder.setMessage(R.string.dialog_message_lost_password);
builder.setPositiveButton(R.string.cancel, null); builder.setPositiveButton(R.string.cancel, null);
builder.setNegativeButton(R.string.delete, builder.setNegativeButton(R.string.delete,

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.login; package org.briarproject.briar.android.login;
import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@@ -75,7 +74,6 @@ public class StartupActivity extends BaseActivity implements
} }
@Override @Override
@SuppressLint("MissingSuperCall")
public void onBackPressed() { public void onBackPressed() {
// Move task and activity to the background instead of showing another // Move task and activity to the background instead of showing another
// password prompt. // password prompt.

View File

@@ -11,7 +11,6 @@ import android.widget.RadioGroup;
import android.widget.ScrollView; import android.widget.ScrollView;
import com.google.android.material.animation.ArgbEvaluatorCompat; import com.google.android.material.animation.ArgbEvaluatorCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.view.BriarButton; import org.briarproject.briar.android.view.BriarButton;
@@ -25,6 +24,7 @@ import javax.inject.Inject;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -148,8 +148,8 @@ public class ErrorWizardFragment extends Fragment {
} }
private void onUnlinkButtonClicked(View v) { private void onUnlinkButtonClicked(View v) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(requireContext(),
requireContext(), R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(R.string.mailbox_status_unlink_dialog_title); builder.setTitle(R.string.mailbox_status_unlink_dialog_title);
builder.setMessage(R.string.mailbox_status_unlink_dialog_question); builder.setMessage(R.string.mailbox_status_unlink_dialog_question);
builder.setPositiveButton(R.string.cancel, builder.setPositiveButton(R.string.cancel,

View File

@@ -5,8 +5,6 @@ import android.view.MenuItem;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.bramble.api.mailbox.MailboxPairingState; import org.briarproject.bramble.api.mailbox.MailboxPairingState;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.ConnectionError; import org.briarproject.bramble.api.mailbox.MailboxPairingState.ConnectionError;
import org.briarproject.bramble.api.mailbox.MailboxPairingState.InvalidQrCode; import org.briarproject.bramble.api.mailbox.MailboxPairingState.InvalidQrCode;
@@ -33,6 +31,7 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -250,8 +249,8 @@ public class MailboxActivity extends BriarActivity {
if (tellUserToWipeMailbox) { if (tellUserToWipeMailbox) {
showFragment(getSupportFragmentManager(), new BlankFragment(), showFragment(getSupportFragmentManager(), new BlankFragment(),
BlankFragment.TAG); BlankFragment.TAG);
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder =
this, R.style.BriarDialogTheme); new AlertDialog.Builder(this, R.style.BriarDialogTheme);
builder.setTitle(R.string.mailbox_status_unlink_no_wipe_title); builder.setTitle(R.string.mailbox_status_unlink_no_wipe_title);
builder.setMessage(R.string.mailbox_status_unlink_no_wipe_message); builder.setMessage(R.string.mailbox_status_unlink_no_wipe_message);
builder.setNeutralButton(R.string.got_it, builder.setNeutralButton(R.string.got_it,

View File

@@ -13,8 +13,6 @@ import android.widget.ImageView;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.bramble.api.mailbox.MailboxStatus; import org.briarproject.bramble.api.mailbox.MailboxStatus;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.view.BriarButton; import org.briarproject.briar.android.view.BriarButton;
@@ -216,8 +214,8 @@ public class MailboxStatusFragment extends Fragment {
} }
private void onUnlinkButtonClicked(boolean showWarning) { private void onUnlinkButtonClicked(boolean showWarning) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(requireContext(),
requireContext(), R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(R.string.mailbox_status_unlink_dialog_title); builder.setTitle(R.string.mailbox_status_unlink_dialog_title);
String msg = getString(R.string.mailbox_status_unlink_dialog_question); String msg = getString(R.string.mailbox_status_unlink_dialog_question);
if (showWarning) { if (showWarning) {

View File

@@ -48,7 +48,6 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE; import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING; import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.util.AndroidUtils.registerReceiver;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.bramble.util.LogUtils.now;
@@ -97,8 +96,7 @@ public class PluginViewModel extends DbViewModel implements EventListener {
this.eventBus = eventBus; this.eventBus = eventBus;
eventBus.addListener(this); eventBus.addListener(this);
receiver = new BluetoothStateReceiver(); receiver = new BluetoothStateReceiver();
registerReceiver(app, receiver, new IntentFilter(ACTION_STATE_CHANGED), app.registerReceiver(receiver, new IntentFilter(ACTION_STATE_CHANGED));
false);
networkStatus.setValue(networkManager.getNetworkStatus()); networkStatus.setValue(networkManager.getNetworkStatus());
torPluginState.setValue(getTransportState(TorConstants.ID)); torPluginState.setValue(getTransportState(TorConstants.ID));
wifiPluginState.setValue(getTransportState(LanTcpConstants.ID)); wifiPluginState.setValue(getTransportState(LanTcpConstants.ID));

View File

@@ -219,8 +219,7 @@ public class TransportsActivity extends BriarActivity {
} }
private void onClicked(TransportId transportId, boolean enable) { private void onClicked(TransportId transportId, boolean enable) {
if (transportId.equals(BluetoothConstants.ID) && enable if (enable && SDK_INT >= 31 && !areBluetoothPermissionsGranted(this)) {
&& SDK_INT >= 31 && !areBluetoothPermissionsGranted(this)) {
if (shouldShowRequestPermissionRationale(BLUETOOTH_CONNECT)) { if (shouldShowRequestPermissionRationale(BLUETOOTH_CONNECT)) {
showRationale(this, R.string.permission_bluetooth_title, showRationale(this, R.string.permission_bluetooth_title,
R.string.permission_bluetooth_body, R.string.permission_bluetooth_body,

View File

@@ -10,8 +10,6 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import java.util.ArrayList; import java.util.ArrayList;
@@ -19,6 +17,7 @@ import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreferenceCompat; import androidx.preference.SwitchPreferenceCompat;
@@ -202,8 +201,8 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
getActivity().finish(); getActivity().finish();
}; };
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder = new AlertDialog.Builder(getContext(),
requireContext(), R.style.BriarDialogTheme); R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.dialog_title_connect_panic_app)); builder.setTitle(getString(R.string.dialog_title_connect_panic_app));
CharSequence app = getString(R.string.unknown_app); CharSequence app = getString(R.string.unknown_app);

View File

@@ -6,8 +6,6 @@ import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.privategroup.creation.GroupInviteActivity; import org.briarproject.briar.android.privategroup.creation.GroupInviteActivity;
@@ -22,6 +20,7 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -179,8 +178,8 @@ public class GroupActivity extends
} }
private void showLeaveGroupDialog() { private void showLeaveGroupDialog() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder =
this, R.style.BriarDialogTheme); new AlertDialog.Builder(this, R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.groups_leave_dialog_title)); builder.setTitle(getString(R.string.groups_leave_dialog_title));
builder.setMessage(getString(R.string.groups_leave_dialog_message)); builder.setMessage(getString(R.string.groups_leave_dialog_message));
builder.setNegativeButton(R.string.dialog_button_leave, builder.setNegativeButton(R.string.dialog_button_leave,
@@ -190,8 +189,8 @@ public class GroupActivity extends
} }
private void showDissolveGroupDialog() { private void showDissolveGroupDialog() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder =
this, R.style.BriarDialogTheme); new AlertDialog.Builder(this, R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.groups_dissolve_dialog_title)); builder.setTitle(getString(R.string.groups_dissolve_dialog_title));
builder.setMessage(getString(R.string.groups_dissolve_dialog_message)); builder.setMessage(getString(R.string.groups_dissolve_dialog_message));
builder.setNegativeButton(R.string.groups_dissolve_button, builder.setNegativeButton(R.string.groups_dissolve_button,
@@ -207,8 +206,8 @@ public class GroupActivity extends
} }
private void onGroupDissolved() { private void onGroupDissolved() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder( AlertDialog.Builder builder =
this, R.style.BriarDialogTheme); new AlertDialog.Builder(this, R.style.BriarDialogTheme);
builder.setTitle(getString(R.string.groups_dissolved_dialog_title)); builder.setTitle(getString(R.string.groups_dissolved_dialog_title));
builder.setMessage(getString(R.string.groups_dissolved_dialog_message)); builder.setMessage(getString(R.string.groups_dissolved_dialog_message));
builder.setNeutralButton(R.string.ok, null); builder.setNeutralButton(R.string.ok, null);

View File

@@ -9,8 +9,6 @@ import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
@@ -28,6 +26,7 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.LayoutRes; import androidx.annotation.LayoutRes;
import androidx.appcompat.app.AlertDialog;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -106,8 +105,7 @@ public class RevealContactsActivity extends ContactSelectorActivity
} }
private void showOnboardingDialog() { private void showOnboardingDialog() {
new MaterialAlertDialogBuilder(this, new AlertDialog.Builder(this, R.style.OnboardingDialogTheme)
R.style.OnboardingDialogTheme)
.setMessage(getString(R.string.groups_reveal_dialog_message)) .setMessage(getString(R.string.groups_reveal_dialog_message))
.setNeutralButton(R.string.got_it, .setNeutralButton(R.string.got_it,
(dialog, which) -> dialog.cancel()) (dialog, which) -> dialog.cancel())

View File

@@ -200,7 +200,6 @@ class BriarReportCollector {
storageInfo); storageInfo);
} }
@SuppressLint({"HardwareIds", "MissingPermission"})
private ReportItem getConnectivity() { private ReportItem getConnectivity() {
MultiReportInfo connectivityInfo = new MultiReportInfo(); MultiReportInfo connectivityInfo = new MultiReportInfo();
@@ -283,14 +282,13 @@ class BriarReportCollector {
connectivityInfo.add("BluetoothAvailable", true); connectivityInfo.add("BluetoothAvailable", true);
// Is Bluetooth enabled? // Is Bluetooth enabled?
boolean btEnabled = hasBtConnectPermission(ctx) && bt.isEnabled(); @SuppressLint("HardwareIds")
try { boolean btEnabled = hasBtConnectPermission(ctx) && bt.isEnabled()
btEnabled = btEnabled && !isNullOrEmpty(bt.getAddress()); && !isNullOrEmpty(bt.getAddress());
} catch (SecurityException ignored) {
}
connectivityInfo.add("BluetoothEnabled", btEnabled); connectivityInfo.add("BluetoothEnabled", btEnabled);
// Is Bluetooth connectable? // Is Bluetooth connectable?
@SuppressLint("MissingPermission")
int scanMode = areBluetoothPermissionsGranted(ctx) ? int scanMode = areBluetoothPermissionsGranted(ctx) ?
bt.getScanMode() : -1; bt.getScanMode() : -1;
boolean btConnectable = scanMode == SCAN_MODE_CONNECTABLE || boolean btConnectable = scanMode == SCAN_MODE_CONNECTABLE ||

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.reporting; package org.briarproject.briar.android.reporting;
import android.annotation.SuppressLint;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@@ -88,7 +87,6 @@ public class CrashReportActivity extends BaseActivity
} }
@Override @Override
@SuppressLint("MissingSuperCall")
public void onBackPressed() { public void onBackPressed() {
exit(); exit();
} }

View File

@@ -10,7 +10,6 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.BaseActivity; import org.briarproject.briar.android.activity.BaseActivity;
@@ -21,6 +20,7 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -86,7 +86,7 @@ public class ConfirmAvatarDialogFragment extends DialogFragment {
); );
int theme = R.style.BriarDialogTheme; int theme = R.style.BriarDialogTheme;
return new MaterialAlertDialogBuilder(activity, theme) return new AlertDialog.Builder(activity, theme)
.setView(view) .setView(view)
.setTitle(R.string.dialog_confirm_profile_picture_title) .setTitle(R.string.dialog_confirm_profile_picture_title)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)

View File

@@ -1,19 +1,21 @@
package org.briarproject.briar.android.settings; package org.briarproject.briar.android.settings;
import android.app.AlertDialog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.Localizer; import org.briarproject.briar.android.Localizer;
import org.briarproject.briar.android.util.UiUtils; import org.briarproject.briar.android.util.UiUtils;
import org.briarproject.nullsafety.NotNullByDefault; import org.briarproject.nullsafety.NotNullByDefault;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.logging.Logger;
import androidx.core.text.TextUtilsCompat;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.Preference; import androidx.preference.Preference;
@@ -22,7 +24,10 @@ import androidx.preference.PreferenceFragmentCompat;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.Build.VERSION.SDK_INT;
import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY; import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY;
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI; import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI;
import static org.briarproject.briar.android.settings.SettingsActivity.EXTRA_THEME_CHANGE; import static org.briarproject.briar.android.settings.SettingsActivity.EXTRA_THEME_CHANGE;
@@ -31,7 +36,10 @@ import static org.briarproject.briar.android.settings.SettingsActivity.EXTRA_THE
public class DisplayFragment extends PreferenceFragmentCompat { public class DisplayFragment extends PreferenceFragmentCompat {
public static final String PREF_LANGUAGE = "pref_key_language"; public static final String PREF_LANGUAGE = "pref_key_language";
public static final String PREF_THEME = "pref_key_theme"; private static final String PREF_THEME = "pref_key_theme";
private static final Logger LOG =
getLogger(DisplayFragment.class.getName());
@Override @Override
public void onCreatePreferences(Bundle bundle, String s) { public void onCreatePreferences(Bundle bundle, String s) {
@@ -42,6 +50,7 @@ public class DisplayFragment extends PreferenceFragmentCompat {
language.setOnPreferenceChangeListener(this::onLanguageChanged); language.setOnPreferenceChangeListener(this::onLanguageChanged);
ListPreference theme = requireNonNull(findPreference(PREF_THEME)); ListPreference theme = requireNonNull(findPreference(PREF_THEME));
setThemeEntries(theme);
theme.setOnPreferenceChangeListener(this::onThemeChanged); theme.setOnPreferenceChangeListener(this::onThemeChanged);
} }
@@ -82,6 +91,30 @@ public class DisplayFragment extends PreferenceFragmentCompat {
language.setEntryValues(entryValues.toArray(new CharSequence[0])); language.setEntryValues(entryValues.toArray(new CharSequence[0]));
} }
private boolean isLeftToRight(Locale locale) {
// TextUtilsCompat returns the wrong direction for Hebrew on some phones
String language = locale.getLanguage();
if (language.equals("iw") || language.equals("he")) return false;
int direction = TextUtilsCompat.getLayoutDirectionFromLocale(locale);
return direction == LAYOUT_DIRECTION_LTR;
}
private void setThemeEntries(ListPreference theme) {
if (SDK_INT < 27) {
// remove System Default Theme option from preference entries
// as it is not functional on this API anyway
List<CharSequence> entries =
new ArrayList<>(Arrays.asList(theme.getEntries()));
entries.remove(getString(R.string.pref_theme_system));
theme.setEntries(entries.toArray(new CharSequence[0]));
// also remove corresponding value
List<CharSequence> values =
new ArrayList<>(Arrays.asList(theme.getEntryValues()));
values.remove(getString(R.string.pref_theme_system_value));
theme.setEntryValues(values.toArray(new CharSequence[0]));
}
}
private boolean onThemeChanged(Preference preference, Object newValue) { private boolean onThemeChanged(Preference preference, Object newValue) {
// activate new theme // activate new theme
FragmentActivity activity = requireActivity(); FragmentActivity activity = requireActivity();
@@ -102,8 +135,8 @@ public class DisplayFragment extends PreferenceFragmentCompat {
private boolean onLanguageChanged(Preference preference, Object newValue) { private boolean onLanguageChanged(Preference preference, Object newValue) {
ListPreference language = (ListPreference) preference; ListPreference language = (ListPreference) preference;
if (!language.getValue().equals(newValue)) { if (!language.getValue().equals(newValue)) {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(requireContext()); new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.pref_language_title); builder.setTitle(R.string.pref_language_title);
builder.setMessage(R.string.pref_language_changed); builder.setMessage(R.string.pref_language_changed);
builder.setPositiveButton(R.string.sign_out_button, (d, i) -> { builder.setPositiveButton(R.string.sign_out_button, (d, i) -> {

View File

@@ -40,12 +40,15 @@ class TorSummaryProvider implements SummaryProvider<ListPreference> {
String country = locationUtils.getCurrentCountry(); String country = locationUtils.getCurrentCountry();
String countryName = getCountryDisplayName(country); String countryName = getCountryDisplayName(country);
boolean useBridgesByDefault = boolean blocked =
circumventionProvider.shouldUseBridges(country); circumventionProvider.isTorProbablyBlocked(country);
boolean useBridges = circumventionProvider.doBridgesWork(country);
String setting = String setting =
ctx.getString(R.string.tor_network_setting_without_bridges); ctx.getString(R.string.tor_network_setting_without_bridges);
if (useBridgesByDefault) { if (blocked && useBridges) {
setting = ctx.getString(R.string.tor_network_setting_with_bridges); setting = ctx.getString(R.string.tor_network_setting_with_bridges);
} else if (blocked) {
setting = ctx.getString(R.string.tor_network_setting_never);
} }
return ctx.getString(R.string.tor_network_setting_summary, setting, return ctx.getString(R.string.tor_network_setting_summary, setting,
countryName); countryName);

View File

@@ -13,7 +13,6 @@ import org.briarproject.briar.android.Localizer;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import static android.content.Intent.ACTION_VIEW; import static android.content.Intent.ACTION_VIEW;
import static android.os.Build.VERSION.SDK_INT;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static org.briarproject.briar.android.TestingConstants.PREVENT_SCREENSHOTS; import static org.briarproject.briar.android.TestingConstants.PREVENT_SCREENSHOTS;
@@ -26,8 +25,6 @@ public class ExpiredActivity extends AppCompatActivity
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE); if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
if (SDK_INT >= 31) getWindow().setHideOverlayWindows(true);
setContentView(R.layout.activity_expired); setContentView(R.layout.activity_expired);
findViewById(R.id.download_briar_button).setOnClickListener(this); findViewById(R.id.download_briar_button).setOnClickListener(this);
} }
@@ -41,7 +38,7 @@ public class ExpiredActivity extends AppCompatActivity
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Uri uri = Uri.parse("https://briarproject.org/download-briar"); Uri uri = Uri.parse("https://briarproject.org/download.html");
startActivity(new Intent(ACTION_VIEW, uri)); startActivity(new Intent(ACTION_VIEW, uri));
finish(); finish();
} }

View File

@@ -18,8 +18,7 @@ import static androidx.core.content.ContextCompat.getColor;
public class BriarSnackbarBuilder { public class BriarSnackbarBuilder {
@ColorRes @ColorRes
@Nullable private int backgroundResId = R.color.briar_primary;
private Integer backgroundResId = null;
@StringRes @StringRes
private int actionResId; private int actionResId;
@Nullable @Nullable
@@ -27,11 +26,7 @@ public class BriarSnackbarBuilder {
public Snackbar make(View view, CharSequence text, int duration) { public Snackbar make(View view, CharSequence text, int duration) {
Snackbar s = Snackbar.make(view, text, duration); Snackbar s = Snackbar.make(view, text, duration);
if (backgroundResId != null) { s.getView().setBackgroundResource(backgroundResId);
s.setBackgroundTint(getColor(view.getContext(), backgroundResId));
s.setTextColor(
getColor(view.getContext(), R.color.md_theme_onSecondary));
}
if (onClickListener != null) { if (onClickListener != null) {
s.setActionTextColor(getColor(view.getContext(), s.setActionTextColor(getColor(view.getContext(),
R.color.briar_button_text_positive)); R.color.briar_button_text_positive));

View File

@@ -6,8 +6,6 @@ import android.content.Intent;
import android.location.LocationManager; import android.location.LocationManager;
import android.net.Uri; import android.net.Uri;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.nullsafety.MethodsNotNullByDefault; import org.briarproject.nullsafety.MethodsNotNullByDefault;
import org.briarproject.nullsafety.ParametersNotNullByDefault; import org.briarproject.nullsafety.ParametersNotNullByDefault;
@@ -18,6 +16,7 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import static android.Manifest.permission.BLUETOOTH_ADVERTISE; import static android.Manifest.permission.BLUETOOTH_ADVERTISE;
@@ -109,8 +108,8 @@ public class PermissionUtils {
} }
public static void showLocationDialog(Context ctx, boolean forBluetooth) { public static void showLocationDialog(Context ctx, boolean forBluetooth) {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(ctx, R.style.BriarDialogTheme); new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
builder.setTitle(R.string.permission_location_setting_title); builder.setTitle(R.string.permission_location_setting_title);
if (forBluetooth) { if (forBluetooth) {
builder.setMessage(R.string.permission_location_setting_body); builder.setMessage(R.string.permission_location_setting_body);
@@ -137,8 +136,8 @@ public class PermissionUtils {
public static void showDenialDialog(FragmentActivity ctx, public static void showDenialDialog(FragmentActivity ctx,
@StringRes int title, @StringRes int body, Runnable onDenied) { @StringRes int title, @StringRes int body, Runnable onDenied) {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(ctx, R.style.BriarDialogTheme); new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
builder.setTitle(title); builder.setTitle(title);
builder.setMessage(body); builder.setMessage(body);
builder.setPositiveButton(R.string.ok, getGoToSettingsListener(ctx)); builder.setPositiveButton(R.string.ok, getGoToSettingsListener(ctx));
@@ -149,8 +148,8 @@ public class PermissionUtils {
public static void showRationale(FragmentActivity ctx, @StringRes int title, public static void showRationale(FragmentActivity ctx, @StringRes int title,
@StringRes int body, @Nullable Runnable onOk) { @StringRes int body, @Nullable Runnable onOk) {
MaterialAlertDialogBuilder builder = AlertDialog.Builder builder =
new MaterialAlertDialogBuilder(ctx, R.style.BriarDialogTheme); new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
builder.setTitle(title); builder.setTitle(title);
builder.setMessage(body); builder.setMessage(body);
builder.setNeutralButton(R.string.continue_button, (dialog, which) -> { builder.setNeutralButton(R.string.continue_button, (dialog, which) -> {

View File

@@ -28,7 +28,6 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
@@ -53,6 +52,7 @@ import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.hardware.fingerprint.FingerprintManagerCompat; import androidx.core.hardware.fingerprint.FingerprintManagerCompat;
import androidx.core.text.HtmlCompat; import androidx.core.text.HtmlCompat;
@@ -92,6 +92,7 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
import static android.view.inputmethod.EditorInfo.IME_NULL; import static android.view.inputmethod.EditorInfo.IME_NULL;
import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT;
import static android.widget.Toast.LENGTH_LONG; import static android.widget.Toast.LENGTH_LONG;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_TIME;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO;
import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES;
@@ -322,7 +323,7 @@ public class UiUtils {
} }
public static void showOnboardingDialog(Context ctx, String text) { public static void showOnboardingDialog(Context ctx, String text) {
new MaterialAlertDialogBuilder(ctx, R.style.OnboardingDialogTheme) new AlertDialog.Builder(ctx, R.style.OnboardingDialogTheme)
.setMessage(text) .setMessage(text)
.setNeutralButton(R.string.got_it, .setNeutralButton(R.string.got_it,
(dialog, which) -> dialog.cancel()) (dialog, which) -> dialog.cancel())
@@ -348,7 +349,12 @@ public class UiUtils {
} else if (theme } else if (theme
.equals(ctx.getString(R.string.pref_theme_dark_value))) { .equals(ctx.getString(R.string.pref_theme_dark_value))) {
setDefaultNightMode(MODE_NIGHT_YES); setDefaultNightMode(MODE_NIGHT_YES);
} else { } else if (theme
.equals(ctx.getString(R.string.pref_theme_auto_value))) {
// TODO remove AUTO-setting as it is deprecated
setDefaultNightMode(MODE_NIGHT_AUTO_TIME);
} else if (theme
.equals(ctx.getString(R.string.pref_theme_system_value))) {
setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM); setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM);
} }
} }
@@ -398,8 +404,8 @@ public class UiUtils {
public static void startDevReportActivity(Context ctx, public static void startDevReportActivity(Context ctx,
Class<? extends FragmentActivity> activity, @Nullable Throwable t, Class<? extends FragmentActivity> activity, @Nullable Throwable t,
@Nullable Long appStartTime, @Nullable byte[] logKey, @Nullable Long appStartTime, @Nullable byte[] logKey, @Nullable
@Nullable String initialComment) { String initialComment) {
// Collect memory stats from the current process, not the crash // Collect memory stats from the current process, not the crash
// reporter process // reporter process
ActivityManager am = ActivityManager am =

View File

@@ -8,13 +8,12 @@ import android.widget.Button;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import com.google.android.material.button.MaterialButton;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.nullsafety.NotNullByDefault; import org.briarproject.nullsafety.NotNullByDefault;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.view.ContextThemeWrapper;
import androidx.appcompat.widget.AppCompatButton;
import static android.content.Context.LAYOUT_INFLATER_SERVICE; import static android.content.Context.LAYOUT_INFLATER_SERVICE;
import static androidx.transition.TransitionManager.beginDelayedTransition; import static androidx.transition.TransitionManager.beginDelayedTransition;
@@ -48,7 +47,8 @@ public class BriarButton extends FrameLayout {
attributes.recycle(); attributes.recycle();
ContextThemeWrapper wrapper = new ContextThemeWrapper(context, style); ContextThemeWrapper wrapper = new ContextThemeWrapper(context, style);
button = new MaterialButton(wrapper, null, style); button = isInEditMode() ? new AppCompatButton(context) :
new AppCompatButton(wrapper, null, style);
button.setText(text); button.setText(text);
addView(button); addView(button);
progressBar = findViewById(R.id.briar_button_progress_bar); progressBar = findViewById(R.id.briar_button_progress_bar);

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.view; package org.briarproject.briar.android.view;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
@@ -39,7 +38,6 @@ public class SnackbarAwareBehavior<V extends View> extends Behavior<V> {
setMargin(child, 0); setMargin(child, 0);
} }
@SuppressLint("RestrictedApi")
@Override @Override
public boolean layoutDependsOn(CoordinatorLayout parent, public boolean layoutDependsOn(CoordinatorLayout parent,
V child, View dependency) { V child, View dependency) {

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:color="@color/briar_button_text_disabled"
android:state_enabled="false"/>
<item
android:color="#ffffffff"/>
</selector>

View File

@@ -0,0 +1,7 @@
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">
<item
android:id="@android:id/mask"
android:drawable="@drawable/button_outline_mask" />
<item android:drawable="@drawable/button_outline_background" />
</ripple>

View File

@@ -0,0 +1,19 @@
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="4dp"
android:insetTop="6dp"
android:insetRight="4dp"
android:insetBottom="6dp">
<shape
android:shape="rectangle">
<corners android:radius="2dp" />
<solid android:color="@android:color/transparent" />
<stroke
android:width="1dp"
android:color="@color/briar_button_outline" />
<padding
android:bottom="4dp"
android:left="8dp"
android:right="8dp"
android:top="4dp" />
</shape>
</inset>

View File

@@ -0,0 +1,19 @@
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="4dp"
android:insetTop="6dp"
android:insetRight="4dp"
android:insetBottom="6dp">
<shape
android:shape="rectangle">
<corners android:radius="2dp" />
<solid android:color="@android:color/white" />
<stroke
android:width="1dp"
android:color="@android:color/white" />
<padding
android:bottom="4dp"
android:left="8dp"
android:right="8dp"
android:top="4dp" />
</shape>
</inset>

View File

@@ -7,7 +7,7 @@
android:radius="32dp"/> android:radius="32dp"/>
<solid <solid
android:color="?colorTertiary"/> android:color="@color/briar_accent"/>
</shape> </shape>

View File

@@ -7,7 +7,7 @@
android:radius="32dp"/> android:radius="32dp"/>
<solid <solid
android:color="?colorTertiaryContainer"/> android:color="@color/briar_lime_600"/>
</shape> </shape>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="32dp"/>
<solid
android:color="?colorSurfaceDim"/>
</shape>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="6dp"
android:left="4dp"
android:right="4dp"
android:top="6dp">
<shape android:shape="rectangle">
<corners android:radius="2dp" />
<solid android:color="@android:color/transparent" />
<stroke
android:width="1dp"
android:color="@color/briar_button_outline" />
</shape>
</item>
</layer-list>

View File

@@ -4,7 +4,6 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".android.login.ChangePasswordActivity"> tools:context=".android.login.ChangePasswordActivity">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@@ -65,27 +64,15 @@
android:maxLines="1" /> android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<org.briarproject.briar.android.login.StrengthMeter
android:id="@+id/strength_meter"
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="8dp"
android:visibility="invisible"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/new_password_entry_wrapper"
tools:visibility="visible" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/new_password_confirm_wrapper" android:id="@+id/new_password_confirm_wrapper"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:errorEnabled="true" app:errorEnabled="true"
app:hintEnabled="false" app:hintEnabled="false"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/strength_meter" app:layout_constraintTop_toBottomOf="@id/new_password_entry_wrapper"
app:passwordToggleEnabled="true"> app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
@@ -99,6 +86,15 @@
android:maxLines="1" /> android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<org.briarproject.briar.android.login.StrengthMeter
android:id="@+id/strength_meter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/new_password_confirm_wrapper" />
<Button <Button
android:id="@+id/change_password" android:id="@+id/change_password"
style="@style/BriarButton" style="@style/BriarButton"
@@ -107,20 +103,16 @@
android:layout_marginTop="@dimen/margin_medium" android:layout_marginTop="@dimen/margin_medium"
android:enabled="false" android:enabled="false"
android:text="@string/change_password" android:text="@string/change_password"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/new_password_confirm_wrapper" app:layout_constraintTop_toBottomOf="@id/strength_meter"
app:layout_constraintVertical_bias="1.0"
tools:enabled="true" /> tools:enabled="true" />
<com.google.android.material.progressindicator.CircularProgressIndicator <ProgressBar
android:id="@+id/progress_wheel" android:id="@+id/progress_wheel"
style="@style/CircularProgress"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:visibility="invisible" android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/change_password"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/change_password" /> app:layout_constraintTop_toTopOf="@id/change_password" />

View File

@@ -12,7 +12,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
style="@style/BriarToolbar" style="@style/BriarToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -40,7 +40,7 @@
</LinearLayout> </LinearLayout>
</com.google.android.material.appbar.MaterialToolbar> </androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@@ -35,9 +35,8 @@
android:text="@string/create_forum_button" android:text="@string/create_forum_button"
tools:enabled="true" /> tools:enabled="true" />
<com.google.android.material.progressindicator.CircularProgressIndicator <ProgressBar
android:id="@+id/createForumProgressBar" android:id="@+id/createForumProgressBar"
style="@style/CircularProgress"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"

View File

@@ -18,7 +18,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/msg_status_bubble_background"> android:background="@color/msg_status_bubble_background">
<com.google.android.material.appbar.MaterialToolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
style="@style/BriarToolbar" style="@style/BriarToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -50,7 +50,7 @@
</LinearLayout> </LinearLayout>
</com.google.android.material.appbar.MaterialToolbar> </androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

Some files were not shown because too many files have changed in this diff Show More