mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Compare commits
4 Commits
alpha-1.4.
...
bluetooth_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a51f0f803f | ||
|
|
8f9d7a70bf | ||
|
|
3ea642c6c0 | ||
|
|
da0a32c613 |
@@ -24,7 +24,9 @@ import org.briarproject.bramble.api.system.Scheduler;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -53,6 +55,7 @@ class Poller implements EventListener {
|
||||
private final Clock clock;
|
||||
private final Lock lock;
|
||||
private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock
|
||||
private final Set<TransportId> polling; // Locking: lock
|
||||
|
||||
@Inject
|
||||
Poller(@IoExecutor Executor ioExecutor,
|
||||
@@ -69,16 +72,19 @@ class Poller implements EventListener {
|
||||
this.clock = clock;
|
||||
lock = new ReentrantLock();
|
||||
tasks = new HashMap<>();
|
||||
polling = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ContactStatusChangedEvent) {
|
||||
ContactStatusChangedEvent c = (ContactStatusChangedEvent) e;
|
||||
/*
|
||||
if (c.isActive()) {
|
||||
// Connect to the newly activated contact
|
||||
connectToContact(c.getContactId());
|
||||
}
|
||||
*/
|
||||
} else if (e instanceof ConnectionClosedEvent) {
|
||||
ConnectionClosedEvent c = (ConnectionClosedEvent) e;
|
||||
// Reschedule polling, the polling interval may have decreased
|
||||
@@ -215,20 +221,33 @@ class Poller implements EventListener {
|
||||
@Override
|
||||
@IoExecutor
|
||||
public void run() {
|
||||
TransportId t = plugin.getId();
|
||||
boolean shouldPoll;
|
||||
lock.lock();
|
||||
try {
|
||||
TransportId t = plugin.getId();
|
||||
ScheduledPollTask scheduled = tasks.get(t);
|
||||
if (scheduled != null && scheduled.task != this)
|
||||
return; // Replaced by another task
|
||||
tasks.remove(t);
|
||||
// Don't poll again if last poll is still running
|
||||
shouldPoll = polling.add(t);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
int delay = plugin.getPollingInterval();
|
||||
if (randomiseNext) delay = (int) (delay * random.nextDouble());
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,11 @@ import org.briarproject.bramble.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -53,6 +55,12 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
||||
private static final Logger LOG =
|
||||
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 = 3000;
|
||||
|
||||
final BluetoothConnectionLimiter connectionLimiter;
|
||||
|
||||
private final Executor ioExecutor;
|
||||
@@ -253,27 +261,42 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
||||
public void poll(Collection<ContactId> connected) {
|
||||
if (!isRunning() || !shouldAllowContactConnections()) return;
|
||||
backoff.increment();
|
||||
// Try to connect to known devices in parallel
|
||||
// Try to connect to known devices in a random order
|
||||
Map<ContactId, TransportProperties> remote =
|
||||
callback.getRemoteProperties();
|
||||
for (Entry<ContactId, TransportProperties> e : remote.entrySet()) {
|
||||
ContactId c = e.getKey();
|
||||
if (connected.contains(c)) continue;
|
||||
String address = e.getValue().get(PROP_ADDRESS);
|
||||
if (StringUtils.isNullOrEmpty(address)) continue;
|
||||
String uuid = e.getValue().get(PROP_UUID);
|
||||
if (StringUtils.isNullOrEmpty(uuid)) continue;
|
||||
ioExecutor.execute(() -> {
|
||||
List<ContactId> keys = new ArrayList<>(remote.keySet());
|
||||
Collections.shuffle(keys);
|
||||
ioExecutor.execute(() -> {
|
||||
boolean first = true;
|
||||
for (ContactId c : keys) {
|
||||
if (!isRunning() || !shouldAllowContactConnections()) return;
|
||||
if (!connectionLimiter.canOpenContactConnection()) return;
|
||||
if (connected.contains(c)) continue;
|
||||
TransportProperties p = remote.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);
|
||||
if (conn != null) {
|
||||
backoff.reset();
|
||||
if (connectionLimiter.contactConnectionOpened(conn))
|
||||
callback.outgoingConnectionCreated(c, conn);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -33,6 +33,10 @@ dependencies {
|
||||
implementation 'com.jpardogo.materialtabstrip:library:1.1.0'
|
||||
implementation 'com.github.bumptech.glide:glide:3.8.0'
|
||||
implementation 'uk.co.samuelwall:material-tap-target-prompt:2.8.0'
|
||||
implementation'fr.bmartel:jspeedtest:1.32.0'
|
||||
implementation 'com.jjoe64:graphview:4.2.2'
|
||||
|
||||
|
||||
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
|
||||
|
||||
|
||||
@@ -4,17 +4,18 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-feature android:name="android.hardware.bluetooth"/>
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera"/>
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.READ_LOGS"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
|
||||
<application
|
||||
@@ -69,8 +70,8 @@
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.splash.SplashScreenActivity"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:label="@string/app_name">
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
@@ -84,15 +85,15 @@
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:launchMode="singleTop">
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.contact.ConversationActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
@@ -132,7 +133,7 @@
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.privategroup.memberlist.GroupMemberListActivity"
|
||||
android:label="@string/groups_member_list"
|
||||
android:parentActivityName="org.briarproject.briar.android.privategroup.conversation.GroupActivity"
|
||||
@@ -304,8 +305,8 @@
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.keyagreement.KeyAgreementActivity"
|
||||
android:label="@string/add_contact_title"
|
||||
android:theme="@style/BriarTheme.NoActionBar"
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity">
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
|
||||
@@ -362,6 +363,16 @@
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.test.PollingTestActivity"
|
||||
android:label="Test polling"
|
||||
android:parentActivityName="org.briarproject.briar.android.settings.SettingsActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.briarproject.briar.android.settings.SettingsActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.panic.PanicPreferencesActivity"
|
||||
android:label="@string/panic_setting"
|
||||
|
||||
@@ -70,6 +70,7 @@ import org.briarproject.briar.android.sharing.ShareForumFragment;
|
||||
import org.briarproject.briar.android.sharing.ShareForumMessageFragment;
|
||||
import org.briarproject.briar.android.sharing.SharingModule;
|
||||
import org.briarproject.briar.android.splash.SplashScreenActivity;
|
||||
import org.briarproject.briar.android.test.PollingTestActivity;
|
||||
import org.briarproject.briar.android.test.TestDataActivity;
|
||||
|
||||
import dagger.Component;
|
||||
@@ -150,6 +151,8 @@ public interface ActivityComponent {
|
||||
|
||||
void inject(TestDataActivity activity);
|
||||
|
||||
void inject(PollingTestActivity activity);
|
||||
|
||||
void inject(ChangePasswordActivity activity);
|
||||
|
||||
void inject(IntroductionActivity activity);
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
package org.briarproject.briar.android.test;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.jjoe64.graphview.GraphView;
|
||||
import com.jjoe64.graphview.series.DataPoint;
|
||||
import com.jjoe64.graphview.series.LineGraphSeries;
|
||||
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||
import org.briarproject.bramble.api.plugin.event.TransportDisabledEvent;
|
||||
import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent;
|
||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
import org.briarproject.briar.api.test.TestDataCreator;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import fr.bmartel.speedtest.SpeedTestReport;
|
||||
import fr.bmartel.speedtest.SpeedTestSocket;
|
||||
import fr.bmartel.speedtest.inter.ISpeedTestListener;
|
||||
import fr.bmartel.speedtest.model.SpeedTestError;
|
||||
|
||||
public class PollingTestActivity extends BriarActivity {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(PollingTestActivity.class.getName());
|
||||
|
||||
// Add one contact after each round up to:
|
||||
private static int NUMBER_OF_CONTACTS = 10;
|
||||
// Download x times per #contacts
|
||||
private static int NUMBER_OF_DOWNLOADS = 1;
|
||||
// File size to download. One of (5,10,50,100,500)MB.
|
||||
private static int DOWNLOAD_SIZE = 10;
|
||||
// Time to wait between each round in ms.
|
||||
private static int PAUSE = 5000;
|
||||
// Socket timeout in ms
|
||||
private static int SO_TIMEOUT = 60000;
|
||||
|
||||
@Inject
|
||||
TestDataCreator testDataCreator;
|
||||
@Inject
|
||||
AndroidExecutor executor;
|
||||
@Inject
|
||||
EventBus eventBus;
|
||||
|
||||
GraphView graphView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setHomeButtonEnabled(true);
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
setContentView(R.layout.activity_test_polling);
|
||||
Button button = findViewById(R.id.run_test_button);
|
||||
button.setOnClickListener(v -> {
|
||||
runTest();
|
||||
});
|
||||
graphView = findViewById(R.id.graph);
|
||||
graphView.getGridLabelRenderer()
|
||||
.setHorizontalAxisTitle("Number of contacts");
|
||||
graphView.getGridLabelRenderer().setVerticalAxisTitle("MBit/s");
|
||||
graphView.getViewport().setXAxisBoundsManual(true);
|
||||
graphView.getViewport().setMinX(0);
|
||||
graphView.getViewport().setMaxX(NUMBER_OF_CONTACTS);
|
||||
}
|
||||
|
||||
private void runTest() {
|
||||
executor.runOnBackgroundThread(() -> {
|
||||
LineGraphSeries<DataPoint> series = new LineGraphSeries<>();
|
||||
graphView.addSeries(series);
|
||||
for (int i = 0; i < NUMBER_OF_CONTACTS; i++) {
|
||||
if (i != 0) {
|
||||
createContact();
|
||||
// Wait to let the previous round of polling settle.
|
||||
synchronized (this) {
|
||||
try {
|
||||
wait(PAUSE);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset BT polling.
|
||||
eventBus.broadcast(new TransportDisabledEvent(
|
||||
BluetoothConstants.ID));
|
||||
eventBus.broadcast(
|
||||
new TransportEnabledEvent(BluetoothConstants.ID));
|
||||
LOG.info("\n###########\nRound " + i + " (Contacts)");
|
||||
double y = run();
|
||||
series.appendData(new DataPoint(i, y), false,
|
||||
NUMBER_OF_CONTACTS);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private double run() {
|
||||
SpeedTestReport reports[] = new SpeedTestReport[3];
|
||||
double average = 0;
|
||||
for (int i = 0; i < NUMBER_OF_DOWNLOADS; i++) {
|
||||
final CountDownLatch cl = new CountDownLatch(1);
|
||||
SpeedTestSocket speedTestSocket = new SpeedTestSocket();
|
||||
speedTestSocket.setSocketTimeout(SO_TIMEOUT);
|
||||
int finalI = i;
|
||||
speedTestSocket.addSpeedTestListener(new ISpeedTestListener() {
|
||||
@Override
|
||||
public void onCompletion(SpeedTestReport report) {
|
||||
LOG.info("[COMPLETED]: rate in bit/s : " +
|
||||
report.getTransferRateBit() + " in " +
|
||||
(report.getReportTime() -
|
||||
report.getStartTime()) + "ms");
|
||||
reports[finalI] = report;
|
||||
cl.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(float percent,
|
||||
SpeedTestReport report) {
|
||||
/* LOG.info("[PROGRESS] rate in bit/s : " +
|
||||
report.getTransferRateBit());
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(SpeedTestError speedTestError,
|
||||
String errorMessage) {
|
||||
LOG.info("Error: " + speedTestError.name() + " : " +
|
||||
errorMessage);
|
||||
|
||||
}
|
||||
});
|
||||
LOG.info("Download " + (i + 1) + " of " + NUMBER_OF_DOWNLOADS);
|
||||
speedTestSocket
|
||||
.startDownload(
|
||||
"http://ikoula.testdebit.info/" + DOWNLOAD_SIZE +
|
||||
"M.iso");
|
||||
try {
|
||||
cl.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
average += reports[i].getTransferRateBit().doubleValue() / 1000000;
|
||||
}
|
||||
return average / NUMBER_OF_DOWNLOADS;
|
||||
}
|
||||
|
||||
private void createContact() {
|
||||
testDataCreator.createTestData(1, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
24
briar-android/src/main/res/layout/activity_test_polling.xml
Normal file
24
briar-android/src/main/res/layout/activity_test_polling.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Button
|
||||
android:id="@+id/run_test_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Run test"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
/>
|
||||
<com.jjoe64.graphview.GraphView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/run_test_button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:id="@+id/graph" />
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
@@ -131,4 +131,13 @@
|
||||
android:targetPackage="@string/app_package"/>
|
||||
</Preference>
|
||||
|
||||
<Preference
|
||||
android:key="pref_key_speed_test"
|
||||
android:title="Test polling impact on bandwith">
|
||||
|
||||
<intent
|
||||
android:targetClass="org.briarproject.briar.android.test.PollingTestActivity"
|
||||
android:targetPackage="@string/app_package"/>
|
||||
</Preference>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
Reference in New Issue
Block a user