diff --git a/res/values/strings.xml b/res/values/strings.xml
index de6073c47..12baeeb47 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -34,7 +34,10 @@
Install using system-permissions
Use system permissions to install, update, and remove packages
Do not use system permissions to install, update, and remove packages
-
+ Broadcast Local Repo
+ Advertize your local repo using Bonjour (mDNS)
+ Do not advertize your local repo.
+
Search Results
App Details
No such app found
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index fa534900f..aca5061f6 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -43,6 +43,12 @@
android:defaultValue="false"
android:key="ignoreTouchscreen" />
+
+
+
compactLayoutListeners = new ArrayList();
private List filterAppsRequiringRootListeners = new ArrayList();
private List updateHistoryListeners = new ArrayList();
+ private List localRepoBonjourListeners = new ArrayList();
private boolean isInitialized(String key) {
return initialized.containsKey(key) && initialized.get(key);
@@ -74,6 +77,10 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
return preferences.getBoolean(PREF_SYSTEM_INSTALLER, DEFAULT_SYSTEM_INSTALLER);
}
+ public boolean isLocalRepoBonjourEnabled() {
+ return preferences.getBoolean(PREF_LOCAL_REPO_BONJOUR, DEFAULT_LOCAL_REPO_BONJOUR);
+ }
+
public boolean hasCompactLayout() {
if (!isInitialized(PREF_COMPACT_LAYOUT)) {
initialize(PREF_COMPACT_LAYOUT);
@@ -146,6 +153,10 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
for ( ChangeListener listener : updateHistoryListeners ) {
listener.onPreferenceChange();
}
+ } else if (key.equals(PREF_LOCAL_REPO_BONJOUR)) {
+ for ( ChangeListener listener : localRepoBonjourListeners ) {
+ listener.onPreferenceChange();
+ }
}
}
@@ -157,6 +168,14 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
updateHistoryListeners.remove(listener);
}
+ public void registerLocalRepoBonjourListeners(ChangeListener listener) {
+ localRepoBonjourListeners.add(listener);
+ }
+
+ public void unregisterLocalRepoBonjourListeners(ChangeListener listener) {
+ localRepoBonjourListeners.remove(listener);
+ }
+
public static interface ChangeListener {
public void onPreferenceChange();
}
diff --git a/src/org/fdroid/fdroid/PreferencesActivity.java b/src/org/fdroid/fdroid/PreferencesActivity.java
index 55c36ec3e..2d7d40191 100644
--- a/src/org/fdroid/fdroid/PreferencesActivity.java
+++ b/src/org/fdroid/fdroid/PreferencesActivity.java
@@ -54,6 +54,7 @@ public class PreferencesActivity extends PreferenceActivity implements
Preferences.PREF_PERMISSIONS,
Preferences.PREF_COMPACT_LAYOUT,
Preferences.PREF_IGN_TOUCH,
+ Preferences.PREF_LOCAL_REPO_BONJOUR,
Preferences.PREF_CACHE_APK,
Preferences.PREF_EXPERT,
Preferences.PREF_ROOT_INSTALLER,
@@ -146,6 +147,10 @@ public class PreferencesActivity extends PreferenceActivity implements
onoffSummary(key, R.string.ignoreTouch_on,
R.string.ignoreTouch_off);
+ } else if (key.equals(Preferences.PREF_LOCAL_REPO_BONJOUR)) {
+ onoffSummary(key, R.string.local_repo_bonjour_on,
+ R.string.local_repo_bonjour_off);
+
} else if (key.equals(Preferences.PREF_CACHE_APK)) {
onoffSummary(key, R.string.cache_downloaded_on,
R.string.cache_downloaded_off);
diff --git a/src/org/fdroid/fdroid/localrepo/LocalRepoService.java b/src/org/fdroid/fdroid/localrepo/LocalRepoService.java
index c9d6511c6..4ecc8e23e 100644
--- a/src/org/fdroid/fdroid/localrepo/LocalRepoService.java
+++ b/src/org/fdroid/fdroid/localrepo/LocalRepoService.java
@@ -2,26 +2,17 @@
package org.fdroid.fdroid.localrepo;
import android.annotation.SuppressLint;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
+import android.app.*;
+import android.content.*;
+import android.os.*;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import org.fdroid.fdroid.FDroidApp;
+import org.fdroid.fdroid.Preferences;
+import org.fdroid.fdroid.Preferences.ChangeListener;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.net.LocalHTTPD;
import org.fdroid.fdroid.net.WifiStateChangeService;
@@ -29,8 +20,12 @@ import org.fdroid.fdroid.views.LocalRepoActivity;
import java.io.IOException;
import java.net.BindException;
+import java.util.HashMap;
import java.util.Random;
+import javax.jmdns.JmDNS;
+import javax.jmdns.ServiceInfo;
+
public class LocalRepoService extends Service {
private static final String TAG = "LocalRepoService";
@@ -39,11 +34,15 @@ public class LocalRepoService extends Service {
public static final String STOPPED = "org.fdroid.fdroid.category.LOCAL_REPO_STOPPED";
private NotificationManager notificationManager;
+ private Notification notification;
// Unique Identification Number for the Notification.
// We use it on Notification start, and to cancel it.
private int NOTIFICATION = R.string.local_repo_running;
private Handler webServerThreadHandler = null;
+ private LocalHTTPD localHttpd;
+ private JmDNS jmdns;
+ private ServiceInfo pairService;
public static int START = 1111111;
public static int STOP = 12345678;
@@ -61,12 +60,12 @@ public class LocalRepoService extends Service {
@Override
public void handleMessage(Message msg) {
if (msg.arg1 == START) {
- service.startWebServer();
+ service.startNetworkServices();
} else if (msg.arg1 == STOP) {
- service.stopWebServer();
+ service.stopNetworkServices();
} else if (msg.arg1 == RESTART) {
- service.stopWebServer();
- service.startWebServer();
+ service.stopNetworkServices();
+ service.startNetworkServices();
} else {
Log.e(TAG, "unsupported msg.arg1, ignored");
}
@@ -76,8 +75,19 @@ public class LocalRepoService extends Service {
private BroadcastReceiver onWifiChange = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent i) {
- stopWebServer();
- startWebServer();
+ stopNetworkServices();
+ startNetworkServices();
+ }
+ };
+
+ private ChangeListener localRepoBonjourChangeListener = new ChangeListener() {
+ @Override
+ public void onPreferenceChange() {
+ if (localHttpd.isAlive())
+ if (Preferences.get().isLocalRepoBonjourEnabled())
+ registerMDNSService();
+ else
+ unregisterMDNSService();
}
};
@@ -88,14 +98,16 @@ public class LocalRepoService extends Service {
Intent intent = new Intent(this, LocalRepoActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
- Notification notification = new NotificationCompat.Builder(this)
+ notification = new NotificationCompat.Builder(this)
.setContentTitle(getText(R.string.local_repo_running))
.setContentText(getText(R.string.touch_to_configure_local_repo))
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentIntent(contentIntent)
.build();
startForeground(NOTIFICATION, notification);
- startWebServer();
+ startNetworkServices();
+ Preferences.get().registerLocalRepoBonjourListeners(localRepoBonjourChangeListener);
+
LocalBroadcastManager.getInstance(this).registerReceiver(onWifiChange,
new IntentFilter(WifiStateChangeService.BROADCAST));
}
@@ -109,9 +121,10 @@ public class LocalRepoService extends Service {
@Override
public void onDestroy() {
- stopWebServer();
+ stopNetworkServices();
notificationManager.cancel(NOTIFICATION);
LocalBroadcastManager.getInstance(this).unregisterReceiver(onWifiChange);
+ Preferences.get().unregisterLocalRepoBonjourListeners(localRepoBonjourChangeListener);
}
@Override
@@ -119,6 +132,17 @@ public class LocalRepoService extends Service {
return messenger.getBinder();
}
+ private void startNetworkServices() {
+ startWebServer();
+ if (Preferences.get().isLocalRepoBonjourEnabled())
+ registerMDNSService();
+ }
+
+ private void stopNetworkServices() {
+ unregisterMDNSService();
+ stopWebServer();
+ }
+
private void startWebServer() {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -127,7 +151,7 @@ public class LocalRepoService extends Service {
@SuppressLint("HandlerLeak")
@Override
public void run() {
- final LocalHTTPD localHttpd = new LocalHTTPD(getFilesDir(),
+ localHttpd = new LocalHTTPD(getFilesDir(),
prefs.getBoolean("use_https", false));
Looper.prepare(); // must be run before creating a Handler
@@ -169,4 +193,46 @@ public class LocalRepoService extends Service {
intent.putExtra(STATE, STOPPED);
LocalBroadcastManager.getInstance(LocalRepoService.this).sendBroadcast(intent);
}
+
+ private void registerMDNSService() {
+ final HashMap values = new HashMap();
+ values.put("path", "/fdroid/repo");
+ values.put("name", FDroidApp.repo.name);
+ // TODO set type based on "use HTTPS" pref
+ // values.put("fingerprint", FDroidApp.repo.fingerprint);
+ values.put("type", "fdroidrepo");
+ pairService = ServiceInfo.create("_http._tcp.local.",
+ FDroidApp.repo.name, FDroidApp.port, 0, 0, values);
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ jmdns = JmDNS.create();
+ jmdns.registerService(pairService);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+
+ private void unregisterMDNSService() {
+ if (localRepoBonjourChangeListener != null) {
+ Preferences.get().unregisterLocalRepoBonjourListeners(localRepoBonjourChangeListener);
+ localRepoBonjourChangeListener = null;
+ }
+ if (jmdns != null) {
+ if (pairService != null)
+ jmdns.unregisterService(pairService);
+ pairService = null;
+ jmdns.unregisterAllServices();
+ try {
+ jmdns.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ jmdns = null;
+ }
+ }
}