diff --git a/F-Droid/res/layout/swap_blank.xml b/F-Droid/res/layout/swap_blank.xml
index f582e90e6..788c51f05 100644
--- a/F-Droid/res/layout/swap_blank.xml
+++ b/F-Droid/res/layout/swap_blank.xml
@@ -57,6 +57,7 @@
android:src="@drawable/ic_bluetooth_white" />
-
-
+ android:layout_height="wrap_content"
+ android:drawableStart="@drawable/ic_fdroid_grey"
+ android:text="@string/swap_send_fdroid"
+ android:drawablePadding="10dp"
+ android:padding="25dp"
+ android:background="@android:color/transparent" />
+ android:drawableStart="@drawable/ic_qr_grey"
+ android:text="@string/swap_scan_qr_code"
+ android:drawablePadding="10dp"
+ android:padding="25dp"
+ android:background="@android:color/transparent" />
+
+
\ No newline at end of file
diff --git a/F-Droid/res/values/strings.xml b/F-Droid/res/values/strings.xml
index 371d9ed2a..1593feaba 100644
--- a/F-Droid/res/values/strings.xml
+++ b/F-Droid/res/values/strings.xml
@@ -324,6 +324,18 @@
Choose Apps
Scan QR Code
People Nearby
+ Searching for nearby peopleā¦
+ Nearby Swap
+ Connect and trade apps with people near you.
+ Visible via Bluetooth
+ Not visible via Bluetooth
+ Visible via WiFi
+ Not visible via WiFi
+ Device Name
+ Can\'t find who you\'re looking for?
+ SEND F-DROID
+ SCAN QR CODE
+ Could not find people nearby to swap with.
Public
@@ -332,13 +344,4 @@
May work
Promising
Best bet
- Nearby Swap
- Connect and trade apps with people near you.
- Visible via Bluetooth
- Not visible via WiFi
- Device Name
- People Nearby
- Can\'t find who you\'re looking for?
- SEND F-DROID
- Could not find people nearby to swap with.
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java
index 407ca941e..d71d90e4d 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java
@@ -10,8 +10,11 @@ import android.os.IBinder;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.text.TextUtils;
import android.util.Log;
+import org.fdroid.fdroid.FDroid;
+import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.localrepo.peers.Peer;
import org.fdroid.fdroid.localrepo.peers.PeerFinder;
@@ -184,7 +187,9 @@ public class SwapManager {
*/
private static Set deserializePackages(String packages) {
Set set = new HashSet<>();
- Collections.addAll(set, packages.split(","));
+ if (!TextUtils.isEmpty(packages)) {
+ Collections.addAll(set, packages.split(","));
+ }
return set;
}
@@ -288,7 +293,6 @@ public class SwapManager {
}
public void ensureBluetoothDiscoverable() {
-
if (bluetooth == null) {
return;
}
@@ -302,9 +306,34 @@ public class SwapManager {
if (bluetooth.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);
+
context.startActivity(discoverableIntent);
}
+ }
+ public void makeBluetoothNonDiscoverable() {
+ if (bluetooth == null) {
+ return;
+ }
+
+ if (isBluetoothDiscoverable()) {
+ // TODO: How to disable this?
+ }
+ }
+
+ private boolean isWifiConnected() {
+ return !TextUtils.isEmpty(FDroidApp.ssid);
+ }
+
+ public boolean isBonjourDiscoverable() {
+ return isWifiConnected() && service != null && service.isEnabled();
+ }
+
+ public boolean isScanningForPeers() {
+ return service != null && service.isScanningForPeers();
}
}
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
index 8d504ea6e..85df7d3f1 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
@@ -65,6 +65,10 @@ public class SwapService extends Service {
@Nullable
private Timer timer;
+ public boolean isScanningForPeers() {
+ return bonjourFinder.isScanning() || bluetoothFinder.isScanning();
+ }
+
public class Binder extends android.os.Binder {
public SwapService getService() {
return SwapService.this;
@@ -140,10 +144,6 @@ public class SwapService extends Service {
bluetoothFinder.cancel();
}
- public void onPeerFound(Peer peer) {
- SwapManager.load(this).onPeerFound(peer);
- }
-
private boolean enabled = false;
/**
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 8c7ae19cf..f6684c513 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java
@@ -29,6 +29,15 @@ public class BluetoothFinder extends PeerFinder {
return;
}
+ if (isScanning) {
+ // 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 ignore request.");
+ return;
+ }
+
+ isScanning = true;
+
final BroadcastReceiver deviceFoundReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -43,6 +52,7 @@ public class BluetoothFinder extends PeerFinder {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Scan complete: " + intent.getAction());
+ isScanning = false;
}
};
@@ -61,6 +71,8 @@ public class BluetoothFinder extends PeerFinder {
Log.d(TAG, "Stopping bluetooth discovery.");
adapter.cancelDiscovery();
}
+
+ isScanning = false;
}
private void onDeviceFound(BluetoothDevice device) {
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 ff73a397b..f56ec1ff5 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java
@@ -38,6 +38,12 @@ public class BonjourFinder extends PeerFinder implements ServiceLis
mMulticastLock.setReferenceCounted(false);
}
+ if (isScanning) {
+ Log.d(TAG, "Requested Bonjour scan, but already scanning, so will ignore request.");
+ return;
+ }
+
+ isScanning = true;
mMulticastLock.acquire();
new AsyncTask() {
@@ -116,6 +122,7 @@ public class BonjourFinder extends PeerFinder implements ServiceLis
mJmdns.removeServiceListener(HTTP_SERVICE_TYPE, this);
mJmdns.removeServiceListener(HTTPS_SERVICE_TYPE, this);
mJmdns = null;
+ isScanning = false;
}
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 1342c7f18..760b495fd 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java
@@ -19,9 +19,15 @@ public abstract class PeerFinder {
private Listener listener;
+ protected boolean isScanning = false;
+
public abstract void scan();
public abstract void cancel();
+ public boolean isScanning() {
+ return isScanning;
+ }
+
protected void foundPeer(T peer) {
Log.i(TAG, "Found peer " + peer.getName());
if (listener != null) {
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 30b285885..5f990647f 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
@@ -1,17 +1,28 @@
package org.fdroid.fdroid.views.swap;
import android.annotation.TargetApi;
+import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.os.Build;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CompoundButton;
import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.Switch;
+import android.widget.TextView;
+import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.localrepo.SwapManager;
import org.fdroid.fdroid.localrepo.peers.Peer;
@@ -77,19 +88,65 @@ public class StartSwapView extends LinearLayout implements SwapWorkflowActivity.
private final BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
private TextView viewBluetoothId;
- private View noPeopleNearby;
- private ListView peopleNearby;
+ private TextView viewWifiId;
+ private TextView viewWifiNetwork;
+ private TextView peopleNearbyText;
+ private ListView peopleNearbyList;
+ private ProgressBar peopleNearbyProgress;
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- noPeopleNearby = findViewById(R.id.no_people_nearby);
- peopleNearby = (ListView)findViewById(R.id.list_people_nearby);
- peopleNearby.setVisibility(View.GONE);
+ uiInitPeers();
+ uiInitBluetooth();
+ uiInitWifi();
+ }
+ /**
+ * Setup the list of nearby peers with an adapter, and hide or show it and the associated
+ * message for when no peers are nearby depending on what is happening.
+ */
+ private void uiInitPeers() {
+
+ peopleNearbyText = (TextView)findViewById(R.id.text_people_nearby);
+ peopleNearbyList = (ListView)findViewById(R.id.list_people_nearby);
+ peopleNearbyProgress = (ProgressBar)findViewById(R.id.searching_people_nearby);
+
+ final PeopleNearbyAdapter adapter = new PeopleNearbyAdapter(getContext());
+ peopleNearbyList.setAdapter(adapter);
+ uiUpdatePeersInfo();
+
+ SwapManager.load(getActivity()).setPeerListener(new PeerFinder.Listener() {
+ @Override
+ public void onPeerFound(Peer peer) {
+ adapter.notifyDataSetChanged();
+ uiUpdatePeersInfo();
+ }
+ });
+
+ }
+
+ private void uiUpdatePeersInfo() {
+ if (getManager().isScanningForPeers()) {
+ peopleNearbyText.setText(getContext().getString(R.string.swap_scanning_for_peers));
+ peopleNearbyProgress.setVisibility(View.VISIBLE);
+ } else {
+ peopleNearbyProgress.setVisibility(View.GONE);
+ if (peopleNearbyList.getAdapter().getCount() > 0) {
+ peopleNearbyText.setText(getContext().getString(R.string.swap_people_nearby));
+ } else {
+ peopleNearbyText.setText(getContext().getString(R.string.swap_no_peers_nearby));
+ }
+ }
+
+ }
+
+ private void uiInitBluetooth() {
if (bluetooth != null) {
+ final TextView textBluetoothVisible = (TextView)findViewById(R.id.bluetooth_visible);
+
viewBluetoothId = (TextView)findViewById(R.id.device_id_bluetooth);
viewBluetoothId.setText(bluetooth.getName());
@@ -100,39 +157,61 @@ public class StartSwapView extends LinearLayout implements SwapWorkflowActivity.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
getManager().ensureBluetoothDiscoverable();
+ getManager().scanForPeers();
+ textBluetoothVisible.setText(getContext().getString(R.string.swap_visible_bluetooth));
+ uiUpdatePeersInfo();
+ // TODO: When they deny the request for enabling bluetooth, we need to disable this switch...
} else {
- // disableBluetooth();
+ getManager().cancelScanningForPeers();
+ getManager().makeBluetoothNonDiscoverable();
+ textBluetoothVisible.setText(getContext().getString(R.string.swap_not_visible_bluetooth));
+ uiUpdatePeersInfo();
}
}
});
} else {
findViewById(R.id.bluetooth_info).setVisibility(View.GONE);
}
+ }
- ((Switch)findViewById(R.id.switch_wifi)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ private void uiInitWifi() {
+
+ final TextView textBluetoothVisible = (TextView)findViewById(R.id.bluetooth_visible);
+
+ viewWifiId = (TextView)findViewById(R.id.device_id_wifi);
+ viewWifiNetwork = (TextView)findViewById(R.id.wifi_network);
+
+ Switch wifiSwitch = (Switch)findViewById(R.id.switch_wifi);
+ wifiSwitch.setChecked(getManager().isBonjourDiscoverable());
+ wifiSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
- enableWifi();
+ textBluetoothVisible.setText(getContext().getString(R.string.swap_visible_wifi));
+ uiUpdatePeersInfo();
} else {
- disableWifi();
+ textBluetoothVisible.setText(getContext().getString(R.string.swap_not_visible_wifi));
+ uiUpdatePeersInfo();
}
}
});
- final PeopleNearbyAdapter adapter = new PeopleNearbyAdapter(getContext());
-
- peopleNearbyList = (ListView)findViewById(R.id.people_nearby);
- peopleNearbyList.setAdapter(adapter);
-
- SwapManager.load(getActivity()).setPeerListener(new PeerFinder.Listener() {
- @Override
- public void onPeerFound(Peer peer) {
- adapter.notifyDataSetChanged();
- }
- });
+ uiUpdateWifi();
+ }
+ private void uiUpdateWifi() {
+ viewWifiId.setText(FDroidApp.ipAddressString);
+ if (TextUtils.isEmpty(FDroidApp.bssid) && !TextUtils.isEmpty(FDroidApp.ipAddressString)) {
+ // empty bssid with an ipAddress means hotspot mode
+ viewWifiNetwork.setText(getContext().getString(R.string.swap_active_hotspot));
+ } else if (TextUtils.isEmpty(FDroidApp.ssid)) {
+ // not connected to or setup with any wifi network
+ viewWifiNetwork.setText(getContext().getString(R.string.swap_no_wifi_network));
+ } else {
+ // connected to a regular wifi network
+ viewWifiNetwork.setText(FDroidApp.ssid);
+ }
}
@Override
@@ -165,16 +244,4 @@ public class StartSwapView extends LinearLayout implements SwapWorkflowActivity.
return getResources().getString(R.string.swap_nearby);
}
-
- // ========================================================================
- // Wifi stuff
- // ========================================================================
-
- private void enableWifi() {
-
- }
-
- private void disableWifi() {
-
- }
}