diff --git a/F-Droid/res/layout/swap_join_wifi.xml b/F-Droid/res/layout/swap_join_wifi.xml
index 2b579ca14..d6a9285d7 100644
--- a/F-Droid/res/layout/swap_join_wifi.xml
+++ b/F-Droid/res/layout/swap_join_wifi.xml
@@ -26,15 +26,10 @@
android:layout_below="@+id/text_description"
android:layout_centerHorizontal="true" />
-
-
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
index 8a54b0f5e..49b78ddca 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
@@ -585,6 +585,7 @@ public class SwapService extends Service {
private void enableSwappingAsynchronous() {
webServerType.startInBackground();
bonjourType.startInBackground();
+ bluetoothType.startInBackground();
}
/**
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java
index aa62f88b1..bcd2d84ce 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java
@@ -2,6 +2,7 @@ package org.fdroid.fdroid.localrepo.peers;
import android.content.Context;
import android.content.Intent;
+import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import org.fdroid.fdroid.localrepo.SwapService;
@@ -33,7 +34,7 @@ public abstract class PeerFinder {
Log.i(TAG, "Found peer " + peer.getName());
Intent intent = new Intent(SwapService.ACTION_PEER_FOUND);
intent.putExtra(SwapService.EXTRA_PEER, peer);
- context.sendBroadcast(intent);
+ LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
protected void removePeer(T peer) {
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothType.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothType.java
index 75681af1a..f4024fada 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothType.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothType.java
@@ -9,6 +9,7 @@ import android.support.annotation.NonNull;
import android.util.Log;
import org.fdroid.fdroid.localrepo.SwapService;
+import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
public class BluetoothType extends SwapType {
@@ -17,6 +18,8 @@ public class BluetoothType extends SwapType {
@NonNull
private final BluetoothAdapter adapter;
+ private final BluetoothServer server;
+
public static SwapType create(@NonNull Context context) {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) {
@@ -29,6 +32,7 @@ public class BluetoothType extends SwapType {
private BluetoothType(@NonNull Context context, @NonNull BluetoothAdapter adapter) {
super(context);
this.adapter = adapter;
+ this.server = new BluetoothServer(context, context.getFilesDir());
context.registerReceiver(new BroadcastReceiver() {
@Override
@@ -50,6 +54,11 @@ public class BluetoothType extends SwapType {
@Override
public void start() {
+ if (server.isAlive()) {
+ Log.d(TAG, "Attempting to start Bluetooth swap, but it appears to be running already.");
+ return;
+ }
+
sendBroadcast(SwapService.EXTRA_STARTING);
if (!adapter.isEnabled()) {
@@ -60,26 +69,22 @@ public class BluetoothType extends SwapType {
}
if (adapter.isEnabled()) {
- Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
-
- // TODO: Hmm, don't like the idea of a background service being able to do this :(
- discoverableIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- // Can't get notified if they cancel this, because we are not an activity and thus
- // can't start an activity for a result :(
- context.startActivity(discoverableIntent);
-
- // Don't setConnected(true) yet, wait for the broadcast to come from the BluetoothAdapter
- // saying its state has changed.
+ server.start();
+ setConnected(true);
+ } else {
+ Log.i(TAG, "Didn't start Bluetooth swapping server, because Bluetooth is disabled and couldn't be enabled.");
+ setConnected(false);
}
}
@Override
public void stop() {
- Log.d(TAG, "Making bluetooth non-discoverable.");
- adapter.cancelDiscovery();
- setConnected(false);
+ if (server.isAlive()) {
+ server.close();
+ setConnected(false);
+ } else {
+ Log.i(TAG, "Attempting to stop Bluetooth swap, but it is not currently running.");
+ }
}
@Override
diff --git a/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java b/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java
index 59192b932..c03eb0376 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java
@@ -11,6 +11,7 @@ public class DownloaderFactory {
public static Downloader create(String url, Context context) throws IOException {
Uri uri = Uri.parse(url);
if (isBluetoothAddress(uri)) {
+ // TODO: Don't pass null!!!
return new BluetoothDownloader(null, uri.getPath(), context);
} else if (isOnionAddress(url)) {
return new TorHttpDownloader(url, context);
@@ -22,6 +23,7 @@ public class DownloaderFactory {
public static Downloader create(String url, File destFile) throws IOException {
Uri uri = Uri.parse(url);
if (isBluetoothAddress(uri)) {
+ // TODO: Don't pass null!!!
return new BluetoothDownloader(null, uri.getPath(), destFile);
} else if (isOnionAddress(url)) {
return new TorHttpDownloader(url, destFile);
diff --git a/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java b/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
index 9066ba5f5..35268a6d1 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
@@ -56,6 +56,8 @@ public class BluetoothServer extends Thread {
connection.interrupt();
}
+ interrupt();
+
if (serverSocket != null) {
Utils.closeQuietly(serverSocket);
}
@@ -86,6 +88,10 @@ public class BluetoothServer extends Thread {
}
while (true) {
+ if (isInterrupted()) {
+ break;
+ }
+
try {
BluetoothSocket clientSocket = serverSocket.accept();
if (clientSocket != null && !isInterrupted()) {
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/JoinWifiView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/JoinWifiView.java
index b1530d97f..2354e65f0 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/JoinWifiView.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/JoinWifiView.java
@@ -72,16 +72,6 @@ public class JoinWifiView extends RelativeLayout implements SwapWorkflowActivity
},
new IntentFilter(WifiStateChangeService.BROADCAST)
);
-
- Button bluetooth = (Button)findViewById(R.id.btn_bluetooth);
- bluetooth.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().connectWithBluetooth();
- }
- }
- );
-
}
// TODO: Listen for "Connecting..." state and reflect that in the view too.
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
index c5565dc27..496ca2aa5 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
@@ -216,7 +216,7 @@ public class StartSwapView extends ScrollView implements SwapWorkflowActivity.In
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
- getManager().ensureBluetoothDiscoverable();
+ getActivity().connectWithBluetooth();
textBluetoothVisible.setText(R.string.swap_visible_bluetooth);
viewBluetoothId.setVisibility(View.VISIBLE);
uiUpdatePeersInfo();
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
index 2fad9a8a4..8cde31216 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
@@ -421,7 +421,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
if (resultCode == RESULT_OK) {
Log.d(TAG, "User enabled Bluetooth, will make sure we are discoverable.");
- ensureBluetoothDiscoverable();
+ ensureBluetoothDiscoverableThenStart();
} else {
// Didn't enable bluetooth
Log.d(TAG, "User chose not to enable Bluetooth, so doing nothing (i.e. sticking with wifi).");
@@ -458,7 +458,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
if (adapter != null)
if (adapter.isEnabled()) {
Log.d(TAG, "Bluetooth enabled, will pair with device.");
- ensureBluetoothDiscoverable();
+ ensureBluetoothDiscoverableThenStart();
} else {
Log.d(TAG, "Bluetooth disabled, asking user to enable it.");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
@@ -466,7 +466,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
}
- private void ensureBluetoothDiscoverable() {
+ private void ensureBluetoothDiscoverableThenStart() {
Log.d(TAG, "Ensuring Bluetooth is in discoverable mode.");
if (BluetoothAdapter.getDefaultAdapter().getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
@@ -475,13 +475,15 @@ public class SwapWorkflowActivity extends AppCompatActivity {
Log.d(TAG, "Not currently in discoverable mode, so prompting user to enable.");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
+ intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); // TODO: What about when this expires? What if user manually disables discovery?
startActivityForResult(intent, REQUEST_BLUETOOTH_DISCOVERABLE);
}
- Log.d(TAG, "Staring the Bluetooth Server whether we are discoverable or not, since paired devices can still connect.");
- startBluetoothServer();
+ if (service == null) {
+ throw new IllegalStateException("Can't start Bluetooth swap because service is null for some strange reason.");
+ }
+ service.getBluetooth().startInBackground();
}
private void startBluetoothServer() {