diff --git a/F-Droid/res/layout/swap_bluetooth_devices.xml b/F-Droid/res/layout/swap_bluetooth_devices.xml
deleted file mode 100644
index fd16a39ed..000000000
--- a/F-Droid/res/layout/swap_bluetooth_devices.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
index 3b376095b..5ef60e9c5 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
@@ -39,7 +39,6 @@ import org.fdroid.fdroid.localrepo.peers.BluetoothFinder;
import org.fdroid.fdroid.localrepo.peers.BonjourFinder;
import org.fdroid.fdroid.localrepo.peers.Peer;
import org.fdroid.fdroid.localrepo.type.BluetoothSwap;
-import org.fdroid.fdroid.localrepo.type.BonjourBroadcast;
import org.fdroid.fdroid.localrepo.type.SwapType;
import org.fdroid.fdroid.localrepo.type.WifiSwap;
import org.fdroid.fdroid.net.WifiStateChangeService;
@@ -65,8 +64,10 @@ import java.util.TimerTask;
public class SwapService extends Service {
private static final String TAG = "SwapManager";
- private static final String SHARED_PREFERENCES = "swap-state";
+ public static final String SHARED_PREFERENCES = "swap-state";
private static final String KEY_APPS_TO_SWAP = "appsToSwap";
+ private static final String KEY_BLUETOOTH_ENABLED = "bluetoothEnabled";
+ private static final String KEY_WIFI_ENABLED = "wifiEnabled";
@NonNull
private Set appsToSwap = new HashSet<>();
@@ -353,6 +354,25 @@ public class SwapService extends Service {
}
+ // =============================================================
+ // Remember which swap technologies a user used in the past
+ // =============================================================
+
+ private void persistPreferredSwapTypes() {
+ persistence().edit()
+ .putBoolean(KEY_BLUETOOTH_ENABLED, bluetoothSwap.isConnected())
+ .putBoolean(KEY_WIFI_ENABLED, wifiSwap.isConnected())
+ .commit();
+ }
+
+ private boolean wasBluetoothEnabled() {
+ return persistence().getBoolean(KEY_BLUETOOTH_ENABLED, false);
+ }
+
+ private boolean wasWifiEnabled() {
+ return persistence().getBoolean(KEY_WIFI_ENABLED, false);
+ }
+
// ==========================================
// Local repo stop/start/restart handling
// ==========================================
@@ -409,6 +429,14 @@ public class SwapService extends Service {
// Interacting with Bluetooth adapter
// ==========================================
+ public BonjourFinder getBonjourFinder() {
+ return bonjourFinder;
+ }
+
+ public BluetoothFinder getBluetoothFinder() {
+ return bluetoothFinder;
+ }
+
public boolean isBluetoothDiscoverable() {
return bluetoothSwap.isConnected();
}
@@ -487,6 +515,16 @@ public class SwapService extends Service {
IntentFilter filter = new IntentFilter(BLUETOOTH_STATE_CHANGE);
filter.addAction(WIFI_STATE_CHANGE);
LocalBroadcastManager.getInstance(this).registerReceiver(receiveSwapStatusChanged, filter);
+
+ if (wasBluetoothEnabled()) {
+ Log.d(TAG, "Previously the user enabled Bluetooth swap, so enabling again automatically.");
+ bluetoothSwap.startInBackground();
+ }
+
+ if (wasWifiEnabled()) {
+ Log.d(TAG, "Previously the user enabled Wifi swap, so enabling again automatically.");
+ wifiSwap.startInBackground();
+ }
}
/**
@@ -505,6 +543,7 @@ public class SwapService extends Service {
detachService();
}
}
+ persistPreferredSwapTypes();
}
};
@@ -520,15 +559,10 @@ public class SwapService extends Service {
}
public void disableAllSwapping() {
- new AsyncTask() {
- @Override
- protected Void doInBackground(Void... params) {
- getBluetoothSwap().stop();
- getWifiSwap().stop();
- detachService();
- return null;
- }
- }.execute();
+ Log.i(TAG, "Asked to stop swapping, will stop bluetooth, wifi, and move service to BG for GC.");
+ getBluetoothSwap().stopInBackground();
+ getWifiSwap().stopInBackground();
+ detachService();
}
@Override
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java
index 6de94e849..d14f07bc0 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java
@@ -8,9 +8,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
-import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
+import org.fdroid.fdroid.localrepo.type.BluetoothSwap;
-// TODO: Still to be implemented
public class BluetoothFinder extends PeerFinder {
private static final String TAG = "BluetoothFinder";
@@ -69,8 +68,8 @@ public class BluetoothFinder extends PeerFinder {
if (adapter.isDiscovering()) {
// TODO: Can we reset the discovering timeout, so that it doesn't, e.g. time out
// in 3 seconds because we had already almost completed the previous scan?
- Log.d(TAG, "Requested bluetooth scan when already scanning, will cancel previous scan before continuing.");
- adapter.cancelDiscovery();
+ Log.d(TAG, "Requested bluetooth scan when already scanning, so will ignore request.");
+ return;
}
if (!adapter.startDiscovery()) {
@@ -90,7 +89,7 @@ public class BluetoothFinder extends PeerFinder {
}
private void onDeviceFound(BluetoothDevice device) {
- if (device != null && device.getName() != null && device.getName().startsWith(BluetoothServer.BLUETOOTH_NAME_TAG)) {
+ if (device != null && device.getName() != null && device.getName().startsWith(BluetoothSwap.BLUETOOTH_NAME_TAG)) {
foundPeer(new BluetoothPeer(device));
}
}
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothPeer.java b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothPeer.java
index ca3f58210..68e5606f2 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothPeer.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothPeer.java
@@ -4,9 +4,8 @@ import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import org.fdroid.fdroid.R;
-import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
+import org.fdroid.fdroid.localrepo.type.BluetoothSwap;
-// TODO: Still to be implemented.
public class BluetoothPeer implements Peer {
private BluetoothDevice device;
@@ -22,7 +21,7 @@ public class BluetoothPeer implements Peer {
@Override
public String getName() {
- return device.getName().replaceAll("^" + BluetoothServer.BLUETOOTH_NAME_TAG, "");
+ return device.getName().replaceAll("^" + BluetoothSwap.BLUETOOTH_NAME_TAG, "");
}
@Override
@@ -37,7 +36,7 @@ public class BluetoothPeer implements Peer {
@Override
public String getRepoAddress() {
- return "bluetooth://" + device.getAddress() + "/fdroid/repo";
+ return "bluetooth://" + device.getAddress().replace(':', '-') + "/fdroid/repo";
}
@Override
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java
index a6ad807e5..a00d21af5 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java
@@ -68,6 +68,7 @@ public class BonjourFinder extends PeerFinder implements ServiceLis
@Override
protected void onPostExecute(Void result) {
+ // TODO: This is not threadsafe - cancelling the discovery will make jmdns null, but it could happen after this check and before call to addServiceListener().
if (jmdns != null) {
Log.d(TAG, "Adding mDNS service listeners for " + HTTP_SERVICE_TYPE + " and " + HTTPS_SERVICE_TYPE);
jmdns.addServiceListener(HTTP_SERVICE_TYPE, BonjourFinder.this);
@@ -80,13 +81,16 @@ public class BonjourFinder extends PeerFinder implements ServiceLis
}
private void listServices() {
+
+ final JmDNS mdns = jmdns;
+
new AsyncTask() {
@Override
protected Void doInBackground(Void... params) {
Log.d(TAG, "Explicitly querying for services, in addition to waiting for notifications.");
- addFDroidServices(jmdns.list(HTTP_SERVICE_TYPE));
- addFDroidServices(jmdns.list(HTTPS_SERVICE_TYPE));
+ addFDroidServices(mdns.list(HTTP_SERVICE_TYPE));
+ addFDroidServices(mdns.list(HTTPS_SERVICE_TYPE));
return null;
}
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
index e7d4504dd..5e01d59df 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
@@ -6,6 +6,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.Log;
import org.fdroid.fdroid.localrepo.SwapService;
@@ -14,11 +15,15 @@ import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
public class BluetoothSwap extends SwapType {
private static final String TAG = "BluetoothBroadcastType";
+ public final static String BLUETOOTH_NAME_TAG = "FDroid:";
@NonNull
private final BluetoothAdapter adapter;
- private final BluetoothServer server;
+ @Nullable
+ private BluetoothServer server;
+
+ private String deviceBluetoothName = null;
public static SwapType create(@NonNull Context context) {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -27,12 +32,11 @@ public class BluetoothSwap extends SwapType {
} else {
return new BluetoothSwap(context, adapter);
}
- };
+ }
private BluetoothSwap(@NonNull Context context, @NonNull BluetoothAdapter adapter) {
super(context);
this.adapter = adapter;
- this.server = new BluetoothServer(context, context.getFilesDir());
context.registerReceiver(new BroadcastReceiver() {
@Override
@@ -52,17 +56,39 @@ public class BluetoothSwap extends SwapType {
}, new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED));
}
+ @Override
+ public boolean isConnected() {
+ return server != null && server.isRunning() && super.isConnected();
+ }
+
@Override
public void start() {
- if (server.isAlive()) {
- Log.d(TAG, "Attempting to start Bluetooth swap, but it appears to be running already.");
- return;
+ if (server != null) {
+ Log.d(TAG, "Attempting to start Bluetooth swap, but it appears to be running already. Will cancel it so it can be restarted.");
+ server.close();
+ server = null;
}
+ server = new BluetoothServer(this, context.getFilesDir());
+
sendBroadcast(SwapService.EXTRA_STARTING);
+ //store the original bluetoothname, and update this one to be unique
+ deviceBluetoothName = adapter.getName();
+
+ Log.d(TAG, "Prefixing Bluetooth adapter name with " + BLUETOOTH_NAME_TAG + " to make it identifiable as a swap device.");
+ if (!deviceBluetoothName.startsWith(BLUETOOTH_NAME_TAG))
+ adapter.setName(BLUETOOTH_NAME_TAG + deviceBluetoothName);
+
+ if (!adapter.getName().startsWith(BLUETOOTH_NAME_TAG)) {
+ Log.e(TAG, "Couldn't change the name of the Bluetooth adapter, it will not get recognized by other swap clients.");
+ // TODO: Should we bail here?
+ }
+
if (!adapter.isEnabled()) {
+ Log.d(TAG, "Bluetooth adapter is disabled, attempting to enable.");
if (!adapter.enable()) {
+ Log.d(TAG, "Could not enable Bluetooth adapter, so bailing out of Bluetooth swap.");
setConnected(false);
return;
}
@@ -79,7 +105,7 @@ public class BluetoothSwap extends SwapType {
@Override
public void stop() {
- if (server.isAlive()) {
+ if (server != null && server.isAlive()) {
server.close();
setConnected(false);
} else {
@@ -87,6 +113,11 @@ public class BluetoothSwap extends SwapType {
}
}
+ protected void onStopped() {
+ Log.d(TAG, "Resetting bluetooth device name to " + deviceBluetoothName + " after swapping.");
+ adapter.setName(deviceBluetoothName);
+ }
+
@Override
public String getBroadcastAction() {
return SwapService.BLUETOOTH_STATE_CHANGE;
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java
index 9f8d48371..1e6f781a1 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java
@@ -2,6 +2,7 @@ package org.fdroid.fdroid.localrepo.type;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
@@ -38,10 +39,13 @@ public abstract class SwapType {
sendBroadcast(SwapService.EXTRA_STARTED);
} else {
isConnected = false;
+ onStopped();
sendBroadcast(SwapService.EXTRA_STOPPED);
}
}
+ protected void onStopped() {}
+
/**
* Sends either a {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STARTING},
* {@link org.fdroid.fdroid.localrepo.SwapService#EXTRA_STARTED} or
@@ -55,7 +59,7 @@ public abstract class SwapType {
}
}
- public final boolean isConnected() {
+ public boolean isConnected() {
return isConnected;
}
@@ -84,4 +88,15 @@ public abstract class SwapType {
}
}.execute();
}
+
+ public void stopInBackground() {
+ new AsyncTask() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ stop();
+ return null;
+ }
+ }.execute();
+ }
+
}
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/WifiSwap.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/WifiSwap.java
index 774b2a4ee..80dc2bc99 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/WifiSwap.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/WifiSwap.java
@@ -60,19 +60,24 @@ public class WifiSwap extends SwapType {
@Override
public void handleMessage(Message msg) {
Log.i(TAG, "we've been asked to stop the webserver: " + msg.obj);
+ setConnected(false);
localHttpd.stop();
}
};
try {
Log.d(TAG, "Starting swap webserver...");
+ sendBroadcast(SwapService.EXTRA_STARTING);
localHttpd.start();
+ setConnected(true);
Log.d(TAG, "Swap webserver started.");
} catch (BindException e) {
int prev = FDroidApp.port;
FDroidApp.port = FDroidApp.port + new Random().nextInt(1111);
+ setConnected(false);
Log.w(TAG, "port " + prev + " occupied, trying on " + FDroidApp.port + "!");
context.startService(new Intent(context, WifiStateChangeService.class));
} catch (IOException e) {
+ setConnected(false);
Log.e(TAG, "Could not start local repo HTTP server: " + e);
Log.e(TAG, Log.getStackTraceString(e));
}
diff --git a/F-Droid/src/org/fdroid/fdroid/net/BluetoothDownloader.java b/F-Droid/src/org/fdroid/fdroid/net/BluetoothDownloader.java
index a860e2aa2..7f90508f7 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/BluetoothDownloader.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/BluetoothDownloader.java
@@ -3,6 +3,7 @@ package org.fdroid.fdroid.net;
import android.content.Context;
import android.util.Log;
import org.apache.commons.io.input.BoundedInputStream;
+import org.fdroid.fdroid.net.bluetooth.BluetoothClient;
import org.fdroid.fdroid.net.bluetooth.BluetoothConnection;
import org.fdroid.fdroid.net.bluetooth.FileDetails;
import org.fdroid.fdroid.net.bluetooth.httpish.Request;
@@ -23,21 +24,15 @@ public class BluetoothDownloader extends Downloader {
private FileDetails fileDetails;
private final String sourcePath;
- public BluetoothDownloader(BluetoothConnection connection, String sourcePath, Context ctx) throws IOException {
+ public BluetoothDownloader(String macAddress, String sourcePath, Context ctx) throws IOException {
super(ctx);
- this.connection = connection;
+ this.connection = new BluetoothClient(macAddress).openConnection();
this.sourcePath = sourcePath;
}
- public BluetoothDownloader(BluetoothConnection connection, String sourcePath, File destFile) throws FileNotFoundException, MalformedURLException {
+ public BluetoothDownloader(String macAddress, String sourcePath, File destFile) throws IOException {
super(destFile);
- this.connection = connection;
- this.sourcePath = sourcePath;
- }
-
- public BluetoothDownloader(BluetoothConnection connection, String sourcePath, OutputStream output) throws MalformedURLException {
- super(output);
- this.connection = connection;
+ this.connection = new BluetoothClient(macAddress).openConnection();
this.sourcePath = sourcePath;
}
diff --git a/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java b/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java
index c03eb0376..6c99584e4 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/DownloaderFactory.java
@@ -11,8 +11,8 @@ 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);
+ String macAddress = uri.getHost().replace("-", ":");
+ return new BluetoothDownloader(macAddress, uri.getPath(), context);
} else if (isOnionAddress(url)) {
return new TorHttpDownloader(url, context);
} else {
@@ -23,8 +23,8 @@ 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);
+ String macAddress = uri.getHost().replace("-", ":");
+ return new BluetoothDownloader(macAddress, uri.getPath(), destFile);
} else if (isOnionAddress(url)) {
return new TorHttpDownloader(url, destFile);
} else {
diff --git a/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothClient.java b/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothClient.java
index 3179c259e..21308b0f2 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothClient.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothClient.java
@@ -1,5 +1,6 @@
package org.fdroid.fdroid.net.bluetooth;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
@@ -10,12 +11,16 @@ public class BluetoothClient {
@SuppressWarnings("unused")
private static final String TAG = "BluetoothClient";
- private BluetoothDevice device;
+ private final BluetoothDevice device;
public BluetoothClient(BluetoothDevice device) {
this.device = device;
}
+ public BluetoothClient(String macAddress) {
+ device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(macAddress);
+ }
+
public BluetoothConnection openConnection() throws IOException {
BluetoothSocket socket = device.createInsecureRfcommSocketToServiceRecord(BluetoothConstants.fdroidUuid());
BluetoothConnection connection = new BluetoothConnection(socket);
diff --git a/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java b/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java
index c74f1e3cd..bc1d5bcf5 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java
@@ -1,6 +1,7 @@
package org.fdroid.fdroid.net.bluetooth;
import android.annotation.TargetApi;
+import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Build;
import android.util.Log;
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 8328e8ec7..0306710c4 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
@@ -3,25 +3,19 @@ package org.fdroid.fdroid.net.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
-import android.content.Context;
-import android.os.Build;
import android.util.Log;
import android.webkit.MimeTypeMap;
-import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Utils;
-import org.fdroid.fdroid.net.HttpDownloader;
+import org.fdroid.fdroid.localrepo.type.BluetoothSwap;
import org.fdroid.fdroid.net.bluetooth.httpish.Request;
import org.fdroid.fdroid.net.bluetooth.httpish.Response;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -37,23 +31,23 @@ public class BluetoothServer extends Thread {
private static final String TAG = "BluetoothServer";
private BluetoothServerSocket serverSocket;
- private List clients = new ArrayList<>();
+ private List clients = new ArrayList<>();
- private final Context context;
-
- private String deviceBluetoothName = null;
- public final static String BLUETOOTH_NAME_TAG = "FDroid:";
private final File webRoot;
+ private final BluetoothSwap swap;
+ private boolean isRunning = false;
- public BluetoothServer(Context context, File webRoot) {
- this.context = context.getApplicationContext();
+ public BluetoothServer(BluetoothSwap swap, File webRoot) {
this.webRoot = webRoot;
+ this.swap = swap;
}
+ public boolean isRunning() { return isRunning; }
+
public void close() {
- for (Connection connection : clients) {
- connection.interrupt();
+ for (ClientConnection clientConnection : clients) {
+ clientConnection.interrupt();
}
interrupt();
@@ -61,61 +55,53 @@ public class BluetoothServer extends Thread {
if (serverSocket != null) {
Utils.closeQuietly(serverSocket);
}
-
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- adapter.setName(deviceBluetoothName.replaceAll("/^" + BLUETOOTH_NAME_TAG + "/",""));
-
}
@Override
public void run() {
+ isRunning = true;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
- //store the original bluetoothname, and update this one to be unique
- deviceBluetoothName = adapter.getName();
-
- if (!deviceBluetoothName.startsWith(BLUETOOTH_NAME_TAG))
- adapter.setName(BLUETOOTH_NAME_TAG + deviceBluetoothName);
-
-
try {
serverSocket = adapter.listenUsingInsecureRfcommWithServiceRecord("FDroid App Swap", BluetoothConstants.fdroidUuid());
} catch (IOException e) {
- Log.e(TAG, "Error starting Bluetooth server socket, will stop the server now - " + e.getMessage());
+ Log.e(TAG, "Error starting Bluetooth server socket, will stop the server now: " + e.getMessage());
+ swap.stop();
+ isRunning = false;
return;
}
while (true) {
if (isInterrupted()) {
+ Log.d(TAG, "Server stopped so will terminate loop looking for client connections.");
break;
}
try {
BluetoothSocket clientSocket = serverSocket.accept();
- if (clientSocket != null && !isInterrupted()) {
- Connection client = new Connection(context, clientSocket, webRoot);
+ if (clientSocket != null) {
+ if (!isInterrupted()) {
+ Log.d(TAG, "Server stopped after socket accepted from client, but before initiating connection.");
+ break;
+ }
+ ClientConnection client = new ClientConnection(clientSocket, webRoot);
client.start();
clients.add(client);
- } else {
- break;
}
} catch (IOException e) {
- Log.e(TAG, "Error receiving client connection over Bluetooth server socket, will continue listening for other clients - " + e.getMessage());
+ Log.e(TAG, "Error receiving client connection over Bluetooth server socket, will continue listening for other clients: " + e.getMessage());
}
}
-
+ isRunning = false;
}
- private static class Connection extends Thread {
+ private static class ClientConnection extends Thread {
- private final Context context;
private final BluetoothSocket socket;
private final File webRoot;
- public Connection(Context context, BluetoothSocket socket, File webRoot) {
- this.context = context.getApplicationContext();
+ public ClientConnection(BluetoothSocket socket, File webRoot) {
this.socket = socket;
this.webRoot = webRoot;
}
@@ -142,13 +128,11 @@ public class BluetoothServer extends Thread {
handleRequest(incomingRequest).send(connection);
} catch (IOException e) {
Log.e(TAG, "Error receiving incoming connection over bluetooth - " + e.getMessage());
-
-
+ break;
}
if (isInterrupted())
break;
-
}
}
@@ -160,7 +144,6 @@ public class BluetoothServer extends Thread {
Response.Builder builder = null;
try {
-// HttpDownloader downloader = new HttpDownloader("http://127.0.0.1:" + ( FDroidApp.port) + "/" + request.getPath(), context);
int statusCode = 404;
int totalSize = -1;
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/BluetoothDeviceListView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/BluetoothDeviceListView.java
deleted file mode 100644
index ef0d06888..000000000
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/BluetoothDeviceListView.java
+++ /dev/null
@@ -1,376 +0,0 @@
-package org.fdroid.fdroid.views.swap;
-
-import android.annotation.TargetApi;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.view.MenuItemCompat;
-import android.support.v4.widget.ContentLoadingProgressBar;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import org.fdroid.fdroid.R;
-import org.fdroid.fdroid.localrepo.SwapService;
-import org.fdroid.fdroid.net.BluetoothDownloader;
-import org.fdroid.fdroid.net.bluetooth.BluetoothClient;
-import org.fdroid.fdroid.net.bluetooth.BluetoothConnection;
-import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.List;
-
-public class BluetoothDeviceListView extends ListView implements
- SwapWorkflowActivity.InnerView,
- ListView.OnItemClickListener {
-
- private static final String TAG = "BluetoothDeviceListView";
-
- private Adapter adapter = null;
-
- private MenuItem scanMenuItem;
- private MenuItem cancelMenuItem;
-
- private boolean firstScan = true;
-
- public BluetoothDeviceListView(Context context) {
- super(context);
- }
-
- public BluetoothDeviceListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public BluetoothDeviceListView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public BluetoothDeviceListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- @Override
- public boolean buildMenu(Menu menu, @NonNull MenuInflater menuInflater) {
- menuInflater.inflate(R.menu.swap_scan, menu);
-
- final int flags = MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT;
-
- scanMenuItem = menu.findItem(R.id.action_scan);
- scanMenuItem.setVisible(true);
- MenuItemCompat.setShowAsAction(scanMenuItem, flags);
-
- scanMenuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- initiateBluetoothScan();
- return true;
- }
- });
-
- cancelMenuItem = menu.findItem(R.id.action_cancel);
- cancelMenuItem.setVisible(false);
- MenuItemCompat.setShowAsAction(cancelMenuItem, flags);
-
- cancelMenuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- cancelBluetoothScan();
- return true;
- }
- });
-
- return true;
- }
-
- @Override
- public int getStep() {
- return SwapService.STEP_BLUETOOTH;
- }
-
- @Override
- public int getPreviousStep() {
- return SwapService.STEP_JOIN_WIFI;
- }
-
- @Override
- public int getToolbarColour() {
- return R.color.swap_blue;
- }
-
- @Override
- public String getToolbarTitle() {
- return getContext().getString(R.string.swap_use_bluetooth);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- adapter = new Adapter(
- getContext(),
- R.layout.select_local_apps_list_item
- );
-
- LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View headerView = inflater.inflate(R.layout.swap_bluetooth_header, this, false);
- addHeaderView(headerView);
-
- setAdapter(adapter);
- setOnItemClickListener(this);
-
- final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
-
- final TextView deviceName = (TextView) headerView.findViewById(R.id.device_name);
- deviceName.setText(bluetooth.getName());
-
- final TextView address = (TextView) headerView.findViewById(R.id.device_address);
- address.setText(bluetooth.getAddress());
-
- initiateBluetoothScan();
-
- // populateBondedDevices();
-
- }
-
-
-
- private void cancelBluetoothScan() {
-
- Log.d(TAG, "Cancelling bluetooth scan.");
-
- cancelMenuItem.setVisible(false);
- scanMenuItem.setVisible(true);
-
- final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
- bluetooth.cancelDiscovery();
-
- getLoadingIndicator().hide();
-
- }
-
- private ContentLoadingProgressBar getLoadingIndicator() {
- return ((ContentLoadingProgressBar)findViewById(R.id.loading_indicator));
- }
-
- private void initiateBluetoothScan()
- {
- Log.d(TAG, "Starting bluetooth scan...");
-
- if (cancelMenuItem != null) {
- cancelMenuItem.setVisible(true);
- scanMenuItem.setVisible(false);
- }
-
- final ContentLoadingProgressBar loadingBar = getLoadingIndicator();
-
- loadingBar.show();
-
- final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
-
- if (firstScan) {
- final BroadcastReceiver deviceFoundReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
-
- if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- Log.d(TAG, "Found bluetooth device: " + device.toString());
-
- if (device != null && device.getName() != null)
- if (device.getName().contains(BluetoothServer.BLUETOOTH_NAME_TAG)) {
- boolean exists = false;
- for (int i = 0; i < adapter.getCount(); i++) {
- if (adapter.getItem(i).getAddress().equals(device.getAddress())) {
- exists = true;
- break;
- }
- }
-
- if (!exists) {
- adapter.add(device);
- }
- }
- }
- }
- };
-
- final BroadcastReceiver scanCompleteReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Scan complete: " + intent.getAction());
- loadingBar.hide();
- cancelMenuItem.setVisible(false);
- scanMenuItem.setVisible(true);
- }
- };
-
- getContext().registerReceiver(deviceFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
- getContext().registerReceiver(scanCompleteReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
-
- firstScan = false;
- }
- else
- {
- if (bluetooth.isDiscovering())
- {
- bluetooth.cancelDiscovery();
- }
- }
-
- if (!bluetooth.startDiscovery()) {
- // TODO: Discovery did not start for some reason :(
- Log.e(TAG, "Could not start bluetooth discovery, but am not sure why :(");
- Toast.makeText(getContext(),"There was a problem looking for Bluetooth devices",Toast.LENGTH_SHORT).show();
- }
- }
-
- private void populateBondedDevices()
- {
- for (BluetoothDevice device : BluetoothAdapter.getDefaultAdapter().getBondedDevices()) {
- adapter.add(device);
- }
- }
-
-
-
- @Override
- public void onItemClick(AdapterView> parent, View view, int position, long id) {
-
- // "position" includes the header view, so ignore that.
- if (position == 0) {
- return;
- }
-
- BluetoothDevice device = adapter.getItem(position - 1);
-
- // TODO: I think that I can connect regardless of the bond state.
- // It sounds like when I attempt to connect to a non-bonded peer, then
- // Android initiates the pairing dialog on our behalf.
-
- BluetoothClient client = new BluetoothClient(device);
-
- try {
- Log.d(TAG, "Testing bluetooth connection (opening connection first).");
- BluetoothConnection connection = client.openConnection();
-
- ByteArrayOutputStream stream = new ByteArrayOutputStream(4096);
- BluetoothDownloader downloader = new BluetoothDownloader(connection, "/", stream);
- downloader.downloadUninterrupted();
- String result = stream.toString();
- Log.d(TAG, "Download complete.");
- Log.d(TAG, result);
-
- Log.d(TAG, "Downloading again...");
- downloader = new BluetoothDownloader(connection, "/fdroid/repo/index.xml", stream);
- downloader.downloadUninterrupted();
- result = stream.toString();
- Log.d(TAG, "Download complete.");
- Log.d(TAG, result);
-
- /*Log.d(TAG, "Creating HEAD request for resource at \"/\"...");
- Request head = Request.createGET("/", connection);
- Log.d(TAG, "Sending request...");
- Response response = head.send();
- Log.d(TAG, "Response from bluetooth: " + response.getStatusCode());
- String contents = response.readContents();
- Log.d(TAG, contents);*/
- } catch (IOException e) {
- Log.e(TAG, "Error: " + e.getMessage());
- }
-
- /*if (device.getBondState() == BluetoothDevice.BOND_NONE) {
- // attempt to bond
-
- } else if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
- // wait for bonding to finish
-
- } else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
- // connect
- BluetoothClient client = new BluetoothClient(device);
- }*/
- }
-
- private class Adapter extends ArrayAdapter {
-
- public Adapter(Context context, int resource) {
- super(context, resource);
- }
-
- public Adapter(Context context, int resource, int textViewResourceId) {
- super(context, resource, textViewResourceId);
- }
-
- public Adapter(Context context, int resource, BluetoothDevice[] objects) {
- super(context, resource, objects);
- }
-
- public Adapter(Context context, int resource, int textViewResourceId, BluetoothDevice[] objects) {
- super(context, resource, textViewResourceId, objects);
- }
-
- public Adapter(Context context, int resource, List objects) {
- super(context, resource, objects);
- }
-
- public Adapter(Context context, int resource, int textViewResourceId, List objects) {
- super(context, resource, textViewResourceId, objects);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View view;
- if (convertView == null) {
- LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- view = inflater.inflate(R.layout.simple_list_item_3, null);
- } else {
- view = convertView;
- }
-
- BluetoothDevice device = getItem(position);
- TextView nameView = (TextView)view.findViewById(android.R.id.text1);
- TextView addressView = (TextView)view.findViewById(android.R.id.text2);
- //TextView descriptionView = (TextView)view.findViewById(R.id.text3);
-
- nameView.setText(device.getName() == null ? getContext().getString(R.string.unknown) : device.getName());
- addressView.setText(device.getAddress());
- //descriptionView.setText(bondStateToLabel(device.getBondState()));
-
- return view;
- }
-
- private String bondStateToLabel(int deviceBondState)
- {
- if (deviceBondState == BluetoothDevice.BOND_BONDED) {
- // TODO: Is the term "Bonded device" common parlance among phone users?
- // It sounds a bit technical to me, maybe something more lay like "Previously connected".
- // Although it is technically not as accurate, it would make sense to more people...
- return getContext().getString(R.string.swap_bluetooth_bonded_device);
- } else if (deviceBondState == BluetoothDevice.BOND_BONDING) {
- return getContext().getString(R.string.swap_bluetooth_bonding_device);
- } else {
- // TODO: Might be a little bit harsh, makes it sound more malicious than it should.
- return getContext().getString(R.string.swap_bluetooth_unknown_device);
- }
- }
- }
-
-}
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/SelectAppsView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/SelectAppsView.java
index b8288830f..f6750e936 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/SelectAppsView.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SelectAppsView.java
@@ -124,7 +124,7 @@ public class SelectAppsView extends ListView implements
@Override
public int getPreviousStep() {
- return getState().isConnectingWithPeer() ? SwapService.STEP_JOIN_WIFI : SwapService.STEP_INTRO;
+ return getState().isConnectingWithPeer() ? SwapService.STEP_INTRO : SwapService.STEP_JOIN_WIFI;
}
@ColorRes
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 53589a841..7204cc717 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
@@ -39,9 +39,9 @@ import org.fdroid.fdroid.data.NewRepoConfig;
import org.fdroid.fdroid.localrepo.LocalRepoManager;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.peers.Peer;
-import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
import java.util.Arrays;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -105,11 +105,12 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private final ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder binder) {
- Log.d(TAG, "Swap service connected, enabling SwapManager to communicate with SwapService.");
+ Log.d(TAG, "Swap service connected. Will hold onto it so we can talk to it regularly.");
service = ((SwapService.Binder)binder).getService();
showRelevantView();
}
+ // TODO: What causes this? Do we need to stop swapping explicitly when this is invoked?
@Override
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, "Swap service disconnected");
@@ -133,6 +134,9 @@ public class SwapWorkflowActivity extends AppCompatActivity {
@Override
public void onBackPressed() {
if (currentView.getStep() == SwapService.STEP_INTRO) {
+ if (service != null) {
+ service.disableAllSwapping();
+ }
finish();
} else {
int nextStep = currentView.getPreviousStep();
@@ -235,6 +239,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
case SwapService.STEP_SUCCESS:
showSwapConnected();
break;
+ case SwapService.STEP_CONNECTING:
+ // TODO: Properly decide what to do here...
+ inflateInnerView(R.layout.swap_blank);
+ break;
}
}
@@ -287,6 +295,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
private void showIntro() {
+ // If we were previously swapping with a specific client, forget that we were doing that,
+ // as we are starting over now.
+ getService().swapWith(null);
+
if (!getService().isEnabled()) {
prepareInitialRepo();
}
@@ -303,7 +315,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
public void sendFDroid() {
- // TODO: What is availble here? Currently we support Bluetooth (see main menu in F-Droid)
+ // TODO: What is available here? Currently we support Bluetooth (see main menu in F-Droid)
// and Android Beam (try touching two devices together when in the app details view).
}
@@ -314,8 +326,8 @@ public class SwapWorkflowActivity extends AppCompatActivity {
if (updateSwappableAppsTask == null && !hasPreparedLocalRepo) {
updateSwappableAppsTask = new PrepareFullSwapRepo(getService().getAppsToSwap());
updateSwappableAppsTask.execute();
- } else if (!attemptToShowNfc()) {
- showWifiQr();
+ } else {
+ onLocalRepoPrepared();
}
}
@@ -355,10 +367,6 @@ public class SwapWorkflowActivity extends AppCompatActivity {
inflateInnerView(R.layout.swap_join_wifi);
}
- private void showBluetoothDeviceList() {
- inflateInnerView(R.layout.swap_bluetooth_devices);
- }
-
public void showWifiQr() {
inflateInnerView(R.layout.swap_wifi_qr);
}
@@ -384,6 +392,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
public void swapWith(Peer peer) {
+ getService().stopScanningForPeers();
getService().swapWith(peer);
showSelectApps();
}
@@ -443,7 +452,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
/**
* The process for setting up bluetooth is as follows:
* * Assume we have bluetooth available (otherwise the button which allowed us to start
- * the bluetooth process should not have been available). TODO: Remove button if bluetooth unavailable.
+ * the bluetooth process should not have been available).
* * Ask user to enable (if not enabled yet).
* * Start bluetooth server socket.
* * Enable bluetooth discoverability, so that people can connect to our server socket.
@@ -609,36 +618,53 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
+ /**
+ * Helper class to try and make sense of what the swap workflow is currently doing.
+ * The more technologies are involved in the process (e.g. Bluetooth/Wifi/NFC/etc)
+ * the harder it becomes to reason about and debug the whole thing. Thus,this class
+ * will periodically dump the state to logcat so that it is easier to see when certain
+ * protocols are enabled/disabled.
+ *
+ * To view only this output from logcat:
+ *
+ * adb logcat | grep 'Swap Status'
+ *
+ * To exclude this output from logcat (it is very noisy):
+ *
+ * adb logcat | grep -v 'Swap Status'
+ *
+ */
class SwapDebug {
- private StringBuilder status = new StringBuilder("\n");
-
public void logStatus() {
- append("service = " + service);
- if (service != null) {
- append("Swap Services:");
- append(" service.getBluetoothSwap() = " + service.getBluetoothSwap());
- append(" service.getBluetoothSwap().isConnected() = " + service.getBluetoothSwap().isConnected());
- append(" service.getWifiSwap() = " + service.getWifiSwap());
- append(" service.getWifiSwap().isConnected() = " + service.getWifiSwap().isConnected());
- append(" service.getWifiSwap().getBonjour() = " + service.getWifiSwap().getBonjour());
- append(" service.getWifiSwap().getBonjour().isConnected() = " + service.getWifiSwap().getBonjour().isConnected());
- append("Discovering Services:");
+ String message = "";
+ if (service == null) {
+ message = "No swap service";
+ } else {
+ {
+ String bluetooth = service.getBluetoothSwap().isConnected() ? "Yes" : " No";
+ String wifi = service.getWifiSwap().isConnected() ? "Yes" : " No";
+ String mdns = service.getWifiSwap().getBonjour().isConnected() ? "Yes" : " No";
+ message += "Broadcast { BT: " + bluetooth + ", WiFi: " + wifi + ", mDNS: " + mdns + "}, ";
+ }
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- if (adapter != null) {
+ {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ String bluetooth = "N/A";
+ if (adapter != null) {
+ Map scanModes = new HashMap<>(3);
+ scanModes.put(BluetoothAdapter.SCAN_MODE_CONNECTABLE, "CONNECTABLE");
+ scanModes.put(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, "CONNECTABLE_DISCOVERABLE");
+ scanModes.put(BluetoothAdapter.SCAN_MODE_NONE, "NONE");
+ bluetooth = "\"" + adapter.getName() + "\" - " + scanModes.get(adapter.getScanMode());
+ }
- Map scanModes = new HashMap<>(3);
- scanModes.put(BluetoothAdapter.SCAN_MODE_CONNECTABLE, "SCAN_MODE_CONNECTABLE");
- scanModes.put(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, "SCAN_MODE_CONNECTABLE_DISCOVERABLE");
- scanModes.put(BluetoothAdapter.SCAN_MODE_NONE, "SCAN_MODE_NONE");
-
- append(" Bluetooth.isEnabled() = " + adapter.isEnabled());
- append(" Bluetooth.isDiscovering() = " + adapter.isDiscovering());
- append(" Bluetooth.getScanMode() = " + scanModes.get(adapter.getScanMode()));
+ String wifi = service.getBonjourFinder().isScanning() ? "Yes" : " No";
+ message += "Discover { BT: " + bluetooth + ", WiFi: " + wifi + "}";
}
}
- Log.d("SwapStatus", status.toString());
+
+ Log.d("Swap Status", new Date().toLocaleString() + " " + message);
new Timer().schedule(new TimerTask() {
@Override
@@ -646,13 +672,9 @@ public class SwapWorkflowActivity extends AppCompatActivity {
new SwapDebug().logStatus();
}
},
- 2000
+ 1000
);
}
-
- private void append(String line) {
- status.append(" ").append(line).append("\n");
- }
}
}