From e343918ef9a3f9a3d6482cec2f3fa35bc2b9a55c Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Tue, 23 Jun 2015 23:12:57 +1000 Subject: [PATCH] WIP: Moving from listener to broadcasts for discovered peers. --- .../fdroid/fdroid/localrepo/SwapManager.java | 31 ++++++++-------- .../fdroid/fdroid/localrepo/SwapService.java | 18 ---------- .../localrepo/peers/BluetoothFinder.java | 3 +- .../fdroid/localrepo/peers/BonjourFinder.java | 3 +- .../fdroid/fdroid/localrepo/peers/Peer.java | 4 ++- .../fdroid/localrepo/peers/PeerFinder.java | 35 ++++++++----------- .../fdroid/views/swap/StartSwapView.java | 18 +++++++--- .../views/swap/SwapWorkflowActivity.java | 5 ++- 8 files changed, 48 insertions(+), 69 deletions(-) diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java index d71d90e4d..e44ae179d 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapManager.java @@ -1,9 +1,11 @@ package org.fdroid.fdroid.localrepo; import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.os.IBinder; @@ -13,10 +15,8 @@ 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; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -59,6 +59,16 @@ public class SwapManager { this.appsToSwap = appsToSwap; this.peers = new ArrayList<>(); + context.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Peer peer = (Peer) intent.getSerializableExtra(EXTRA_PEER); + if (!peers.contains(peer)) { + peers.add(peer); + } + } + }, new IntentFilter(ACTION_PEER_FOUND)); + setupService(); } @@ -76,12 +86,6 @@ public class SwapManager { // Search for peers to swap // ========================================================== - private PeerFinder.Listener peerListener; - - public void setPeerListener(PeerFinder.Listener listener) { - this.peerListener = listener; - } - public void scanForPeers() { if (service != null) { Log.d(TAG, "Scanning for nearby devices to swap with..."); @@ -99,15 +103,6 @@ public class SwapManager { } } - public void onPeerFound(Peer peer) { - if (!peers.contains(peer)) { - peers.add(peer); - if (peerListener != null) { - peerListener.onPeerFound(peer); - } - } - } - @NonNull public List getPeers() { return peers; @@ -336,4 +331,6 @@ public class SwapManager { return service != null && service.isScanningForPeers(); } + public static final String ACTION_PEER_FOUND = "org.fdroid.fdroid.SwapManager.ACTION_PEER_FOUND"; + public static final String EXTRA_PEER = "EXTRA_PEER"; } diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java index 85df7d3f1..845fefd74 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java @@ -17,11 +17,7 @@ import android.util.Log; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; import org.fdroid.fdroid.localrepo.peers.BluetoothFinder; -import org.fdroid.fdroid.localrepo.peers.BluetoothPeer; import org.fdroid.fdroid.localrepo.peers.BonjourFinder; -import org.fdroid.fdroid.localrepo.peers.BonjourPeer; -import org.fdroid.fdroid.localrepo.peers.Peer; -import org.fdroid.fdroid.localrepo.peers.PeerFinder; import org.fdroid.fdroid.localrepo.type.BonjourType; import org.fdroid.fdroid.localrepo.type.NfcType; import org.fdroid.fdroid.localrepo.type.WebServerType; @@ -79,22 +75,8 @@ public class SwapService extends Service { nfcType = new NfcType(this); bonjourType = new BonjourType(this); webServerType = new WebServerType(this); - bonjourFinder = new BonjourFinder(this); bluetoothFinder = new BluetoothFinder(this); - - bonjourFinder.setListener(new PeerFinder.Listener() { - @Override - public void onPeerFound(BonjourPeer peer) { - SwapManager.load(SwapService.this).onPeerFound(peer); - } - }); - bluetoothFinder.setListener(new PeerFinder.Listener() { - @Override - public void onPeerFound(BluetoothPeer peer) { - SwapManager.load(SwapService.this).onPeerFound(peer); - } - }); } public void onCreate() { 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 f6684c513..f87edd018 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BluetoothFinder.java @@ -13,11 +13,10 @@ public class BluetoothFinder extends PeerFinder { private static final String TAG = "BluetoothFinder"; - private final Context context; private final BluetoothAdapter adapter; public BluetoothFinder(Context context) { - this.context = context; + super(context); adapter = BluetoothAdapter.getDefaultAdapter(); } 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 f56ec1ff5..4ae9b3728 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/BonjourFinder.java @@ -20,13 +20,12 @@ public class BonjourFinder extends PeerFinder implements ServiceLis public static final String HTTP_SERVICE_TYPE = "_http._tcp.local."; public static final String HTTPS_SERVICE_TYPE = "_https._tcp.local."; - private final Context context; private JmDNS mJmdns; private WifiManager wifiManager; private WifiManager.MulticastLock mMulticastLock; public BonjourFinder(Context context) { - this.context = context; + super(context); } @Override diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/Peer.java b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/Peer.java index cd7e74db4..a7f5e765b 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/Peer.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/Peer.java @@ -2,7 +2,9 @@ package org.fdroid.fdroid.localrepo.peers; import android.support.annotation.DrawableRes; -public interface Peer { +import java.io.Serializable; + +public interface Peer extends Serializable { String getName(); 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 760b495fd..34915b270 100644 --- a/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java +++ b/F-Droid/src/org/fdroid/fdroid/localrepo/peers/PeerFinder.java @@ -1,47 +1,40 @@ package org.fdroid.fdroid.localrepo.peers; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.util.Log; +import org.fdroid.fdroid.localrepo.SwapManager; + /** * Searches for other devices in the vicinity, using specific technologies. - * Once found, alerts a listener through the - * {@link org.fdroid.fdroid.localrepo.peers.PeerFinder.Listener#onPeerFound(Object)} - * method. Note that this could have instead been done with {@link android.content.Context#sendBroadcast(Intent)} - * and {@link android.content.BroadcastReceiver}, but that would require making the {@link Peer}s - * {@link android.os.Parcelable}, which is difficult. The main reason it is difficult is because - * they encapsulate information about network connectivity, such as {@link android.bluetooth.BluetoothDevice} - * and {@link javax.jmdns.ServiceInfo}, which may be difficult to serialize and reconstruct again. + * Once found, sends an {@link SwapManager#ACTION_PEER_FOUND} intent with the {@link SwapManager#EXTRA_PEER} + * extra attribute set to the subclass of {@link Peer} that was found. */ public abstract class PeerFinder { private static final String TAG = "PeerFinder"; - private Listener listener; - protected boolean isScanning = false; + protected final Context context; public abstract void scan(); public abstract void cancel(); + public PeerFinder(Context context) { + this.context = context; + } + public boolean isScanning() { return isScanning; } protected void foundPeer(T peer) { Log.i(TAG, "Found peer " + peer.getName()); - if (listener != null) { - listener.onPeerFound(peer); - } - } - - public void setListener(Listener listener) { - this.listener = listener; - } - - public interface Listener { - void onPeerFound(T peer); - // TODO: What about peers removed, e.g. as with jmdns ServiceListener#serviceRemoved() + Intent intent = new Intent(SwapManager.ACTION_PEER_FOUND); + intent.putExtra(SwapManager.EXTRA_PEER, peer); + context.sendBroadcast(intent); } } 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 5f990647f..1de14d0ad 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java @@ -2,13 +2,17 @@ package org.fdroid.fdroid.views.swap; import android.annotation.TargetApi; import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; 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.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -30,6 +34,8 @@ import org.fdroid.fdroid.localrepo.peers.PeerFinder; public class StartSwapView extends LinearLayout implements SwapWorkflowActivity.InnerView { + private static final String TAG = "StartSwapView"; + // TODO: Is there a way to guarangee which of these constructors the inflater will call? // Especially on different API levels? It would be nice to only have the one which accepts // a Context, but I'm not sure if that is correct or not. As it stands, this class provides @@ -57,7 +63,7 @@ public class StartSwapView extends LinearLayout implements SwapWorkflowActivity. private class PeopleNearbyAdapter extends ArrayAdapter { public PeopleNearbyAdapter(Context context) { - super(context, 0, SwapManager.load(context).getPeers()); + super(context, 0, new Peer[] {}); } @Override @@ -117,13 +123,15 @@ public class StartSwapView extends LinearLayout implements SwapWorkflowActivity. peopleNearbyList.setAdapter(adapter); uiUpdatePeersInfo(); - SwapManager.load(getActivity()).setPeerListener(new PeerFinder.Listener() { + getContext().registerReceiver(new BroadcastReceiver() { @Override - public void onPeerFound(Peer peer) { - adapter.notifyDataSetChanged(); + public void onReceive(Context context, Intent intent) { + Peer peer = intent.getParcelableExtra(SwapManager.EXTRA_PEER); + Log.d(TAG, "Found peer: " + peer + ", adding to list of peers in UI."); + adapter.add(peer); uiUpdatePeersInfo(); } - }); + }, new IntentFilter(SwapManager.ACTION_PEER_FOUND)); } 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 e06fceb3b..f45ee9184 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java @@ -10,8 +10,7 @@ import android.os.Bundle; import android.support.annotation.ColorRes; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; -import android.support.v4.app.FragmentActivity; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.Menu; @@ -35,7 +34,7 @@ import org.fdroid.fdroid.localrepo.SwapManager; import java.util.Set; -public class SwapWorkflowActivity extends ActionBarActivity { +public class SwapWorkflowActivity extends AppCompatActivity { private ViewGroup container;