replace Android NSD browsing with jmdns
Android's NSD is only included in Android >= 16, and seems to be buggy. So This replaces the NSD code entirely with jmdns, which works on all Android versions. fixes #2900 https://dev.guardianproject.info/issues/2900 fixes #3379 https://dev.guardianproject.info/issues/3379
This commit is contained in:
parent
b5f7c0a481
commit
f2994b0764
@ -10,7 +10,6 @@
|
|||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:paddingLeft="8sp"
|
android:paddingLeft="8sp"
|
||||||
android:paddingStart="8sp"
|
android:paddingStart="8sp"
|
||||||
android:text="@string/discovered_repo_name"
|
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
@ -23,7 +22,7 @@
|
|||||||
android:paddingLeft="8sp"
|
android:paddingLeft="8sp"
|
||||||
android:paddingStart="8sp"
|
android:paddingStart="8sp"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="@string/repo_address"
|
android:text="@string/waiting_for_ipaddress"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -165,6 +165,7 @@
|
|||||||
<string name="local_repos_title">Local FDroid Repos</string>
|
<string name="local_repos_title">Local FDroid Repos</string>
|
||||||
<string name="local_repos_scanning">Discovering local FDroid repos…</string>
|
<string name="local_repos_scanning">Discovering local FDroid repos…</string>
|
||||||
<string name="local_repo_running">Your local FDroid repo is accessible.</string>
|
<string name="local_repo_running">Your local FDroid repo is accessible.</string>
|
||||||
|
<string name="waiting_for_ipaddress">waiting for IP address…</string>
|
||||||
<string name="setup_repo">Setup Local Repo</string>
|
<string name="setup_repo">Setup Local Repo</string>
|
||||||
<string name="touch_to_configure_local_repo">Touch to setup your local repo.</string>
|
<string name="touch_to_configure_local_repo">Touch to setup your local repo.</string>
|
||||||
<string name="touch_to_turn_on_local_repo">Touch to turn on your local repo.</string>
|
<string name="touch_to_turn_on_local_repo">Touch to turn on your local repo.</string>
|
||||||
@ -251,9 +252,6 @@
|
|||||||
<string name="not_on_same_wifi">Your device is not on the same WiFi as the local repo you just added! Try joining this network: %s</string>
|
<string name="not_on_same_wifi">Your device is not on the same WiFi as the local repo you just added! Try joining this network: %s</string>
|
||||||
<string name="requires_features">Requires: %1$s</string>
|
<string name="requires_features">Requires: %1$s</string>
|
||||||
|
|
||||||
<string name="discovered_repo_name">Discovered Repo Name</string>
|
|
||||||
<string name="repo_address">Repo Address</string>
|
|
||||||
|
|
||||||
<string name="app_icon">App icon</string>
|
<string name="app_icon">App icon</string>
|
||||||
<string name="repo_icon">Repo icon</string>
|
<string name="repo_icon">Repo icon</string>
|
||||||
|
|
||||||
|
249
src/org/fdroid/fdroid/net/MDnsHelper.java
Normal file
249
src/org/fdroid/fdroid/net/MDnsHelper.java
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
|
||||||
|
package org.fdroid.fdroid.net;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.fdroid.fdroid.R;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.jmdns.*;
|
||||||
|
|
||||||
|
public class MDnsHelper implements ServiceListener {
|
||||||
|
|
||||||
|
public static final String TAG = "MDnsHelper";
|
||||||
|
public static final String HTTP_SERVICE_TYPE = "_http._tcp.local.";
|
||||||
|
public static final String HTTPS_SERVICE_TYPE = "_https._tcp.local.";
|
||||||
|
|
||||||
|
final Activity mActivity;
|
||||||
|
final RepoScanListAdapter mAdapter;
|
||||||
|
|
||||||
|
private JmDNS mJmdns;
|
||||||
|
|
||||||
|
public MDnsHelper(Activity activity, final RepoScanListAdapter adapter) {
|
||||||
|
mActivity = activity;
|
||||||
|
mAdapter = adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serviceAdded(ServiceEvent event) {
|
||||||
|
// a ListView Adapter can only be updated on the UI thread
|
||||||
|
final ServiceInfo serviceInfo = event.getInfo();
|
||||||
|
mActivity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mAdapter.addItem(serviceInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serviceRemoved(ServiceEvent event) {
|
||||||
|
// a ListView Adapter can only be updated on the UI thread
|
||||||
|
final ServiceInfo serviceInfo = event.getInfo();
|
||||||
|
mActivity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mAdapter.removeItem(serviceInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serviceResolved(ServiceEvent event) {
|
||||||
|
// a ListView Adapter can only be updated on the UI thread
|
||||||
|
final ServiceInfo serviceInfo = event.getInfo();
|
||||||
|
mActivity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mAdapter.addItem(serviceInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void discoverServices() {
|
||||||
|
new AsyncTask<Void, Void, Void>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
mJmdns = JmDNS.create();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void result) {
|
||||||
|
if (mJmdns != null) {
|
||||||
|
mJmdns.addServiceListener(HTTP_SERVICE_TYPE, MDnsHelper.this);
|
||||||
|
mJmdns.addServiceListener(HTTPS_SERVICE_TYPE, MDnsHelper.this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopDiscovery() {
|
||||||
|
if (mJmdns == null)
|
||||||
|
return;
|
||||||
|
mJmdns.removeServiceListener(HTTP_SERVICE_TYPE, MDnsHelper.this);
|
||||||
|
mJmdns.removeServiceListener(HTTPS_SERVICE_TYPE, MDnsHelper.this);
|
||||||
|
mJmdns = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RepoScanListAdapter extends BaseAdapter {
|
||||||
|
private Context mContext;
|
||||||
|
private LayoutInflater mLayoutInflater;
|
||||||
|
private List<DiscoveredRepo> mEntries = new ArrayList<DiscoveredRepo>();
|
||||||
|
|
||||||
|
public RepoScanListAdapter(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
mLayoutInflater = (LayoutInflater) mContext
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mEntries.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return mEntries.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(int position) {
|
||||||
|
DiscoveredRepo service = mEntries.get(position);
|
||||||
|
ServiceInfo serviceInfo = service.getServiceInfo();
|
||||||
|
InetAddress[] addresses = serviceInfo.getInetAddresses();
|
||||||
|
if (addresses != null && addresses.length > 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
RelativeLayout itemView;
|
||||||
|
if (convertView == null) {
|
||||||
|
itemView = (RelativeLayout) mLayoutInflater.inflate(
|
||||||
|
R.layout.repodiscoveryitem, parent, false);
|
||||||
|
} else {
|
||||||
|
itemView = (RelativeLayout) convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextView nameLabel = (TextView) itemView.findViewById(R.id.reposcanitemname);
|
||||||
|
TextView addressLabel = (TextView) itemView.findViewById(R.id.reposcanitemaddress);
|
||||||
|
|
||||||
|
final DiscoveredRepo service = mEntries.get(position);
|
||||||
|
final ServiceInfo serviceInfo = service.getServiceInfo();
|
||||||
|
|
||||||
|
nameLabel.setText(serviceInfo.getName());
|
||||||
|
|
||||||
|
InetAddress[] addresses = serviceInfo.getInetAddresses();
|
||||||
|
if (addresses != null && addresses.length > 0) {
|
||||||
|
String addressTxt = "Hosted @ " + addresses[0] + ":" + serviceInfo.getPort();
|
||||||
|
addressLabel.setText(addressTxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItem(ServiceInfo item) {
|
||||||
|
if (item == null || item.getName() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Construct a DiscoveredRepo wrapper for the service being
|
||||||
|
// added in order to use a name based equals().
|
||||||
|
DiscoveredRepo newDRepo = new DiscoveredRepo(item);
|
||||||
|
// if an unresolved entry with the same name exists, remove it
|
||||||
|
for (DiscoveredRepo dr : mEntries)
|
||||||
|
if (dr.equals(newDRepo)) {
|
||||||
|
InetAddress[] addresses = dr.mServiceInfo.getInetAddresses();
|
||||||
|
if (addresses == null || addresses.length == 0)
|
||||||
|
mEntries.remove(dr);
|
||||||
|
}
|
||||||
|
mEntries.add(newDRepo);
|
||||||
|
|
||||||
|
notifyUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeItem(ServiceInfo item) {
|
||||||
|
if (item == null || item.getName() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Construct a DiscoveredRepo wrapper for the service being
|
||||||
|
// removed in order to use a name based equals().
|
||||||
|
DiscoveredRepo lostServiceBean = new DiscoveredRepo(item);
|
||||||
|
|
||||||
|
if (mEntries.contains(lostServiceBean)) {
|
||||||
|
mEntries.remove(lostServiceBean);
|
||||||
|
notifyUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyUpdate() {
|
||||||
|
// Need to call notifyDataSetChanged from the UI thread
|
||||||
|
// in order for it to update the ListView without error
|
||||||
|
Handler refresh = new Handler(Looper.getMainLooper());
|
||||||
|
refresh.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DiscoveredRepo {
|
||||||
|
private final ServiceInfo mServiceInfo;
|
||||||
|
|
||||||
|
public DiscoveredRepo(ServiceInfo serviceInfo) {
|
||||||
|
if (serviceInfo == null || serviceInfo.getName() == null)
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Parameters \"serviceInfo\" and \"name\" must not be null.");
|
||||||
|
mServiceInfo = serviceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceInfo getServiceInfo() {
|
||||||
|
return mServiceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return mServiceInfo.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (!(other instanceof DiscoveredRepo))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Treat two services the same based on name. Eventually
|
||||||
|
// there should be a persistent mapping between fingerprint
|
||||||
|
// of the repo key and the discovered service such that we
|
||||||
|
// could maintain trust across hostnames/ips/networks
|
||||||
|
DiscoveredRepo otherRepo = (DiscoveredRepo) other;
|
||||||
|
return getName().equals(otherRepo.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,252 +0,0 @@
|
|||||||
package org.fdroid.fdroid.net;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.nsd.NsdServiceInfo;
|
|
||||||
import android.net.nsd.NsdManager;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.fdroid.fdroid.R;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@TargetApi(16) // AKA Android 4.1 AKA Jelly Bean
|
|
||||||
public class NsdHelper {
|
|
||||||
|
|
||||||
public static final String TAG = "NsdHelper";
|
|
||||||
public static final String HTTP_SERVICE_TYPE = "_fdroidrepo._tcp.";
|
|
||||||
public static final String HTTPS_SERVICE_TYPE = "_fdroidrepos._tcp.";
|
|
||||||
|
|
||||||
final Context mContext;
|
|
||||||
final NsdManager mNsdManager;
|
|
||||||
final RepoScanListAdapter mAdapter;
|
|
||||||
|
|
||||||
NsdManager.ResolveListener mResolveListener;
|
|
||||||
NsdManager.DiscoveryListener mDiscoveryListener;
|
|
||||||
|
|
||||||
public NsdHelper(Context context, final RepoScanListAdapter adapter) {
|
|
||||||
mContext = context;
|
|
||||||
mAdapter = adapter;
|
|
||||||
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
|
|
||||||
|
|
||||||
initializeResolveListener();
|
|
||||||
initializeDiscoveryListener();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initializeDiscoveryListener() {
|
|
||||||
mDiscoveryListener = new NsdManager.DiscoveryListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDiscoveryStarted(String regType) {
|
|
||||||
Log.i(TAG, "Service discovery started");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceFound(NsdServiceInfo service)
|
|
||||||
{
|
|
||||||
Log.d(TAG, "Discovered service: "+ service.getServiceName() +
|
|
||||||
" Type: "+ service.getServiceType());
|
|
||||||
|
|
||||||
if (service.getServiceType().equals(HTTP_SERVICE_TYPE) ||
|
|
||||||
service.getServiceType().equals(HTTPS_SERVICE_TYPE))
|
|
||||||
{
|
|
||||||
Log.d(TAG, "Resolving FDroid service");
|
|
||||||
mNsdManager.resolveService(service, mResolveListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceLost(NsdServiceInfo service) {
|
|
||||||
Log.e(TAG, "service lost" + service);
|
|
||||||
mAdapter.removeItem(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDiscoveryStopped(String serviceType) {
|
|
||||||
Log.i(TAG, "Discovery stopped: " + serviceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
|
|
||||||
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
|
|
||||||
mNsdManager.stopServiceDiscovery(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
|
|
||||||
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
|
|
||||||
mNsdManager.stopServiceDiscovery(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initializeResolveListener() {
|
|
||||||
mResolveListener = new NsdManager.ResolveListener() {
|
|
||||||
@Override
|
|
||||||
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
|
|
||||||
Log.e(TAG, "Resolve failed: Error code: " + errorCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceResolved(NsdServiceInfo serviceInfo) {
|
|
||||||
Log.d(TAG, "Resolve Succeeded. " + serviceInfo);
|
|
||||||
mAdapter.addItem(serviceInfo);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void discoverServices() {
|
|
||||||
mNsdManager.discoverServices(
|
|
||||||
HTTP_SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
|
|
||||||
mNsdManager.discoverServices(
|
|
||||||
HTTPS_SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopDiscovery() {
|
|
||||||
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RepoScanListAdapter extends BaseAdapter {
|
|
||||||
private Context mContext;
|
|
||||||
private LayoutInflater mLayoutInflater;
|
|
||||||
private List<DiscoveredRepo> mEntries = new ArrayList<DiscoveredRepo>();
|
|
||||||
|
|
||||||
public RepoScanListAdapter(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
mLayoutInflater = (LayoutInflater) mContext
|
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return mEntries.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getItem(int position) {
|
|
||||||
return mEntries.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
RelativeLayout itemView;
|
|
||||||
if (convertView == null)
|
|
||||||
{
|
|
||||||
itemView = (RelativeLayout) mLayoutInflater.inflate(
|
|
||||||
R.layout.repodiscoveryitem, parent, false);
|
|
||||||
} else {
|
|
||||||
itemView = (RelativeLayout) convertView;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView nameLabel = (TextView) itemView.findViewById(R.id.reposcanitemname);
|
|
||||||
TextView addressLabel = (TextView) itemView.findViewById(R.id.reposcanitemaddress);
|
|
||||||
|
|
||||||
final DiscoveredRepo service = mEntries.get(position);
|
|
||||||
final NsdServiceInfo serviceInfo = service.getServiceInfo();
|
|
||||||
|
|
||||||
String addressTxt = "Hosted @ "+
|
|
||||||
serviceInfo.getHost().getHostAddress() + ":"+ serviceInfo.getPort();
|
|
||||||
|
|
||||||
nameLabel.setText(serviceInfo.getServiceName());
|
|
||||||
addressLabel.setText(addressTxt);
|
|
||||||
|
|
||||||
return itemView;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addItem(NsdServiceInfo item)
|
|
||||||
{
|
|
||||||
if(item == null || item.getServiceName() == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Construct a DiscoveredRepo wrapper for the service being
|
|
||||||
//added in order to use a name based equals().
|
|
||||||
DiscoveredRepo repoBean = new DiscoveredRepo(item);
|
|
||||||
mEntries.add(repoBean);
|
|
||||||
|
|
||||||
notifyUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeItem(NsdServiceInfo item)
|
|
||||||
{
|
|
||||||
if(item == null || item.getServiceName() == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Construct a DiscoveredRepo wrapper for the service being
|
|
||||||
//removed in order to use a name based equals().
|
|
||||||
DiscoveredRepo lostServiceBean = new DiscoveredRepo(item);
|
|
||||||
|
|
||||||
if(mEntries.contains(lostServiceBean))
|
|
||||||
{
|
|
||||||
mEntries.remove(lostServiceBean);
|
|
||||||
notifyUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyUpdate()
|
|
||||||
{
|
|
||||||
//Need to call notifyDataSetChanged from the UI thread
|
|
||||||
//in order for it to update the ListView without error
|
|
||||||
Handler refresh = new Handler(Looper.getMainLooper());
|
|
||||||
refresh.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DiscoveredRepo {
|
|
||||||
private final NsdServiceInfo mServiceInfo;
|
|
||||||
|
|
||||||
public DiscoveredRepo(NsdServiceInfo serviceInfo)
|
|
||||||
{
|
|
||||||
if(serviceInfo == null || serviceInfo.getServiceName() == null)
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Parameters \"serviceInfo\" and \"name\" must not be null.");
|
|
||||||
mServiceInfo = serviceInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NsdServiceInfo getServiceInfo()
|
|
||||||
{
|
|
||||||
return mServiceInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return mServiceInfo.getServiceName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other)
|
|
||||||
{
|
|
||||||
if(!(other instanceof DiscoveredRepo))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//Treat two services the same based on name. Eventually
|
|
||||||
//there should be a persistent mapping between fingerprint
|
|
||||||
//of the repo key and the discovered service such that we
|
|
||||||
//could maintain trust across hostnames/ips/networks
|
|
||||||
DiscoveredRepo otherRepo = (DiscoveredRepo) other;
|
|
||||||
return getName().equals(otherRepo.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,19 +1,11 @@
|
|||||||
|
|
||||||
package org.fdroid.fdroid.views.fragments;
|
package org.fdroid.fdroid.views.fragments;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.ContentValues;
|
import android.content.*;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.nsd.NsdServiceInfo;
|
|
||||||
import android.net.wifi.WifiInfo;
|
|
||||||
import android.net.wifi.WifiManager;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
@ -22,31 +14,18 @@ import android.support.v4.app.LoaderManager;
|
|||||||
import android.support.v4.content.CursorLoader;
|
import android.support.v4.content.CursorLoader;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.support.v4.view.MenuItemCompat;
|
import android.support.v4.view.MenuItemCompat;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.*;
|
||||||
import android.view.MenuInflater;
|
import android.widget.*;
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.*;
|
||||||
import org.fdroid.fdroid.net.NsdHelper;
|
|
||||||
import org.fdroid.fdroid.net.NsdHelper.DiscoveredRepo;
|
|
||||||
import org.fdroid.fdroid.Preferences;
|
|
||||||
import org.fdroid.fdroid.ProgressListener;
|
|
||||||
import org.fdroid.fdroid.R;
|
|
||||||
import org.fdroid.fdroid.net.NsdHelper.RepoScanListAdapter;
|
|
||||||
import org.fdroid.fdroid.UpdateService;
|
|
||||||
import org.fdroid.fdroid.compat.ClipboardCompat;
|
import org.fdroid.fdroid.compat.ClipboardCompat;
|
||||||
import org.fdroid.fdroid.data.Repo;
|
import org.fdroid.fdroid.data.Repo;
|
||||||
import org.fdroid.fdroid.data.RepoProvider;
|
import org.fdroid.fdroid.data.RepoProvider;
|
||||||
|
import org.fdroid.fdroid.net.MDnsHelper;
|
||||||
|
import org.fdroid.fdroid.net.MDnsHelper.DiscoveredRepo;
|
||||||
|
import org.fdroid.fdroid.net.MDnsHelper.RepoScanListAdapter;
|
||||||
import org.fdroid.fdroid.views.RepoAdapter;
|
import org.fdroid.fdroid.views.RepoAdapter;
|
||||||
import org.fdroid.fdroid.views.RepoDetailsActivity;
|
import org.fdroid.fdroid.views.RepoDetailsActivity;
|
||||||
|
|
||||||
@ -55,6 +34,8 @@ import java.net.URL;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import javax.jmdns.ServiceInfo;
|
||||||
|
|
||||||
public class RepoListFragment extends ListFragment
|
public class RepoListFragment extends ListFragment
|
||||||
implements LoaderManager.LoaderCallbacks<Cursor>, RepoAdapter.EnabledListener {
|
implements LoaderManager.LoaderCallbacks<Cursor>, RepoAdapter.EnabledListener {
|
||||||
|
|
||||||
@ -246,12 +227,11 @@ public class RepoListFragment extends ListFragment
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(16) // AKA Android 4.1 AKA Jelly Bean
|
|
||||||
private void scanForRepos() {
|
private void scanForRepos() {
|
||||||
final Activity a = getActivity();
|
final Activity activity = getActivity();
|
||||||
|
|
||||||
final RepoScanListAdapter adapter = new RepoScanListAdapter(a);
|
final RepoScanListAdapter adapter = new RepoScanListAdapter(activity);
|
||||||
final NsdHelper nsdHelper = new NsdHelper(a.getApplicationContext(), adapter);
|
final MDnsHelper mDnsHelper = new MDnsHelper(activity, adapter);
|
||||||
|
|
||||||
final View view = getLayoutInflater(null).inflate(R.layout.repodiscoverylist, null);
|
final View view = getLayoutInflater(null).inflate(R.layout.repodiscoverylist, null);
|
||||||
final ListView repoScanList = (ListView) view.findViewById(R.id.reposcanlist);
|
final ListView repoScanList = (ListView) view.findViewById(R.id.reposcanlist);
|
||||||
@ -260,7 +240,7 @@ public class RepoListFragment extends ListFragment
|
|||||||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
nsdHelper.stopDiscovery();
|
mDnsHelper.stopDiscovery();
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
}).create();
|
}).create();
|
||||||
@ -269,7 +249,7 @@ public class RepoListFragment extends ListFragment
|
|||||||
alrt.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
alrt.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDismiss(DialogInterface dialog) {
|
public void onDismiss(DialogInterface dialog) {
|
||||||
nsdHelper.stopDiscovery();
|
mDnsHelper.stopDiscovery();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -282,21 +262,21 @@ public class RepoListFragment extends ListFragment
|
|||||||
final DiscoveredRepo discoveredService =
|
final DiscoveredRepo discoveredService =
|
||||||
(DiscoveredRepo) parent.getItemAtPosition(position);
|
(DiscoveredRepo) parent.getItemAtPosition(position);
|
||||||
|
|
||||||
final NsdServiceInfo serviceInfo = discoveredService.getServiceInfo();
|
final ServiceInfo serviceInfo = discoveredService.getServiceInfo();
|
||||||
|
|
||||||
String serviceType = serviceInfo.getServiceType();
|
String serviceType = serviceInfo.getType();
|
||||||
String protocol = serviceType.contains("fdroidrepos") ? "https://" : "http://";
|
// TODO get repo type from TXT record
|
||||||
|
String protocol = serviceType.contains("fdroidrepos") ? "https:/" : "http:/";
|
||||||
|
|
||||||
String serviceAddress = protocol + serviceInfo.getHost().getHostAddress()
|
String serviceAddress = protocol + serviceInfo.getInetAddresses()[0]
|
||||||
+ ":" + serviceInfo.getPort() + "/fdroid/repo";
|
+ ":" + serviceInfo.getPort() + "/fdroid/repo";
|
||||||
|
// TODO get path from TXT record
|
||||||
showAddRepo(serviceAddress, "");
|
showAddRepo(serviceAddress, "");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
alrt.show();
|
alrt.show();
|
||||||
|
mDnsHelper.discoverServices();
|
||||||
Log.d("FDroid", "Starting network service discovery");
|
|
||||||
nsdHelper.discoverServices();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importRepo(String uri, String fingerprint) {
|
public void importRepo(String uri, String fingerprint) {
|
||||||
@ -416,7 +396,8 @@ public class RepoListFragment extends ListFragment
|
|||||||
ContentValues values = new ContentValues(2);
|
ContentValues values = new ContentValues(2);
|
||||||
values.put(RepoProvider.DataColumns.ADDRESS, address);
|
values.put(RepoProvider.DataColumns.ADDRESS, address);
|
||||||
if (fingerprint != null && fingerprint.length() > 0) {
|
if (fingerprint != null && fingerprint.length() > 0) {
|
||||||
values.put(RepoProvider.DataColumns.FINGERPRINT, fingerprint.toUpperCase(Locale.ENGLISH));
|
values.put(RepoProvider.DataColumns.FINGERPRINT,
|
||||||
|
fingerprint.toUpperCase(Locale.ENGLISH));
|
||||||
}
|
}
|
||||||
RepoProvider.Helper.insert(getActivity(), values);
|
RepoProvider.Helper.insert(getActivity(), values);
|
||||||
finishedAddingRepo();
|
finishedAddingRepo();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user