purge last RxAndroid code, replace with good ol' Intents
Rx needs to be used as the basis of the whole system, it doesn't make sense to just have one small part handled by Rx. RxJava is still used in InstallAppProviderService, so that would have to be tackled separately.
This commit is contained in:
parent
18a7690758
commit
7f35420e37
@ -153,7 +153,6 @@ dependencies {
|
|||||||
implementation 'commons-net:commons-net:3.6'
|
implementation 'commons-net:commons-net:3.6'
|
||||||
implementation 'ch.acra:acra:4.9.1'
|
implementation 'ch.acra:acra:4.9.1'
|
||||||
implementation 'io.reactivex:rxjava:1.1.0'
|
implementation 'io.reactivex:rxjava:1.1.0'
|
||||||
implementation 'io.reactivex:rxandroid:0.23.0'
|
|
||||||
implementation 'com.hannesdorfmann:adapterdelegates3:3.0.1'
|
implementation 'com.hannesdorfmann:adapterdelegates3:3.0.1'
|
||||||
implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.5'
|
implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.5'
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package org.fdroid.fdroid.localrepo;
|
package org.fdroid.fdroid.localrepo;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
@ -11,6 +14,8 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
|
import org.fdroid.fdroid.Utils;
|
||||||
|
import org.fdroid.fdroid.localrepo.peers.BluetoothPeer;
|
||||||
import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
|
import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@ -26,6 +31,9 @@ import java.lang.ref.WeakReference;
|
|||||||
public class BluetoothManager {
|
public class BluetoothManager {
|
||||||
private static final String TAG = "BluetoothManager";
|
private static final String TAG = "BluetoothManager";
|
||||||
|
|
||||||
|
public static final String ACTION_FOUND = "BluetoothNewPeer";
|
||||||
|
public static final String EXTRA_PEER = "extraBluetoothPeer";
|
||||||
|
|
||||||
public static final String ACTION_STATUS = "BluetoothStatus";
|
public static final String ACTION_STATUS = "BluetoothStatus";
|
||||||
public static final String EXTRA_STATUS = "BluetoothStatusExtra";
|
public static final String EXTRA_STATUS = "BluetoothStatusExtra";
|
||||||
public static final int STATUS_STARTING = 0;
|
public static final int STATUS_STARTING = 0;
|
||||||
@ -74,6 +82,9 @@ public class BluetoothManager {
|
|||||||
handlerThread = new HandlerThread("BluetoothManager", Process.THREAD_PRIORITY_LESS_FAVORABLE) {
|
handlerThread = new HandlerThread("BluetoothManager", Process.THREAD_PRIORITY_LESS_FAVORABLE) {
|
||||||
@Override
|
@Override
|
||||||
protected void onLooperPrepared() {
|
protected void onLooperPrepared() {
|
||||||
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
|
||||||
|
localBroadcastManager.registerReceiver(bluetoothDeviceFound,
|
||||||
|
new IntentFilter(BluetoothDevice.ACTION_FOUND));
|
||||||
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (!bluetoothAdapter.enable()) {
|
if (!bluetoothAdapter.enable()) {
|
||||||
sendBroadcast(STATUS_ERROR, context.getString(R.string.swap_error_cannot_start_bluetooth));
|
sendBroadcast(STATUS_ERROR, context.getString(R.string.swap_error_cannot_start_bluetooth));
|
||||||
@ -85,12 +96,17 @@ public class BluetoothManager {
|
|||||||
} else {
|
} else {
|
||||||
sendBroadcast(STATUS_ERROR, context.getString(R.string.swap_error_cannot_start_bluetooth));
|
sendBroadcast(STATUS_ERROR, context.getString(R.string.swap_error_cannot_start_bluetooth));
|
||||||
}
|
}
|
||||||
|
for (BluetoothDevice device : bluetoothAdapter.getBondedDevices()) {
|
||||||
|
sendFoundBroadcast(context, device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
handlerThread.start();
|
handlerThread.start();
|
||||||
handler = new Handler(handlerThread.getLooper()) {
|
handler = new Handler(handlerThread.getLooper()) {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
|
||||||
|
localBroadcastManager.unregisterReceiver(bluetoothDeviceFound);
|
||||||
bluetoothServer.close();
|
bluetoothServer.close();
|
||||||
if (bluetoothAdapter != null) {
|
if (bluetoothAdapter != null) {
|
||||||
bluetoothAdapter.cancelDiscovery();
|
bluetoothAdapter.cancelDiscovery();
|
||||||
@ -132,4 +148,23 @@ public class BluetoothManager {
|
|||||||
}
|
}
|
||||||
LocalBroadcastManager.getInstance(context.get()).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(context.get()).sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final BroadcastReceiver bluetoothDeviceFound = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
sendFoundBroadcast(context, (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static void sendFoundBroadcast(Context context, BluetoothDevice device) {
|
||||||
|
BluetoothPeer bluetoothPeer = BluetoothPeer.getInstance(device);
|
||||||
|
if (bluetoothPeer == null) {
|
||||||
|
Utils.debugLog(TAG, "IGNORING: " + device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Intent intent = new Intent(ACTION_FOUND);
|
||||||
|
intent.putExtra(EXTRA_PEER, bluetoothPeer);
|
||||||
|
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
|
||||||
|
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package org.fdroid.fdroid.localrepo;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
@ -12,6 +13,7 @@ import android.util.Log;
|
|||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.Preferences;
|
import org.fdroid.fdroid.Preferences;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
|
import org.fdroid.fdroid.localrepo.peers.BonjourPeer;
|
||||||
|
|
||||||
import javax.jmdns.JmDNS;
|
import javax.jmdns.JmDNS;
|
||||||
import javax.jmdns.ServiceEvent;
|
import javax.jmdns.ServiceEvent;
|
||||||
@ -30,9 +32,9 @@ import java.util.HashMap;
|
|||||||
public class BonjourManager {
|
public class BonjourManager {
|
||||||
private static final String TAG = "BonjourManager";
|
private static final String TAG = "BonjourManager";
|
||||||
|
|
||||||
public static final String ACTION_ADDED = "BonjourAdded";
|
public static final String ACTION_FOUND = "BonjourNewPeer";
|
||||||
public static final String ACTION_RESOLVED = "BonjourResolved";
|
public static final String ACTION_REMOVED = "BonjourPeerRemoved";
|
||||||
public static final String ACTION_REMOVED = "BonjourRemoved";
|
public static final String EXTRA_BONJOUR_PEER = "extraBonjourPeer";
|
||||||
|
|
||||||
public static final String ACTION_STATUS = "BonjourStatus";
|
public static final String ACTION_STATUS = "BonjourStatus";
|
||||||
public static final String EXTRA_STATUS = "BonjourStatusExtra";
|
public static final String EXTRA_STATUS = "BonjourStatusExtra";
|
||||||
@ -56,6 +58,7 @@ public class BonjourManager {
|
|||||||
private static volatile HandlerThread handlerThread;
|
private static volatile HandlerThread handlerThread;
|
||||||
private static ServiceInfo pairService;
|
private static ServiceInfo pairService;
|
||||||
private static JmDNS jmdns;
|
private static JmDNS jmdns;
|
||||||
|
private static WifiManager.MulticastLock multicastLock;
|
||||||
|
|
||||||
public static boolean isAlive() {
|
public static boolean isAlive() {
|
||||||
return handlerThread != null && handlerThread.isAlive();
|
return handlerThread != null && handlerThread.isAlive();
|
||||||
@ -116,6 +119,8 @@ public class BonjourManager {
|
|||||||
}
|
}
|
||||||
sendBroadcast(STATUS_STARTING, null);
|
sendBroadcast(STATUS_STARTING, null);
|
||||||
|
|
||||||
|
final WifiManager wifiManager = (WifiManager) context.getApplicationContext()
|
||||||
|
.getSystemService(Context.WIFI_SERVICE);
|
||||||
handlerThread = new HandlerThread("BonjourManager", Process.THREAD_PRIORITY_LESS_FAVORABLE) {
|
handlerThread = new HandlerThread("BonjourManager", Process.THREAD_PRIORITY_LESS_FAVORABLE) {
|
||||||
@Override
|
@Override
|
||||||
protected void onLooperPrepared() {
|
protected void onLooperPrepared() {
|
||||||
@ -124,6 +129,11 @@ public class BonjourManager {
|
|||||||
jmdns = JmDNS.create(address);
|
jmdns = JmDNS.create(address);
|
||||||
jmdns.addServiceListener(HTTP_SERVICE_TYPE, httpServiceListener);
|
jmdns.addServiceListener(HTTP_SERVICE_TYPE, httpServiceListener);
|
||||||
jmdns.addServiceListener(HTTPS_SERVICE_TYPE, httpsServiceListener);
|
jmdns.addServiceListener(HTTPS_SERVICE_TYPE, httpsServiceListener);
|
||||||
|
|
||||||
|
multicastLock = wifiManager.createMulticastLock(context.getPackageName());
|
||||||
|
multicastLock.setReferenceCounted(false);
|
||||||
|
multicastLock.acquire();
|
||||||
|
|
||||||
sendBroadcast(STATUS_STARTED, null);
|
sendBroadcast(STATUS_STARTED, null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
@ -155,15 +165,15 @@ public class BonjourManager {
|
|||||||
|
|
||||||
private void handleVisible(String localRepoName, boolean useHttps) {
|
private void handleVisible(String localRepoName, boolean useHttps) {
|
||||||
HashMap<String, String> values = new HashMap<>();
|
HashMap<String, String> values = new HashMap<>();
|
||||||
values.put("path", "/fdroid/repo");
|
values.put(BonjourPeer.PATH, "/fdroid/repo");
|
||||||
values.put("name", localRepoName);
|
values.put(BonjourPeer.NAME, localRepoName);
|
||||||
values.put("fingerprint", FDroidApp.repo.fingerprint);
|
values.put(BonjourPeer.FINGERPRINT, FDroidApp.repo.fingerprint);
|
||||||
String type;
|
String type;
|
||||||
if (useHttps) {
|
if (useHttps) {
|
||||||
values.put("type", "fdroidrepos");
|
values.put(BonjourPeer.TYPE, "fdroidrepos");
|
||||||
type = HTTPS_SERVICE_TYPE;
|
type = HTTPS_SERVICE_TYPE;
|
||||||
} else {
|
} else {
|
||||||
values.put("type", "fdroidrepo");
|
values.put(BonjourPeer.TYPE, "fdroidrepo");
|
||||||
type = HTTP_SERVICE_TYPE;
|
type = HTTP_SERVICE_TYPE;
|
||||||
}
|
}
|
||||||
ServiceInfo newPairService = ServiceInfo.create(type, localRepoName, FDroidApp.port, 0, 0, values);
|
ServiceInfo newPairService = ServiceInfo.create(type, localRepoName, FDroidApp.port, 0, 0, values);
|
||||||
@ -190,6 +200,9 @@ public class BonjourManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleStop() {
|
private void handleStop() {
|
||||||
|
if (multicastLock != null) {
|
||||||
|
multicastLock.release();
|
||||||
|
}
|
||||||
if (jmdns != null) {
|
if (jmdns != null) {
|
||||||
jmdns.unregisterAllServices();
|
jmdns.unregisterAllServices();
|
||||||
Utils.closeQuietly(jmdns);
|
Utils.closeQuietly(jmdns);
|
||||||
@ -228,9 +241,14 @@ public class BonjourManager {
|
|||||||
start(context, localRepoName, useHttps, httpServiceListener, httpsServiceListener);
|
start(context, localRepoName, useHttps, httpServiceListener, httpsServiceListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendBroadcast(String action, String message) {
|
private static void sendBroadcast(String action, ServiceInfo serviceInfo) {
|
||||||
|
BonjourPeer bonjourPeer = BonjourPeer.getInstance(serviceInfo);
|
||||||
|
if (bonjourPeer == null) {
|
||||||
|
Utils.debugLog(TAG, "IGNORING: " + serviceInfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Intent intent = new Intent(action);
|
Intent intent = new Intent(action);
|
||||||
intent.putExtra(Intent.EXTRA_TEXT, message);
|
intent.putExtra(EXTRA_BONJOUR_PEER, bonjourPeer);
|
||||||
LocalBroadcastManager.getInstance(context.get()).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(context.get()).sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,20 +268,17 @@ public class BonjourManager {
|
|||||||
private static class SwapServiceListener implements ServiceListener {
|
private static class SwapServiceListener implements ServiceListener {
|
||||||
@Override
|
@Override
|
||||||
public void serviceAdded(ServiceEvent serviceEvent) {
|
public void serviceAdded(ServiceEvent serviceEvent) {
|
||||||
Utils.debugLog(TAG, "Service added: " + serviceEvent.getInfo());
|
// ignored, we only need resolved info
|
||||||
sendBroadcast(ACTION_ADDED, serviceEvent.getInfo().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serviceRemoved(ServiceEvent serviceEvent) {
|
public void serviceRemoved(ServiceEvent serviceEvent) {
|
||||||
Utils.debugLog(TAG, "Service removed: " + serviceEvent.getInfo());
|
sendBroadcast(ACTION_REMOVED, serviceEvent.getInfo());
|
||||||
sendBroadcast(ACTION_REMOVED, serviceEvent.getInfo().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serviceResolved(ServiceEvent serviceEvent) {
|
public void serviceResolved(ServiceEvent serviceEvent) {
|
||||||
Utils.debugLog(TAG, "Service resolved: " + serviceEvent.getInfo());
|
sendBroadcast(ACTION_FOUND, serviceEvent.getInfo());
|
||||||
sendBroadcast(ACTION_RESOLVED, serviceEvent.getInfo().toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,14 +31,9 @@ import org.fdroid.fdroid.data.Repo;
|
|||||||
import org.fdroid.fdroid.data.RepoProvider;
|
import org.fdroid.fdroid.data.RepoProvider;
|
||||||
import org.fdroid.fdroid.data.Schema;
|
import org.fdroid.fdroid.data.Schema;
|
||||||
import org.fdroid.fdroid.localrepo.peers.Peer;
|
import org.fdroid.fdroid.localrepo.peers.Peer;
|
||||||
import org.fdroid.fdroid.localrepo.peers.PeerFinder;
|
|
||||||
import org.fdroid.fdroid.net.Downloader;
|
import org.fdroid.fdroid.net.Downloader;
|
||||||
import org.fdroid.fdroid.net.WifiStateChangeService;
|
import org.fdroid.fdroid.net.WifiStateChangeService;
|
||||||
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
|
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
|
||||||
import rx.Observable;
|
|
||||||
import rx.Subscription;
|
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
|
||||||
import rx.schedulers.Schedulers;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -55,9 +50,7 @@ import java.util.TimerTask;
|
|||||||
* Central service which manages all of the different moving parts of swap which are required
|
* Central service which manages all of the different moving parts of swap which are required
|
||||||
* to enable p2p swapping of apps.
|
* to enable p2p swapping of apps.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("LineLength")
|
|
||||||
public class SwapService extends Service {
|
public class SwapService extends Service {
|
||||||
|
|
||||||
private static final String TAG = "SwapService";
|
private static final String TAG = "SwapService";
|
||||||
|
|
||||||
private static final String SHARED_PREFERENCES = "swap-state";
|
private static final String SHARED_PREFERENCES = "swap-state";
|
||||||
@ -69,6 +62,7 @@ public class SwapService extends Service {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Set<String> appsToSwap = new HashSet<>();
|
private final Set<String> appsToSwap = new HashSet<>();
|
||||||
|
private final Set<Peer> activePeers = new HashSet<>();
|
||||||
|
|
||||||
private static LocalBroadcastManager localBroadcastManager;
|
private static LocalBroadcastManager localBroadcastManager;
|
||||||
private static SharedPreferences swapPreferences;
|
private static SharedPreferences swapPreferences;
|
||||||
@ -90,41 +84,16 @@ public class SwapService extends Service {
|
|||||||
context.stopService(intent);
|
context.stopService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for peers to swap
|
|
||||||
*/
|
|
||||||
private Observable<Peer> peerFinder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call {@link Observable#subscribe()} on this in order to be notified of peers
|
|
||||||
* which are found. Call {@link Subscription#unsubscribe()} on the resulting
|
|
||||||
* subscription when finished and you no longer want to scan for peers.
|
|
||||||
* <p>
|
|
||||||
* The returned object will scan for peers on a background thread, and emit
|
|
||||||
* found peers on the mian thread.
|
|
||||||
* <p>
|
|
||||||
* Invoking this in multiple places will return the same, cached, peer finder.
|
|
||||||
* That is, if in the past it already found some peers, then you subscribe
|
|
||||||
* to it in the future, the future subscriber will still receive the peers
|
|
||||||
* that were found previously.
|
|
||||||
* TODO: What about removing peers that no longer are present?
|
|
||||||
*/
|
|
||||||
public Observable<Peer> scanForPeers() {
|
|
||||||
Utils.debugLog(TAG, "Scanning for nearby devices to swap with...");
|
|
||||||
if (peerFinder == null) {
|
|
||||||
peerFinder = PeerFinder.createObservable(getApplicationContext())
|
|
||||||
.subscribeOn(Schedulers.newThread())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.distinct();
|
|
||||||
}
|
|
||||||
return peerFinder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Set<String> getAppsToSwap() {
|
public Set<String> getAppsToSwap() {
|
||||||
return appsToSwap;
|
return appsToSwap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public Set<Peer> getActivePeers() {
|
||||||
|
return activePeers;
|
||||||
|
}
|
||||||
|
|
||||||
public void connectToPeer() {
|
public void connectToPeer() {
|
||||||
if (getPeer() == null) {
|
if (getPeer() == null) {
|
||||||
throw new IllegalStateException("Cannot connect to peer, no peer has been selected.");
|
throw new IllegalStateException("Cannot connect to peer, no peer has been selected.");
|
||||||
@ -387,6 +356,9 @@ public class SwapService extends Service {
|
|||||||
|
|
||||||
localBroadcastManager.registerReceiver(onWifiChange, new IntentFilter(WifiStateChangeService.BROADCAST));
|
localBroadcastManager.registerReceiver(onWifiChange, new IntentFilter(WifiStateChangeService.BROADCAST));
|
||||||
localBroadcastManager.registerReceiver(bluetoothStatus, new IntentFilter(BluetoothManager.ACTION_STATUS));
|
localBroadcastManager.registerReceiver(bluetoothStatus, new IntentFilter(BluetoothManager.ACTION_STATUS));
|
||||||
|
localBroadcastManager.registerReceiver(bluetoothPeerFound, new IntentFilter(BluetoothManager.ACTION_FOUND));
|
||||||
|
localBroadcastManager.registerReceiver(bonjourPeerFound, new IntentFilter(BonjourManager.ACTION_FOUND));
|
||||||
|
localBroadcastManager.registerReceiver(bonjourPeerRemoved, new IntentFilter(BonjourManager.ACTION_REMOVED));
|
||||||
localBroadcastManager.registerReceiver(localRepoStatus, new IntentFilter(LocalRepoService.ACTION_STATUS));
|
localBroadcastManager.registerReceiver(localRepoStatus, new IntentFilter(LocalRepoService.ACTION_STATUS));
|
||||||
|
|
||||||
BonjourManager.start(this);
|
BonjourManager.start(this);
|
||||||
@ -418,6 +390,9 @@ public class SwapService extends Service {
|
|||||||
Preferences.get().unregisterLocalRepoHttpsListeners(httpsEnabledListener);
|
Preferences.get().unregisterLocalRepoHttpsListeners(httpsEnabledListener);
|
||||||
localBroadcastManager.unregisterReceiver(onWifiChange);
|
localBroadcastManager.unregisterReceiver(onWifiChange);
|
||||||
localBroadcastManager.unregisterReceiver(bluetoothStatus);
|
localBroadcastManager.unregisterReceiver(bluetoothStatus);
|
||||||
|
localBroadcastManager.unregisterReceiver(bluetoothPeerFound);
|
||||||
|
localBroadcastManager.unregisterReceiver(bonjourPeerFound);
|
||||||
|
localBroadcastManager.unregisterReceiver(bonjourPeerRemoved);
|
||||||
|
|
||||||
unregisterReceiver(bluetoothScanModeChanged);
|
unregisterReceiver(bluetoothScanModeChanged);
|
||||||
|
|
||||||
@ -597,4 +572,25 @@ public class SwapService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver bluetoothPeerFound = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
activePeers.add((Peer) intent.getParcelableExtra(BluetoothManager.EXTRA_PEER));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver bonjourPeerFound = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
activePeers.add((Peer) intent.getParcelableExtra(BonjourManager.EXTRA_BONJOUR_PEER));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver bonjourPeerRemoved = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
activePeers.remove((Peer) intent.getParcelableExtra(BonjourManager.EXTRA_BONJOUR_PEER));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
@ -1,126 +0,0 @@
|
|||||||
package org.fdroid.fdroid.localrepo.peers;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
|
||||||
import android.bluetooth.BluetoothClass;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.fdroid.fdroid.Utils;
|
|
||||||
|
|
||||||
import rx.Observable;
|
|
||||||
import rx.Subscriber;
|
|
||||||
import rx.functions.Action0;
|
|
||||||
import rx.subscriptions.Subscriptions;
|
|
||||||
|
|
||||||
@SuppressWarnings("LineLength")
|
|
||||||
final class BluetoothFinder extends PeerFinder {
|
|
||||||
|
|
||||||
public static Observable<Peer> createBluetoothObservable(final Context context) {
|
|
||||||
return Observable.create(new Observable.OnSubscribe<Peer>() {
|
|
||||||
@Override
|
|
||||||
public void call(Subscriber<? super Peer> subscriber) {
|
|
||||||
final BluetoothFinder finder = new BluetoothFinder(context, subscriber);
|
|
||||||
|
|
||||||
subscriber.add(Subscriptions.create(new Action0() {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
finder.cancel();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
finder.scan();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String TAG = "BluetoothFinder";
|
|
||||||
|
|
||||||
private final BluetoothAdapter adapter;
|
|
||||||
|
|
||||||
private BluetoothFinder(Context context, Subscriber<? super Peer> subscriber) {
|
|
||||||
super(context, subscriber);
|
|
||||||
adapter = BluetoothAdapter.getDefaultAdapter();
|
|
||||||
}
|
|
||||||
|
|
||||||
private BroadcastReceiver deviceFoundReceiver;
|
|
||||||
private BroadcastReceiver scanCompleteReceiver;
|
|
||||||
|
|
||||||
private void scan() {
|
|
||||||
|
|
||||||
if (adapter == null) {
|
|
||||||
Log.i(TAG, "Not scanning for bluetooth peers to swap with, couldn't find a bluetooth adapter on this device.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isScanning = true;
|
|
||||||
|
|
||||||
if (deviceFoundReceiver == null) {
|
|
||||||
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);
|
|
||||||
onDeviceFound(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.registerReceiver(deviceFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scanCompleteReceiver == null) {
|
|
||||||
scanCompleteReceiver = new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
if (isScanning) {
|
|
||||||
Utils.debugLog(TAG, "Scan complete, but we haven't been asked to stop scanning yet, so will restart scan.");
|
|
||||||
startDiscovery();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Unregister this receiver at the appropriate time.
|
|
||||||
context.registerReceiver(scanCompleteReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
|
|
||||||
}
|
|
||||||
|
|
||||||
startDiscovery();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startDiscovery() {
|
|
||||||
|
|
||||||
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? We could
|
|
||||||
// cancelDiscovery(), but then it will probably prompt the user again.
|
|
||||||
Utils.debugLog(TAG, "Requested bluetooth scan when already scanning, so will ignore request.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!adapter.startDiscovery()) {
|
|
||||||
Log.e(TAG, "Couldn't start bluetooth scanning.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancel() {
|
|
||||||
if (adapter != null) {
|
|
||||||
Utils.debugLog(TAG, "Stopping bluetooth discovery.");
|
|
||||||
adapter.cancelDiscovery();
|
|
||||||
}
|
|
||||||
|
|
||||||
isScanning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onDeviceFound(BluetoothDevice device) {
|
|
||||||
if (device != null && device.getName() != null &&
|
|
||||||
(device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA ||
|
|
||||||
device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA ||
|
|
||||||
device.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.PHONE_SMART)) {
|
|
||||||
subscriber.onNext(new BluetoothPeer(device));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +1,9 @@
|
|||||||
package org.fdroid.fdroid.localrepo.peers;
|
package org.fdroid.fdroid.localrepo.peers;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothClass.Device;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
|
|
||||||
@ -11,7 +13,22 @@ public class BluetoothPeer implements Peer {
|
|||||||
|
|
||||||
private final BluetoothDevice device;
|
private final BluetoothDevice device;
|
||||||
|
|
||||||
public BluetoothPeer(BluetoothDevice device) {
|
/**
|
||||||
|
* Return a instance if the {@link BluetoothDevice} is a device that could
|
||||||
|
* host a swap repo.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static BluetoothPeer getInstance(@Nullable BluetoothDevice device) {
|
||||||
|
if (device != null && device.getName() != null &&
|
||||||
|
(device.getBluetoothClass().getDeviceClass() == Device.COMPUTER_HANDHELD_PC_PDA
|
||||||
|
|| device.getBluetoothClass().getDeviceClass() == Device.COMPUTER_PALM_SIZE_PC_PDA
|
||||||
|
|| device.getBluetoothClass().getDeviceClass() == Device.PHONE_SMART)) {
|
||||||
|
return new BluetoothPeer(device);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BluetoothPeer(BluetoothDevice device) {
|
||||||
this.device = device;
|
this.device = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,162 +0,0 @@
|
|||||||
package org.fdroid.fdroid.localrepo.peers;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.wifi.WifiManager;
|
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
|
||||||
import org.fdroid.fdroid.Utils;
|
|
||||||
import rx.Observable;
|
|
||||||
import rx.Subscriber;
|
|
||||||
import rx.functions.Action0;
|
|
||||||
import rx.subscriptions.Subscriptions;
|
|
||||||
|
|
||||||
import javax.jmdns.JmDNS;
|
|
||||||
import javax.jmdns.ServiceEvent;
|
|
||||||
import javax.jmdns.ServiceInfo;
|
|
||||||
import javax.jmdns.ServiceListener;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
|
|
||||||
import static org.fdroid.fdroid.localrepo.BonjourManager.HTTPS_SERVICE_TYPE;
|
|
||||||
import static org.fdroid.fdroid.localrepo.BonjourManager.HTTP_SERVICE_TYPE;
|
|
||||||
|
|
||||||
@SuppressWarnings("LineLength")
|
|
||||||
final class BonjourFinder extends PeerFinder implements ServiceListener {
|
|
||||||
|
|
||||||
public static Observable<Peer> createBonjourObservable(final Context context) {
|
|
||||||
return Observable.create(new Observable.OnSubscribe<Peer>() {
|
|
||||||
@Override
|
|
||||||
public void call(Subscriber<? super Peer> subscriber) {
|
|
||||||
final BonjourFinder finder = new BonjourFinder(context, subscriber);
|
|
||||||
|
|
||||||
subscriber.add(Subscriptions.create(new Action0() {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
finder.cancel();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
finder.scan();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String TAG = "BonjourFinder";
|
|
||||||
|
|
||||||
private JmDNS jmdns;
|
|
||||||
private WifiManager wifiManager;
|
|
||||||
private WifiManager.MulticastLock multicastLock;
|
|
||||||
|
|
||||||
private BonjourFinder(Context context, Subscriber<? super Peer> subscriber) {
|
|
||||||
super(context, subscriber);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scan() {
|
|
||||||
|
|
||||||
Utils.debugLog(TAG, "Requested Bonjour (mDNS) scan for peers.");
|
|
||||||
|
|
||||||
if (wifiManager == null) {
|
|
||||||
wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
|
||||||
multicastLock = wifiManager.createMulticastLock(context.getPackageName());
|
|
||||||
multicastLock.setReferenceCounted(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isScanning) {
|
|
||||||
Utils.debugLog(TAG, "Requested Bonjour scan, but already scanning. But we will still try to explicitly scan for services.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isScanning = true;
|
|
||||||
multicastLock.acquire();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Utils.debugLog(TAG, "Searching for Bonjour (mDNS) clients...");
|
|
||||||
jmdns = JmDNS.create(InetAddress.getByName(FDroidApp.ipAddressString));
|
|
||||||
} catch (IOException e) {
|
|
||||||
subscriber.onError(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils.debugLog(TAG, "Adding mDNS service listeners for " + HTTP_SERVICE_TYPE + " and " + HTTPS_SERVICE_TYPE);
|
|
||||||
jmdns.addServiceListener(HTTP_SERVICE_TYPE, this);
|
|
||||||
jmdns.addServiceListener(HTTPS_SERVICE_TYPE, this);
|
|
||||||
listServices();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listServices() {
|
|
||||||
Utils.debugLog(TAG, "Explicitly querying for services, in addition to waiting for notifications.");
|
|
||||||
addFDroidServices(jmdns.list(HTTP_SERVICE_TYPE));
|
|
||||||
addFDroidServices(jmdns.list(HTTPS_SERVICE_TYPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serviceRemoved(ServiceEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serviceAdded(final ServiceEvent event) {
|
|
||||||
// TODO: Get clarification, but it looks like this is:
|
|
||||||
// 1) Identifying that there is _a_ bonjour service available
|
|
||||||
// 2) Adding it to the list to give some sort of feedback to the user
|
|
||||||
// 3) Requesting more detailed info in an async manner
|
|
||||||
// 4) If that is in fact an fdroid repo (after requesting info), then add it again
|
|
||||||
// so that more detailed info can be shown to the user.
|
|
||||||
//
|
|
||||||
// If so, when is the old one removed?
|
|
||||||
addFDroidService(event.getInfo());
|
|
||||||
|
|
||||||
Utils.debugLog(TAG, "Found JmDNS service, now requesting further details of service");
|
|
||||||
jmdns.requestServiceInfo(event.getType(), event.getName(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serviceResolved(ServiceEvent event) {
|
|
||||||
addFDroidService(event.getInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addFDroidServices(ServiceInfo[] services) {
|
|
||||||
for (ServiceInfo info : services) {
|
|
||||||
addFDroidService(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Broadcasts the fact that a Bonjour peer was found to swap with.
|
|
||||||
* Checks that the service is an F-Droid service, and also that it is not the F-Droid service
|
|
||||||
* for this device (by comparing its signing fingerprint to our signing fingerprint).
|
|
||||||
*/
|
|
||||||
private void addFDroidService(ServiceInfo serviceInfo) {
|
|
||||||
final String type = serviceInfo.getPropertyString("type");
|
|
||||||
final String fingerprint = serviceInfo.getPropertyString("fingerprint");
|
|
||||||
final boolean isFDroid = type != null && type.startsWith("fdroidrepo");
|
|
||||||
final boolean isSelf = FDroidApp.repo != null && fingerprint != null && fingerprint.equalsIgnoreCase(FDroidApp.repo.fingerprint);
|
|
||||||
if (isFDroid && !isSelf) {
|
|
||||||
Utils.debugLog(TAG, "Found F-Droid swap Bonjour service:\n" + serviceInfo);
|
|
||||||
subscriber.onNext(new BonjourPeer(serviceInfo));
|
|
||||||
} else {
|
|
||||||
if (isSelf) {
|
|
||||||
Utils.debugLog(TAG, "Ignoring Bonjour service because it belongs to this device:\n" + serviceInfo);
|
|
||||||
} else {
|
|
||||||
Utils.debugLog(TAG, "Ignoring Bonjour service because it doesn't look like an F-Droid swap repo:\n" + serviceInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancel() {
|
|
||||||
Utils.debugLog(TAG, "Cancelling BonjourFinder, releasing multicast lock, removing jmdns service listeners");
|
|
||||||
|
|
||||||
if (multicastLock != null) {
|
|
||||||
multicastLock.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
isScanning = false;
|
|
||||||
|
|
||||||
if (jmdns == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
jmdns.removeServiceListener(HTTP_SERVICE_TYPE, this);
|
|
||||||
jmdns.removeServiceListener(HTTPS_SERVICE_TYPE, this);
|
|
||||||
jmdns = null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -2,16 +2,39 @@ package org.fdroid.fdroid.localrepo.peers;
|
|||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
|
|
||||||
import javax.jmdns.ServiceInfo;
|
import javax.jmdns.ServiceInfo;
|
||||||
import javax.jmdns.impl.FDroidServiceInfo;
|
import javax.jmdns.impl.FDroidServiceInfo;
|
||||||
|
|
||||||
public class BonjourPeer extends WifiPeer {
|
public class BonjourPeer extends WifiPeer {
|
||||||
|
private static final String TAG = "BonjourPeer";
|
||||||
|
|
||||||
|
public static final String FINGERPRINT = "fingerprint";
|
||||||
|
public static final String NAME = "name";
|
||||||
|
public static final String PATH = "path";
|
||||||
|
public static final String TYPE = "type";
|
||||||
|
|
||||||
private final FDroidServiceInfo serviceInfo;
|
private final FDroidServiceInfo serviceInfo;
|
||||||
|
|
||||||
public BonjourPeer(ServiceInfo serviceInfo) {
|
/**
|
||||||
|
* Return a instance if the {@link ServiceInfo} is fully resolved and does
|
||||||
|
* not represent this device, but something else on the network.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static BonjourPeer getInstance(ServiceInfo serviceInfo) {
|
||||||
|
String type = serviceInfo.getPropertyString(TYPE);
|
||||||
|
String fingerprint = serviceInfo.getPropertyString(FINGERPRINT);
|
||||||
|
if (type == null || !type.startsWith("fdroidrepo")
|
||||||
|
|| TextUtils.equals(FDroidApp.repo.fingerprint, fingerprint)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new BonjourPeer(serviceInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BonjourPeer(ServiceInfo serviceInfo) {
|
||||||
this.serviceInfo = new FDroidServiceInfo(serviceInfo);
|
this.serviceInfo = new FDroidServiceInfo(serviceInfo);
|
||||||
this.name = serviceInfo.getDomain();
|
this.name = serviceInfo.getDomain();
|
||||||
this.uri = Uri.parse(this.serviceInfo.getRepoAddress());
|
this.uri = Uri.parse(this.serviceInfo.getRepoAddress());
|
||||||
|
@ -3,11 +3,20 @@ package org.fdroid.fdroid.localrepo.peers;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.support.annotation.DrawableRes;
|
import android.support.annotation.DrawableRes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO This model assumes that "peers" from Bluetooth, Bonjour, and WiFi are
|
||||||
|
* different things. They are not different repos though, they all point to
|
||||||
|
* the same repos. This should really be combined to be a single "RemoteRepo"
|
||||||
|
* class that represents a single device's local repo, and can have zero to
|
||||||
|
* many ways to connect to it (e.g. Bluetooth, WiFi, USB Thumb Drive, SD Card,
|
||||||
|
* WiFi Direct, etc).
|
||||||
|
*/
|
||||||
public interface Peer extends Parcelable {
|
public interface Peer extends Parcelable {
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
@DrawableRes int getIcon();
|
@DrawableRes
|
||||||
|
int getIcon();
|
||||||
|
|
||||||
boolean equals(Object peer);
|
boolean equals(Object peer);
|
||||||
|
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
package org.fdroid.fdroid.localrepo.peers;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import rx.Observable;
|
|
||||||
import rx.Subscriber;
|
|
||||||
import rx.schedulers.Schedulers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches for other devices in the vicinity, using specific technologies.
|
|
||||||
* Once found, emits a {@link Peer} to interested {@link Subscriber}s.
|
|
||||||
*/
|
|
||||||
public abstract class PeerFinder {
|
|
||||||
|
|
||||||
protected boolean isScanning;
|
|
||||||
protected final Context context;
|
|
||||||
protected final Subscriber<? super Peer> subscriber;
|
|
||||||
|
|
||||||
protected PeerFinder(Context context, Subscriber<? super Peer> subscriber) {
|
|
||||||
this.context = context;
|
|
||||||
this.subscriber = subscriber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Observable<Peer> createObservable(final Context context) {
|
|
||||||
return Observable.merge(
|
|
||||||
BluetoothFinder.createBluetoothObservable(context).subscribeOn(Schedulers.newThread()),
|
|
||||||
BonjourFinder.createBonjourObservable(context).subscribeOn(Schedulers.newThread())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -31,8 +31,6 @@ import org.fdroid.fdroid.localrepo.SwapService;
|
|||||||
import org.fdroid.fdroid.localrepo.SwapView;
|
import org.fdroid.fdroid.localrepo.SwapView;
|
||||||
import org.fdroid.fdroid.localrepo.peers.Peer;
|
import org.fdroid.fdroid.localrepo.peers.Peer;
|
||||||
import org.fdroid.fdroid.net.WifiStateChangeService;
|
import org.fdroid.fdroid.net.WifiStateChangeService;
|
||||||
import rx.Subscriber;
|
|
||||||
import rx.Subscription;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ public class StartSwapView extends SwapView {
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PeopleNearbyAdapter extends ArrayAdapter<Peer> {
|
class PeopleNearbyAdapter extends ArrayAdapter<Peer> {
|
||||||
|
|
||||||
PeopleNearbyAdapter(Context context) {
|
PeopleNearbyAdapter(Context context) {
|
||||||
super(context, 0, new ArrayList<Peer>());
|
super(context, 0, new ArrayList<Peer>());
|
||||||
@ -93,45 +91,14 @@ public class StartSwapView extends SwapView {
|
|||||||
|
|
||||||
private PeopleNearbyAdapter peopleNearbyAdapter;
|
private PeopleNearbyAdapter peopleNearbyAdapter;
|
||||||
|
|
||||||
/**
|
|
||||||
* When peers are emitted by the peer finder, add them to the adapter
|
|
||||||
* so that they will show up in the list of peers.
|
|
||||||
*/
|
|
||||||
private final Subscriber<Peer> onPeerFound = new Subscriber<Peer>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCompleted() {
|
|
||||||
uiShowNotSearchingForPeers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable e) {
|
|
||||||
uiShowNotSearchingForPeers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(Peer peer) {
|
|
||||||
Utils.debugLog(TAG, "Found peer: " + peer + ", adding to list of peers in UI.");
|
|
||||||
peopleNearbyAdapter.add(peer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private Subscription peerFinderSubscription;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove relevant listeners/subscriptions/etc so that they do not receive and process events
|
* Remove relevant listeners/subscriptions/etc so that they do not receive and process events
|
||||||
* when this view is not in use.
|
* when this view is not in use.
|
||||||
* <p>
|
* <p>
|
||||||
* TODO: Not sure if this is the best place to handle being removed from the view.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
if (peerFinderSubscription != null) {
|
|
||||||
peerFinderSubscription.unsubscribe();
|
|
||||||
peerFinderSubscription = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bluetoothSwitch != null) {
|
if (bluetoothSwitch != null) {
|
||||||
bluetoothSwitch.setOnCheckedChangeListener(null);
|
bluetoothSwitch.setOnCheckedChangeListener(null);
|
||||||
}
|
}
|
||||||
@ -143,10 +110,6 @@ public class StartSwapView extends SwapView {
|
|||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
|
|
||||||
if (peerFinderSubscription == null) {
|
|
||||||
peerFinderSubscription = getActivity().getSwapService().scanForPeers().subscribe(onPeerFound);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiInitPeers();
|
uiInitPeers();
|
||||||
uiInitBluetooth();
|
uiInitBluetooth();
|
||||||
uiInitWifi();
|
uiInitWifi();
|
||||||
@ -184,6 +147,7 @@ public class StartSwapView extends SwapView {
|
|||||||
|
|
||||||
peopleNearbyAdapter = new PeopleNearbyAdapter(getContext());
|
peopleNearbyAdapter = new PeopleNearbyAdapter(getContext());
|
||||||
peopleNearbyList.setAdapter(peopleNearbyAdapter);
|
peopleNearbyList.setAdapter(peopleNearbyAdapter);
|
||||||
|
peopleNearbyAdapter.addAll(getActivity().getSwapService().getActivePeers());
|
||||||
|
|
||||||
peopleNearbyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
peopleNearbyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -36,10 +36,12 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ListView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -345,7 +347,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
localBroadcastManager.registerReceiver(localRepoStatus, new IntentFilter(LocalRepoService.ACTION_STATUS));
|
localBroadcastManager.registerReceiver(localRepoStatus, new IntentFilter(LocalRepoService.ACTION_STATUS));
|
||||||
localBroadcastManager.registerReceiver(repoUpdateReceiver,
|
localBroadcastManager.registerReceiver(repoUpdateReceiver,
|
||||||
new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
|
new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
|
||||||
|
localBroadcastManager.registerReceiver(bonjourFound, new IntentFilter(BonjourManager.ACTION_FOUND));
|
||||||
|
localBroadcastManager.registerReceiver(bonjourRemoved, new IntentFilter(BonjourManager.ACTION_REMOVED));
|
||||||
localBroadcastManager.registerReceiver(bonjourStatus, new IntentFilter(BonjourManager.ACTION_STATUS));
|
localBroadcastManager.registerReceiver(bonjourStatus, new IntentFilter(BonjourManager.ACTION_STATUS));
|
||||||
|
localBroadcastManager.registerReceiver(bluetoothFound, new IntentFilter(BluetoothManager.ACTION_FOUND));
|
||||||
localBroadcastManager.registerReceiver(bluetoothStatus, new IntentFilter(BluetoothManager.ACTION_STATUS));
|
localBroadcastManager.registerReceiver(bluetoothStatus, new IntentFilter(BluetoothManager.ACTION_STATUS));
|
||||||
|
|
||||||
registerReceiver(bluetoothScanModeChanged,
|
registerReceiver(bluetoothScanModeChanged,
|
||||||
@ -368,7 +373,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
localBroadcastManager.unregisterReceiver(onWifiStateChanged);
|
localBroadcastManager.unregisterReceiver(onWifiStateChanged);
|
||||||
localBroadcastManager.unregisterReceiver(localRepoStatus);
|
localBroadcastManager.unregisterReceiver(localRepoStatus);
|
||||||
localBroadcastManager.unregisterReceiver(repoUpdateReceiver);
|
localBroadcastManager.unregisterReceiver(repoUpdateReceiver);
|
||||||
|
localBroadcastManager.unregisterReceiver(bonjourFound);
|
||||||
|
localBroadcastManager.unregisterReceiver(bonjourRemoved);
|
||||||
localBroadcastManager.unregisterReceiver(bonjourStatus);
|
localBroadcastManager.unregisterReceiver(bonjourStatus);
|
||||||
|
localBroadcastManager.unregisterReceiver(bluetoothFound);
|
||||||
localBroadcastManager.unregisterReceiver(bluetoothStatus);
|
localBroadcastManager.unregisterReceiver(bluetoothStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,6 +1068,28 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver bonjourFound = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
ListView peopleNearbyList = container.findViewById(R.id.list_people_nearby);
|
||||||
|
if (peopleNearbyList != null) {
|
||||||
|
ArrayAdapter<Peer> peopleNearbyAdapter = (ArrayAdapter<Peer>) peopleNearbyList.getAdapter();
|
||||||
|
peopleNearbyAdapter.add((Peer) intent.getParcelableExtra(BonjourManager.EXTRA_BONJOUR_PEER));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver bonjourRemoved = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
ListView peopleNearbyList = container.findViewById(R.id.list_people_nearby);
|
||||||
|
if (peopleNearbyList != null) {
|
||||||
|
ArrayAdapter<Peer> peopleNearbyAdapter = (ArrayAdapter<Peer>) peopleNearbyList.getAdapter();
|
||||||
|
peopleNearbyAdapter.remove((Peer) intent.getParcelableExtra(BonjourManager.EXTRA_BONJOUR_PEER));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final BroadcastReceiver bluetoothStatus = new BroadcastReceiver() {
|
private final BroadcastReceiver bluetoothStatus = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@ -1132,7 +1162,17 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Bad intent: " + intent);
|
throw new IllegalArgumentException("Bad intent: " + intent);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver bluetoothFound = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
ListView peopleNearbyList = container.findViewById(R.id.list_people_nearby);
|
||||||
|
if (peopleNearbyList != null) {
|
||||||
|
ArrayAdapter<Peer> peopleNearbyAdapter = (ArrayAdapter<Peer>) peopleNearbyList.getAdapter();
|
||||||
|
peopleNearbyAdapter.add((Peer) intent.getParcelableExtra(BluetoothManager.EXTRA_PEER));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user