WIP: Refactoring Bonjour from manage repos to swap.
Implementing the bare bones of a generic "peer finder" framework. This may or may not eventuate to something which can live in its own library and be used by other projects. Might go hand in hand with Carries idea of having a common UI to be shared among projects. Got Bluetooth and Bonjour kinda working, but the UI is crud, and it doesn't remove items and ends up with duplicates. Otherwise, on our way to a proper "nearby peers" screen.
This commit is contained in:
parent
a30ec646b2
commit
0100415e3e
@ -44,6 +44,7 @@
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="18" />
|
||||
|
@ -16,7 +16,6 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:paddingBottom="2dip"
|
||||
android:paddingTop="2dip">
|
||||
|
@ -181,26 +181,11 @@
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.00"
|
||||
android:drawableStart="@drawable/ic_fdroid_grey"
|
||||
android:drawablePadding="10dp"
|
||||
android:paddingStart="20dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:text="@string/swap_send_fdroid"
|
||||
android:gravity="start|center_vertical" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.00"
|
||||
android:drawableStart="@drawable/ic_qr_grey"
|
||||
android:drawablePadding="10dp"
|
||||
android:paddingStart="20dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:text="@string/swap_scan_qr"
|
||||
android:gravity="start|center_vertical" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_width="match_parent"/>
|
||||
|
||||
</org.fdroid.fdroid.views.swap.StartSwapView>
|
@ -321,6 +321,10 @@
|
||||
<string name="swap_dont_show_again">Don\'t show this again</string>
|
||||
<string name="swap_tap_for_details_and_install">Tap an app for details and to install.</string>
|
||||
<string name="swap_scan_or_type_url">One person needs to scan the code, or type the URL of the other in a browser.</string>
|
||||
<string name="swap_choose_apps">Choose Apps</string>
|
||||
<string name="swap_scan_qr">Scan QR Code</string>
|
||||
<string name="swap_people_nearby">People Nearby</string>
|
||||
|
||||
<!-- WiFi AP status for Swap flow -->
|
||||
<string name="wifi_ap_public">Public</string>
|
||||
<string name="wifi_ap_private">Private</string>
|
||||
@ -328,8 +332,6 @@
|
||||
<string name="wifi_warning_public">May work</string>
|
||||
<string name="wifi_warning_private">Promising</string>
|
||||
<string name="wifi_warning_personal">Best bet</string>
|
||||
<string name="swap_choose_apps">Choose Apps</string>
|
||||
<string name="swap_scan_qr">Scan QR Code</string>
|
||||
<string name="swap_nearby">Nearby Swap</string>
|
||||
<string name="swap_intro">Connect and trade apps with people near you.</string>
|
||||
<string name="swap_visible_bluetooth">Visible via Bluetooth</string>
|
||||
|
@ -18,9 +18,9 @@ import org.fdroid.fdroid.localrepo.peers.PeerFinder;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SwapManager {
|
||||
@ -49,7 +49,7 @@ public class SwapManager {
|
||||
private Set<String> appsToSwap;
|
||||
|
||||
@NonNull
|
||||
private Collection<Peer> peers;
|
||||
private List<Peer> peers;
|
||||
|
||||
private SwapManager(@NonNull Context context, @NonNull Set<String> appsToSwap) {
|
||||
this.context = context.getApplicationContext();
|
||||
@ -73,6 +73,12 @@ public class SwapManager {
|
||||
// Search for peers to swap
|
||||
// ==========================================================
|
||||
|
||||
private PeerFinder.Listener<Peer> peerListener;
|
||||
|
||||
public void setPeerListener(PeerFinder.Listener<Peer> listener) {
|
||||
this.peerListener = listener;
|
||||
}
|
||||
|
||||
public void scanForPeers() {
|
||||
if (service != null) {
|
||||
Log.d(TAG, "Scanning for nearby devices to swap with...");
|
||||
@ -91,7 +97,17 @@ public class SwapManager {
|
||||
}
|
||||
|
||||
public void onPeerFound(Peer peer) {
|
||||
peers.add(peer);
|
||||
if (!peers.contains(peer)) {
|
||||
peers.add(peer);
|
||||
if (peerListener != null) {
|
||||
peerListener.onPeerFound(peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<Peer> getPeers() {
|
||||
return peers;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,21 +1,70 @@
|
||||
package org.fdroid.fdroid.localrepo.peers;
|
||||
|
||||
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.util.Log;
|
||||
|
||||
// TODO: Still to be implemented
|
||||
public class BluetoothFinder extends PeerFinder<BluetoothPeer> {
|
||||
|
||||
private static final String TAG = "BluetoothFinder";
|
||||
|
||||
private final Context context;
|
||||
private final BluetoothAdapter adapter;
|
||||
|
||||
public BluetoothFinder(Context context) {
|
||||
this.context = context;
|
||||
adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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;
|
||||
}
|
||||
|
||||
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);
|
||||
onDeviceFound(device);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final BroadcastReceiver scanCompleteReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(TAG, "Scan complete: " + intent.getAction());
|
||||
}
|
||||
};
|
||||
|
||||
context.registerReceiver(deviceFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
|
||||
context.registerReceiver(scanCompleteReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
|
||||
|
||||
if (!adapter.startDiscovery()) {
|
||||
Log.e(TAG, "Couldn't start bluetooth scanning.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (adapter != null) {
|
||||
Log.d(TAG, "Stopping bluetooth discovery.");
|
||||
adapter.cancelDiscovery();
|
||||
}
|
||||
}
|
||||
|
||||
private void onDeviceFound(BluetoothDevice device) {
|
||||
foundPeer(new BluetoothPeer(device));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,4 +21,9 @@ public class BluetoothPeer implements Peer {
|
||||
return android.R.drawable.stat_sys_data_bluetooth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Peer peer) {
|
||||
return peer != null && peer instanceof BluetoothPeer && ((BluetoothPeer)peer).device.getAddress() == device.getAddress();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public class BonjourFinder extends PeerFinder<BonjourPeer> implements ServiceLis
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
Log.d(TAG, "Cleaning up mDNS service listeners.");
|
||||
Log.d(TAG, "Adding mDNS service listeners.");
|
||||
if (mJmdns != null) {
|
||||
mJmdns.addServiceListener(HTTP_SERVICE_TYPE, BonjourFinder.this);
|
||||
mJmdns.addServiceListener(HTTPS_SERVICE_TYPE, BonjourFinder.this);
|
||||
@ -78,6 +78,14 @@ public class BonjourFinder extends PeerFinder<BonjourPeer> implements ServiceLis
|
||||
|
||||
@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);
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
|
@ -22,4 +22,14 @@ public class BonjourPeer implements Peer {
|
||||
return R.drawable.wifi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Peer peer) {
|
||||
if (peer != null && peer instanceof BonjourPeer) {
|
||||
BonjourPeer that = (BonjourPeer)peer;
|
||||
// TODO: Don't us "name" for comparing, but rather fingerprint of the swap repo.
|
||||
return that.serviceInfo.getName().equals(this.serviceInfo.getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,4 +8,6 @@ public interface Peer {
|
||||
|
||||
@DrawableRes int getIcon();
|
||||
|
||||
boolean equals(Peer peer);
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class BonjourType implements SwapType {
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
if (Preferences.get().isLocalRepoBonjourEnabled())
|
||||
if (!Preferences.get().isLocalRepoBonjourEnabled())
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -72,17 +72,6 @@ public class SelectAppsView extends ListView implements
|
||||
|
||||
private AppListAdapter adapter;
|
||||
private String mCurrentFilterString;
|
||||
private final Presenter presenter = new Presenter();
|
||||
|
||||
public static class Presenter {
|
||||
|
||||
private SelectAppsView view;
|
||||
|
||||
public void setView(@NonNull SelectAppsView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
@ -101,8 +90,6 @@ public class SelectAppsView extends ListView implements
|
||||
toggleAppSelected(position);
|
||||
}
|
||||
});
|
||||
|
||||
presenter.setView(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,26 +1,21 @@
|
||||
package org.fdroid.fdroid.views.swap;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.compat.SwitchCompat;
|
||||
import org.fdroid.fdroid.localrepo.SwapManager;
|
||||
import org.fdroid.fdroid.localrepo.peers.Peer;
|
||||
import org.fdroid.fdroid.localrepo.peers.PeerFinder;
|
||||
|
||||
public class StartSwapView extends LinearLayout implements SwapWorkflowActivity.InnerView {
|
||||
|
||||
@ -48,6 +43,27 @@ public class StartSwapView extends LinearLayout implements SwapWorkflowActivity.
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
private class PeopleNearbyAdapter extends ArrayAdapter<Peer> {
|
||||
|
||||
public PeopleNearbyAdapter(Context context) {
|
||||
super(context, 0, SwapManager.load(context).getPeers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(getContext()).inflate(android.R.layout.two_line_list_item, parent, false);
|
||||
}
|
||||
|
||||
Peer peer = getItem(position);
|
||||
((TextView)convertView.findViewById(android.R.id.text1)).setText(peer.getName());
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private SwapWorkflowActivity getActivity() {
|
||||
// TODO: Try and find a better way to get to the SwapActivity, which makes less asumptions.
|
||||
return (SwapWorkflowActivity)getContext();
|
||||
@ -104,6 +120,18 @@ public class StartSwapView extends LinearLayout implements SwapWorkflowActivity.
|
||||
}
|
||||
});
|
||||
|
||||
final PeopleNearbyAdapter adapter = new PeopleNearbyAdapter(getContext());
|
||||
|
||||
peopleNearbyList = (ListView)findViewById(R.id.people_nearby);
|
||||
peopleNearbyList.setAdapter(adapter);
|
||||
|
||||
SwapManager.load(getActivity()).setPeerListener(new PeerFinder.Listener<Peer>() {
|
||||
@Override
|
||||
public void onPeerFound(Peer peer) {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class SwapWorkflowActivity extends ActionBarActivity {
|
||||
/** @return True if the menu should be shown. */
|
||||
boolean buildMenu(Menu menu, @NonNull MenuInflater inflater);
|
||||
|
||||
/** @return The step that this view represents. */
|
||||
/** @return The steap that this view represents. */
|
||||
@SwapManager.SwapStep int getStep();
|
||||
|
||||
@SwapManager.SwapStep int getPreviousStep();
|
||||
|
Loading…
x
Reference in New Issue
Block a user