Compare commits

..

3 Commits

Author SHA1 Message Date
akwizgran
eb98cb2f23 Pause between connection attempts. 2018-05-31 09:59:06 +01:00
akwizgran
aa331981cc Don't poll again if last poll is still running. 2018-05-31 09:59:05 +01:00
akwizgran
e9a6faad2d Poll contacts in series rather than parallel. 2018-05-31 09:59:01 +01:00
290 changed files with 2186 additions and 4416 deletions

View File

@@ -21,7 +21,11 @@ test:
test_reproducible: test_reproducible:
image: briar/reproducer:latest
script: script:
- "curl -X POST -F token=${RELEASE_CHECK_TOKEN} -F ref=master -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/61/trigger/pipeline" - cd /opt/briar-reproducer
- ./reproduce.py ${CI_COMMIT_REF_NAME}
only: only:
- tags - tags

View File

@@ -8,11 +8,9 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 26 targetSdkVersion 26
versionCode 10011 versionCode 10005
versionName "1.0.11" versionName "1.0.5"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
compileOptions { compileOptions {
@@ -33,42 +31,36 @@ dependencies {
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2' annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
compileOnly 'javax.annotation:jsr250-api:1.0' compileOnly 'javax.annotation:jsr250-api:1.0'
androidTestImplementation project(path: ':bramble-api', configuration: 'testOutput')
androidTestImplementation project(path: ':bramble-core', configuration: 'testOutput')
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
androidTestCompileOnly 'javax.annotation:jsr250-api:1.0'
} }
dependencyVerification { dependencyVerification {
verify = [ verify = [
'com.android.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3', 'com.android.tools.analytics-library:protos:26.1.2:protos-26.1.2.jar:52672a0b42b572a06aecc3535d5068eb46c0e15d129b9f1085d3c16a1da5cdbb',
'com.android.tools.analytics-library:shared:26.1.3:shared-26.1.3.jar:7110706c7ada96c8b6f5ca80c478291bc7899d46277de2c48527e045442401a3', 'com.android.tools.analytics-library:shared:26.1.2:shared-26.1.2.jar:5c7e0eda18c6f87feeb83628c707e8aaa3298b41fb72e38efe31ad1675f9e8e9',
'com.android.tools.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418', 'com.android.tools.analytics-library:tracker:26.1.2:tracker-26.1.2.jar:06f97aa0adf44ffb06f8681c6a79d9be153a08f61d21eddc42b8d3db96df4282',
'com.android.tools.build:apksig:3.1.3:apksig-3.1.3.jar:7e1f8e675a6e768e5b56405e41d6c3cc05befe62e601b04177de1029902c9c89', 'com.android.tools.build:apksig:3.1.2:apksig-3.1.2.jar:40696a4559124d1d57873d208857eee059d48859239d569c7d18374ac644a8be',
'com.android.tools.build:builder-model:3.1.3:builder-model-3.1.3.jar:06ad1c422d679fc698451479cb40ba863849d67bfd1de23f6d2c16d78b024b0b', 'com.android.tools.build:builder-model:3.1.2:builder-model-3.1.2.jar:d49bfa2a135c9562b6ca7aa4342036cfa1582c7074c2d1d93d1dae8b3a134e17',
'com.android.tools.build:builder-test-api:3.1.3:builder-test-api-3.1.3.jar:4d989f780436794f0f8b2f50e9e079b786571eac90f26c208ab2ae6d4012f389', 'com.android.tools.build:builder-test-api:3.1.2:builder-test-api-3.1.2.jar:dfe2a50b740d41b11189101062434d4283d18647e89a492ad51710c719363e9f',
'com.android.tools.build:builder:3.1.3:builder-3.1.3.jar:8a1092012c89d0ec1ee2eff09c5708c71ef4482a6862df8d3a44a67fccace01c', 'com.android.tools.build:builder:3.1.2:builder-3.1.2.jar:b60f825a42e2efe8433619fbc759f3d9effecab718279048d36881188ceb1d14',
'com.android.tools.build:gradle-api:3.1.3:gradle-api-3.1.3.jar:01e4df521456aef66514336f1d492346730dd1fb8f6433a89f62da834941ed72', 'com.android.tools.build:gradle-api:3.1.2:gradle-api-3.1.2.jar:e58bcc5b893e4583ab0f5c8ef89c4dbcce202b405a9d7fcc116d21e5357d4893',
'com.android.tools.build:manifest-merger:26.1.3:manifest-merger-26.1.3.jar:1e4fc7e932adb4607082409800e5e6fccb42e6c5360ae5990094bf522f3ada55', 'com.android.tools.build:manifest-merger:26.1.2:manifest-merger-26.1.2.jar:9c61c27ea5266573107b954acf1216d398f4d7e7ae6fad6409d6b2b767eb091c',
'com.android.tools.ddms:ddmlib:26.1.3:ddmlib-26.1.3.jar:c54931cd68df5d1ea2923b3b320eae47cd2307a5a916bb8674c0acf93cd1d3cd', 'com.android.tools.ddms:ddmlib:26.1.2:ddmlib-26.1.2.jar:18a2a5fbef36882f07d03c2b9e59eba05cf8248177bf5cbff736e4b582804c44',
'com.android.tools.external.com-intellij:intellij-core:26.1.3:intellij-core-26.1.3.jar:af67f5535fef2e1a28b1007a4acb8c5deb6a1e33b8afe7b11d012c9e778ebcec', 'com.android.tools.external.com-intellij:intellij-core:26.1.2:intellij-core-26.1.2.jar:37c5acf279f1ae3e85b1a5be3c9f15f43bde7b08f978eefefffb9c4035760c52',
'com.android.tools.external.com-intellij:kotlin-compiler:26.1.3:kotlin-compiler-26.1.3.jar:c746d2859dc11cc05c84b692b3498d3a621e0929511f8440ee009c6557838fd4', 'com.android.tools.external.com-intellij:kotlin-compiler:26.1.2:kotlin-compiler-26.1.2.jar:152df0bee7580326c77316b669a9d96e3b09efb1d45f545dce4147271b0b8944',
'com.android.tools.external.org-jetbrains:uast:26.1.3:uast-26.1.3.jar:3f3f6651d0c7685a77ecb22e9c82d6b49fdf24322c17360768dc530678f43265', 'com.android.tools.external.org-jetbrains:uast:26.1.2:uast-26.1.2.jar:02d39582206d3f5fc0a6cb18bfd9e8b9f9c1acb805ec6dac08b4e3a56849d279',
'com.android.tools.layoutlib:layoutlib-api:26.1.3:layoutlib-api-26.1.3.jar:10bc73ce706c45629872d6a999dbe12116df64e24f47ff93b7b13121ff57b4b0', 'com.android.tools.layoutlib:layoutlib-api:26.1.2:layoutlib-api-26.1.2.jar:20220039fcc7d799f928153beff862e704457c0f55ab44258f3745ebeb662b4f',
'com.android.tools.lint:lint-api:26.1.3:lint-api-26.1.3.jar:6f97323f9af8deda86278717885b5c927f3766757db89709f52d11d42b6fb751', 'com.android.tools.lint:lint-api:26.1.2:lint-api-26.1.2.jar:e1d5b62b870a7c566e9877a6b96b27784a4d713f8caa07fdcb4705d47a40a1d9',
'com.android.tools.lint:lint-checks:26.1.3:lint-checks-26.1.3.jar:73c3d53784c9ce3e6d5968506581918e0179645d20809927ca4a001dd766b001', 'com.android.tools.lint:lint-checks:26.1.2:lint-checks-26.1.2.jar:211e2afd58504372385d71b1e5be982c2b5121ab6fee1c04ddabeb75a8729e07',
'com.android.tools.lint:lint-gradle-api:26.1.3:lint-gradle-api-26.1.3.jar:7ca3c4866ec21dc21d53a9d86f752b77ace6f6c610a0c9dc877313856c733d9d', 'com.android.tools.lint:lint-gradle-api:26.1.2:lint-gradle-api-26.1.2.jar:71284f2a8b03c3e55c94511c9eb36f8184fbb85324325fc6b78abf5183f03d90',
'com.android.tools.lint:lint-gradle:26.1.3:lint-gradle-26.1.3.jar:db0c354b8f4b6f6637e31f91c564785a59ff896325331fcbc3de7458e0b6c067', 'com.android.tools.lint:lint-gradle:26.1.2:lint-gradle-26.1.2.jar:855f0c82b7fc690df1b7319c0774f7517f7f8f5dd4eee1f6077dcf50e07c6240',
'com.android.tools.lint:lint-kotlin:26.1.3:lint-kotlin-26.1.3.jar:94e2b0f4565a241561cfb8fc1222bb3f132a3b98d2a90421dbb72ee8358e7d68', 'com.android.tools.lint:lint-kotlin:26.1.2:lint-kotlin-26.1.2.jar:1e591f70bcbbc11569720a9bbcca2bc1f3d4f789f01f40f642848d920643d484',
'com.android.tools.lint:lint:26.1.3:lint-26.1.3.jar:8d5f32c989c6d191d712e90ad3ca2d1c409313599551d04d834caa44d26c78df', 'com.android.tools.lint:lint:26.1.2:lint-26.1.2.jar:93736c62e9f1976998c2b4aa716aea0734cdb162d05502f4af7292654aedb182',
'com.android.tools:annotations:26.1.3:annotations-26.1.3.jar:c950430b24ac5d58fc97e7283b8f0115f99587e76e08b4e1e2aaa780f2d77323', 'com.android.tools:annotations:26.1.2:annotations-26.1.2.jar:72773dcaf5c4ccca828e3c8467f1b78a8a00b3cc5f8ad1aab88fcf9379928018',
'com.android.tools:common:26.1.3:common-26.1.3.jar:7c31a90581a148ab219f615a59667f0dded7fa39b248529784474da3c2274ef2', 'com.android.tools:common:26.1.2:common-26.1.2.jar:ea4320f0c17dcbc4491896bb705c4d25ec08bd62ef02ab0579fe154e75e788e6',
'com.android.tools:dvlib:26.1.3:dvlib-26.1.3.jar:0cae87906f53d3f1088366a916ed180a7312b6d9919b90797f238875c8492855', 'com.android.tools:dvlib:26.1.2:dvlib-26.1.2.jar:1187aa4fb666595c96c4deb6bc0e0f4b7e396bde9f6243330b49a232946130ea',
'com.android.tools:repository:26.1.3:repository-26.1.3.jar:52d4539cc68db91b261e2a33b2c8206b26e05539078758dc28cfb3854adb4f59', 'com.android.tools:repository:26.1.2:repository-26.1.2.jar:8b86e512ad6d32bd76989451eefe2b271f5efce6d4d65ecb173afaf14606e01a',
'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1', 'com.android.tools:sdk-common:26.1.2:sdk-common-26.1.2.jar:23584720a60a21cdcb5b1ec10269e3013789d6805d153cc696c39ec7ce251896',
'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b', 'com.android.tools:sdklib:26.1.2:sdklib-26.1.2.jar:d3870fafc59ab8efa70d3f9649f40ee299c8ec5b58377b06e8853d7272a5bf4e',
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed', 'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
'com.google.code.gson:gson:2.7:gson-2.7.jar:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32', 'com.google.code.gson:gson:2.7:gson-2.7.jar:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32',
'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3', 'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',

View File

@@ -1,23 +0,0 @@
package org.briarproject.bramble;
import org.briarproject.bramble.event.EventModule;
import org.briarproject.bramble.plugin.PluginModule;
import org.briarproject.bramble.plugin.tor.BridgeTest;
import org.briarproject.bramble.system.SystemModule;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {
BrambleAndroidModule.class,
PluginModule.class, // needed for BackoffFactory
EventModule.class,
SystemModule.class,
})
public interface IntegrationTestComponent {
void inject(BridgeTest init);
}

View File

@@ -1,126 +0,0 @@
package org.briarproject.bramble.plugin.tor;
import android.content.Context;
import android.support.test.runner.AndroidJUnit4;
import org.briarproject.bramble.DaggerIntegrationTestComponent;
import org.briarproject.bramble.IntegrationTestComponent;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.plugin.BackoffFactory;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.test.BrambleTestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.net.SocketFactory;
import static android.support.test.InstrumentationRegistry.getTargetContext;
import static java.util.Collections.singletonList;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class)
public class BridgeTest extends BrambleTestCase {
private final static long TIMEOUT = SECONDS.toMillis(23);
private final static Logger LOG =
Logger.getLogger(BridgeTest.class.getSimpleName());
@Inject
EventBus eventBus;
@Inject
BackoffFactory backoffFactory;
@Inject
Clock clock;
private final Context appContext = getTargetContext();
private final CircumventionProvider circumventionProvider;
private final List<String> bridges;
private TorPluginFactory factory;
private volatile int currentBridge = 0;
public BridgeTest() {
super();
circumventionProvider = new CircumventionProvider() {
@Override
public boolean isTorProbablyBlocked(String countryCode) {
return true;
}
@Override
public boolean doBridgesWork(String countryCode) {
return true;
}
@Override
public List<String> getBridges() {
return singletonList(bridges.get(currentBridge));
}
};
bridges = new CircumventionProviderImpl(appContext).getBridges();
}
@Before
public void setUp() {
IntegrationTestComponent component =
DaggerIntegrationTestComponent.builder().build();
component.inject(this);
Executor ioExecutor = Executors.newCachedThreadPool();
ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
LocationUtils locationUtils = () -> "US";
SocketFactory torSocketFactory = SocketFactory.getDefault();
factory = new TorPluginFactory(ioExecutor, scheduler, appContext,
locationUtils, eventBus, torSocketFactory,
backoffFactory, circumventionProvider, clock);
}
@Test
public void testBridges() throws Exception {
assertTrue(bridges.size() > 0);
for (int i = 0; i < bridges.size(); i++) {
testBridge(i);
}
}
private void testBridge(int bridge) throws Exception {
DuplexPlugin duplexPlugin =
factory.createPlugin(new TorPluginCallBack());
assertNotNull(duplexPlugin);
TorPlugin plugin = (TorPlugin) duplexPlugin;
currentBridge = bridge;
LOG.warning("Testing " + bridges.get(currentBridge));
try {
plugin.start();
long start = clock.currentTimeMillis();
while (clock.currentTimeMillis() - start < TIMEOUT) {
if (plugin.isRunning()) return;
clock.sleep(500);
}
if (!plugin.isRunning()) {
fail("Could not connect to Tor within timeout.");
}
} finally {
plugin.stop();
}
}
}

View File

@@ -1,54 +0,0 @@
package org.briarproject.bramble.plugin.tor;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.settings.Settings;
@NotNullByDefault
public class TorPluginCallBack implements DuplexPluginCallback {
@Override
public void incomingConnectionCreated(DuplexTransportConnection d) {
}
@Override
public void outgoingConnectionCreated(ContactId c,
DuplexTransportConnection d) {
}
@Override
public Settings getSettings() {
return new Settings();
}
@Override
public TransportProperties getLocalProperties() {
return new TransportProperties();
}
@Override
public void mergeSettings(Settings s) {
}
@Override
public void mergeLocalProperties(TransportProperties p) {
}
@Override
public void transportEnabled() {
}
@Override
public void transportDisabled() {
}
}

View File

@@ -1,25 +1,11 @@
package org.briarproject.bramble; package org.briarproject.bramble;
import android.app.Application;
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
import org.briarproject.bramble.plugin.tor.CircumventionProviderImpl;
import org.briarproject.bramble.system.AndroidSystemModule; import org.briarproject.bramble.system.AndroidSystemModule;
import javax.inject.Singleton;
import dagger.Module; import dagger.Module;
import dagger.Provides;
@Module(includes = { @Module(includes = {
AndroidSystemModule.class AndroidSystemModule.class
}) })
public class BrambleAndroidModule { public class BrambleAndroidModule {
@Provides
@Singleton
CircumventionProvider provideCircumventionProvider(Application app) {
return new CircumventionProviderImpl(app.getApplicationContext());
}
} }

View File

@@ -1,8 +0,0 @@
package org.briarproject.bramble;
public interface PowerTestingConstants {
int WAKE_LOCK_DURATION = 5000;
int ALARM_DELAY = 5000;
boolean USE_TOR_WAKE_LOCK = true;
}

View File

@@ -38,7 +38,6 @@ import static android.bluetooth.BluetoothAdapter.SCAN_MODE_NONE;
import static android.bluetooth.BluetoothAdapter.STATE_OFF; import static android.bluetooth.BluetoothAdapter.STATE_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.bluetooth.BluetoothAdapter.STATE_ON;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -146,7 +145,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
try { try {
if (ss != null) ss.close(); if (ss != null) ss.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -186,7 +185,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
try { try {
if (c != null) c.close(); if (c != null) c.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -1,30 +0,0 @@
package org.briarproject.bramble.plugin.tor;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import java.util.List;
public interface CircumventionProvider {
/**
* Countries where Tor is blocked, i.e. vanilla Tor connection won't work.
*
* See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
* and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki
*/
String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"};
/**
* Countries where vanilla bridge connection are likely to work.
* Should be a subset of {@link #BLOCKED}.
*/
String[] BRIDGES = { "EG", "BY", "TR", "SY", "VE" };
boolean isTorProbablyBlocked(String countryCode);
boolean doBridgesWork(String countryCode);
@IoExecutor
List<String> getBridges();
}

View File

@@ -1,68 +0,0 @@
package org.briarproject.bramble.plugin.tor;
import android.content.Context;
import android.content.res.Resources;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject;
public class CircumventionProviderImpl implements CircumventionProvider {
private final static String BRIDGE_FILE_NAME = "bridges";
private final Context ctx;
@Nullable
private volatile List<String> bridges = null;
@Inject
public CircumventionProviderImpl(Context ctx) {
this.ctx = ctx;
}
private static final Set<String> BLOCKED_IN_COUNTRIES =
new HashSet<>(Arrays.asList(BLOCKED));
private static final Set<String> BRIDGES_WORK_IN_COUNTRIES =
new HashSet<>(Arrays.asList(BRIDGES));
@Override
public boolean isTorProbablyBlocked(String countryCode) {
return BLOCKED_IN_COUNTRIES.contains(countryCode);
}
@Override
public boolean doBridgesWork(String countryCode) {
return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode);
}
@Override
@IoExecutor
public List<String> getBridges() {
if (this.bridges != null) return this.bridges;
Resources res = ctx.getResources();
int resId = res.getIdentifier(BRIDGE_FILE_NAME, "raw",
ctx.getPackageName());
InputStream is = ctx.getResources().openRawResource(resId);
Scanner scanner = new Scanner(is);
List<String> bridges = new ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (!line.startsWith("#")) bridges.add(line);
}
scanner.close();
this.bridges = bridges;
return bridges;
}
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.bramble.plugin.tor;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
class TorNetworkMetadata {
// See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
// and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki
// TODO: get a more complete list
private static final Set<String> BLOCKED_IN_COUNTRIES =
new HashSet<>(Arrays.asList("CN", "IR", "SY", "ZZ"));
static boolean isTorProbablyBlocked(String countryCode) {
return BLOCKED_IN_COUNTRIES.contains(countryCode);
}
}

View File

@@ -10,6 +10,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.os.FileObserver;
import android.os.PowerManager; import android.os.PowerManager;
import net.freehaven.tor.control.EventHandler; import net.freehaven.tor.control.EventHandler;
@@ -33,10 +34,8 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.IoUtils; import org.briarproject.bramble.util.IoUtils;
import org.briarproject.bramble.util.RenewableWakeLock;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import java.io.Closeable; import java.io.Closeable;
@@ -50,14 +49,13 @@ import java.io.OutputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@@ -80,12 +78,12 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED; import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.MINUTES;
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 net.freehaven.tor.control.TorControlCommands.HS_ADDRESS; import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY; import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
import static org.briarproject.bramble.PowerTestingConstants.USE_TOR_WAKE_LOCK;
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.ID; import static org.briarproject.bramble.api.plugin.TorConstants.ID;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
@@ -94,7 +92,6 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI;
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; import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion; import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -105,11 +102,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR" "CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
}; };
private static final String OWNER = "__OwningControllerProcess"; private static final String OWNER = "__OwningControllerProcess";
private static final int COOKIE_TIMEOUT_MS = 3000; private static final int COOKIE_TIMEOUT = 3000; // Milliseconds
private static final int COOKIE_POLLING_INTERVAL_MS = 200;
private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}"); private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}");
// This tag may prevent Huawei's power manager from killing us
private static final String WAKE_LOCK_TAG = "LocationManagerService";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(TorPlugin.class.getName()); Logger.getLogger(TorPlugin.class.getName());
@@ -118,16 +112,14 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final Context appContext; private final Context appContext;
private final LocationUtils locationUtils; private final LocationUtils locationUtils;
private final SocketFactory torSocketFactory; private final SocketFactory torSocketFactory;
private final Clock clock;
private final Backoff backoff; private final Backoff backoff;
private final DuplexPluginCallback callback; private final DuplexPluginCallback callback;
private final String architecture; private final String architecture;
private final CircumventionProvider circumventionProvider;
private final int maxLatency, maxIdleTime, socketTimeout; private final int maxLatency, maxIdleTime, socketTimeout;
private final ConnectionStatus connectionStatus; private final ConnectionStatus connectionStatus;
private final File torDirectory, torFile, geoIpFile, configFile; private final File torDirectory, torFile, geoIpFile, configFile;
private final File doneFile, cookieFile; private final File doneFile, cookieFile;
private final RenewableWakeLock wakeLock; private final PowerManager.WakeLock wakeLock;
private final AtomicReference<Future<?>> connectivityCheck = private final AtomicReference<Future<?>> connectivityCheck =
new AtomicReference<>(); new AtomicReference<>();
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
@@ -140,19 +132,17 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
TorPlugin(Executor ioExecutor, ScheduledExecutorService scheduler, TorPlugin(Executor ioExecutor, ScheduledExecutorService scheduler,
Context appContext, LocationUtils locationUtils, Context appContext, LocationUtils locationUtils,
SocketFactory torSocketFactory, Clock clock, Backoff backoff, SocketFactory torSocketFactory, Backoff backoff,
DuplexPluginCallback callback, String architecture, DuplexPluginCallback callback, String architecture,
CircumventionProvider circumventionProvider, int maxLatency, int maxIdleTime) { int maxLatency, int maxIdleTime) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.scheduler = scheduler; this.scheduler = scheduler;
this.appContext = appContext; this.appContext = appContext;
this.locationUtils = locationUtils; this.locationUtils = locationUtils;
this.torSocketFactory = torSocketFactory; this.torSocketFactory = torSocketFactory;
this.clock = clock;
this.backoff = backoff; this.backoff = backoff;
this.callback = callback; this.callback = callback;
this.architecture = architecture; this.architecture = architecture;
this.circumventionProvider = circumventionProvider;
this.maxLatency = maxLatency; this.maxLatency = maxLatency;
this.maxIdleTime = maxIdleTime; this.maxIdleTime = maxIdleTime;
if (maxIdleTime > Integer.MAX_VALUE / 2) if (maxIdleTime > Integer.MAX_VALUE / 2)
@@ -165,13 +155,14 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
configFile = new File(torDirectory, "torrc"); configFile = new File(torDirectory, "torrc");
doneFile = new File(torDirectory, "done"); doneFile = new File(torDirectory, "done");
cookieFile = new File(torDirectory, ".tor/control_auth_cookie"); cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
Object o = appContext.getSystemService(POWER_SERVICE);
PowerManager pm = (PowerManager) o;
// This tag will prevent Huawei's powermanager from killing us.
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService");
wakeLock.setReferenceCounted(false);
// Don't execute more than one connection status check at a time // Don't execute more than one connection status check at a time
connectionStatusExecutor = new PoliteExecutor("TorPlugin", connectionStatusExecutor = new PoliteExecutor("TorPlugin",
ioExecutor, 1); ioExecutor, 1);
PowerManager pm = (PowerManager)
appContext.getSystemService(POWER_SERVICE);
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
WAKE_LOCK_TAG, 1, MINUTES);
} }
@Override @Override
@@ -194,10 +185,18 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (used.getAndSet(true)) throw new IllegalStateException(); if (used.getAndSet(true)) throw new IllegalStateException();
// Install or update the assets if necessary // Install or update the assets if necessary
if (!assetsAreUpToDate()) installAssets(); if (!assetsAreUpToDate()) installAssets();
if (cookieFile.exists() && !cookieFile.delete())
LOG.warning("Old auth cookie not deleted");
// Start a new Tor process
LOG.info("Starting Tor"); LOG.info("Starting Tor");
// Watch for the auth cookie file being updated
try {
cookieFile.getParentFile().mkdirs();
cookieFile.createNewFile();
} catch (IOException e) {
throw new PluginException(e);
}
CountDownLatch latch = new CountDownLatch(1);
FileObserver obs = new WriteObserver(cookieFile, latch);
obs.startWatching();
// Start a new Tor process
String torPath = torFile.getAbsolutePath(); String torPath = torFile.getAbsolutePath();
String configPath = configFile.getAbsolutePath(); String configPath = configFile.getAbsolutePath();
String pid = String.valueOf(android.os.Process.myPid()); String pid = String.valueOf(android.os.Process.myPid());
@@ -236,16 +235,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
throw new PluginException(); throw new PluginException();
} }
// Wait for the auth cookie file to be created/updated // Wait for the auth cookie file to be created/updated
long start = clock.currentTimeMillis(); if (!latch.await(COOKIE_TIMEOUT, MILLISECONDS)) {
while (cookieFile.length() < 32) { LOG.warning("Auth cookie not created");
if (clock.currentTimeMillis() - start > COOKIE_TIMEOUT_MS) { if (LOG.isLoggable(INFO)) listFiles(torDirectory);
LOG.warning("Auth cookie not created"); throw new PluginException();
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
throw new PluginException();
}
Thread.sleep(COOKIE_POLLING_INTERVAL_MS);
} }
LOG.info("Auth cookie created");
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.warning("Interrupted while starting Tor"); LOG.warning("Interrupted while starting Tor");
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
@@ -353,7 +347,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try { try {
if (c != null) c.close(); if (c != null) c.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -361,7 +355,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try { try {
if (s != null) s.close(); if (s != null) s.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -370,7 +364,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
File[] children = f.listFiles(); File[] children = f.listFiles();
if (children != null) for (File child : children) listFiles(child); if (children != null) for (File child : children) listFiles(child);
} else { } else {
LOG.info(f.getAbsolutePath() + " " + f.length()); LOG.info(f.getAbsolutePath());
} }
} }
@@ -403,7 +397,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
ss = new ServerSocket(); ss = new ServerSocket();
ss.bind(new InetSocketAddress("127.0.0.1", port)); ss.bind(new InetSocketAddress("127.0.0.1", port));
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(ss); tryToClose(ss);
return; return;
} }
@@ -429,7 +423,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try { try {
if (ss != null) ss.close(); if (ss != null) ss.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} finally { } finally {
callback.transportDisabled(); callback.transportDisabled();
} }
@@ -448,7 +442,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
response = controlConnection.addOnion(portLines); response = controlConnection.addOnion(portLines);
else response = controlConnection.addOnion(privKey, portLines); else response = controlConnection.addOnion(privKey, portLines);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return; return;
} }
if (!response.containsKey(HS_ADDRESS)) { if (!response.containsKey(HS_ADDRESS)) {
@@ -494,23 +488,12 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private void enableNetwork(boolean enable) throws IOException { private void enableNetwork(boolean enable) throws IOException {
if (!running) return; if (!running) return;
if (enable && USE_TOR_WAKE_LOCK) wakeLock.acquire(); if (enable) wakeLock.acquire();
connectionStatus.enableNetwork(enable); connectionStatus.enableNetwork(enable);
controlConnection.setConf("DisableNetwork", enable ? "0" : "1"); controlConnection.setConf("DisableNetwork", enable ? "0" : "1");
if (!enable) { if (!enable) {
callback.transportDisabled(); callback.transportDisabled();
if (USE_TOR_WAKE_LOCK) wakeLock.release(); wakeLock.release();
}
}
private void enableBridges(boolean enable) throws IOException {
if (enable) {
Collection<String> conf = new ArrayList<>();
conf.add("UseBridges 1");
conf.addAll(circumventionProvider.getBridges());
controlConnection.setConf(conf);
} else {
controlConnection.setConf("UseBridges", "0");
} }
} }
@@ -527,10 +510,10 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
controlConnection.shutdownTor("TERM"); controlConnection.shutdownTor("TERM");
controlSocket.close(); controlSocket.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
if (USE_TOR_WAKE_LOCK) wakeLock.release(); wakeLock.release();
} }
@Override @Override
@@ -658,6 +641,22 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LOG.info("Descriptor uploaded"); LOG.info("Descriptor uploaded");
} }
private static class WriteObserver extends FileObserver {
private final CountDownLatch latch;
private WriteObserver(File file, CountDownLatch latch) {
super(file.getAbsolutePath(), CLOSE_WRITE);
this.latch = latch;
}
@Override
public void onEvent(int event, @Nullable String path) {
stopWatching();
latch.countDown();
}
}
@Override @Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof SettingsUpdatedEvent) { if (e instanceof SettingsUpdatedEvent) {
@@ -678,8 +677,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
boolean online = net != null && net.isConnected(); boolean online = net != null && net.isConnected();
boolean wifi = online && net.getType() == TYPE_WIFI; boolean wifi = online && net.getType() == TYPE_WIFI;
String country = locationUtils.getCurrentCountry(); String country = locationUtils.getCurrentCountry();
boolean blocked = boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
circumventionProvider.isTorProbablyBlocked(country); country);
Settings s = callback.getSettings(); Settings s = callback.getSettings();
int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS);
@@ -693,26 +692,19 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (!online) { if (!online) {
LOG.info("Disabling network, device is offline"); LOG.info("Disabling network, device is offline");
enableNetwork(false); enableNetwork(false);
} else if (blocked) {
LOG.info("Disabling network, country is blocked");
enableNetwork(false);
} else if (network == PREF_TOR_NETWORK_NEVER } else if (network == PREF_TOR_NETWORK_NEVER
|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) { || (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
LOG.info("Disabling network due to data setting"); LOG.info("Disabling network due to data setting");
enableNetwork(false); enableNetwork(false);
} else if (blocked) {
if (circumventionProvider.doBridgesWork(country)) {
LOG.info("Enabling network, using bridges");
enableBridges(true);
enableNetwork(true);
} else {
LOG.info("Disabling network, country is blocked");
enableNetwork(false);
}
} else { } else {
LOG.info("Enabling network"); LOG.info("Enabling network");
enableBridges(false);
enableNetwork(true); enableNetwork(true);
} }
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -12,7 +12,6 @@ import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.AndroidUtils;
@@ -43,15 +42,11 @@ public class TorPluginFactory implements DuplexPluginFactory {
private final EventBus eventBus; private final EventBus eventBus;
private final SocketFactory torSocketFactory; private final SocketFactory torSocketFactory;
private final BackoffFactory backoffFactory; private final BackoffFactory backoffFactory;
private final CircumventionProvider circumventionProvider;
private final Clock clock;
public TorPluginFactory(Executor ioExecutor, public TorPluginFactory(Executor ioExecutor,
ScheduledExecutorService scheduler, Context appContext, ScheduledExecutorService scheduler, Context appContext,
LocationUtils locationUtils, EventBus eventBus, LocationUtils locationUtils, EventBus eventBus,
SocketFactory torSocketFactory, BackoffFactory backoffFactory, SocketFactory torSocketFactory, BackoffFactory backoffFactory) {
CircumventionProvider circumventionProvider,
Clock clock) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.scheduler = scheduler; this.scheduler = scheduler;
this.appContext = appContext; this.appContext = appContext;
@@ -59,8 +54,6 @@ public class TorPluginFactory implements DuplexPluginFactory {
this.eventBus = eventBus; this.eventBus = eventBus;
this.torSocketFactory = torSocketFactory; this.torSocketFactory = torSocketFactory;
this.backoffFactory = backoffFactory; this.backoffFactory = backoffFactory;
this.circumventionProvider = circumventionProvider;
this.clock = clock;
} }
@Override @Override
@@ -97,8 +90,8 @@ public class TorPluginFactory implements DuplexPluginFactory {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE); MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorPlugin plugin = new TorPlugin(ioExecutor, scheduler, appContext, TorPlugin plugin = new TorPlugin(ioExecutor, scheduler, appContext,
locationUtils, torSocketFactory, clock, backoff, callback, locationUtils, torSocketFactory, backoff, callback,
architecture, circumventionProvider, MAX_LATENCY, MAX_IDLE_TIME); architecture, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin); eventBus.addListener(plugin);
return plugin; return plugin;
} }

View File

@@ -1,100 +0,0 @@
package org.briarproject.bramble.util;
import android.os.PowerManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
@ThreadSafe
@NotNullByDefault
public class RenewableWakeLock {
private static final Logger LOG =
Logger.getLogger(RenewableWakeLock.class.getName());
/**
* Automatically release the lock this many milliseconds after it's due
* to have been replaced and released.
*/
private static final int SAFETY_MARGIN_MS = 10_000;
private final PowerManager powerManager;
private final ScheduledExecutorService scheduler;
private final int levelAndFlags;
private final String tag;
private final long durationMs;
private final Runnable renewTask;
private final Object lock = new Object();
@Nullable
private PowerManager.WakeLock wakeLock; // Locking: lock
@Nullable
private ScheduledFuture future; // Locking: lock
public RenewableWakeLock(PowerManager powerManager,
ScheduledExecutorService scheduler, int levelAndFlags, String tag,
long duration, TimeUnit timeUnit) {
this.powerManager = powerManager;
this.scheduler = scheduler;
this.levelAndFlags = levelAndFlags;
this.tag = tag;
durationMs = MILLISECONDS.convert(duration, timeUnit);
renewTask = this::renew;
}
public void acquire() {
if (LOG.isLoggable(INFO)) LOG.info("Acquiring wake lock " + tag);
synchronized (lock) {
if (wakeLock != null) {
LOG.info("Already acquired");
return;
}
wakeLock = powerManager.newWakeLock(levelAndFlags, tag);
wakeLock.setReferenceCounted(false);
wakeLock.acquire(durationMs + SAFETY_MARGIN_MS);
future = scheduler.schedule(renewTask, durationMs, MILLISECONDS);
}
}
private void renew() {
if (LOG.isLoggable(INFO)) LOG.info("Renewing wake lock " + tag);
synchronized (lock) {
if (wakeLock == null) {
LOG.info("Already released");
return;
}
PowerManager.WakeLock oldWakeLock = wakeLock;
wakeLock = powerManager.newWakeLock(levelAndFlags, tag);
wakeLock.setReferenceCounted(false);
wakeLock.acquire(durationMs + SAFETY_MARGIN_MS);
oldWakeLock.release();
future = scheduler.schedule(renewTask, durationMs, MILLISECONDS);
}
}
public void release() {
if (LOG.isLoggable(INFO)) LOG.info("Releasing wake lock " + tag);
synchronized (lock) {
if (wakeLock == null) {
LOG.info("Already released");
return;
}
if (future == null) throw new AssertionError();
future.cancel(false);
future = null;
wakeLock.release();
wakeLock = null;
}
}
}

View File

@@ -1,5 +0,0 @@
Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42
Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98
Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D
Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC
#Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B

View File

@@ -12,7 +12,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
/** /**
* Annotation for injecting the executor for long-running IO tasks. Also used * Annotation for injecting the executor for long-running IO tasks. Also used
* for annotating methods that should run on the IO executor. * for annotating methods that should run on the UI executor.
* <p> * <p>
* The contract of this executor is that tasks may be run concurrently, and * The contract of this executor is that tasks may be run concurrently, and
* submitting a task will never block. Tasks may run indefinitely. Tasks * submitting a task will never block. Tasks may run indefinitely. Tasks

View File

@@ -1,36 +0,0 @@
package org.briarproject.bramble.util;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
public class LogUtils {
private static final int NANOS_PER_MILLI = 1000 * 1000;
/**
* Returns the elapsed time in milliseconds since some arbitrary
* starting time. This is only useful for measuring elapsed time.
*/
public static long now() {
return System.nanoTime() / NANOS_PER_MILLI;
}
/**
* Logs the duration of a task.
* @param logger the logger to use
* @param task a description of the task
* @param start the start time of the task, as returned by {@link #now()}
*/
public static void logDuration(Logger logger, String task, long start) {
if (logger.isLoggable(FINE)) {
long duration = now() - start;
logger.fine(task + " took " + duration + " ms");
}
}
public static void logException(Logger logger, Level level, Throwable t) {
if (logger.isLoggable(level)) logger.log(level, t.toString(), t);
}
}

View File

@@ -5,12 +5,12 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.GuardedBy;
import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINE;
import static org.briarproject.bramble.util.LogUtils.now;
/** /**
* An {@link Executor} that delegates its tasks to another {@link Executor} * An {@link Executor} that delegates its tasks to another {@link Executor}
@@ -20,6 +20,8 @@ import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault @NotNullByDefault
public class PoliteExecutor implements Executor { public class PoliteExecutor implements Executor {
private static final Level LOG_LEVEL = FINE;
private final Object lock = new Object(); private final Object lock = new Object();
@GuardedBy("lock") @GuardedBy("lock")
private final Queue<Runnable> queue = new LinkedList<>(); private final Queue<Runnable> queue = new LinkedList<>();
@@ -47,11 +49,11 @@ public class PoliteExecutor implements Executor {
@Override @Override
public void execute(Runnable r) { public void execute(Runnable r) {
long submitted = now(); long submitted = System.currentTimeMillis();
Runnable wrapped = () -> { Runnable wrapped = () -> {
if (log.isLoggable(FINE)) { if (log.isLoggable(LOG_LEVEL)) {
long queued = now() - submitted; long queued = System.currentTimeMillis() - submitted;
log.fine("Queue time " + queued + " ms"); log.log(LOG_LEVEL, "Queue time " + queued + " ms");
} }
try { try {
r.run(); r.run();

View File

@@ -6,14 +6,16 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINE;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault @NotNullByDefault
public class TimeLoggingExecutor extends ThreadPoolExecutor { public class TimeLoggingExecutor extends ThreadPoolExecutor {
private static final Level LOG_LEVEL = FINE;
private final Logger log; private final Logger log;
public TimeLoggingExecutor(String tag, int corePoolSize, int maxPoolSize, public TimeLoggingExecutor(String tag, int corePoolSize, int maxPoolSize,
@@ -27,15 +29,15 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
@Override @Override
public void execute(Runnable r) { public void execute(Runnable r) {
if (log.isLoggable(FINE)) { if (log.isLoggable(LOG_LEVEL)) {
long submitted = now(); long submitted = System.currentTimeMillis();
super.execute(() -> { super.execute(() -> {
long started = now(); long started = System.currentTimeMillis();
long queued = started - submitted; long queued = started - submitted;
log.fine("Queue time " + queued + " ms"); log.log(LOG_LEVEL, "Queue time " + queued + " ms");
r.run(); r.run();
long executing = now() - started; long executing = System.currentTimeMillis() - started;
log.fine("Execution time " + executing + " ms"); log.log(LOG_LEVEL, "Execution time " + executing + " ms");
}); });
} else { } else {
super.execute(r); super.execute(r);

View File

@@ -46,7 +46,6 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO; import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.ValidationUtils.checkLength; import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkSize; import static org.briarproject.bramble.util.ValidationUtils.checkSize;
@@ -123,7 +122,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
in = conn.getReader().getInputStream(); in = conn.getReader().getInputStream();
out = conn.getWriter().getOutputStream(); out = conn.getWriter().getOutputStream();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
listener.contactExchangeFailed(); listener.contactExchangeFailed();
tryToClose(conn); tryToClose(conn);
return; return;
@@ -134,7 +133,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
try { try {
localProperties = transportPropertyManager.getLocalProperties(); localProperties = transportPropertyManager.getLocalProperties();
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
listener.contactExchangeFailed(); listener.contactExchangeFailed();
tryToClose(conn); tryToClose(conn);
return; return;
@@ -195,7 +194,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
LOG.info("End of stream"); LOG.info("End of stream");
} }
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
listener.contactExchangeFailed(); listener.contactExchangeFailed();
tryToClose(conn); tryToClose(conn);
return; return;
@@ -223,11 +222,11 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
LOG.info("Pseudonym exchange succeeded"); LOG.info("Pseudonym exchange succeeded");
listener.contactExchangeSucceeded(remoteInfo.author); listener.contactExchangeSucceeded(remoteInfo.author);
} catch (ContactExistsException e) { } catch (ContactExistsException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(conn); tryToClose(conn);
listener.duplicateContact(remoteInfo.author); listener.duplicateContact(remoteInfo.author);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(conn); tryToClose(conn);
listener.contactExchangeFailed(); listener.contactExchangeFailed();
} }
@@ -308,7 +307,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
conn.getReader().dispose(true, true); conn.getReader().dispose(true, true);
conn.getWriter().dispose(true); conn.getWriter().dispose(true);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -32,8 +32,6 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES; import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault @NotNullByDefault
class CryptoComponentImpl implements CryptoComponent { class CryptoComponentImpl implements CryptoComponent {
@@ -129,14 +127,16 @@ class CryptoComponentImpl implements CryptoComponent {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (!(pub instanceof Curve25519PublicKey)) if (!(pub instanceof Curve25519PublicKey))
throw new IllegalArgumentException(); throw new IllegalArgumentException();
long start = now(); long now = System.currentTimeMillis();
byte[] secret = curve25519.calculateAgreement(pub.getEncoded(), byte[] secret = curve25519.calculateAgreement(pub.getEncoded(),
priv.getEncoded()); priv.getEncoded());
// If the shared secret is all zeroes, the public key is invalid // If the shared secret is all zeroes, the public key is invalid
byte allZero = 0; byte allZero = 0;
for (byte b : secret) allZero |= b; for (byte b : secret) allZero |= b;
if (allZero == 0) throw new GeneralSecurityException(); if (allZero == 0) throw new GeneralSecurityException();
logDuration(LOG, "Deriving shared secret", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Deriving shared secret took " + duration + " ms");
return secret; return secret;
} }

View File

@@ -10,8 +10,6 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
class ScryptKdf implements PasswordBasedKdf { class ScryptKdf implements PasswordBasedKdf {
@@ -52,11 +50,13 @@ class ScryptKdf implements PasswordBasedKdf {
@Override @Override
public SecretKey deriveKey(String password, byte[] salt, int cost) { public SecretKey deriveKey(String password, byte[] salt, int cost) {
long start = now(); long start = System.currentTimeMillis();
byte[] passwordBytes = StringUtils.toUtf8(password); byte[] passwordBytes = StringUtils.toUtf8(password);
SecretKey k = new SecretKey(SCrypt.generate(passwordBytes, salt, cost, SecretKey k = new SecretKey(SCrypt.generate(passwordBytes, salt, cost,
BLOCK_SIZE, PARALLELIZATION, SecretKey.LENGTH)); BLOCK_SIZE, PARALLELIZATION, SecretKey.LENGTH));
logDuration(LOG, "Deriving key from password", start); long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO))
LOG.info("Deriving key from password took " + duration + " ms");
return k; return k;
} }
} }

View File

@@ -16,8 +16,7 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.LogUtils.now;
/** /**
* A key parser that uses the encoding defined in "SEC 1: Elliptic Curve * A key parser that uses the encoding defined in "SEC 1: Elliptic Curve
@@ -49,7 +48,7 @@ class Sec1KeyParser implements KeyParser {
throws GeneralSecurityException { throws GeneralSecurityException {
// The validation procedure comes from SEC 1, section 3.2.2.1. Note // The validation procedure comes from SEC 1, section 3.2.2.1. Note
// that SEC 1 parameter names are used below, not RFC 5639 names // that SEC 1 parameter names are used below, not RFC 5639 names
long start = now(); long now = System.currentTimeMillis();
if (encodedKey.length != publicKeyBytes) if (encodedKey.length != publicKeyBytes)
throw new GeneralSecurityException(); throw new GeneralSecurityException();
// The first byte must be 0x04 // The first byte must be 0x04
@@ -81,14 +80,16 @@ class Sec1KeyParser implements KeyParser {
// Construct a public key from the point (x, y) and the params // Construct a public key from the point (x, y) and the params
ECPublicKeyParameters k = new ECPublicKeyParameters(pub, params); ECPublicKeyParameters k = new ECPublicKeyParameters(pub, params);
PublicKey p = new Sec1PublicKey(k); PublicKey p = new Sec1PublicKey(k);
logDuration(LOG, "Parsing public key", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Parsing public key took " + duration + " ms");
return p; return p;
} }
@Override @Override
public PrivateKey parsePrivateKey(byte[] encodedKey) public PrivateKey parsePrivateKey(byte[] encodedKey)
throws GeneralSecurityException { throws GeneralSecurityException {
long start = now(); long now = System.currentTimeMillis();
if (encodedKey.length != privateKeyBytes) if (encodedKey.length != privateKeyBytes)
throw new GeneralSecurityException(); throw new GeneralSecurityException();
BigInteger d = new BigInteger(1, encodedKey); // Positive signum BigInteger d = new BigInteger(1, encodedKey); // Positive signum
@@ -98,7 +99,9 @@ class Sec1KeyParser implements KeyParser {
// Construct a private key from the private value and the params // Construct a private key from the private value and the params
ECPrivateKeyParameters k = new ECPrivateKeyParameters(d, params); ECPrivateKeyParameters k = new ECPrivateKeyParameters(d, params);
PrivateKey p = new Sec1PrivateKey(k, keyBits); PrivateKey p = new Sec1PrivateKey(k, keyBits);
logDuration(LOG, "Parsing private key", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Parsing private key took " + duration + " ms");
return p; return p;
} }
} }

View File

@@ -68,15 +68,13 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN; import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES; import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -110,7 +108,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
try { try {
close(); close();
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
return reopened; return reopened;
@@ -127,13 +125,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
// Don't allow reentrant locking // Don't allow reentrant locking
if (lock.getReadHoldCount() > 0) throw new IllegalStateException(); if (lock.getReadHoldCount() > 0) throw new IllegalStateException();
if (lock.getWriteHoldCount() > 0) throw new IllegalStateException(); if (lock.getWriteHoldCount() > 0) throw new IllegalStateException();
long start = now(); long start = System.currentTimeMillis();
if (readOnly) { if (readOnly) lock.readLock().lock();
lock.readLock().lock(); else lock.writeLock().lock();
logDuration(LOG, "Waiting for read lock", start); if (LOG.isLoggable(FINE)) {
} else { long duration = System.currentTimeMillis() - start;
lock.writeLock().lock(); if (readOnly) LOG.fine("Waited " + duration + " ms for read lock");
logDuration(LOG, "Waiting for write lock", start); else LOG.fine("Waited " + duration + " ms for write lock");
} }
try { try {
return new Transaction(db.startTransaction(), readOnly); return new Transaction(db.startTransaction(), readOnly);

View File

@@ -66,7 +66,6 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE; import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY; import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry; import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
import static org.briarproject.bramble.util.LogUtils.logException;
/** /**
* A generic database implementation that can be used with any JDBC-compatible * A generic database implementation that can be used with any JDBC-compatible
@@ -405,7 +404,7 @@ abstract class JdbcDatabase implements Database<Connection> {
try { try {
if (rs != null) rs.close(); if (rs != null) rs.close();
} catch (SQLException e) { } catch (SQLException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -413,7 +412,7 @@ abstract class JdbcDatabase implements Database<Connection> {
try { try {
if (s != null) s.close(); if (s != null) s.close();
} catch (SQLException e) { } catch (SQLException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -510,11 +509,12 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} catch (SQLException e) { } catch (SQLException e) {
// Try to close the connection // Try to close the connection
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
try { try {
txn.close(); txn.close();
} catch (SQLException e1) { } catch (SQLException e1) {
logException(LOG, WARNING, e1); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e1.toString(), e1);
} }
// Whatever happens, allow the database to close // Whatever happens, allow the database to close
connectionsLock.lock(); connectionsLock.lock();

View File

@@ -10,7 +10,6 @@ import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
class Migration38_39 implements Migration<Connection> { class Migration38_39 implements Migration<Connection> {
@@ -49,7 +48,7 @@ class Migration38_39 implements Migration<Connection> {
try { try {
if (s != null) s.close(); if (s != null) s.close();
} catch (SQLException e) { } catch (SQLException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }

View File

@@ -31,7 +31,6 @@ import javax.annotation.Nullable;
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 org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.CONNECTION_TIMEOUT; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.CONNECTION_TIMEOUT;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class KeyAgreementConnector { class KeyAgreementConnector {
@@ -135,7 +134,7 @@ class KeyAgreementConnector {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
return null; return null;
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null; return null;
} finally { } finally {
stopListening(); stopListening();

View File

@@ -28,7 +28,6 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -121,11 +120,13 @@ class KeyAgreementTaskImpl extends Thread implements KeyAgreementTask,
// Broadcast result to caller // Broadcast result to caller
eventBus.broadcast(new KeyAgreementFinishedEvent(result)); eventBus.broadcast(new KeyAgreementFinishedEvent(result));
} catch (AbortException e) { } catch (AbortException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
// Notify caller that the protocol was aborted // Notify caller that the protocol was aborted
eventBus.broadcast(new KeyAgreementAbortedEvent(e.receivedAbort)); eventBus.broadcast(new KeyAgreementAbortedEvent(e.receivedAbort));
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
// Notify caller that the connection failed // Notify caller that the connection failed
eventBus.broadcast(new KeyAgreementFailedEvent()); eventBus.broadcast(new KeyAgreementFailedEvent());
} }

View File

@@ -20,7 +20,6 @@ import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PR
import static org.briarproject.bramble.api.keyagreement.RecordTypes.ABORT; import static org.briarproject.bramble.api.keyagreement.RecordTypes.ABORT;
import static org.briarproject.bramble.api.keyagreement.RecordTypes.CONFIRM; import static org.briarproject.bramble.api.keyagreement.RecordTypes.CONFIRM;
import static org.briarproject.bramble.api.keyagreement.RecordTypes.KEY; import static org.briarproject.bramble.api.keyagreement.RecordTypes.KEY;
import static org.briarproject.bramble.util.LogUtils.logException;
/** /**
* Handles the sending and receiving of BQP records. * Handles the sending and receiving of BQP records.
@@ -73,7 +72,7 @@ class KeyAgreementTransport {
try { try {
writeRecord(ABORT, new byte[0]); writeRecord(ABORT, new byte[0]);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
exception = true; exception = true;
} }
tryToClose(exception); tryToClose(exception);
@@ -84,7 +83,7 @@ class KeyAgreementTransport {
kac.getConnection().getReader().dispose(exception, true); kac.getConnection().getReader().dispose(exception, true);
kac.getConnection().getWriter().dispose(exception); kac.getConnection().getWriter().dispose(exception);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -30,7 +30,6 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
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.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
@@ -44,9 +43,6 @@ import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResul
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DB_ERROR; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DB_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SERVICE_ERROR; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SERVICE_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -105,20 +101,24 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
} }
private LocalAuthor createLocalAuthor(String nickname) { private LocalAuthor createLocalAuthor(String nickname) {
long start = now(); long now = System.currentTimeMillis();
KeyPair keyPair = crypto.generateSignatureKeyPair(); KeyPair keyPair = crypto.generateSignatureKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded(); byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded(); byte[] privateKey = keyPair.getPrivate().getEncoded();
LocalAuthor localAuthor = authorFactory LocalAuthor localAuthor = authorFactory
.createLocalAuthor(nickname, publicKey, privateKey); .createLocalAuthor(nickname, publicKey, privateKey);
logDuration(LOG, "Creating local author", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Creating local author took " + duration + " ms");
return localAuthor; return localAuthor;
} }
private void registerLocalAuthor(LocalAuthor author) throws DbException { private void registerLocalAuthor(LocalAuthor author) throws DbException {
long start = now(); long now = System.currentTimeMillis();
identityManager.registerLocalAuthor(author); identityManager.registerLocalAuthor(author);
logDuration(LOG, "Registering local author", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Registering local author took " + duration + " ms");
} }
@Override @Override
@@ -129,11 +129,15 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
} }
try { try {
LOG.info("Starting services"); LOG.info("Starting services");
long start = now(); long start = System.currentTimeMillis();
boolean reopened = db.open(this); boolean reopened = db.open(this);
if (reopened) logDuration(LOG, "Reopening database", start); long duration = System.currentTimeMillis() - start;
else logDuration(LOG, "Creating database", start); if (LOG.isLoggable(INFO)) {
if (reopened)
LOG.info("Reopening database took " + duration + " ms");
else LOG.info("Creating database took " + duration + " ms");
}
if (nickname != null) { if (nickname != null) {
registerLocalAuthor(createLocalAuthor(nickname)); registerLocalAuthor(createLocalAuthor(nickname));
@@ -146,11 +150,13 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
for (Client c : clients) { for (Client c : clients) {
start = now(); start = System.currentTimeMillis();
c.createLocalState(txn); c.createLocalState(txn);
if (LOG.isLoggable(FINE)) { duration = System.currentTimeMillis() - start;
logDuration(LOG, "Starting client " if (LOG.isLoggable(INFO)) {
+ c.getClass().getSimpleName(), start); LOG.info("Starting client "
+ c.getClass().getSimpleName()
+ " took " + duration + " ms");
} }
} }
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -158,11 +164,12 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
db.endTransaction(txn); db.endTransaction(txn);
} }
for (Service s : services) { for (Service s : services) {
start = now(); start = System.currentTimeMillis();
s.startService(); s.startService();
if (LOG.isLoggable(FINE)) { duration = System.currentTimeMillis() - start;
logDuration(LOG, "Starting service " if (LOG.isLoggable(INFO)) {
+ s.getClass().getSimpleName(), start); LOG.info("Starting service " + s.getClass().getSimpleName()
+ " took " + duration + " ms");
} }
} }
@@ -171,16 +178,16 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
eventBus.broadcast(new LifecycleEvent(RUNNING)); eventBus.broadcast(new LifecycleEvent(RUNNING));
return SUCCESS; return SUCCESS;
} catch (DataTooOldException e) { } catch (DataTooOldException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return DATA_TOO_OLD_ERROR; return DATA_TOO_OLD_ERROR;
} catch (DataTooNewException e) { } catch (DataTooNewException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return DATA_TOO_NEW_ERROR; return DATA_TOO_NEW_ERROR;
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return DB_ERROR; return DB_ERROR;
} catch (ServiceException e) { } catch (ServiceException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return SERVICE_ERROR; return SERVICE_ERROR;
} finally { } finally {
startStopSemaphore.release(); startStopSemaphore.release();
@@ -206,26 +213,29 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
state = STOPPING; state = STOPPING;
eventBus.broadcast(new LifecycleEvent(STOPPING)); eventBus.broadcast(new LifecycleEvent(STOPPING));
for (Service s : services) { for (Service s : services) {
long start = now(); long start = System.currentTimeMillis();
s.stopService(); s.stopService();
if (LOG.isLoggable(FINE)) { long duration = System.currentTimeMillis() - start;
logDuration(LOG, "Stopping service " if (LOG.isLoggable(INFO)) {
+ s.getClass().getSimpleName(), start); LOG.info("Stopping service " + s.getClass().getSimpleName()
+ " took " + duration + " ms");
} }
} }
for (ExecutorService e : executors) { for (ExecutorService e : executors) {
if (LOG.isLoggable(FINE)) { if (LOG.isLoggable(INFO)) {
LOG.fine("Stopping executor " LOG.info("Stopping executor "
+ e.getClass().getSimpleName()); + e.getClass().getSimpleName());
} }
e.shutdownNow(); e.shutdownNow();
} }
long start = now(); long start = System.currentTimeMillis();
db.close(); db.close();
logDuration(LOG, "Closing database", start); long duration = System.currentTimeMillis() - start;
if (LOG.isLoggable(INFO))
LOG.info("Closing database took " + duration + " ms");
shutdownLatch.countDown(); shutdownLatch.countDown();
} catch (DbException | ServiceException e) { } catch (DbException | ServiceException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} finally { } finally {
startStopSemaphore.release(); startStopSemaphore.release();
} }

View File

@@ -27,7 +27,6 @@ import javax.inject.Inject;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.util.LogUtils.logException;
class ConnectionManagerImpl implements ConnectionManager { class ConnectionManagerImpl implements ConnectionManager {
@@ -136,7 +135,7 @@ class ConnectionManagerImpl implements ConnectionManager {
byte[] tag = readTag(reader); byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag); ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException | DbException e) { } catch (IOException | DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, false); disposeReader(true, false);
return; return;
} }
@@ -152,7 +151,7 @@ class ConnectionManagerImpl implements ConnectionManager {
createIncomingSession(ctx, reader).run(); createIncomingSession(ctx, reader).run();
disposeReader(false, true); disposeReader(false, true);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, true); disposeReader(true, true);
} finally { } finally {
connectionRegistry.unregisterConnection(contactId, transportId, connectionRegistry.unregisterConnection(contactId, transportId,
@@ -164,7 +163,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
reader.dispose(exception, recognised); reader.dispose(exception, recognised);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }
@@ -189,7 +188,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
ctx = keyManager.getStreamContext(contactId, transportId); ctx = keyManager.getStreamContext(contactId, transportId);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeWriter(true); disposeWriter(true);
return; return;
} }
@@ -205,7 +204,7 @@ class ConnectionManagerImpl implements ConnectionManager {
createSimplexOutgoingSession(ctx, writer).run(); createSimplexOutgoingSession(ctx, writer).run();
disposeWriter(false); disposeWriter(false);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeWriter(true); disposeWriter(true);
} finally { } finally {
connectionRegistry.unregisterConnection(contactId, transportId, connectionRegistry.unregisterConnection(contactId, transportId,
@@ -217,7 +216,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
writer.dispose(exception); writer.dispose(exception);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }
@@ -247,7 +246,7 @@ class ConnectionManagerImpl implements ConnectionManager {
byte[] tag = readTag(reader); byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag); ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException | DbException e) { } catch (IOException | DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, false); disposeReader(true, false);
return; return;
} }
@@ -266,7 +265,7 @@ class ConnectionManagerImpl implements ConnectionManager {
incomingSession.run(); incomingSession.run();
disposeReader(false, true); disposeReader(false, true);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, true); disposeReader(true, true);
} finally { } finally {
connectionRegistry.unregisterConnection(contactId, transportId, connectionRegistry.unregisterConnection(contactId, transportId,
@@ -280,7 +279,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
ctx = keyManager.getStreamContext(contactId, transportId); ctx = keyManager.getStreamContext(contactId, transportId);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeWriter(true); disposeWriter(true);
return; return;
} }
@@ -295,7 +294,7 @@ class ConnectionManagerImpl implements ConnectionManager {
outgoingSession.run(); outgoingSession.run();
disposeWriter(false); disposeWriter(false);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeWriter(true); disposeWriter(true);
} }
} }
@@ -306,7 +305,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
reader.dispose(exception, recognised); reader.dispose(exception, recognised);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -318,7 +317,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
writer.dispose(exception); writer.dispose(exception);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }
@@ -348,7 +347,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
ctx = keyManager.getStreamContext(contactId, transportId); ctx = keyManager.getStreamContext(contactId, transportId);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeWriter(true); disposeWriter(true);
return; return;
} }
@@ -365,7 +364,7 @@ class ConnectionManagerImpl implements ConnectionManager {
outgoingSession.run(); outgoingSession.run();
disposeWriter(false); disposeWriter(false);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeWriter(true); disposeWriter(true);
} }
} }
@@ -377,7 +376,7 @@ class ConnectionManagerImpl implements ConnectionManager {
byte[] tag = readTag(reader); byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag); ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException | DbException e) { } catch (IOException | DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, false); disposeReader(true, false);
return; return;
} }
@@ -401,7 +400,7 @@ class ConnectionManagerImpl implements ConnectionManager {
incomingSession.run(); incomingSession.run();
disposeReader(false, true); disposeReader(false, true);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
disposeReader(true, true); disposeReader(true, true);
} finally { } finally {
connectionRegistry.unregisterConnection(contactId, transportId, connectionRegistry.unregisterConnection(contactId, transportId,
@@ -415,7 +414,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
reader.dispose(exception, recognised); reader.dispose(exception, recognised);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -427,7 +426,7 @@ class ConnectionManagerImpl implements ConnectionManager {
try { try {
writer.dispose(exception); writer.dispose(exception);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }

View File

@@ -49,12 +49,8 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject; import javax.inject.Inject;
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.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -209,16 +205,17 @@ class PluginManagerImpl implements PluginManager, Service {
@Override @Override
public void run() { public void run() {
try { try {
long start = now(); long start = System.currentTimeMillis();
plugin.start(); plugin.start();
if (LOG.isLoggable(FINE)) { long duration = System.currentTimeMillis() - start;
logDuration(LOG, "Starting plugin " + plugin.getId(), if (LOG.isLoggable(INFO)) {
start); LOG.info("Starting plugin " + plugin.getId() + " took " +
duration + " ms");
} }
} catch (PluginException e) { } catch (PluginException e) {
if (LOG.isLoggable(WARNING)) { if (LOG.isLoggable(WARNING)) {
LOG.warning("Plugin " + plugin.getId() + " did not start"); LOG.warning("Plugin " + plugin.getId() + " did not start");
logException(LOG, WARNING, e); LOG.log(WARNING, e.toString(), e);
} }
} finally { } finally {
startLatch.countDown(); startLatch.countDown();
@@ -246,11 +243,12 @@ class PluginManagerImpl implements PluginManager, Service {
// Wait for the plugin to finish starting // Wait for the plugin to finish starting
startLatch.await(); startLatch.await();
// Stop the plugin // Stop the plugin
long start = now(); long start = System.currentTimeMillis();
plugin.stop(); plugin.stop();
if (LOG.isLoggable(FINE)) { long duration = System.currentTimeMillis() - start;
logDuration(LOG, "Stopping plugin " + plugin.getId(), if (LOG.isLoggable(INFO)) {
start); LOG.info("Stopping plugin " + plugin.getId()
+ " took " + duration + " ms");
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOG.warning("Interrupted while waiting for plugin to stop"); LOG.warning("Interrupted while waiting for plugin to stop");
@@ -258,7 +256,7 @@ class PluginManagerImpl implements PluginManager, Service {
} catch (PluginException e) { } catch (PluginException e) {
if (LOG.isLoggable(WARNING)) { if (LOG.isLoggable(WARNING)) {
LOG.warning("Plugin " + plugin.getId() + " did not stop"); LOG.warning("Plugin " + plugin.getId() + " did not stop");
logException(LOG, WARNING, e); LOG.log(WARNING, e.toString(), e);
} }
} finally { } finally {
stopLatch.countDown(); stopLatch.countDown();
@@ -280,7 +278,7 @@ class PluginManagerImpl implements PluginManager, Service {
try { try {
return settingsManager.getSettings(id.getString()); return settingsManager.getSettings(id.getString());
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return new Settings(); return new Settings();
} }
} }
@@ -290,7 +288,7 @@ class PluginManagerImpl implements PluginManager, Service {
try { try {
return transportPropertyManager.getLocalProperties(id); return transportPropertyManager.getLocalProperties(id);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return new TransportProperties(); return new TransportProperties();
} }
} }
@@ -300,7 +298,7 @@ class PluginManagerImpl implements PluginManager, Service {
try { try {
settingsManager.mergeSettings(s, id.getString()); settingsManager.mergeSettings(s, id.getString());
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -309,7 +307,7 @@ class PluginManagerImpl implements PluginManager, Service {
try { try {
transportPropertyManager.mergeLocalProperties(id, p); transportPropertyManager.mergeLocalProperties(id, p);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -28,7 +28,9 @@ import org.briarproject.bramble.api.system.Scheduler;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@@ -41,7 +43,6 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
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 org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -59,6 +60,7 @@ class Poller implements EventListener {
private final Clock clock; private final Clock clock;
private final Lock lock; private final Lock lock;
private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock
private final Set<TransportId> polling; // Locking: lock
Poller(@IoExecutor Executor ioExecutor, Poller(@IoExecutor Executor ioExecutor,
@Scheduler ScheduledExecutorService scheduler, @Scheduler ScheduledExecutorService scheduler,
@@ -76,6 +78,7 @@ class Poller implements EventListener {
this.clock = clock; this.clock = clock;
lock = new ReentrantLock(); lock = new ReentrantLock();
tasks = new HashMap<>(); tasks = new HashMap<>();
polling = new HashSet<>();
} }
@Override @Override
@@ -135,7 +138,7 @@ class Poller implements EventListener {
if (w != null) if (w != null)
connectionManager.manageOutgoingConnection(c, t, w); connectionManager.manageOutgoingConnection(c, t, w);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -151,7 +154,7 @@ class Poller implements EventListener {
if (d != null) if (d != null)
connectionManager.manageOutgoingConnection(c, t, d); connectionManager.manageOutgoingConnection(c, t, d);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -212,7 +215,7 @@ class Poller implements EventListener {
remote.keySet().removeAll(connected); remote.keySet().removeAll(connected);
if (!remote.isEmpty()) p.poll(remote); if (!remote.isEmpty()) p.poll(remote);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -242,20 +245,33 @@ class Poller implements EventListener {
@Override @Override
@IoExecutor @IoExecutor
public void run() { public void run() {
TransportId t = plugin.getId();
boolean shouldPoll;
lock.lock(); lock.lock();
try { try {
TransportId t = plugin.getId();
ScheduledPollTask scheduled = tasks.get(t); ScheduledPollTask scheduled = tasks.get(t);
if (scheduled != null && scheduled.task != this) if (scheduled != null && scheduled.task != this)
return; // Replaced by another task return; // Replaced by another task
tasks.remove(t); tasks.remove(t);
// Don't poll again if last poll is still running
shouldPoll = polling.add(t);
} finally { } finally {
lock.unlock(); lock.unlock();
} }
int delay = plugin.getPollingInterval(); int delay = plugin.getPollingInterval();
if (randomiseNext) delay = (int) (delay * random.nextDouble()); if (randomiseNext) delay = (int) (delay * random.nextDouble());
schedule(plugin, delay, false); schedule(plugin, delay, false);
poll(plugin); if (shouldPoll) {
poll(plugin);
} else if (LOG.isLoggable(INFO)) {
LOG.info("Last poll for " + t + " is still running");
}
lock.lock();
try {
polling.remove(t);
} finally {
lock.unlock();
}
} }
} }
} }

View File

@@ -13,7 +13,6 @@ import javax.annotation.concurrent.ThreadSafe;
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 org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
@ThreadSafe @ThreadSafe
@@ -93,7 +92,7 @@ class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
conn.getWriter().dispose(false); conn.getWriter().dispose(false);
conn.getReader().dispose(false, false); conn.getReader().dispose(false, false);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -26,8 +26,10 @@ import org.briarproject.bramble.util.StringUtils;
import java.io.IOException; import java.io.IOException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@@ -43,7 +45,6 @@ import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENA
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES; import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -53,6 +54,12 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(BluetoothPlugin.class.getName()); Logger.getLogger(BluetoothPlugin.class.getName());
/**
* How many milliseconds to pause between connection attempts when
* polling, to avoid interfering with other Bluetooth or wifi connections.
*/
private static final int POLLING_PAUSE_MS = 1000;
final BluetoothConnectionLimiter connectionLimiter; final BluetoothConnectionLimiter connectionLimiter;
private final Executor ioExecutor; private final Executor ioExecutor;
@@ -170,7 +177,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
try { try {
ss = openServerSocket(contactConnectionsUuid); ss = openServerSocket(contactConnectionsUuid);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return; return;
} }
if (!isRunning() || !shouldAllowContactConnections()) { if (!isRunning() || !shouldAllowContactConnections()) {
@@ -253,24 +260,39 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
public void poll(Map<ContactId, TransportProperties> contacts) { public void poll(Map<ContactId, TransportProperties> contacts) {
if (!isRunning() || !shouldAllowContactConnections()) return; if (!isRunning() || !shouldAllowContactConnections()) return;
backoff.increment(); backoff.increment();
// Try to connect to known devices in parallel // Try to connect to known devices in a random order
for (Entry<ContactId, TransportProperties> e : contacts.entrySet()) { List<ContactId> keys = new ArrayList<>(contacts.keySet());
String address = e.getValue().get(PROP_ADDRESS); Collections.shuffle(keys);
if (StringUtils.isNullOrEmpty(address)) continue; ioExecutor.execute(() -> {
String uuid = e.getValue().get(PROP_UUID); boolean first = true;
if (StringUtils.isNullOrEmpty(uuid)) continue; for (ContactId c : keys) {
ContactId c = e.getKey();
ioExecutor.execute(() -> {
if (!isRunning() || !shouldAllowContactConnections()) return; if (!isRunning() || !shouldAllowContactConnections()) return;
if (!connectionLimiter.canOpenContactConnection()) return; if (!connectionLimiter.canOpenContactConnection()) return;
TransportProperties p = contacts.get(c);
String address = p.get(PROP_ADDRESS);
if (StringUtils.isNullOrEmpty(address)) continue;
String uuid = p.get(PROP_UUID);
if (StringUtils.isNullOrEmpty(uuid)) continue;
// Pause between connection attempts
if (first) {
first = false;
} else {
try {
Thread.sleep(POLLING_PAUSE_MS);
} catch (InterruptedException ex) {
LOG.info("Interrupted while polling");
Thread.currentThread().interrupt();
return;
}
}
DuplexTransportConnection conn = connect(address, uuid); DuplexTransportConnection conn = connect(address, uuid);
if (conn != null) { if (conn != null) {
backoff.reset(); backoff.reset();
if (connectionLimiter.contactConnectionOpened(conn)) if (connectionLimiter.contactConnectionOpened(conn))
callback.outgoingConnectionCreated(c, conn); callback.outgoingConnectionCreated(c, conn);
} }
}); }
} });
} }
@Nullable @Nullable
@@ -337,7 +359,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
try { try {
ss = openServerSocket(uuid); ss = openServerSocket(uuid);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null; return null;
} }
if (!isRunning()) { if (!isRunning()) {

View File

@@ -15,7 +15,6 @@ import java.util.logging.Logger;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH; import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@NotNullByDefault @NotNullByDefault
@@ -52,7 +51,7 @@ abstract class FilePlugin implements SimplexPlugin {
FileInputStream in = new FileInputStream(file); FileInputStream in = new FileInputStream(file);
return new FileTransportReader(file, in, this); return new FileTransportReader(file, in, this);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null; return null;
} }
} }
@@ -71,7 +70,7 @@ abstract class FilePlugin implements SimplexPlugin {
FileOutputStream out = new FileOutputStream(file); FileOutputStream out = new FileOutputStream(file);
return new FileTransportWriter(file, out, this); return new FileTransportWriter(file, out, this);
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null; return null;
} }
} }

View File

@@ -9,7 +9,6 @@ import java.io.InputStream;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class FileTransportReader implements TransportConnectionReader { class FileTransportReader implements TransportConnectionReader {
@@ -37,7 +36,7 @@ class FileTransportReader implements TransportConnectionReader {
try { try {
in.close(); in.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
plugin.readerFinished(file, exception, recognised); plugin.readerFinished(file, exception, recognised);
} }

View File

@@ -9,7 +9,6 @@ import java.io.OutputStream;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class FileTransportWriter implements TransportConnectionWriter { class FileTransportWriter implements TransportConnectionWriter {
@@ -47,7 +46,7 @@ class FileTransportWriter implements TransportConnectionWriter {
try { try {
out.close(); out.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
plugin.writerFinished(file, exception); plugin.writerFinished(file, exception);
} }

View File

@@ -35,7 +35,6 @@ import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS; import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS; import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS;
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED; import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
@NotNullByDefault @NotNullByDefault
@@ -296,7 +295,7 @@ class LanTcpPlugin extends TcpPlugin {
try { try {
ss.close(); ss.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }

View File

@@ -17,7 +17,6 @@ import javax.xml.parsers.ParserConfigurationException;
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 org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
@ThreadSafe @ThreadSafe
@@ -60,7 +59,7 @@ class PortMapperImpl implements PortMapper {
if (externalString != null) if (externalString != null)
external = InetAddress.getByName(externalString); external = InetAddress.getByName(externalString);
} catch (IOException | SAXException e) { } catch (IOException | SAXException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
return new MappingResult(internal, external, port, succeeded); return new MappingResult(internal, external, port, succeeded);
} }
@@ -77,7 +76,7 @@ class PortMapperImpl implements PortMapper {
try { try {
d.discover(); d.discover();
} catch (IOException | SAXException | ParserConfigurationException e) { } catch (IOException | SAXException | ParserConfigurationException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
gateway = d.getValidGateway(); gateway = d.getValidGateway();
} }
@@ -88,7 +87,7 @@ class PortMapperImpl implements PortMapper {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Deleted mapping for port " + port); LOG.info("Deleted mapping for port " + port);
} catch (IOException | SAXException e) { } catch (IOException | SAXException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }

View File

@@ -37,7 +37,6 @@ import javax.annotation.Nullable;
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 org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -153,7 +152,7 @@ abstract class TcpPlugin implements DuplexPlugin {
try { try {
if (ss != null) ss.close(); if (ss != null) ss.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} finally { } finally {
callback.transportDisabled(); callback.transportDisabled();
} }
@@ -307,7 +306,7 @@ abstract class TcpPlugin implements DuplexPlugin {
try { try {
ifaces = Collections.list(NetworkInterface.getNetworkInterfaces()); ifaces = Collections.list(NetworkInterface.getNetworkInterfaces());
} catch (SocketException e) { } catch (SocketException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return Collections.emptyList(); return Collections.emptyList();
} }
List<InetAddress> addrs = new ArrayList<>(); List<InetAddress> addrs = new ArrayList<>();

View File

@@ -16,7 +16,6 @@ import java.util.logging.Logger;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -79,7 +78,7 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
running = false; running = false;
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
running = false; running = false;
} }
}); });

View File

@@ -32,7 +32,6 @@ import javax.inject.Inject;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -133,7 +132,7 @@ class DevReporterImpl implements DevReporter, EventListener {
try { try {
if (c != null) c.close(); if (c != null) c.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -141,7 +140,7 @@ class DevReporterImpl implements DevReporter, EventListener {
try { try {
if (s != null) s.close(); if (s != null) s.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }

View File

@@ -42,7 +42,6 @@ import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES; import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
import static org.briarproject.bramble.util.LogUtils.logException;
/** /**
* An outgoing {@link SyncSession} suitable for duplex transports. The session * An outgoing {@link SyncSession} suitable for duplex transports. The session
@@ -241,7 +240,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated ack: " + (a != null)); LOG.info("Generated ack: " + (a != null));
if (a != null) writerTasks.add(new WriteAck(a)); if (a != null) writerTasks.add(new WriteAck(a));
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }
@@ -288,7 +287,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated batch: " + (b != null)); LOG.info("Generated batch: " + (b != null));
if (b != null) writerTasks.add(new WriteBatch(b)); if (b != null) writerTasks.add(new WriteBatch(b));
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }
@@ -335,7 +334,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated offer: " + (o != null)); LOG.info("Generated offer: " + (o != null));
if (o != null) writerTasks.add(new WriteOffer(o)); if (o != null) writerTasks.add(new WriteOffer(o));
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }
@@ -380,7 +379,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
LOG.info("Generated request: " + (r != null)); LOG.info("Generated request: " + (r != null));
if (r != null) writerTasks.add(new WriteRequest(r)); if (r != null) writerTasks.add(new WriteRequest(r));
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }

View File

@@ -28,7 +28,6 @@ import javax.annotation.concurrent.ThreadSafe;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.util.LogUtils.logException;
/** /**
* An incoming {@link SyncSession}. * An incoming {@link SyncSession}.
@@ -128,7 +127,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn); db.endTransaction(txn);
} }
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }
@@ -154,7 +153,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn); db.endTransaction(txn);
} }
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }
@@ -180,7 +179,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn); db.endTransaction(txn);
} }
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }
@@ -206,7 +205,7 @@ class IncomingSession implements SyncSession, EventListener {
db.endTransaction(txn); db.endTransaction(txn);
} }
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }

View File

@@ -32,7 +32,6 @@ import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES; import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
import static org.briarproject.bramble.util.LogUtils.logException;
/** /**
* An outgoing {@link SyncSession} suitable for simplex transports. The session * An outgoing {@link SyncSession} suitable for simplex transports. The session
@@ -140,7 +139,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
if (a == null) decrementOutstandingQueries(); if (a == null) decrementOutstandingQueries();
else writerTasks.add(new WriteAck(a)); else writerTasks.add(new WriteAck(a));
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }
@@ -185,7 +184,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
if (b == null) decrementOutstandingQueries(); if (b == null) decrementOutstandingQueries();
else writerTasks.add(new WriteBatch(b)); else writerTasks.add(new WriteBatch(b));
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
interrupt(); interrupt();
} }
} }

View File

@@ -40,7 +40,6 @@ import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID; import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING; import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -111,7 +110,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
validateNextMessageAsync(unvalidated); validateNextMessageAsync(unvalidated);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -145,7 +144,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Group removed before validation"); LOG.info("Group removed before validation");
validateNextMessageAsync(unvalidated); validateNextMessageAsync(unvalidated);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -166,7 +165,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
deliverNextPendingMessageAsync(pending); deliverNextPendingMessageAsync(pending);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -232,7 +231,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Group removed before delivery"); LOG.info("Group removed before delivery");
deliverNextPendingMessageAsync(pending); deliverNextPendingMessageAsync(pending);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -253,7 +252,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
storeMessageContextAsync(m, g.getClientId(), storeMessageContextAsync(m, g.getClientId(),
g.getMajorVersion(), context); g.getMajorVersion(), context);
} catch (InvalidMessageException e) { } catch (InvalidMessageException e) {
logException(LOG, INFO, e); if (LOG.isLoggable(INFO))
LOG.log(INFO, e.toString(), e);
Queue<MessageId> invalidate = new LinkedList<>(); Queue<MessageId> invalidate = new LinkedList<>();
invalidate.add(m.getId()); invalidate.add(m.getId());
invalidateNextMessageAsync(invalidate); invalidateNextMessageAsync(invalidate);
@@ -326,7 +326,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} catch (NoSuchGroupException e) { } catch (NoSuchGroupException e) {
LOG.info("Group removed during validation"); LOG.info("Group removed during validation");
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -377,7 +377,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} }
shareNextMessageAsync(toShare); shareNextMessageAsync(toShare);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -412,7 +412,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Group removed before sharing"); LOG.info("Group removed before sharing");
shareNextMessageAsync(toShare); shareNextMessageAsync(toShare);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -440,7 +440,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
LOG.info("Message removed before invalidation"); LOG.info("Message removed before invalidation");
invalidateNextMessageAsync(invalidate); invalidateNextMessageAsync(invalidate);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -492,7 +492,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
} catch (NoSuchGroupException e) { } catch (NoSuchGroupException e) {
LOG.info("Group removed before validation"); LOG.info("Group removed before validation");
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -13,7 +13,6 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -50,7 +49,7 @@ class LinuxSecureRandomProvider extends AbstractSecureRandomProvider {
out.close(); out.close();
} catch (IOException e) { } catch (IOException e) {
// On some devices /dev/urandom isn't writable - this isn't fatal // On some devices /dev/urandom isn't writable - this isn't fatal
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -10,7 +10,6 @@ import java.security.SecureRandomSpi;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
public class LinuxSecureRandomSpi extends SecureRandomSpi { public class LinuxSecureRandomSpi extends SecureRandomSpi {
@@ -40,7 +39,7 @@ public class LinuxSecureRandomSpi extends SecureRandomSpi {
out.close(); out.close();
} catch (IOException e) { } catch (IOException e) {
// On some devices /dev/urandom isn't writable - this isn't fatal // On some devices /dev/urandom isn't writable - this isn't fatal
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -36,7 +36,6 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC
import static org.briarproject.bramble.api.transport.TransportConstants.PROTOCOL_VERSION; import static org.briarproject.bramble.api.transport.TransportConstants.PROTOCOL_VERSION;
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
import static org.briarproject.bramble.util.ByteUtils.MAX_32_BIT_UNSIGNED; import static org.briarproject.bramble.util.ByteUtils.MAX_32_BIT_UNSIGNED;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -170,7 +169,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
db.endTransaction(txn); db.endTransaction(txn);
} }
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -28,7 +28,6 @@ import javax.annotation.concurrent.ThreadSafe;
import static com.sun.jna.Library.OPTION_FUNCTION_MAPPER; import static com.sun.jna.Library.OPTION_FUNCTION_MAPPER;
import static com.sun.jna.Library.OPTION_TYPE_MAPPER; import static com.sun.jna.Library.OPTION_TYPE_MAPPER;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@ThreadSafe @ThreadSafe
@NotNullByDefault @NotNullByDefault
@@ -142,7 +141,7 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
user32.DispatchMessage(msg); user32.DispatchMessage(msg);
} }
} catch (UnsatisfiedLinkError e) { } catch (UnsatisfiedLinkError e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }

View File

@@ -19,7 +19,6 @@ import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier; import javax.microedition.io.StreamConnectionNotifier;
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.StringUtils.isValidMac; import static org.briarproject.bramble.util.StringUtils.isValidMac;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -86,7 +85,7 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
try { try {
if (ss != null) ss.close(); if (ss != null) ss.close();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -27,7 +27,6 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static jssc.SerialPort.PURGE_RXCLEAR; import static jssc.SerialPort.PURGE_RXCLEAR;
import static jssc.SerialPort.PURGE_TXCLEAR; import static jssc.SerialPort.PURGE_TXCLEAR;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -137,7 +136,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
try { try {
if (port != null) port.closePort(); if (port != null) port.closePort();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -328,7 +327,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
} }
} }
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
@@ -395,7 +394,8 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
try { try {
answer(); answer();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -23,7 +23,6 @@ import java.util.logging.Logger;
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 org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -82,7 +81,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
running = true; running = true;
return; return;
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
throw new PluginException(); throw new PluginException();
@@ -95,7 +94,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
try { try {
modem.stop(); modem.stop();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
} }
@@ -132,7 +131,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
LOG.info("Initialised modem on " + portName); LOG.info("Initialised modem on " + portName);
return true; return true;
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
} }
running = false; running = false;
@@ -158,7 +157,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
try { try {
if (!modem.dial(number)) return null; if (!modem.dial(number)) return null;
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
resetModem(); resetModem();
return null; return null;
} }
@@ -210,7 +209,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
try { try {
modem.hangUp(); modem.hangUp();
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
exception = true; exception = true;
} }
if (exception) resetModem(); if (exception) resetModem();

View File

@@ -4,4 +4,3 @@ build
local.properties local.properties
.settings .settings
src/main/assets/*.zip src/main/assets/*.zip
src/main/res/values-iw

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Ebene_1"
x="0px"
y="0px"
viewBox="0 0 24 24"
xml:space="preserve"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="notification_ongoing.svg"
width="24"
height="24"><metadata
id="metadata61"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs59" /><sodipodi:namedview
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview57"
showgrid="false"
inkscape:zoom="11.466748"
inkscape:cx="-4.790356"
inkscape:cy="17.536496"
inkscape:window-x="1442"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="Ebene_1"
units="px" /><style
type="text/css"
id="style3">
.st0{fill:#FFFFFF;}
.st1{display:none;fill:#87C214;}
.st2{fill:#87C214;}
.st3{display:none;fill:#FFFFFF;}
.st4{fill:#95D220;}
.st5{display:none;fill:#95D220;}
</style><path
style="fill:#ffffff;stroke-width:0.07272727"
d="M 12,0 A 12,12 0 0 0 0,12 12,12 0 0 0 12,24 12,12 0 0 0 24,12 12,12 0 0 0 12,0 Z M 8.1454545,3.4764204 h 0.6036931 c 0.7054546,0 1.2872164,0.5817614 1.2872164,1.287216 V 6.4 H 6.8582386 V 4.7636364 c 0,-0.7054546 0.5817614,-1.287216 1.2872159,-1.287216 z m 7.0545455,0 h 0.603693 c 0.712727,0 1.287216,0.5817614 1.287216,1.287216 V 13.454545 H 13.912784 V 4.7636364 c 0,-0.7054546 0.581761,-1.287216 1.287216,-1.287216 z M 4.7127841,6.9090909 H 13.403693 V 10.087216 H 4.7127841 c -0.7127273,0 -1.287358,-0.5817618 -1.287358,-1.2872156 V 8.1963069 c 0,-0.7127273 0.5819034,-1.287216 1.287358,-1.287216 z m 12.8872159,0 h 1.636364 c 0.705454,0 1.279943,0.5817615 1.287216,1.287216 v 0.6036935 c 0,0.7127269 -0.581762,1.2872156 -1.287216,1.2872156 H 17.6 Z M 6.8582386,10.596307 h 3.1781254 v 8.690909 c 0,0.705454 -0.5817618,1.287358 -1.2872164,1.287358 H 8.1454545 c -0.7127272,0 -1.2872159,-0.581904 -1.2872159,-1.287358 z m -2.1454545,3.367329 h 1.6363636 v 3.178125 H 4.7127841 c -0.7127273,0 -1.287358,-0.581761 -1.287358,-1.287216 v -0.603693 c 0,-0.712727 0.5819034,-1.287216 1.287358,-1.287216 z m 5.8326709,0 h 8.690909 c 0.705454,0 1.279943,0.581761 1.287216,1.287216 v 0.603693 c 0,0.705455 -0.581762,1.287216 -1.287216,1.287216 h -8.690909 z m 3.367329,3.687216 h 3.178125 v 1.636364 c 0,0.705454 -0.581761,1.287358 -1.287216,1.287358 H 15.2 c -0.705455,0 -1.287216,-0.581904 -1.287216,-1.287358 z"
id="circle7"
inkscape:connector-curvature="0" /></svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Ebene_1"
x="0px"
y="0px"
viewBox="0 0 24 24"
xml:space="preserve"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="notification_reminder.svg"
width="24"
height="24"><metadata
id="metadata61"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs59" /><sodipodi:namedview
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview57"
showgrid="false"
inkscape:zoom="32.43286"
inkscape:cx="6.4172501"
inkscape:cy="12.231457"
inkscape:window-x="1442"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="Ebene_1"
units="px" /><style
type="text/css"
id="style3">
.st0{fill:#FFFFFF;}
.st1{display:none;fill:#87C214;}
.st2{fill:#87C214;}
.st3{display:none;fill:#FFFFFF;}
.st4{fill:#95D220;}
.st5{display:none;fill:#95D220;}
</style><path
style="display:inline;fill:#ffffff;stroke-width:0.07272727"
d="M 12 0 A 12 12 0 0 0 4.875 2.3613281 L 6.9316406 4.4160156 C 7.0875805 3.8805807 7.5639651 3.4765625 8.1464844 3.4765625 L 8.7480469 3.4765625 C 9.4535014 3.4765625 10.035156 4.0582174 10.035156 4.7636719 L 10.035156 6.4003906 L 8.9140625 6.4003906 L 9.4238281 6.9101562 L 13.404297 6.9101562 L 13.404297 10.085938 L 12.601562 10.085938 L 13.914062 11.398438 L 13.914062 4.7636719 C 13.914062 4.0582174 14.495717 3.4765625 15.201172 3.4765625 L 15.802734 3.4765625 C 16.515461 3.4765625 17.089844 4.0582174 17.089844 4.7636719 L 17.089844 13.455078 L 15.96875 13.455078 L 16.478516 13.964844 L 19.236328 13.964844 C 19.941782 13.964844 20.516165 14.546498 20.523438 15.251953 L 20.523438 15.853516 C 20.523438 16.436036 20.119418 16.91242 19.583984 17.068359 L 21.638672 19.125 A 12 12 0 0 0 24 12 A 12 12 0 0 0 12 0 z M 1.2617188 1.3632812 L 0 2.6269531 L 2.3125 4.9472656 A 12 12 0 0 0 0 12 A 12 12 0 0 0 12 24 A 12 12 0 0 0 19.027344 21.707031 L 21.314453 24 L 22.576172 22.734375 L 2.7519531 2.8554688 L 1.9863281 2.0898438 L 1.2617188 1.3632812 z M 17.599609 6.9101562 L 19.236328 6.9101562 C 19.941782 6.9101562 20.516165 7.4918111 20.523438 8.1972656 L 20.523438 8.7988281 C 20.523438 9.511555 19.941782 10.085937 19.236328 10.085938 L 17.599609 10.085938 L 17.599609 6.9101562 z M 4.359375 6.9980469 L 7.4394531 10.085938 L 4.7128906 10.085938 C 4.0001632 10.085938 3.4257813 9.504282 3.4257812 8.7988281 L 3.4257812 8.1972656 C 3.4257812 7.6133228 3.8294199 7.1540656 4.359375 6.9980469 z M 6.859375 10.595703 L 7.9472656 10.595703 L 10.035156 12.689453 L 10.035156 19.287109 C 10.035156 19.992562 9.4535014 20.574219 8.7480469 20.574219 L 8.1464844 20.574219 C 7.4337573 20.574219 6.859375 19.992563 6.859375 19.287109 L 6.859375 10.595703 z M 4.7128906 13.964844 L 6.3496094 13.964844 L 6.3496094 17.140625 L 4.7128906 17.140625 C 4.0001632 17.140625 3.4257813 16.558971 3.4257812 15.853516 L 3.4257812 15.251953 C 3.4257812 14.539226 4.007436 13.964844 4.7128906 13.964844 z M 10.544922 13.964844 L 11.306641 13.964844 L 14.474609 17.140625 L 10.544922 17.140625 L 10.544922 13.964844 z M 13.914062 17.650391 L 14.982422 17.650391 L 16.992188 19.666016 C 16.827053 20.182975 16.371277 20.574219 15.802734 20.574219 L 15.201172 20.574219 C 14.495717 20.574219 13.914063 19.992563 13.914062 19.287109 L 13.914062 17.650391 z "
id="circle7" /></svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -22,7 +22,7 @@ dependencies {
implementation "com.android.support:support-annotations:$supportVersion" implementation "com.android.support:support-annotations:$supportVersion"
implementation 'com.android.support.constraint:constraint-layout:1.1.0' implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation('ch.acra:acra:4.9.1') { implementation('ch.acra:acra:4.8.5') {
exclude module: 'support-v4' exclude module: 'support-v4'
exclude module: 'support-annotations' exclude module: 'support-annotations'
} }
@@ -61,7 +61,7 @@ dependencyVerification {
'android.arch.lifecycle:viewmodel:1.1.0:viewmodel-1.1.0.aar:6407c93a5ea9850661dca42a0068d6f3deccefd7228ee69bae1c35d70cbc2557', 'android.arch.lifecycle:viewmodel:1.1.0:viewmodel-1.1.0.aar:6407c93a5ea9850661dca42a0068d6f3deccefd7228ee69bae1c35d70cbc2557',
'backport-util-concurrent:backport-util-concurrent:3.1:backport-util-concurrent-3.1.jar:f5759b7fcdfc83a525a036deedcbd32e5b536b625ebc282426f16ca137eb5902', 'backport-util-concurrent:backport-util-concurrent:3.1:backport-util-concurrent-3.1.jar:f5759b7fcdfc83a525a036deedcbd32e5b536b625ebc282426f16ca137eb5902',
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861', 'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
'ch.acra:acra:4.9.1:acra-4.9.1.aar:d2762968c448757a7d6acc9f141881d9632f664988e9723ece33b5f7c79f3bc9', 'ch.acra:acra:4.8.5:acra-4.8.5.aar:afd5b28934d5166b55f261c85685ad59e8a4ebe9ca1960906afaa8c76d8dc9eb',
'classworlds:classworlds:1.1-alpha-2:classworlds-1.1-alpha-2.jar:2bf4e59f3acd106fea6145a9a88fe8956509f8b9c0fdd11eb96fee757269e3f3', 'classworlds:classworlds:1.1-alpha-2:classworlds-1.1-alpha-2.jar:2bf4e59f3acd106fea6145a9a88fe8956509f8b9c0fdd11eb96fee757269e3f3',
'com.almworks.sqlite4java:sqlite4java:0.282:sqlite4java-0.282.jar:9e1d8dd83ca6003f841e3af878ce2dc7c22497493a7bb6d1b62ec1b0d0a83c05', 'com.almworks.sqlite4java:sqlite4java:0.282:sqlite4java-0.282.jar:9e1d8dd83ca6003f841e3af878ce2dc7c22497493a7bb6d1b62ec1b0d0a83c05',
'com.android.support.constraint:constraint-layout-solver:1.1.0:constraint-layout-solver-1.1.0.jar:fcb4c7d705754ca3d69b1b2c3caf445a425599fda8caabbcf855d98ea0663e4e', 'com.android.support.constraint:constraint-layout-solver:1.1.0:constraint-layout-solver-1.1.0.jar:fcb4c7d705754ca3d69b1b2c3caf445a425599fda8caabbcf855d98ea0663e4e',
@@ -82,32 +82,32 @@ dependencyVerification {
'com.android.support:support-v4:27.1.1:support-v4-27.1.1.aar:4f41dfc3e89f2738e45c86264a85c0934d055ee8ebe2020e23c97f303b80a48b', 'com.android.support:support-v4:27.1.1:support-v4-27.1.1.aar:4f41dfc3e89f2738e45c86264a85c0934d055ee8ebe2020e23c97f303b80a48b',
'com.android.support:support-vector-drawable:27.1.1:support-vector-drawable-27.1.1.aar:1c0f421114cf4627cf208776d6eb4f76340c78b7e96fe6e12b3e6eb950caf1b9', 'com.android.support:support-vector-drawable:27.1.1:support-vector-drawable-27.1.1.aar:1c0f421114cf4627cf208776d6eb4f76340c78b7e96fe6e12b3e6eb950caf1b9',
'com.android.support:transition:27.1.1:transition-27.1.1.aar:c0765b2f3c78696567ec5b3f519d22da1e3df11ac994625adf4bb4dc571caacc', 'com.android.support:transition:27.1.1:transition-27.1.1.aar:c0765b2f3c78696567ec5b3f519d22da1e3df11ac994625adf4bb4dc571caacc',
'com.android.tools.analytics-library:protos:26.1.3:protos-26.1.3.jar:818c9f256f141d9dafec03a1aa2b94d240b2c140acfd7ee31a8b3e6c2b9479e3', 'com.android.tools.analytics-library:protos:26.1.2:protos-26.1.2.jar:52672a0b42b572a06aecc3535d5068eb46c0e15d129b9f1085d3c16a1da5cdbb',
'com.android.tools.analytics-library:shared:26.1.3:shared-26.1.3.jar:7110706c7ada96c8b6f5ca80c478291bc7899d46277de2c48527e045442401a3', 'com.android.tools.analytics-library:shared:26.1.2:shared-26.1.2.jar:5c7e0eda18c6f87feeb83628c707e8aaa3298b41fb72e38efe31ad1675f9e8e9',
'com.android.tools.analytics-library:tracker:26.1.3:tracker-26.1.3.jar:4155424bf2ce4872da83332579a1707252bc66cbd77c5144fdc4483d0f2e1418', 'com.android.tools.analytics-library:tracker:26.1.2:tracker-26.1.2.jar:06f97aa0adf44ffb06f8681c6a79d9be153a08f61d21eddc42b8d3db96df4282',
'com.android.tools.build:apksig:3.1.3:apksig-3.1.3.jar:7e1f8e675a6e768e5b56405e41d6c3cc05befe62e601b04177de1029902c9c89', 'com.android.tools.build:apksig:3.1.2:apksig-3.1.2.jar:40696a4559124d1d57873d208857eee059d48859239d569c7d18374ac644a8be',
'com.android.tools.build:builder-model:3.1.3:builder-model-3.1.3.jar:06ad1c422d679fc698451479cb40ba863849d67bfd1de23f6d2c16d78b024b0b', 'com.android.tools.build:builder-model:3.1.2:builder-model-3.1.2.jar:d49bfa2a135c9562b6ca7aa4342036cfa1582c7074c2d1d93d1dae8b3a134e17',
'com.android.tools.build:builder-test-api:3.1.3:builder-test-api-3.1.3.jar:4d989f780436794f0f8b2f50e9e079b786571eac90f26c208ab2ae6d4012f389', 'com.android.tools.build:builder-test-api:3.1.2:builder-test-api-3.1.2.jar:dfe2a50b740d41b11189101062434d4283d18647e89a492ad51710c719363e9f',
'com.android.tools.build:builder:3.1.3:builder-3.1.3.jar:8a1092012c89d0ec1ee2eff09c5708c71ef4482a6862df8d3a44a67fccace01c', 'com.android.tools.build:builder:3.1.2:builder-3.1.2.jar:b60f825a42e2efe8433619fbc759f3d9effecab718279048d36881188ceb1d14',
'com.android.tools.build:gradle-api:3.1.3:gradle-api-3.1.3.jar:01e4df521456aef66514336f1d492346730dd1fb8f6433a89f62da834941ed72', 'com.android.tools.build:gradle-api:3.1.2:gradle-api-3.1.2.jar:e58bcc5b893e4583ab0f5c8ef89c4dbcce202b405a9d7fcc116d21e5357d4893',
'com.android.tools.build:manifest-merger:26.1.3:manifest-merger-26.1.3.jar:1e4fc7e932adb4607082409800e5e6fccb42e6c5360ae5990094bf522f3ada55', 'com.android.tools.build:manifest-merger:26.1.2:manifest-merger-26.1.2.jar:9c61c27ea5266573107b954acf1216d398f4d7e7ae6fad6409d6b2b767eb091c',
'com.android.tools.ddms:ddmlib:26.1.3:ddmlib-26.1.3.jar:c54931cd68df5d1ea2923b3b320eae47cd2307a5a916bb8674c0acf93cd1d3cd', 'com.android.tools.ddms:ddmlib:26.1.2:ddmlib-26.1.2.jar:18a2a5fbef36882f07d03c2b9e59eba05cf8248177bf5cbff736e4b582804c44',
'com.android.tools.external.com-intellij:intellij-core:26.1.3:intellij-core-26.1.3.jar:af67f5535fef2e1a28b1007a4acb8c5deb6a1e33b8afe7b11d012c9e778ebcec', 'com.android.tools.external.com-intellij:intellij-core:26.1.2:intellij-core-26.1.2.jar:37c5acf279f1ae3e85b1a5be3c9f15f43bde7b08f978eefefffb9c4035760c52',
'com.android.tools.external.com-intellij:kotlin-compiler:26.1.3:kotlin-compiler-26.1.3.jar:c746d2859dc11cc05c84b692b3498d3a621e0929511f8440ee009c6557838fd4', 'com.android.tools.external.com-intellij:kotlin-compiler:26.1.2:kotlin-compiler-26.1.2.jar:152df0bee7580326c77316b669a9d96e3b09efb1d45f545dce4147271b0b8944',
'com.android.tools.external.org-jetbrains:uast:26.1.3:uast-26.1.3.jar:3f3f6651d0c7685a77ecb22e9c82d6b49fdf24322c17360768dc530678f43265', 'com.android.tools.external.org-jetbrains:uast:26.1.2:uast-26.1.2.jar:02d39582206d3f5fc0a6cb18bfd9e8b9f9c1acb805ec6dac08b4e3a56849d279',
'com.android.tools.layoutlib:layoutlib-api:26.1.3:layoutlib-api-26.1.3.jar:10bc73ce706c45629872d6a999dbe12116df64e24f47ff93b7b13121ff57b4b0', 'com.android.tools.layoutlib:layoutlib-api:26.1.2:layoutlib-api-26.1.2.jar:20220039fcc7d799f928153beff862e704457c0f55ab44258f3745ebeb662b4f',
'com.android.tools.lint:lint-api:26.1.3:lint-api-26.1.3.jar:6f97323f9af8deda86278717885b5c927f3766757db89709f52d11d42b6fb751', 'com.android.tools.lint:lint-api:26.1.2:lint-api-26.1.2.jar:e1d5b62b870a7c566e9877a6b96b27784a4d713f8caa07fdcb4705d47a40a1d9',
'com.android.tools.lint:lint-checks:26.1.3:lint-checks-26.1.3.jar:73c3d53784c9ce3e6d5968506581918e0179645d20809927ca4a001dd766b001', 'com.android.tools.lint:lint-checks:26.1.2:lint-checks-26.1.2.jar:211e2afd58504372385d71b1e5be982c2b5121ab6fee1c04ddabeb75a8729e07',
'com.android.tools.lint:lint-gradle-api:26.1.3:lint-gradle-api-26.1.3.jar:7ca3c4866ec21dc21d53a9d86f752b77ace6f6c610a0c9dc877313856c733d9d', 'com.android.tools.lint:lint-gradle-api:26.1.2:lint-gradle-api-26.1.2.jar:71284f2a8b03c3e55c94511c9eb36f8184fbb85324325fc6b78abf5183f03d90',
'com.android.tools.lint:lint-gradle:26.1.3:lint-gradle-26.1.3.jar:db0c354b8f4b6f6637e31f91c564785a59ff896325331fcbc3de7458e0b6c067', 'com.android.tools.lint:lint-gradle:26.1.2:lint-gradle-26.1.2.jar:855f0c82b7fc690df1b7319c0774f7517f7f8f5dd4eee1f6077dcf50e07c6240',
'com.android.tools.lint:lint-kotlin:26.1.3:lint-kotlin-26.1.3.jar:94e2b0f4565a241561cfb8fc1222bb3f132a3b98d2a90421dbb72ee8358e7d68', 'com.android.tools.lint:lint-kotlin:26.1.2:lint-kotlin-26.1.2.jar:1e591f70bcbbc11569720a9bbcca2bc1f3d4f789f01f40f642848d920643d484',
'com.android.tools.lint:lint:26.1.3:lint-26.1.3.jar:8d5f32c989c6d191d712e90ad3ca2d1c409313599551d04d834caa44d26c78df', 'com.android.tools.lint:lint:26.1.2:lint-26.1.2.jar:93736c62e9f1976998c2b4aa716aea0734cdb162d05502f4af7292654aedb182',
'com.android.tools:annotations:26.1.3:annotations-26.1.3.jar:c950430b24ac5d58fc97e7283b8f0115f99587e76e08b4e1e2aaa780f2d77323', 'com.android.tools:annotations:26.1.2:annotations-26.1.2.jar:72773dcaf5c4ccca828e3c8467f1b78a8a00b3cc5f8ad1aab88fcf9379928018',
'com.android.tools:common:26.1.3:common-26.1.3.jar:7c31a90581a148ab219f615a59667f0dded7fa39b248529784474da3c2274ef2', 'com.android.tools:common:26.1.2:common-26.1.2.jar:ea4320f0c17dcbc4491896bb705c4d25ec08bd62ef02ab0579fe154e75e788e6',
'com.android.tools:dvlib:26.1.3:dvlib-26.1.3.jar:0cae87906f53d3f1088366a916ed180a7312b6d9919b90797f238875c8492855', 'com.android.tools:dvlib:26.1.2:dvlib-26.1.2.jar:1187aa4fb666595c96c4deb6bc0e0f4b7e396bde9f6243330b49a232946130ea',
'com.android.tools:repository:26.1.3:repository-26.1.3.jar:52d4539cc68db91b261e2a33b2c8206b26e05539078758dc28cfb3854adb4f59', 'com.android.tools:repository:26.1.2:repository-26.1.2.jar:8b86e512ad6d32bd76989451eefe2b271f5efce6d4d65ecb173afaf14606e01a',
'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1', 'com.android.tools:sdk-common:26.1.2:sdk-common-26.1.2.jar:23584720a60a21cdcb5b1ec10269e3013789d6805d153cc696c39ec7ce251896',
'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b', 'com.android.tools:sdklib:26.1.2:sdklib-26.1.2.jar:d3870fafc59ab8efa70d3f9649f40ee299c8ec5b58377b06e8853d7272a5bf4e',
'com.github.bumptech.glide:glide:3.8.0:glide-3.8.0.jar:750d9e7b940dc0ee48f8680623b55d46e14e8727acc922d7b156e57e7c549655', 'com.github.bumptech.glide:glide:3.8.0:glide-3.8.0.jar:750d9e7b940dc0ee48f8680623b55d46e14e8727acc922d7b156e57e7c549655',
'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1:accessibility-test-framework-2.1.jar:7b0aa6ed7553597ce0610684a9f7eca8021eee218f2e2f427c04a7fbf5f920bd', 'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1:accessibility-test-framework-2.1.jar:7b0aa6ed7553597ce0610684a9f7eca8021eee218f2e2f427c04a7fbf5f920bd',
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed', 'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
@@ -238,16 +238,15 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 26 targetSdkVersion 26
versionCode 10011 versionCode 10005
versionName "1.0.11" versionName "1.0.5"
applicationId "org.briarproject.briar.android" applicationId "org.briarproject.briar.android"
resValue "string", "app_package", "org.briarproject.briar.android" resValue "string", "app_package", "org.briarproject.briar.android"
resValue "string", "app_name", "Briar" resValue "string", "app_name", "Briar"
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)
buildConfigField "Long", "BuildTimestamp", buildConfigField "Long", "BuildTimestamp",
"${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L" "${getStdout(['git', 'log', '-n', '1', '--format=%ct'], 0)}000L"
} }
buildTypes { buildTypes {
@@ -261,7 +260,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
} }
release { release {
shrinkResources false shrinkResources true
minifyEnabled true minifyEnabled true
crunchPngs false crunchPngs false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
@@ -285,46 +284,3 @@ android {
warning 'ExtraTranslation' warning 'ExtraTranslation'
} }
} }
task verifyTranslations {
doLast {
def file = project.file("src/main/res/values/arrays.xml")
def arrays = new XmlParser().parse(file)
def lc = arrays.children().find { it.@name == "pref_language_values" }
def translations = []
lc.children().each { value -> translations.add(value.text()) }
def folders = ["default", "en-US"]
project.file("src/main/res").eachDir { dir ->
if (dir.name.startsWith("values-") && !dir.name.endsWith("night")) {
folders.add(dir.name.substring(7).replace("-r", "-"))
}
}
folders.each { n ->
if (!translations.remove(n) && n != 'iw') {
throw new GradleException("Translation " + n + " is missing in $file")
}
}
if (translations.size() != 0)
throw new GradleException("Translations\n" + translations.join("\n")
+ "\nhave no matching value folder")
// Some devices use iw instead of he for hebrew
def hebrew_legacy = project.file("src/main/res/values-iw")
def hebrew = project.file("src/main/res/values-he")
// Copy values-he to values-iw
if (hebrew.exists()) {
hebrew_legacy.mkdir()
copy {
from hebrew.getAbsolutePath()
into hebrew_legacy.getAbsolutePath()
}
}
}
}
project.afterEvaluate {
preBuild.dependsOn.add(verifyTranslations)
}

View File

@@ -14,7 +14,6 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> <uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<application <application
@@ -25,14 +24,6 @@
android:logo="@mipmap/ic_launcher_round" android:logo="@mipmap/ic_launcher_round"
android:theme="@style/BriarTheme"> android:theme="@style/BriarTheme">
<receiver
android:name="org.briarproject.briar.android.BootReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service <service
android:name="org.briarproject.briar.android.BriarService" android:name="org.briarproject.briar.android.BriarService"
android:exported="false"> android:exported="false">
@@ -53,6 +44,7 @@
android:finishOnTaskLaunch="true" android:finishOnTaskLaunch="true"
android:label="@string/crash_report_title" android:label="@string/crash_report_title"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:process=":briar_error_handler"
android:theme="@style/BriarTheme.NoActionBar" android:theme="@style/BriarTheme.NoActionBar"
android:windowSoftInputMode="stateHidden"> android:windowSoftInputMode="stateHidden">
</activity> </activity>
@@ -309,7 +301,7 @@
</activity> </activity>
<activity <activity
android:name="org.briarproject.briar.android.keyagreement.ContactExchangeActivity" android:name="org.briarproject.briar.android.keyagreement.KeyAgreementActivity"
android:label="@string/add_contact_title" android:label="@string/add_contact_title"
android:theme="@style/BriarTheme.NoActionBar" android:theme="@style/BriarTheme.NoActionBar"
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"> android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity">

View File

@@ -150,8 +150,6 @@ public interface AndroidComponent
@IoExecutor @IoExecutor
Executor ioExecutor(); Executor ioExecutor();
void inject(BootReceiver briarService);
void inject(BriarService briarService); void inject(BriarService briarService);
void inject(BriarReportSender briarReportSender); void inject(BriarReportSender briarReportSender);

View File

@@ -70,7 +70,6 @@ import static android.os.Build.VERSION.SDK_INT;
import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE; import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE;
import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL; import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL;
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.briar.android.activity.BriarActivity.GROUP_ID; import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID; import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_BLOGS; import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.INTENT_BLOGS;
@@ -85,6 +84,13 @@ import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_
class AndroidNotificationManagerImpl implements AndroidNotificationManager, class AndroidNotificationManagerImpl implements AndroidNotificationManager,
Service, EventListener { Service, EventListener {
// Notification IDs
private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3;
private static final int GROUP_MESSAGE_NOTIFICATION_ID = 4;
private static final int FORUM_POST_NOTIFICATION_ID = 5;
private static final int BLOG_POST_NOTIFICATION_ID = 6;
private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 7;
private static final long SOUND_DELAY = TimeUnit.SECONDS.toMillis(2); private static final long SOUND_DELAY = TimeUnit.SECONDS.toMillis(2);
private static final Logger LOG = private static final Logger LOG =
@@ -259,7 +265,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
try { try {
settings = settingsManager.getSettings(SETTINGS_NAMESPACE); settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -20,17 +20,16 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
import org.briarproject.bramble.api.reporting.DevConfig; import org.briarproject.bramble.api.reporting.DevConfig;
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.LocationUtils; import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.api.system.Scheduler;
import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory; import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory;
import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory; import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory;
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
import org.briarproject.bramble.plugin.tor.TorPluginFactory; import org.briarproject.bramble.plugin.tor.TorPluginFactory;
import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.bramble.util.StringUtils; import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.android.DozeWatchdog; import org.briarproject.briar.api.android.DozeWatchdog;
import org.briarproject.briar.api.android.ReferenceManager;
import org.briarproject.briar.api.android.ScreenFilterMonitor; import org.briarproject.briar.api.android.ScreenFilterMonitor;
import java.io.File; import java.io.File;
@@ -98,15 +97,14 @@ public class AppModule {
@Scheduler ScheduledExecutorService scheduler, @Scheduler ScheduledExecutorService scheduler,
AndroidExecutor androidExecutor, SecureRandom random, AndroidExecutor androidExecutor, SecureRandom random,
SocketFactory torSocketFactory, BackoffFactory backoffFactory, SocketFactory torSocketFactory, BackoffFactory backoffFactory,
Application app, LocationUtils locationUtils, EventBus eventBus, Application app, LocationUtils locationUtils, EventBus eventBus) {
CircumventionProvider circumventionProvider, Clock clock) {
Context appContext = app.getApplicationContext(); Context appContext = app.getApplicationContext();
DuplexPluginFactory bluetooth = DuplexPluginFactory bluetooth =
new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor, new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor,
appContext, random, eventBus, backoffFactory); appContext, random, eventBus, backoffFactory);
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler, DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler,
appContext, locationUtils, eventBus, torSocketFactory, appContext, locationUtils, eventBus,
backoffFactory, circumventionProvider, clock); torSocketFactory, backoffFactory);
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
scheduler, backoffFactory, appContext); scheduler, backoffFactory, appContext);
Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan); Collection<DuplexPluginFactory> duplex = asList(bluetooth, tor, lan);
@@ -165,6 +163,12 @@ public class AppModule {
return app.getSharedPreferences("db", MODE_PRIVATE); return app.getSharedPreferences("db", MODE_PRIVATE);
} }
@Provides
@Singleton
ReferenceManager provideReferenceManager() {
return new ReferenceManagerImpl();
}
@Provides @Provides
@Singleton @Singleton
AndroidNotificationManager provideAndroidNotificationManager( AndroidNotificationManager provideAndroidNotificationManager(

View File

@@ -1,83 +0,0 @@
package org.briarproject.briar.android;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.briar.R;
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
import javax.inject.Inject;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.Intent.ACTION_BOOT_COMPLETED;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.Build.VERSION.SDK_INT;
import static android.support.v4.app.NotificationCompat.PRIORITY_LOW;
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER;
import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_NOTIFICATION_ID;
public class BootReceiver extends BroadcastReceiver {
@Inject
DatabaseConfig databaseConfig;
@Override
public void onReceive(Context ctx, Intent intent) {
if (!FEATURE_FLAG_SIGN_IN_REMINDER) return;
AndroidComponent applicationComponent =
((BriarApplication) ctx.getApplicationContext())
.getApplicationComponent();
applicationComponent.inject(this);
String action = intent.getAction();
if (action != null && action.equals(ACTION_BOOT_COMPLETED)) {
if (databaseConfig.databaseExists()) {
showSignInNotification(ctx);
}
}
}
private void showSignInNotification(Context ctx) {
NotificationManager nm = (NotificationManager)
ctx.getSystemService(NOTIFICATION_SERVICE);
if (nm == null) return;
if (SDK_INT >= 26) {
NotificationChannel channel =
new NotificationChannel(REMINDER_CHANNEL_ID, ctx.getString(
R.string.reminder_notification_channel_title),
IMPORTANCE_LOW);
channel.setLockscreenVisibility(VISIBILITY_SECRET);
nm.createNotificationChannel(channel);
}
NotificationCompat.Builder b =
new NotificationCompat.Builder(ctx, REMINDER_CHANNEL_ID);
b.setSmallIcon(R.drawable.notification_reminder);
b.setColor(ContextCompat.getColor(ctx, R.color.briar_primary));
b.setContentTitle(ctx.getText(R.string.reminder_notification_title));
b.setContentText(ctx.getText(R.string.reminder_notification_text));
b.setAutoCancel(true);
b.setWhen(0); // Don't show the time
b.setPriority(PRIORITY_LOW);
Intent i = new Intent(ctx, NavDrawerActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
b.setContentIntent(PendingIntent.getActivity(ctx, 0, i, 0));
nm.notify(REMINDER_NOTIFICATION_ID, b.build());
}
}

View File

@@ -2,12 +2,9 @@ package org.briarproject.briar.android;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.StrictMode; import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy; import android.os.StrictMode.ThreadPolicy;
import android.os.StrictMode.VmPolicy; import android.os.StrictMode.VmPolicy;
import android.preference.PreferenceManager;
import org.acra.ACRA; import org.acra.ACRA;
import org.acra.ReportingInteractionMode; import org.acra.ReportingInteractionMode;
@@ -19,14 +16,12 @@ import org.briarproject.briar.android.logging.CachingLogHandler;
import org.briarproject.briar.android.reporting.BriarReportPrimer; import org.briarproject.briar.android.reporting.BriarReportPrimer;
import org.briarproject.briar.android.reporting.BriarReportSenderFactory; import org.briarproject.briar.android.reporting.BriarReportSenderFactory;
import org.briarproject.briar.android.reporting.DevReportActivity; import org.briarproject.briar.android.reporting.DevReportActivity;
import org.briarproject.briar.android.util.UiUtils;
import java.util.Collection; import java.util.Collection;
import java.util.logging.Handler; import java.util.logging.Handler;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static org.acra.ReportField.ANDROID_VERSION; import static org.acra.ReportField.ANDROID_VERSION;
import static org.acra.ReportField.APP_VERSION_CODE; import static org.acra.ReportField.APP_VERSION_CODE;
@@ -80,13 +75,7 @@ public class BriarApplicationImpl extends Application
@Override @Override
protected void attachBaseContext(Context base) { protected void attachBaseContext(Context base) {
SharedPreferences prefs = super.attachBaseContext(base);
PreferenceManager.getDefaultSharedPreferences(base);
// Loading the language needs to be done here.
Localizer.initialize(prefs);
super.attachBaseContext(
Localizer.getInstance().setLocale(base));
setTheme(base, prefs);
ACRA.init(this); ACRA.init(this);
} }
@@ -104,7 +93,7 @@ public class BriarApplicationImpl extends Application
} }
} }
rootLogger.addHandler(logHandler); rootLogger.addHandler(logHandler);
rootLogger.setLevel(IS_DEBUG_BUILD || IS_BETA_BUILD ? FINE : INFO); rootLogger.setLevel(INFO);
LOG.info("Created"); LOG.info("Created");
@@ -117,24 +106,6 @@ public class BriarApplicationImpl extends Application
BrambleCoreModule.initEagerSingletons(applicationComponent); BrambleCoreModule.initEagerSingletons(applicationComponent);
BriarCoreModule.initEagerSingletons(applicationComponent); BriarCoreModule.initEagerSingletons(applicationComponent);
AndroidEagerSingletons.initEagerSingletons(applicationComponent); AndroidEagerSingletons.initEagerSingletons(applicationComponent);
new SleepMonitor().start();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Localizer.getInstance().setLocale(this);
}
private void setTheme(Context ctx, SharedPreferences prefs) {
String theme = prefs.getString("pref_key_theme", null);
if (theme == null) {
// set default value
theme = getString(R.string.pref_theme_light_value);
prefs.edit().putString("pref_key_theme", theme).apply();
}
// set theme
UiUtils.setTheme(ctx, theme);
} }
private void enableStrictMode() { private void enableStrictMode() {

View File

@@ -1,84 +0,0 @@
package org.briarproject.briar.android;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.PowerManager;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
import static android.content.Context.CONNECTIVITY_SERVICE;
import static android.content.Context.POWER_SERVICE;
import static android.content.Intent.ACTION_AIRPLANE_MODE_CHANGED;
import static android.content.Intent.ACTION_BATTERY_CHANGED;
import static android.content.Intent.ACTION_POWER_CONNECTED;
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_SCREEN_ON;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.os.BatteryManager.EXTRA_LEVEL;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static android.os.BatteryManager.EXTRA_SCALE;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
import static android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGED;
public class BriarBroadcastReceiver extends WakefulBroadcastReceiver {
IntentFilter getIntentFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_SCREEN_ON);
filter.addAction(ACTION_SCREEN_OFF);
filter.addAction(ACTION_BATTERY_CHANGED);
filter.addAction(ACTION_POWER_CONNECTED);
filter.addAction(ACTION_POWER_DISCONNECTED);
if (SDK_INT >= 21) filter.addAction(ACTION_POWER_SAVE_MODE_CHANGED);
if (SDK_INT >= 23) filter.addAction(ACTION_DEVICE_IDLE_MODE_CHANGED);
filter.addAction(ACTION_AIRPLANE_MODE_CHANGED);
filter.addAction(CONNECTIVITY_ACTION);
return filter;
}
@Override
public void onReceive(Context ctx, Intent i) {
String action = i.getAction();
if (ACTION_SCREEN_ON.equals(action)) {
Log.i("DEVICE_STATUS", "Screen on");
} else if (ACTION_SCREEN_OFF.equals(action)) {
Log.i("DEVICE_STATUS", "Screen off");
} else if (ACTION_BATTERY_CHANGED.equals(action)) {
int level = i.getIntExtra(EXTRA_LEVEL, -1);
int scale = i.getIntExtra(EXTRA_SCALE, -1);
int plugged = i.getIntExtra(EXTRA_PLUGGED, -1);
Log.i("DEVICE_STATUS", "Battery level: " + (level / (float) scale)
+ ", plugged: " + (plugged != 0));
} else if (ACTION_POWER_CONNECTED.equals(action)) {
Log.i("DEVICE_STATUS", "Power connected");
} else if (ACTION_POWER_DISCONNECTED.equals(action)) {
Log.i("DEVICE_STATUS", "Power disconnected");
} else if (SDK_INT >= 21
&& ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
PowerManager pm = (PowerManager)
ctx.getSystemService(POWER_SERVICE);
Log.i("DEVICE_STATUS", "Power save mode: " + pm.isPowerSaveMode());
} else if (SDK_INT >= 23
&& ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
PowerManager pm = (PowerManager)
ctx.getSystemService(POWER_SERVICE);
Log.i("DEVICE_STATUS", " Idle mode: " + pm.isDeviceIdleMode());
} else if (ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
Log.i("DEVICE_STATUS",
"Airplane mode: " + i.getBooleanExtra("state", false));
} else if (CONNECTIVITY_ACTION.equals(action)) {
ConnectivityManager cm = (ConnectivityManager)
ctx.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo net = cm.getActiveNetworkInfo();
boolean online = net != null && net.isConnected();
boolean wifi = net != null && net.getType() == TYPE_WIFI;
Log.i("DEVICE_STATUS", "Online: " + online + ", wifi: " + wifi);
}
}
}

View File

@@ -1,8 +1,5 @@
package org.briarproject.briar.android; package org.briarproject.briar.android;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.AlarmManager;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
@@ -14,14 +11,9 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.Binder; import android.os.Binder;
import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.util.Log;
import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
@@ -38,11 +30,8 @@ import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static android.content.Intent.ACTION_SHUTDOWN; import static android.content.Intent.ACTION_SHUTDOWN;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
@@ -51,22 +40,13 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION; import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE; import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE;
import static android.support.v4.app.NotificationCompat.PRIORITY_MIN; import static android.support.v4.app.NotificationCompat.PRIORITY_MIN;
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET; import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.PowerTestingConstants.ALARM_DELAY;
import static org.briarproject.bramble.PowerTestingConstants.USE_TOR_WAKE_LOCK;
import static org.briarproject.bramble.PowerTestingConstants.WAKE_LOCK_DURATION;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.FAILURE_NOTIFICATION_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_CHANNEL_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.ONGOING_NOTIFICATION_ID;
import static org.briarproject.briar.api.android.AndroidNotificationManager.REMINDER_NOTIFICATION_ID;
public class BriarService extends Service { public class BriarService extends Service {
@@ -77,12 +57,13 @@ public class BriarService extends Service {
public static String EXTRA_STARTUP_FAILED = public static String EXTRA_STARTUP_FAILED =
"org.briarproject.briar.STARTUP_FAILED"; "org.briarproject.briar.STARTUP_FAILED";
// This tag prevents the wake lock from being ignored on some Huawei devices private static final int ONGOING_NOTIFICATION_ID = 1;
private static final String WAKE_LOCK_TAG = "LocationManagerService"; private static final int FAILURE_NOTIFICATION_ID = 2;
private static final String ACTION_ALARM =
"org.briarproject.briar.android.ACTION_ALARM"; // Channels are sorted by channel ID in the Settings app, so use IDs
private static final String EXTRA_DUE_MILLIS = // that will sort below the main channels such as contacts
"org.briarproject.briar.android.DUE_MILLIS"; private static final String ONGOING_CHANNEL_ID = "zForegroundService";
private static final String FAILURE_CHANNEL_ID = "zStartupFailure";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(BriarService.class.getName()); Logger.getLogger(BriarService.class.getName());
@@ -90,14 +71,9 @@ public class BriarService extends Service {
private final AtomicBoolean created = new AtomicBoolean(false); private final AtomicBoolean created = new AtomicBoolean(false);
private final Binder binder = new BriarBinder(); private final Binder binder = new BriarBinder();
private AlarmManager alarm;
@Nullable @Nullable
private BroadcastReceiver receiver = null; private BroadcastReceiver receiver = null;
@Nullable
private BriarBroadcastReceiver testReceiver = null;
@Inject @Inject
protected DatabaseConfig databaseConfig; protected DatabaseConfig databaseConfig;
// Fields that are accessed from background threads must be volatile // Fields that are accessed from background threads must be volatile
@@ -114,11 +90,6 @@ public class BriarService extends Service {
BriarApplication application = (BriarApplication) getApplication(); BriarApplication application = (BriarApplication) getApplication();
application.getApplicationComponent().inject(this); application.getApplicationComponent().inject(this);
alarm = (AlarmManager)
getApplicationContext().getSystemService(ALARM_SERVICE);
setAlarm();
LOG.info("Created"); LOG.info("Created");
if (created.getAndSet(true)) { if (created.getAndSet(true)) {
LOG.info("Already created"); LOG.info("Already created");
@@ -132,9 +103,9 @@ public class BriarService extends Service {
} }
// Create notification channels // Create notification channels
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
if (SDK_INT >= 26) { if (SDK_INT >= 26) {
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
NotificationChannel ongoingChannel = new NotificationChannel( NotificationChannel ongoingChannel = new NotificationChannel(
ONGOING_CHANNEL_ID, ONGOING_CHANNEL_ID,
getString(R.string.ongoing_notification_title), getString(R.string.ongoing_notification_title),
@@ -166,8 +137,6 @@ public class BriarService extends Service {
} }
b.setPriority(PRIORITY_MIN); b.setPriority(PRIORITY_MIN);
startForeground(ONGOING_NOTIFICATION_ID, b.build()); startForeground(ONGOING_NOTIFICATION_ID, b.build());
// Remove sign-in reminder notification
nm.cancel(REMINDER_NOTIFICATION_ID);
// Start the services in a background thread // Start the services in a background thread
new Thread(() -> { new Thread(() -> {
String nickname = databaseConfig.getLocalAuthorName(); String nickname = databaseConfig.getLocalAuthorName();
@@ -197,39 +166,6 @@ public class BriarService extends Service {
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");
registerReceiver(receiver, filter); registerReceiver(receiver, filter);
testReceiver = new BriarBroadcastReceiver();
registerReceiver(testReceiver, testReceiver.getIntentFilter());
}
private void setAlarm() {
long dueMillis = SystemClock.elapsedRealtime() + ALARM_DELAY;
PendingIntent pi = getPendingIntent(dueMillis);
if (SDK_INT >= 23) {
alarm.setExactAndAllowWhileIdle(ELAPSED_REALTIME_WAKEUP,
dueMillis, pi);
} else if (SDK_INT >= 19) {
alarm.setExact(ELAPSED_REALTIME_WAKEUP, dueMillis, pi);
} else {
alarm.set(ELAPSED_REALTIME_WAKEUP, dueMillis, pi);
}
Log.i("ALARM_TEST", "Alarm set for " + ALARM_DELAY + " ms");
}
PendingIntent getPendingIntent(long dueMillis) {
return PendingIntent.getService(getApplicationContext(), 0,
getAlarmIntent(dueMillis), FLAG_CANCEL_CURRENT);
}
Intent getAlarmIntent(long dueMillis) {
Intent i = new Intent(getApplicationContext(), BriarService.class);
i.setAction(ACTION_ALARM);
i.putExtra(EXTRA_DUE_MILLIS, dueMillis);
return i;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(Localizer.getInstance().setLocale(base));
} }
private void showStartupFailureNotification(StartResult result) { private void showStartupFailureNotification(StartResult result) {
@@ -261,30 +197,6 @@ public class BriarService extends Service {
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_ALARM.equals(intent.getAction())) {
long dueMillis = intent.getLongExtra(EXTRA_DUE_MILLIS, 0);
long late = SystemClock.elapsedRealtime() - dueMillis;
Log.i("ALARM_TEST", "Alarm fired " + late + " ms late");
PowerManager powerManager = (PowerManager)
getApplicationContext().getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PARTIAL_WAKE_LOCK,
WAKE_LOCK_TAG);
if (!USE_TOR_WAKE_LOCK) {
//acquire wakelock
wakeLock.acquire();
Log.i("ALARM_TEST", "WakeLock acquired for "
+ WAKE_LOCK_DURATION + " ms");
}
new Handler().postDelayed(() -> {
//set alarm before releasing wake lock
setAlarm();
if (!USE_TOR_WAKE_LOCK) {
//release wakelock
Log.i("ALARM_TEST", "Releasing WakeLock");
wakeLock.release();
}
}, WAKE_LOCK_DURATION);
}
return START_NOT_STICKY; // Don't restart automatically if killed return START_NOT_STICKY; // Don't restart automatically if killed
} }
@@ -299,12 +211,10 @@ public class BriarService extends Service {
LOG.info("Destroyed"); LOG.info("Destroyed");
stopForeground(true); stopForeground(true);
if (receiver != null) unregisterReceiver(receiver); if (receiver != null) unregisterReceiver(receiver);
if (testReceiver != null) unregisterReceiver(testReceiver);
// Stop the services in a background thread // Stop the services in a background thread
new Thread(() -> { new Thread(() -> {
if (started) lifecycleManager.stopServices(); if (started) lifecycleManager.stopServices();
}).start(); }).start();
} }
@Override @Override
@@ -333,10 +243,8 @@ public class BriarService extends Service {
LOG.info("Trim memory: running low"); LOG.info("Trim memory: running low");
} else if (level == TRIM_MEMORY_RUNNING_CRITICAL) { } else if (level == TRIM_MEMORY_RUNNING_CRITICAL) {
LOG.info("Trim memory: running critically low"); LOG.info("Trim memory: running critically low");
// If we're not in the foreground, clear the UI to save memory // Clear the UI to save some memory
RunningAppProcessInfo info = new RunningAppProcessInfo(); hideUi();
ActivityManager.getMyMemoryState(info);
if (info.importance != IMPORTANCE_FOREGROUND) hideUi();
} else if (LOG.isLoggable(INFO)) { } else if (LOG.isLoggable(INFO)) {
LOG.info("Trim memory: unknown level " + level); LOG.info("Trim memory: unknown level " + level);
} }

View File

@@ -1,92 +0,0 @@
package org.briarproject.briar.android;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.Locale;
import javax.annotation.Nullable;
import static android.os.Build.VERSION.SDK_INT;
import static org.briarproject.briar.android.settings.SettingsFragment.LANGUAGE;
@NotNullByDefault
public class Localizer {
// Locking: class
@Nullable
private static Localizer INSTANCE;
private final Locale systemLocale;
private final Locale locale;
private Localizer(SharedPreferences sharedPreferences) {
this(Locale.getDefault(), getLocaleFromTag(
sharedPreferences.getString(LANGUAGE, "default")));
}
private Localizer(Locale systemLocale, @Nullable Locale userLocale) {
this.systemLocale = systemLocale;
if (userLocale == null) locale = systemLocale;
else locale = userLocale;
}
// Instantiate the Localizer.
public static synchronized void initialize(SharedPreferences prefs) {
if (INSTANCE == null)
INSTANCE = new Localizer(prefs);
}
// Reinstantiate the Localizer with the system locale
public static synchronized void reinitialize() {
if (INSTANCE != null)
INSTANCE = new Localizer(INSTANCE.systemLocale, null);
}
// Get the current instance.
public static synchronized Localizer getInstance() {
if (INSTANCE == null)
throw new IllegalStateException("Localizer not initialized");
return INSTANCE;
}
// Get Locale from BCP-47 tag
@Nullable
public static Locale getLocaleFromTag(String tag) {
if (tag.equals("default"))
return null;
if (SDK_INT >= 21) {
return Locale.forLanguageTag(tag);
}
if (tag.contains("-")) {
String[] langArray = tag.split("-");
return new Locale(langArray[0], langArray[1]);
} else
return new Locale(tag);
}
// Returns the localized version of context
public Context setLocale(Context context) {
Resources res = context.getResources();
Configuration conf = res.getConfiguration();
Locale currentLocale;
if (SDK_INT >= 24) {
currentLocale = conf.getLocales().get(0);
} else
currentLocale = conf.locale;
if (locale.equals(currentLocale))
return context;
Locale.setDefault(locale);
if (SDK_INT >= 17) {
conf.setLocale(locale);
context.createConfigurationContext(conf);
} else
conf.locale = locale;
//noinspection deprecation
res.updateConfiguration(conf, res.getDisplayMetrics());
return context;
}
}

View File

@@ -4,11 +4,11 @@ import android.net.TrafficStats;
import android.os.Process; import android.os.Process;
import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.Service;
import org.briarproject.bramble.api.lifecycle.ServiceException;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static org.briarproject.bramble.util.LogUtils.now;
class NetworkUsageLogger implements Service { class NetworkUsageLogger implements Service {
@@ -18,17 +18,17 @@ class NetworkUsageLogger implements Service {
private volatile long startTime, rxBytes, txBytes; private volatile long startTime, rxBytes, txBytes;
@Override @Override
public void startService() { public void startService() throws ServiceException {
startTime = now(); startTime = System.currentTimeMillis();
int uid = Process.myUid(); int uid = Process.myUid();
rxBytes = TrafficStats.getUidRxBytes(uid); rxBytes = TrafficStats.getUidRxBytes(uid);
txBytes = TrafficStats.getUidTxBytes(uid); txBytes = TrafficStats.getUidTxBytes(uid);
} }
@Override @Override
public void stopService() { public void stopService() throws ServiceException {
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
long sessionDuration = now() - startTime; long sessionDuration = System.currentTimeMillis() - startTime;
int uid = Process.myUid(); int uid = Process.myUid();
long rx = TrafficStats.getUidRxBytes(uid) - rxBytes; long rx = TrafficStats.getUidRxBytes(uid) - rxBytes;
long tx = TrafficStats.getUidTxBytes(uid) - txBytes; long tx = TrafficStats.getUidTxBytes(uid) - txBytes;

View File

@@ -0,0 +1,83 @@
package org.briarproject.briar.android;
import org.briarproject.briar.api.android.ReferenceManager;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
class ReferenceManagerImpl implements ReferenceManager {
private static final Logger LOG =
Logger.getLogger(ReferenceManagerImpl.class.getName());
private final Lock lock = new ReentrantLock();
// The following are locking: lock
private final Map<Class<?>, Map<Long, Object>> outerMap = new HashMap<>();
private long nextHandle = 0;
@Override
public <T> T getReference(long handle, Class<T> c) {
lock.lock();
try {
Map<Long, Object> innerMap = outerMap.get(c);
if (innerMap == null) {
if (LOG.isLoggable(INFO))
LOG.info("0 handles for " + c.getName());
return null;
}
if (LOG.isLoggable(INFO))
LOG.info(innerMap.size() + " handles for " + c.getName());
Object o = innerMap.get(handle);
return c.cast(o);
} finally {
lock.unlock();
}
}
@Override
public <T> long putReference(T reference, Class<T> c) {
lock.lock();
try {
Map<Long, Object> innerMap = outerMap.get(c);
if (innerMap == null) {
innerMap = new HashMap<>();
outerMap.put(c, innerMap);
}
long handle = nextHandle++;
innerMap.put(handle, reference);
if (LOG.isLoggable(INFO)) {
LOG.info(innerMap.size() + " handles for " + c.getName() +
" after put");
}
return handle;
} finally {
lock.unlock();
}
}
@Override
public <T> T removeReference(long handle, Class<T> c) {
lock.lock();
try {
Map<Long, Object> innerMap = outerMap.get(c);
if (innerMap == null) return null;
Object o = innerMap.remove(handle);
if (innerMap.isEmpty()) outerMap.remove(c);
if (LOG.isLoggable(INFO)) {
LOG.info(innerMap.size() + " handles for " + c.getName() +
" after remove");
}
return c.cast(o);
} finally {
lock.unlock();
}
}
}

View File

@@ -48,7 +48,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.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service { class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service {
@@ -190,7 +189,7 @@ class ScreenFilterMonitorImpl implements ScreenFilterMonitor, Service {
String publicKey = StringUtils.toHexString(publicKeyBytes); String publicKey = StringUtils.toHexString(publicKeyBytes);
return PLAY_SERVICES_PUBLIC_KEY.equals(publicKey); return PLAY_SERVICES_PUBLIC_KEY.equals(publicKey);
} catch (NameNotFoundException | CertificateException e) { } catch (NameNotFoundException | CertificateException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return false; return false;
} }
} }

View File

@@ -1,77 +0,0 @@
package org.briarproject.briar.android;
import android.os.SystemClock;
import android.util.Log;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import static java.util.Locale.US;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class SleepMonitor implements Runnable {
/**
* How often to check the uptime and real time.
*/
private static final int INTERVAL_MS = 5000;
/**
* If the difference between uptime and real time changes by more than
* this amount, assume deep sleep has occurred.
*/
private static final int MIN_SLEEP_DURATION_MS = 1000;
private final ScheduledExecutorService executorService;
private volatile long uptime, realtime, diff;
SleepMonitor() {
uptime = SystemClock.uptimeMillis();
realtime = SystemClock.elapsedRealtime();
diff = realtime - uptime;
executorService = Executors.newSingleThreadScheduledExecutor();
}
void start() {
executorService.scheduleAtFixedRate(this, 0, INTERVAL_MS, MILLISECONDS);
}
@Override
public void run() {
long lastRealtime = realtime;
long sleepDuration = getSleepDuration();
if (sleepDuration > MIN_SLEEP_DURATION_MS) {
long elapsed = realtime - lastRealtime;
long now = System.currentTimeMillis();
String earliestStart = getTime(now - elapsed);
String earliestEnd = getTime(now - elapsed + sleepDuration);
String latestStart = getTime(now - sleepDuration);
String latestEnd = getTime(now);
Log.i("SLEEP_INFO", "System slept for " + sleepDuration
+ " ms since last check " + elapsed
+ " ms ago (earliest " + earliestStart + " - "
+ earliestEnd + ", latest " + latestStart + " - "
+ latestEnd + ")");
}
}
/**
* Returns the amount of time spent in deep sleep since the last check.
*/
private long getSleepDuration() {
uptime = SystemClock.uptimeMillis();
realtime = SystemClock.elapsedRealtime();
long lastDiff = diff;
diff = realtime - uptime;
return diff - lastDiff;
}
private String getTime(long time) {
DateFormat sdf = new SimpleDateFormat("HH:mm:ss", US);
return sdf.format(new Date(time));
}
}

View File

@@ -30,14 +30,4 @@ public interface TestingConstants {
long EXPIRY_DATE = IS_DEBUG_BUILD || IS_BETA_BUILD ? long EXPIRY_DATE = IS_DEBUG_BUILD || IS_BETA_BUILD ?
BuildConfig.BuildTimestamp + 90 * 24 * 60 * 60 * 1000L : BuildConfig.BuildTimestamp + 90 * 24 * 60 * 60 * 1000L :
Long.MAX_VALUE; Long.MAX_VALUE;
/**
* Feature flag for enabling the dark UI theme in release builds.
*/
boolean FEATURE_FLAG_DARK_THEME = false;
/**
* Feature flag for enabling the sign-in reminder in release builds.
*/
boolean FEATURE_FLAG_SIGN_IN_REMINDER = IS_DEBUG_BUILD;
} }

View File

@@ -26,10 +26,9 @@ import org.briarproject.briar.android.fragment.ScreenFilterDialogFragment;
import org.briarproject.briar.android.introduction.ContactChooserFragment; import org.briarproject.briar.android.introduction.ContactChooserFragment;
import org.briarproject.briar.android.introduction.IntroductionActivity; import org.briarproject.briar.android.introduction.IntroductionActivity;
import org.briarproject.briar.android.introduction.IntroductionMessageFragment; import org.briarproject.briar.android.introduction.IntroductionMessageFragment;
import org.briarproject.briar.android.keyagreement.ContactExchangeActivity;
import org.briarproject.briar.android.keyagreement.IntroFragment; import org.briarproject.briar.android.keyagreement.IntroFragment;
import org.briarproject.briar.android.keyagreement.KeyAgreementActivity; import org.briarproject.briar.android.keyagreement.KeyAgreementActivity;
import org.briarproject.briar.android.keyagreement.KeyAgreementFragment; import org.briarproject.briar.android.keyagreement.ShowQrCodeFragment;
import org.briarproject.briar.android.login.AuthorNameFragment; import org.briarproject.briar.android.login.AuthorNameFragment;
import org.briarproject.briar.android.login.ChangePasswordActivity; import org.briarproject.briar.android.login.ChangePasswordActivity;
import org.briarproject.briar.android.login.DozeFragment; import org.briarproject.briar.android.login.DozeFragment;
@@ -101,8 +100,6 @@ public interface ActivityComponent {
void inject(PanicPreferencesActivity activity); void inject(PanicPreferencesActivity activity);
void inject(ContactExchangeActivity activity);
void inject(KeyAgreementActivity activity); void inject(KeyAgreementActivity activity);
void inject(ConversationActivity activity); void inject(ConversationActivity activity);
@@ -188,7 +185,7 @@ public interface ActivityComponent {
void inject(IntroFragment fragment); void inject(IntroFragment fragment);
void inject(KeyAgreementFragment fragment); void inject(ShowQrCodeFragment fragment);
void inject(ContactChooserFragment fragment); void inject(ContactChooserFragment fragment);

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.android.activity; package org.briarproject.briar.android.activity;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
@@ -19,7 +18,6 @@ import org.briarproject.briar.R;
import org.briarproject.briar.android.AndroidComponent; import org.briarproject.briar.android.AndroidComponent;
import org.briarproject.briar.android.BriarApplication; import org.briarproject.briar.android.BriarApplication;
import org.briarproject.briar.android.DestroyableContext; import org.briarproject.briar.android.DestroyableContext;
import org.briarproject.briar.android.Localizer;
import org.briarproject.briar.android.controller.ActivityLifecycleController; import org.briarproject.briar.android.controller.ActivityLifecycleController;
import org.briarproject.briar.android.forum.ForumModule; import org.briarproject.briar.android.forum.ForumModule;
import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment;
@@ -86,12 +84,6 @@ public abstract class BaseActivity extends AppCompatActivity
} }
} }
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(
Localizer.getInstance().setLocale(base));
}
public ActivityComponent getActivityComponent() { public ActivityComponent getActivityComponent() {
return activityComponent; return activityComponent;
} }

View File

@@ -92,6 +92,7 @@ public abstract class BriarActivity extends BaseActivity {
window.setEnterTransition(slide); window.setEnterTransition(slide);
window.setTransitionBackgroundFadeDuration(getResources() window.setTransitionBackgroundFadeDuration(getResources()
.getInteger(android.R.integer.config_longAnimTime)); .getInteger(android.R.integer.config_longAnimTime));
window.setBackgroundDrawableResource(android.R.color.transparent);
} }
/** /**

View File

@@ -32,10 +32,8 @@ import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.util.HtmlUtils.ARTICLE; import static org.briarproject.briar.util.HtmlUtils.ARTICLE;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -103,25 +101,30 @@ abstract class BaseControllerImpl extends DbControllerImpl
Collection<BlogPostItem> items = loadItems(groupId); Collection<BlogPostItem> items = loadItems(groupId);
handler.onResult(items); handler.onResult(items);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });
} }
Collection<BlogPostItem> loadItems(GroupId groupId) throws DbException { Collection<BlogPostItem> loadItems(GroupId groupId) throws DbException {
long start = now(); long now = System.currentTimeMillis();
Collection<BlogPostHeader> headers = Collection<BlogPostHeader> headers =
blogManager.getPostHeaders(groupId); blogManager.getPostHeaders(groupId);
logDuration(LOG, "Loading headers", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading headers took " + duration + " ms");
Collection<BlogPostItem> items = new ArrayList<>(headers.size()); Collection<BlogPostItem> items = new ArrayList<>(headers.size());
start = now(); now = System.currentTimeMillis();
for (BlogPostHeader h : headers) { for (BlogPostHeader h : headers) {
headerCache.put(h.getId(), h); headerCache.put(h.getId(), h);
BlogPostItem item = getItem(h); BlogPostItem item = getItem(h);
items.add(item); items.add(item);
} }
logDuration(LOG, "Loading bodies", start); duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading bodies took " + duration + " ms");
return items; return items;
} }
@@ -137,12 +140,15 @@ abstract class BaseControllerImpl extends DbControllerImpl
} }
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
BlogPostItem item = getItem(header); BlogPostItem item = getItem(header);
logDuration(LOG, "Loading body", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading body took " + duration + " ms");
handler.onResult(item); handler.onResult(item);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });
@@ -160,13 +166,16 @@ abstract class BaseControllerImpl extends DbControllerImpl
} }
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
BlogPostHeader header1 = getPostHeader(g, m); BlogPostHeader header1 = getPostHeader(g, m);
BlogPostItem item = getItem(header1); BlogPostItem item = getItem(header1);
logDuration(LOG, "Loading post", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading post took " + duration + " ms");
handler.onResult(item); handler.onResult(item);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });
@@ -182,7 +191,8 @@ abstract class BaseControllerImpl extends DbControllerImpl
BlogPostHeader h = item.getHeader(); BlogPostHeader h = item.getHeader();
blogManager.addLocalComment(a, b.getId(), comment, h); blogManager.addLocalComment(a, b.getId(), comment, h);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });

View File

@@ -35,10 +35,8 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
@@ -156,16 +154,19 @@ class BlogControllerImpl extends BaseControllerImpl
if (groupId == null) throw new IllegalStateException(); if (groupId == null) throw new IllegalStateException();
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
LocalAuthor a = identityManager.getLocalAuthor(); LocalAuthor a = identityManager.getLocalAuthor();
Blog b = blogManager.getBlog(groupId); Blog b = blogManager.getBlog(groupId);
boolean ours = a.getId().equals(b.getAuthor().getId()); boolean ours = a.getId().equals(b.getAuthor().getId());
boolean removable = blogManager.canBeRemoved(b); boolean removable = blogManager.canBeRemoved(b);
BlogItem blog = new BlogItem(b, ours, removable); BlogItem blog = new BlogItem(b, ours, removable);
logDuration(LOG, "Loading blog", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading blog took " + duration + " ms");
handler.onResult(blog); handler.onResult(blog);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });
@@ -176,13 +177,16 @@ class BlogControllerImpl extends BaseControllerImpl
if (groupId == null) throw new IllegalStateException(); if (groupId == null) throw new IllegalStateException();
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
Blog b = blogManager.getBlog(groupId); Blog b = blogManager.getBlog(groupId);
blogManager.removeBlog(b); blogManager.removeBlog(b);
logDuration(LOG, "Removing blog", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Removing blog took " + duration + " ms");
handler.onResult(null); handler.onResult(null);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });
@@ -201,7 +205,8 @@ class BlogControllerImpl extends BaseControllerImpl
for (Contact c : contacts) contactIds.add(c.getId()); for (Contact c : contacts) contactIds.add(c.getId());
handler.onResult(contactIds); handler.onResult(contactIds);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });

View File

@@ -11,7 +11,7 @@ import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
@@ -40,7 +40,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
private final ViewGroup layout; private final ViewGroup layout;
private final AuthorView reblogger; private final AuthorView reblogger;
private final AuthorView author; private final AuthorView author;
private final ImageButton reblogButton; private final ImageView reblogButton;
private final TextView body; private final TextView body;
private final ViewGroup commentContainer; private final ViewGroup commentContainer;
private final boolean fullText; private final boolean fullText;

View File

@@ -26,10 +26,8 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID; import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -101,19 +99,22 @@ class FeedControllerImpl extends BaseControllerImpl
ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) { ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
Collection<BlogPostItem> posts = new ArrayList<>(); Collection<BlogPostItem> posts = new ArrayList<>();
for (Blog b : blogManager.getBlogs()) { for (Blog b : blogManager.getBlogs()) {
try { try {
posts.addAll(loadItems(b.getId())); posts.addAll(loadItems(b.getId()));
} catch (NoSuchGroupException | NoSuchMessageException e) { } catch (NoSuchGroupException | NoSuchMessageException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
} }
logDuration(LOG, "Loading all posts", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading all posts took " + duration + " ms");
handler.onResult(posts); handler.onResult(posts);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });
@@ -124,13 +125,15 @@ class FeedControllerImpl extends BaseControllerImpl
ResultExceptionHandler<Blog, DbException> handler) { ResultExceptionHandler<Blog, DbException> handler) {
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
Author a = identityManager.getLocalAuthor(); Author a = identityManager.getLocalAuthor();
Blog b = blogManager.getPersonalBlog(a); Blog b = blogManager.getPersonalBlog(a);
logDuration(LOG, "Loading personal blog", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading blog took " + duration + " ms");
handler.onResult(b); handler.onResult(b);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });

View File

@@ -30,7 +30,6 @@ import javax.inject.Inject;
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 java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
public class RssFeedImportActivity extends BriarActivity { public class RssFeedImportActivity extends BriarActivity {
@@ -125,7 +124,7 @@ public class RssFeedImportActivity extends BriarActivity {
feedManager.addFeed(url); feedManager.addFeed(url);
feedImported(); feedImported();
} catch (DbException | IOException e) { } catch (DbException | IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
importFailed(); importFailed();
} }
}); });

View File

@@ -27,7 +27,6 @@ import javax.inject.Inject;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.support.design.widget.Snackbar.LENGTH_LONG; import static android.support.design.widget.Snackbar.LENGTH_LONG;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
public class RssFeedManageActivity extends BriarActivity public class RssFeedManageActivity extends BriarActivity
implements RssFeedListener { implements RssFeedListener {
@@ -124,7 +123,7 @@ public class RssFeedManageActivity extends BriarActivity
try { try {
displayFeeds(revision, feedManager.getFeeds()); displayFeeds(revision, feedManager.getFeeds());
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
onLoadError(); onLoadError();
} }
}); });
@@ -149,7 +148,7 @@ public class RssFeedManageActivity extends BriarActivity
feedManager.removeFeed(feed); feedManager.removeFeed(feed);
onFeedDeleted(feed); onFeedDeleted(feed);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
onDeleteError(); onDeleteError();
} }
}); });

View File

@@ -34,7 +34,6 @@ import javax.inject.Inject;
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 java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_BODY_LENGTH; import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_BODY_LENGTH;
public class WriteBlogPostActivity extends BriarActivity public class WriteBlogPostActivity extends BriarActivity
@@ -143,16 +142,16 @@ public class WriteBlogPostActivity extends BriarActivity
private void storePost(String body) { private void storePost(String body) {
runOnDbThread(() -> { runOnDbThread(() -> {
long timestamp = System.currentTimeMillis(); long now = System.currentTimeMillis();
try { try {
LocalAuthor author = identityManager.getLocalAuthor(); LocalAuthor author = identityManager.getLocalAuthor();
BlogPost p = blogPostFactory BlogPost p = blogPostFactory
.createBlogPost(groupId, timestamp, null, author, body); .createBlogPost(groupId, now, null, author, body);
blogManager.addLocalPost(p); blogManager.addLocalPost(p);
postPublished(); postPublished();
} catch (DbException | GeneralSecurityException } catch (DbException | GeneralSecurityException
| FormatException e) { | FormatException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
postFailedToPublish(); postFailedToPublish();
} }
}); });

View File

@@ -33,7 +33,7 @@ import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener; import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener;
import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.keyagreement.ContactExchangeActivity; import org.briarproject.briar.android.keyagreement.KeyAgreementActivity;
import org.briarproject.briar.android.view.BriarRecyclerView; import org.briarproject.briar.android.view.BriarRecyclerView;
import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.client.BaseMessageHeader; import org.briarproject.briar.api.client.BaseMessageHeader;
@@ -59,10 +59,8 @@ import javax.inject.Inject;
import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation; import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation;
import static android.support.v4.view.ViewCompat.getTransitionName; import static android.support.v4.view.ViewCompat.getTransitionName;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID; import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -165,7 +163,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_add_contact: case R.id.action_add_contact:
Intent intent = Intent intent =
new Intent(getContext(), ContactExchangeActivity.class); new Intent(getContext(), KeyAgreementActivity.class);
startActivity(intent); startActivity(intent);
return true; return true;
default: default:
@@ -196,7 +194,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
int revision = adapter.getRevision(); int revision = adapter.getRevision();
listener.runOnDbThread(() -> { listener.runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
List<ContactListItem> contacts = new ArrayList<>(); List<ContactListItem> contacts = new ArrayList<>();
for (Contact c : contactManager.getActiveContacts()) { for (Contact c : contactManager.getActiveContacts()) {
try { try {
@@ -210,10 +208,12 @@ public class ContactListFragment extends BaseFragment implements EventListener {
// Continue // Continue
} }
} }
logDuration(LOG, "Full load", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
displayContacts(revision, contacts); displayContacts(revision, contacts);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -106,9 +106,6 @@ import static android.support.v7.util.SortedList.INVALID_POSITION;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
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 org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRODUCTION; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRODUCTION;
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE; import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.android.util.UiUtils.getAvatarTransitionName; import static org.briarproject.briar.android.util.UiUtils.getAvatarTransitionName;
@@ -293,19 +290,21 @@ public class ConversationActivity extends BriarActivity
private void loadContactDetailsAndMessages() { private void loadContactDetailsAndMessages() {
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
if (contactName == null || contactAuthorId == null) { if (contactName == null || contactAuthorId == null) {
Contact contact = contactManager.getContact(contactId); Contact contact = contactManager.getContact(contactId);
contactName = contact.getAuthor().getName(); contactName = contact.getAuthor().getName();
contactAuthorId = contact.getAuthor().getId(); contactAuthorId = contact.getAuthor().getId();
} }
logDuration(LOG, "Loading contact", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading contact took " + duration + " ms");
loadMessages(); loadMessages();
displayContactDetails(); displayContactDetails();
} catch (NoSuchContactException e) { } catch (NoSuchContactException e) {
finishOnUiThread(); finishOnUiThread();
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -341,7 +340,7 @@ public class ConversationActivity extends BriarActivity
int revision = adapter.getRevision(); int revision = adapter.getRevision();
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
Collection<PrivateMessageHeader> headers = Collection<PrivateMessageHeader> headers =
messagingManager.getMessageHeaders(contactId); messagingManager.getMessageHeaders(contactId);
Collection<IntroductionMessage> introductions = Collection<IntroductionMessage> introductions =
@@ -358,12 +357,14 @@ public class ConversationActivity extends BriarActivity
invitations.addAll(forumInvitations); invitations.addAll(forumInvitations);
invitations.addAll(blogInvitations); invitations.addAll(blogInvitations);
invitations.addAll(groupInvitations); invitations.addAll(groupInvitations);
logDuration(LOG, "Loading messages", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading messages took " + duration + " ms");
displayMessages(revision, headers, introductions, invitations); displayMessages(revision, headers, introductions, invitations);
} catch (NoSuchContactException e) { } catch (NoSuchContactException e) {
finishOnUiThread(); finishOnUiThread();
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -437,12 +438,14 @@ public class ConversationActivity extends BriarActivity
private void loadMessageBody(MessageId m) { private void loadMessageBody(MessageId m) {
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
String body = messagingManager.getMessageBody(m); String body = messagingManager.getMessageBody(m);
logDuration(LOG, "Loading body", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading body took " + duration + " ms");
displayMessageBody(m, body); displayMessageBody(m, body);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -666,7 +669,7 @@ public class ConversationActivity extends BriarActivity
messagingManager.getConversationId(contactId); messagingManager.getConversationId(contactId);
createMessage(body, timestamp); createMessage(body, timestamp);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
@@ -686,9 +689,11 @@ public class ConversationActivity extends BriarActivity
private void storeMessage(PrivateMessage m, String body) { private void storeMessage(PrivateMessage m, String body) {
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
messagingManager.addLocalMessage(m); messagingManager.addLocalMessage(m);
logDuration(LOG, "Storing message", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing message took " + duration + " ms");
Message message = m.getMessage(); Message message = m.getMessage();
PrivateMessageHeader h = new PrivateMessageHeader( PrivateMessageHeader h = new PrivateMessageHeader(
message.getId(), message.getGroupId(), message.getId(), message.getGroupId(),
@@ -698,7 +703,7 @@ public class ConversationActivity extends BriarActivity
bodyCache.put(message.getId(), body); bodyCache.put(message.getId(), body);
addConversationItem(item); addConversationItem(item);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -721,7 +726,7 @@ public class ConversationActivity extends BriarActivity
try { try {
contactManager.removeContact(contactId); contactManager.removeContact(contactId);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} finally { } finally {
finishAfterContactRemoved(); finishAfterContactRemoved();
} }
@@ -750,7 +755,7 @@ public class ConversationActivity extends BriarActivity
} }
} }
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -798,7 +803,7 @@ public class ConversationActivity extends BriarActivity
settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false); settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false);
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -811,11 +816,13 @@ public class ConversationActivity extends BriarActivity
private void markMessageRead(GroupId g, MessageId m) { private void markMessageRead(GroupId g, MessageId m) {
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
messagingManager.setReadFlag(g, m, true); messagingManager.setReadFlag(g, m, true);
logDuration(LOG, "Marking read", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Marking read took " + duration + " ms");
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -853,10 +860,10 @@ public class ConversationActivity extends BriarActivity
loadMessages(); loadMessages();
} catch (ProtocolStateException e) { } catch (ProtocolStateException e) {
// Action is no longer valid - reloading should solve the issue // Action is no longer valid - reloading should solve the issue
logException(LOG, INFO, e); if (LOG.isLoggable(INFO)) LOG.log(INFO, e.toString(), e);
} catch (DbException e) { } catch (DbException e) {
// TODO show an error message // TODO show an error message
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -19,7 +19,6 @@ import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
@@ -54,7 +53,7 @@ public abstract class ContactSelectorControllerImpl
} }
handler.onResult(contacts); handler.onResult(contacts);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });

View File

@@ -21,7 +21,6 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
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.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE; import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
@@ -102,7 +101,8 @@ public class BriarControllerImpl implements BriarController {
boolean ask = settings.getBoolean(DOZE_ASK_AGAIN, true); boolean ask = settings.getBoolean(DOZE_ASK_AGAIN, true);
handler.onResult(ask); handler.onResult(ask);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -115,7 +115,8 @@ public class BriarControllerImpl implements BriarController {
settings.putBoolean(DOZE_ASK_AGAIN, false); settings.putBoolean(DOZE_ASK_AGAIN, false);
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -20,7 +20,6 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
public class ConfigControllerImpl implements ConfigController { public class ConfigControllerImpl implements ConfigController {
@@ -90,7 +89,7 @@ public class ConfigControllerImpl implements ConfigController {
reader.close(); reader.close();
return key; return key;
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null; return null;
} }
} }
@@ -138,7 +137,7 @@ public class ConfigControllerImpl implements ConfigController {
LOG.info("Stored second copy of database key in backup file"); LOG.info("Stored second copy of database key in backup file");
return true; return true;
} catch (IOException e) { } catch (IOException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return false; return false;
} }
} }

View File

@@ -28,10 +28,8 @@ import javax.inject.Inject;
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 android.widget.Toast.LENGTH_LONG; import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH; import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -124,12 +122,14 @@ public class CreateForumActivity extends BriarActivity {
private void storeForum(String name) { private void storeForum(String name) {
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
Forum f = forumManager.addForum(name); Forum f = forumManager.addForum(name);
logDuration(LOG, "Storing forum", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing forum took " + duration + " ms");
displayForum(f); displayForum(f);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
finishOnUiThread(); finishOnUiThread();
} }
}); });

View File

@@ -39,7 +39,6 @@ import javax.inject.Inject;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class ForumControllerImpl extends class ForumControllerImpl extends
@@ -131,7 +130,7 @@ class ForumControllerImpl extends
for (Contact c : contacts) contactIds.add(c.getId()); for (Contact c : contacts) contactIds.add(c.getId());
handler.onResult(contactIds); handler.onResult(contactIds);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });
@@ -151,7 +150,7 @@ class ForumControllerImpl extends
parentItem.getId() : null; parentItem.getId() : null;
createMessage(body, timestamp, parentId, author, handler); createMessage(body, timestamp, parentId, author, handler);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
handler.onException(e); handler.onException(e);
} }
}); });

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.android.forum;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -54,8 +55,12 @@ class ForumListAdapter
ui.postCount.setText(ctx.getResources() ui.postCount.setText(ctx.getResources()
.getQuantityString(R.plurals.posts, postCount, .getQuantityString(R.plurals.posts, postCount,
postCount)); postCount));
ui.postCount.setTextColor(
ContextCompat.getColor(ctx, R.color.briar_text_secondary));
} else { } else {
ui.postCount.setText(ctx.getString(R.string.no_posts)); ui.postCount.setText(ctx.getString(R.string.no_posts));
ui.postCount.setTextColor(
ContextCompat.getColor(ctx, R.color.briar_text_tertiary));
} }
// Date // Date

View File

@@ -44,10 +44,8 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE; import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.api.forum.ForumManager.CLIENT_ID; import static org.briarproject.briar.api.forum.ForumManager.CLIENT_ID;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -159,7 +157,7 @@ public class ForumListFragment extends BaseEventFragment implements
int revision = adapter.getRevision(); int revision = adapter.getRevision();
listener.runOnDbThread(() -> { listener.runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
Collection<ForumListItem> forums = new ArrayList<>(); Collection<ForumListItem> forums = new ArrayList<>();
for (Forum f : forumManager.getForums()) { for (Forum f : forumManager.getForums()) {
try { try {
@@ -170,10 +168,12 @@ public class ForumListFragment extends BaseEventFragment implements
// Continue // Continue
} }
} }
logDuration(LOG, "Full load", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Full load took " + duration + " ms");
displayForums(revision, forums); displayForums(revision, forums);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -194,12 +194,14 @@ public class ForumListFragment extends BaseEventFragment implements
private void loadAvailableForums() { private void loadAvailableForums() {
listener.runOnDbThread(() -> { listener.runOnDbThread(() -> {
try { try {
long start = now(); long now = System.currentTimeMillis();
int available = forumSharingManager.getInvitations().size(); int available = forumSharingManager.getInvitations().size();
logDuration(LOG, "Loading available", start); long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading available took " + duration + " ms");
displayAvailableForums(available); displayAvailableForums(available);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -29,7 +29,6 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
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.briar.android.contact.ConversationActivity.CONTACT_ID; import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
public class ContactChooserFragment extends BaseFragment { public class ContactChooserFragment extends BaseFragment {
@@ -130,7 +129,7 @@ public class ContactChooserFragment extends BaseFragment {
} }
displayContacts(contacts); displayContacts(contacts);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }

View File

@@ -36,7 +36,6 @@ import static android.view.View.GONE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
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.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH; import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_REQUEST_MESSAGE_LENGTH;
public class IntroductionMessageFragment extends BaseFragment public class IntroductionMessageFragment extends BaseFragment
@@ -130,7 +129,7 @@ public class IntroductionMessageFragment extends BaseFragment
boolean possible = introductionManager.canIntroduce(c1, c2); boolean possible = introductionManager.canIntroduce(c1, c2);
setUpViews(c1, c2, possible); setUpViews(c1, c2, possible);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -205,7 +204,7 @@ public class IntroductionMessageFragment extends BaseFragment
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
introductionManager.makeIntroduction(c1, c2, msg, timestamp); introductionManager.makeIntroduction(c1, c2, msg, timestamp);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
introductionError(); introductionError();
} }
}); });

View File

@@ -9,12 +9,10 @@ import android.hardware.Camera.Size;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.Display;
import android.view.Surface; import android.view.Surface;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.View; import android.view.View;
import android.view.WindowManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
@@ -23,7 +21,6 @@ import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import static android.content.Context.WINDOW_SERVICE;
import static android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK; import static android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK;
import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT; import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;
import static android.hardware.Camera.Parameters.FLASH_MODE_OFF; import static android.hardware.Camera.Parameters.FLASH_MODE_OFF;
@@ -38,7 +35,6 @@ import static android.hardware.Camera.Parameters.SCENE_MODE_BARCODE;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
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 org.briarproject.bramble.util.LogUtils.logException;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -100,7 +96,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
} }
@UiThread @UiThread
public void start() throws CameraException { public void start(int rotationDegrees) throws CameraException {
LOG.info("Opening camera"); LOG.info("Opening camera");
try { try {
int cameras = Camera.getNumberOfCameras(); int cameras = Camera.getNumberOfCameras();
@@ -125,7 +121,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw new CameraException(e); throw new CameraException(e);
} }
setDisplayOrientation(getScreenRotationDegrees()); setDisplayOrientation(rotationDegrees);
// Use barcode scene mode if it's available // Use barcode scene mode if it's available
Parameters params = camera.getParameters(); Parameters params = camera.getParameters();
params = setSceneMode(camera, params); params = setSceneMode(camera, params);
@@ -160,27 +156,6 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
camera = null; camera = null;
} }
/**
* See {@link Camera#setDisplayOrientation(int)}.
*/
private int getScreenRotationDegrees() {
WindowManager wm =
(WindowManager) getContext().getSystemService(WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
switch (d.getRotation()) {
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return 270;
default:
throw new AssertionError();
}
}
@UiThread @UiThread
private void startPreview(SurfaceHolder holder) throws CameraException { private void startPreview(SurfaceHolder holder) throws CameraException {
LOG.info("Starting preview"); LOG.info("Starting preview");
@@ -433,7 +408,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
try { try {
surfaceCreatedUi(holder); surfaceCreatedUi(holder);
} catch (CameraException e) { } catch (CameraException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -455,7 +430,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
try { try {
surfaceChangedUi(holder, w, h); surfaceChangedUi(holder, w, h);
} catch (CameraException e) { } catch (CameraException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} }
}); });
} }
@@ -513,7 +488,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
try { try {
startAutoFocus(); startAutoFocus();
} catch (CameraException e) { } catch (CameraException e) {
logException(LOG, WARNING, e); LOG.log(WARNING, e.toString(), e);
} }
} }

View File

@@ -1,144 +0,0 @@
package org.briarproject.briar.android.keyagreement;
import android.os.Bundle;
import android.support.annotation.UiThread;
import android.widget.Toast;
import org.briarproject.bramble.api.contact.ContactExchangeListener;
import org.briarproject.bramble.api.contact.ContactExchangeTask;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.R.string;
import org.briarproject.briar.android.activity.ActivityComponent;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ContactExchangeActivity extends KeyAgreementActivity implements
ContactExchangeListener {
private static final Logger LOG =
Logger.getLogger(ContactExchangeActivity.class.getName());
// Fields that are accessed from background threads must be volatile
@Inject
volatile ContactExchangeTask contactExchangeTask;
@Inject
volatile IdentityManager identityManager;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
getSupportActionBar().setTitle(string.add_contact_title);
}
private void startContactExchange(KeyAgreementResult result) {
runOnDbThread(() -> {
LocalAuthor localAuthor;
// Load the local pseudonym
try {
localAuthor = identityManager.getLocalAuthor();
} catch (DbException e) {
logException(LOG, WARNING, e);
contactExchangeFailed();
return;
}
// Exchange contact details
contactExchangeTask.startExchange(ContactExchangeActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
});
}
@Override
public void contactExchangeSucceeded(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_added_toast);
String text = String.format(format, contactName);
Toast.makeText(ContactExchangeActivity.this, text, LENGTH_LONG)
.show();
supportFinishAfterTransition();
});
}
@Override
public void duplicateContact(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_already_exists);
String text = String.format(format, contactName);
Toast.makeText(ContactExchangeActivity.this, text, LENGTH_LONG)
.show();
finish();
});
}
@Override
public void contactExchangeFailed() {
runOnUiThreadUnlessDestroyed(() -> {
Toast.makeText(ContactExchangeActivity.this,
string.contact_exchange_failed, LENGTH_LONG).show();
finish();
});
}
@UiThread
@Override
public void keyAgreementFailed() {
// TODO show failure somewhere persistent?
Toast.makeText(this, R.string.connection_failed,
LENGTH_LONG).show();
}
@UiThread
@Override
public String keyAgreementWaiting() {
return getString(R.string.waiting_for_contact_to_scan);
}
@UiThread
@Override
public String keyAgreementStarted() {
return getString(R.string.authenticating_with_device);
}
@UiThread
@Override
public String keyAgreementAborted(boolean remoteAborted) {
// TODO show abort somewhere persistent?
Toast.makeText(this,
remoteAborted ? R.string.connection_aborted_remote :
R.string.connection_aborted_local, LENGTH_LONG)
.show();
return null;
}
@UiThread
@Override
public String keyAgreementFinished(KeyAgreementResult result) {
startContactExchange(result);
return getString(string.exchanging_contact_details);
}
}

View File

@@ -16,7 +16,17 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.Toast; import android.widget.Toast;
import org.briarproject.bramble.api.contact.ContactExchangeListener;
import org.briarproject.bramble.api.contact.ContactExchangeTask;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFinishedEvent;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent; import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
@@ -43,14 +53,15 @@ import static android.bluetooth.BluetoothAdapter.STATE_ON;
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.widget.Toast.LENGTH_LONG; import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.WARNING;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ENABLE_BLUETOOTH; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ENABLE_BLUETOOTH;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
public abstract class KeyAgreementActivity extends BriarActivity implements public class KeyAgreementActivity extends BriarActivity implements
BaseFragmentListener, IntroScreenSeenListener, BaseFragmentListener, IntroScreenSeenListener, EventListener,
KeyAgreementFragment.KeyAgreementEventListener { ContactExchangeListener {
private enum BluetoothState { private enum BluetoothState {
UNKNOWN, NO_ADAPTER, WAITING, REFUSED, ENABLED UNKNOWN, NO_ADAPTER, WAITING, REFUSED, ENABLED
@@ -62,6 +73,12 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
@Inject @Inject
EventBus eventBus; EventBus eventBus;
// Fields that are accessed from background threads must be volatile
@Inject
volatile ContactExchangeTask contactExchangeTask;
@Inject
volatile IdentityManager identityManager;
private boolean isResumed = false, enableWasRequested = false; private boolean isResumed = false, enableWasRequested = false;
private boolean continueClicked, gotCameraPermission; private boolean continueClicked, gotCameraPermission;
private BluetoothState bluetoothState = BluetoothState.UNKNOWN; private BluetoothState bluetoothState = BluetoothState.UNKNOWN;
@@ -77,9 +94,13 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
public void onCreate(@Nullable Bundle state) { public void onCreate(@Nullable Bundle state) {
super.onCreate(state); super.onCreate(state);
setContentView(R.layout.activity_fragment_container_toolbar); setContentView(R.layout.activity_fragment_container_toolbar);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(R.string.add_contact_title);
if (state == null) { if (state == null) {
showInitialFragment(IntroFragment.newInstance()); showInitialFragment(IntroFragment.newInstance());
} }
@@ -94,6 +115,18 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
if (bluetoothReceiver != null) unregisterReceiver(bluetoothReceiver); if (bluetoothReceiver != null) unregisterReceiver(bluetoothReceiver);
} }
@Override
public void onStart() {
super.onStart();
eventBus.addListener(this);
}
@Override
protected void onStop() {
super.onStop();
eventBus.removeListener(this);
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
@@ -114,7 +147,7 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
if (canShowQrCodeFragment()) showQrCodeFragment(); if (canShowQrCodeFragment()) showQrCodeFragment();
} }
private boolean canShowQrCodeFragment() { boolean canShowQrCodeFragment() {
return isResumed && continueClicked return isResumed && continueClicked
&& (SDK_INT < 23 || gotCameraPermission) && (SDK_INT < 23 || gotCameraPermission)
&& bluetoothState != BluetoothState.UNKNOWN && bluetoothState != BluetoothState.UNKNOWN
@@ -173,11 +206,10 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
} }
private void showQrCodeFragment() { private void showQrCodeFragment() {
continueClicked = false;
// FIXME #824 // FIXME #824
FragmentManager fm = getSupportFragmentManager(); FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentByTag(KeyAgreementFragment.TAG) == null) { if (fm.findFragmentByTag(ShowQrCodeFragment.TAG) == null) {
BaseFragment f = KeyAgreementFragment.newInstance(); BaseFragment f = ShowQrCodeFragment.newInstance();
fm.beginTransaction() fm.beginTransaction()
.replace(R.id.fragmentContainer, f, f.getUniqueTag()) .replace(R.id.fragmentContainer, f, f.getUniqueTag())
.addToBackStack(f.getUniqueTag()) .addToBackStack(f.getUniqueTag())
@@ -247,6 +279,69 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
} }
} }
@Override
public void eventOccurred(Event e) {
if (e instanceof KeyAgreementFinishedEvent) {
KeyAgreementFinishedEvent event = (KeyAgreementFinishedEvent) e;
keyAgreementFinished(event.getResult());
}
}
private void keyAgreementFinished(KeyAgreementResult result) {
runOnUiThreadUnlessDestroyed(() -> startContactExchange(result));
}
private void startContactExchange(KeyAgreementResult result) {
runOnDbThread(() -> {
LocalAuthor localAuthor;
// Load the local pseudonym
try {
localAuthor = identityManager.getLocalAuthor();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
contactExchangeFailed();
return;
}
// Exchange contact details
contactExchangeTask.startExchange(KeyAgreementActivity.this,
localAuthor, result.getMasterKey(),
result.getConnection(), result.getTransportId(),
result.wasAlice());
});
}
@Override
public void contactExchangeSucceeded(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_added_toast);
String text = String.format(format, contactName);
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
supportFinishAfterTransition();
});
}
@Override
public void duplicateContact(Author remoteAuthor) {
runOnUiThreadUnlessDestroyed(() -> {
String contactName = remoteAuthor.getName();
String format = getString(string.contact_already_exists);
String text = String.format(format, contactName);
Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
finish();
});
}
@Override
public void contactExchangeFailed() {
runOnUiThreadUnlessDestroyed(() -> {
Toast.makeText(KeyAgreementActivity.this,
string.contact_exchange_failed, LENGTH_LONG).show();
finish();
});
}
private class BluetoothStateReceiver extends BroadcastReceiver { private class BluetoothStateReceiver extends BroadcastReceiver {
@Override @Override

View File

@@ -18,7 +18,6 @@ import static android.graphics.Color.BLACK;
import static android.graphics.Color.WHITE; import static android.graphics.Color.WHITE;
import static com.google.zxing.BarcodeFormat.QR_CODE; import static com.google.zxing.BarcodeFormat.QR_CODE;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault @NotNullByDefault
class QrCodeUtils { class QrCodeUtils {
@@ -35,7 +34,7 @@ class QrCodeUtils {
smallestDimen, smallestDimen); smallestDimen, smallestDimen);
return renderQrCode(encoded); return renderQrCode(encoded);
} catch (WriterException e) { } catch (WriterException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null; return null;
} }
} }

View File

@@ -2,12 +2,18 @@ package org.briarproject.briar.android.keyagreement;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.Display;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams; import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView; import android.widget.TextView;
@@ -18,7 +24,6 @@ import com.google.zxing.Result;
import org.briarproject.bramble.api.UnsupportedVersionException; import org.briarproject.bramble.api.UnsupportedVersionException;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask; import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
import org.briarproject.bramble.api.keyagreement.Payload; import org.briarproject.bramble.api.keyagreement.Payload;
import org.briarproject.bramble.api.keyagreement.PayloadEncoder; import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
@@ -31,13 +36,11 @@ import org.briarproject.bramble.api.keyagreement.event.KeyAgreementStartedEvent;
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementWaitingEvent; import org.briarproject.bramble.api.keyagreement.event.KeyAgreementWaitingEvent;
import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseEventFragment; import org.briarproject.briar.android.fragment.BaseEventFragment;
import org.briarproject.briar.android.fragment.ErrorFragment; import org.briarproject.briar.android.fragment.ErrorFragment;
import org.briarproject.briar.android.view.QrCodeView;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@@ -56,14 +59,13 @@ import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.Toast.LENGTH_LONG; import static android.widget.Toast.LENGTH_LONG;
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 org.briarproject.bramble.util.LogUtils.logException;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
public class KeyAgreementFragment extends BaseEventFragment public class ShowQrCodeFragment extends BaseEventFragment
implements QrCodeDecoder.ResultCallback, QrCodeView.FullscreenListener { implements QrCodeDecoder.ResultCallback {
static final String TAG = KeyAgreementFragment.class.getName(); static final String TAG = ShowQrCodeFragment.class.getName();
private static final Logger LOG = Logger.getLogger(TAG); private static final Logger LOG = Logger.getLogger(TAG);
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
@@ -81,29 +83,26 @@ public class KeyAgreementFragment extends BaseEventFragment
EventBus eventBus; EventBus eventBus;
private CameraView cameraView; private CameraView cameraView;
private LinearLayout cameraOverlay;
private View statusView; private View statusView;
private QrCodeView qrCodeView;
private TextView status; private TextView status;
private ImageView qrCode;
private TextView mainProgressTitle;
private ViewGroup mainProgressContainer;
private boolean fullscreen = false;
private boolean gotRemotePayload; private boolean gotRemotePayload;
private volatile boolean gotLocalPayload; private volatile boolean gotLocalPayload;
private KeyAgreementTask task; private KeyAgreementTask task;
private KeyAgreementEventListener listener;
public static KeyAgreementFragment newInstance() { public static ShowQrCodeFragment newInstance() {
Bundle args = new Bundle(); Bundle args = new Bundle();
KeyAgreementFragment fragment = new KeyAgreementFragment();
ShowQrCodeFragment fragment = new ShowQrCodeFragment();
fragment.setArguments(args); fragment.setArguments(args);
return fragment; return fragment;
} }
@Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (KeyAgreementEventListener) context;
}
@Override @Override
public void injectFragment(ActivityComponent component) { public void injectFragment(ActivityComponent component) {
component.inject(this); component.inject(this);
@@ -119,6 +118,7 @@ public class KeyAgreementFragment extends BaseEventFragment
public View onCreateView(LayoutInflater inflater, public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_keyagreement_qr, container, return inflater.inflate(R.layout.fragment_keyagreement_qr, container,
false); false);
} }
@@ -126,17 +126,47 @@ public class KeyAgreementFragment extends BaseEventFragment
@Override @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
cameraView = view.findViewById(R.id.camera_view); cameraView = view.findViewById(R.id.camera_view);
cameraOverlay = view.findViewById(R.id.camera_overlay);
statusView = view.findViewById(R.id.status_container); statusView = view.findViewById(R.id.status_container);
status = view.findViewById(R.id.connect_status); status = view.findViewById(R.id.connect_status);
qrCodeView = view.findViewById(R.id.qr_code_view); qrCode = view.findViewById(R.id.qr_code);
qrCodeView.setFullscreenListener(this); mainProgressTitle = view.findViewById(R.id.title_progress_bar);
mainProgressContainer = view.findViewById(R.id.container_progress);
ImageView fullscreenButton = view.findViewById(R.id.fullscreen_button);
fullscreenButton.setOnClickListener(v -> {
View qrCodeContainer = view.findViewById(R.id.qr_code_container);
LinearLayout cameraOverlay = view.findViewById(R.id.camera_overlay);
LayoutParams statusParams, qrCodeParams;
if (fullscreen) {
// Shrink the QR code container to fill half its parent
if (cameraOverlay.getOrientation() == HORIZONTAL) {
statusParams = new LayoutParams(0, MATCH_PARENT, 1f);
qrCodeParams = new LayoutParams(0, MATCH_PARENT, 1f);
} else {
statusParams = new LayoutParams(MATCH_PARENT, 0, 1f);
qrCodeParams = new LayoutParams(MATCH_PARENT, 0, 1f);
}
fullscreenButton.setImageResource(
R.drawable.ic_fullscreen_black_48dp);
} else {
// Grow the QR code container to fill its parent
statusParams = new LayoutParams(0, 0, 0f);
qrCodeParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT, 1f);
fullscreenButton.setImageResource(
R.drawable.ic_fullscreen_exit_black_48dp);
}
statusView.setLayoutParams(statusParams);
qrCodeContainer.setLayoutParams(qrCodeParams);
cameraOverlay.invalidate();
fullscreen = !fullscreen;
});
} }
@Override @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) { public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
getActivity().setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR); getActivity().setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
cameraView.setPreviewConsumer(new QrCodeDecoder(this)); cameraView.setPreviewConsumer(new QrCodeDecoder(this));
} }
@@ -145,33 +175,30 @@ public class KeyAgreementFragment extends BaseEventFragment
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
try { try {
cameraView.start(); cameraView.start(getScreenRotationDegrees());
} catch (CameraException e) { } catch (CameraException e) {
logCameraExceptionAndFinish(e); logCameraExceptionAndFinish(e);
} }
startListening(); startListening();
} }
@Override /**
public void setFullscreen(boolean fullscreen) { * See {@link Camera#setDisplayOrientation(int)}.
LinearLayout.LayoutParams statusParams, qrCodeParams; */
if (fullscreen) { private int getScreenRotationDegrees() {
// Grow the QR code view to fill its parent Display d = getActivity().getWindowManager().getDefaultDisplay();
statusParams = new LayoutParams(0, 0, 0f); switch (d.getRotation()) {
qrCodeParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT, 1f); case Surface.ROTATION_0:
} else { return 0;
// Shrink the QR code view to fill half its parent case Surface.ROTATION_90:
if (cameraOverlay.getOrientation() == HORIZONTAL) { return 90;
statusParams = new LayoutParams(0, MATCH_PARENT, 1f); case Surface.ROTATION_180:
qrCodeParams = new LayoutParams(0, MATCH_PARENT, 1f); return 180;
} else { case Surface.ROTATION_270:
statusParams = new LayoutParams(MATCH_PARENT, 0, 1f); return 270;
qrCodeParams = new LayoutParams(MATCH_PARENT, 0, 1f); default:
} throw new AssertionError();
} }
statusView.setLayoutParams(statusParams);
qrCodeView.setLayoutParams(qrCodeParams);
cameraOverlay.invalidate();
} }
@Override @Override
@@ -187,7 +214,7 @@ public class KeyAgreementFragment extends BaseEventFragment
@UiThread @UiThread
private void logCameraExceptionAndFinish(CameraException e) { private void logCameraExceptionAndFinish(CameraException e) {
logException(LOG, WARNING, e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
Toast.makeText(getActivity(), R.string.camera_error, Toast.makeText(getActivity(), R.string.camera_error,
LENGTH_LONG).show(); LENGTH_LONG).show();
finish(); finish();
@@ -217,7 +244,7 @@ public class KeyAgreementFragment extends BaseEventFragment
// If we've stopped the camera view, restart it // If we've stopped the camera view, restart it
if (gotRemotePayload) { if (gotRemotePayload) {
try { try {
cameraView.start(); cameraView.start(getScreenRotationDegrees());
} catch (CameraException e) { } catch (CameraException e) {
logCameraExceptionAndFinish(e); logCameraExceptionAndFinish(e);
return; return;
@@ -251,7 +278,7 @@ public class KeyAgreementFragment extends BaseEventFragment
} catch (CameraException e) { } catch (CameraException e) {
logCameraExceptionAndFinish(e); logCameraExceptionAndFinish(e);
} catch (IOException | IllegalArgumentException e) { } catch (IOException | IllegalArgumentException e) {
LOG.log(WARNING, "QR Code Invalid", e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, "QR Code Invalid", e);
reset(); reset();
Toast.makeText(getActivity(), R.string.qr_code_invalid, Toast.makeText(getActivity(), R.string.qr_code_invalid,
LENGTH_LONG).show(); LENGTH_LONG).show();
@@ -274,60 +301,82 @@ public class KeyAgreementFragment extends BaseEventFragment
KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e; KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e;
keyAgreementAborted(event.didRemoteAbort()); keyAgreementAborted(event.didRemoteAbort());
} else if (e instanceof KeyAgreementFinishedEvent) { } else if (e instanceof KeyAgreementFinishedEvent) {
keyAgreementFinished(((KeyAgreementFinishedEvent) e).getResult()); runOnUiThreadUnlessDestroyed(() -> {
mainProgressContainer.setVisibility(VISIBLE);
mainProgressTitle.setText(R.string.exchanging_contact_details);
});
} }
} }
@UiThread
private void generateBitmapQR(Payload payload) {
// Get narrowest screen dimension
Context context = getContext();
if (context == null) return;
DisplayMetrics dm = context.getResources().getDisplayMetrics();
new AsyncTask<Void, Void, Bitmap>() {
@Override
@Nullable
protected Bitmap doInBackground(Void... params) {
byte[] payloadBytes = payloadEncoder.encode(payload);
if (LOG.isLoggable(INFO)) {
LOG.info("Local payload is " + payloadBytes.length
+ " bytes");
}
// Use ISO 8859-1 to encode bytes directly as a string
String content = new String(payloadBytes, ISO_8859_1);
return QrCodeUtils.createQrCode(dm, content);
}
@Override
protected void onPostExecute(@Nullable Bitmap bitmap) {
if (bitmap != null && !isDetached()) {
qrCode.setImageBitmap(bitmap);
// Simple fade-in animation
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(200);
qrCode.startAnimation(anim);
}
}
}.execute();
}
private void setQrCode(Payload localPayload) {
runOnUiThreadUnlessDestroyed(() -> generateBitmapQR(localPayload));
}
private void keyAgreementFailed() { private void keyAgreementFailed() {
runOnUiThreadUnlessDestroyed(() -> { runOnUiThreadUnlessDestroyed(() -> {
reset(); reset();
listener.keyAgreementFailed(); // TODO show failure somewhere persistent?
Toast.makeText(getActivity(), R.string.connection_failed,
LENGTH_LONG).show();
}); });
} }
private void keyAgreementWaiting() { private void keyAgreementWaiting() {
runOnUiThreadUnlessDestroyed( runOnUiThreadUnlessDestroyed(
() -> status.setText(listener.keyAgreementWaiting())); () -> status.setText(R.string.waiting_for_contact_to_scan));
} }
private void keyAgreementStarted() { private void keyAgreementStarted() {
runOnUiThreadUnlessDestroyed(() -> { runOnUiThreadUnlessDestroyed(() -> {
qrCodeView.setVisibility(INVISIBLE); mainProgressContainer.setVisibility(VISIBLE);
statusView.setVisibility(VISIBLE); mainProgressTitle.setText(R.string.authenticating_with_device);
status.setText(listener.keyAgreementStarted());
}); });
} }
private void keyAgreementAborted(boolean remoteAborted) { private void keyAgreementAborted(boolean remoteAborted) {
runOnUiThreadUnlessDestroyed(() -> { runOnUiThreadUnlessDestroyed(() -> {
reset(); reset();
qrCodeView.setVisibility(VISIBLE); mainProgressContainer.setVisibility(INVISIBLE);
statusView.setVisibility(INVISIBLE); mainProgressTitle.setText("");
status.setText(listener.keyAgreementAborted(remoteAborted)); // TODO show abort somewhere persistent?
}); Toast.makeText(getActivity(),
} remoteAborted ? R.string.connection_aborted_remote :
R.string.connection_aborted_local, LENGTH_LONG)
private void keyAgreementFinished(KeyAgreementResult result) { .show();
runOnUiThreadUnlessDestroyed(() -> {
statusView.setVisibility(VISIBLE);
status.setText(listener.keyAgreementFinished(result));
});
}
private void setQrCode(Payload localPayload) {
Context context = getContext();
if (context == null) return;
DisplayMetrics dm = context.getResources().getDisplayMetrics();
ioExecutor.execute(() -> {
byte[] payloadBytes = payloadEncoder.encode(localPayload);
if (LOG.isLoggable(INFO)) {
LOG.info("Local payload is " + payloadBytes.length
+ " bytes");
}
// Use ISO 8859-1 to encode bytes directly as a string
String content = new String(payloadBytes, ISO_8859_1);
Bitmap qrCode = QrCodeUtils.createQrCode(dm, content);
runOnUiThreadUnlessDestroyed(() -> qrCodeView.setQrCode(qrCode));
}); });
} }
@@ -345,31 +394,4 @@ public class KeyAgreementFragment extends BaseEventFragment
protected void finish() { protected void finish() {
getActivity().getSupportFragmentManager().popBackStack(); getActivity().getSupportFragmentManager().popBackStack();
} }
@NotNullByDefault
interface KeyAgreementEventListener {
@UiThread
void keyAgreementFailed();
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementWaiting();
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementStarted();
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementAborted(boolean remoteAborted);
// Should return a string to be displayed as status.
@UiThread
@Nullable
String keyAgreementFinished(KeyAgreementResult result);
}
} }

View File

@@ -42,22 +42,6 @@ public class BriefLogFormatter extends Formatter {
tag = tag.substring(tag.lastIndexOf('.') + 1); tag = tag.substring(tag.lastIndexOf('.') + 1);
sb.append(tag).append(": "); sb.append(tag).append(": ");
sb.append(record.getMessage()); sb.append(record.getMessage());
Throwable t = record.getThrown();
if (t != null) {
sb.append('\n');
appendThrowable(sb, t);
}
return sb.toString(); return sb.toString();
} }
private void appendThrowable(StringBuilder sb, Throwable t) {
sb.append(t);
for (StackTraceElement e : t.getStackTrace())
sb.append("\n at ").append(e);
Throwable cause = t.getCause();
if (cause != null) {
sb.append("\n Caused by: ");
appendThrowable(sb, cause);
}
}
} }

View File

@@ -16,8 +16,6 @@ import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static android.os.Build.VERSION.SDK_INT;
@UiThread @UiThread
@NotNullByDefault @NotNullByDefault
class HuaweiView extends PowerView { class HuaweiView extends PowerView {
@@ -47,8 +45,6 @@ class HuaweiView extends PowerView {
} }
public static boolean needsToBeShown(Context context) { public static boolean needsToBeShown(Context context) {
// "Protected apps" no longer exists on Huawei EMUI 5.0 (Android 7.0)
if (SDK_INT >= 24) return false;
PackageManager pm = context.getPackageManager(); PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(getIntent(), List<ResolveInfo> resolveInfos = pm.queryIntentActivities(getIntent(),
PackageManager.MATCH_DEFAULT_ONLY); PackageManager.MATCH_DEFAULT_ONLY);

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