From 2c2d8c868c9f154cf92706c88fcecb030429f24a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 2 May 2014 17:35:12 -0400 Subject: [PATCH] monitor Wifi changes with BroadcastReceiver/Service The local repo will need to both have current wifi settings in order to send the correct IP address, SSID, etc. Also, this could be used to handle interrupted downloads and updates, but that is not included in this commit. refs #3204 https://dev.guardianproject.info/issues/3204 --- AndroidManifest.xml | 7 ++ src/org/fdroid/fdroid/FDroidApp.java | 34 ++++++- src/org/fdroid/fdroid/Utils.java | 15 ++-- .../fdroid/WifiStateChangeReceiver.java | 21 +++++ .../fdroid/net/WifiStateChangeService.java | 88 +++++++++++++++++++ 5 files changed, 154 insertions(+), 11 deletions(-) create mode 100644 src/org/fdroid/fdroid/WifiStateChangeReceiver.java create mode 100644 src/org/fdroid/fdroid/net/WifiStateChangeService.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 86c0946fa..e4d28bff9 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -33,6 +33,7 @@ + @@ -303,8 +304,14 @@ + + + + + + diff --git a/src/org/fdroid/fdroid/FDroidApp.java b/src/org/fdroid/fdroid/FDroidApp.java index 1a4a02600..4c01e72cb 100644 --- a/src/org/fdroid/fdroid/FDroidApp.java +++ b/src/org/fdroid/fdroid/FDroidApp.java @@ -23,6 +23,8 @@ import android.app.Activity; import android.app.Application; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothManager; +import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; @@ -30,7 +32,11 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.net.Uri; +import android.net.wifi.WifiManager; import android.os.Build; +import android.os.IBinder; +import android.os.Message; +import android.os.RemoteException; import android.preference.PreferenceManager; import android.util.Log; import android.widget.Toast; @@ -46,19 +52,36 @@ import de.duenndns.ssl.MemorizingTrustManager; import org.fdroid.fdroid.compat.PRNGFixes; import org.fdroid.fdroid.data.AppProvider; import org.fdroid.fdroid.data.InstalledAppCacheUpdater; +import org.fdroid.fdroid.data.Repo; +import org.fdroid.fdroid.net.WifiStateChangeService; import org.thoughtcrime.ssl.pinning.PinningTrustManager; import org.thoughtcrime.ssl.pinning.SystemKeyStore; -import javax.net.ssl.*; import java.io.File; -import java.lang.Thread; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.util.HashSet; +import java.util.Set; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; public class FDroidApp extends Application { + // for the local repo on this device, all static since there is only one + public static int ipAddress = 0; + public static int port = 8888; + public static String ipAddressString = null; + public static String ssid = ""; + public static String bssid = ""; + public static Repo repo = new Repo(); + static Set selectedApps = new HashSet(); + BluetoothAdapter bluetoothAdapter = null; private static enum Theme { @@ -196,6 +219,13 @@ public class FDroidApp extends Application { } catch (KeyStoreException e) { Log.e("FDroid", "Unable to set up trust manager chain. KeyStoreException"); } + + // initialized the local repo information + WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); + int wifiState = wifiManager.getWifiState(); + if (wifiState == WifiManager.WIFI_STATE_ENABLING + || wifiState == WifiManager.WIFI_STATE_ENABLED) + startService(new Intent(this, WifiStateChangeService.class)); } @TargetApi(18) diff --git a/src/org/fdroid/fdroid/Utils.java b/src/org/fdroid/fdroid/Utils.java index 39edc418e..6d0957028 100644 --- a/src/org/fdroid/fdroid/Utils.java +++ b/src/org/fdroid/fdroid/Utils.java @@ -197,15 +197,12 @@ public final class Utils { return Uri.parse("http://wifi-not-enabled"); Uri uri = Uri.parse(repo.address.replaceFirst("http", "fdroidrepo")); Uri.Builder b = uri.buildUpon(); - b.appendQueryParameter("fingerprint", repo.fingerprint); - WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); - WifiInfo wifiInfo = wifiManager.getConnectionInfo(); - String ssid = wifiInfo.getSSID().replaceAll("^\"(.*)\"$", "$1"); - String bssid = wifiInfo.getBSSID(); - if (!TextUtils.isEmpty(bssid)) { - b.appendQueryParameter("bssid", Uri.encode(bssid)); - if (!TextUtils.isEmpty(ssid)) - b.appendQueryParameter("ssid", Uri.encode(ssid)); + if (!TextUtils.isEmpty(repo.fingerprint)) + b.appendQueryParameter("fingerprint", repo.fingerprint); + if (!TextUtils.isEmpty(FDroidApp.bssid)) { + b.appendQueryParameter("bssid", Uri.encode(FDroidApp.bssid)); + if (!TextUtils.isEmpty(FDroidApp.ssid)) + b.appendQueryParameter("ssid", Uri.encode(FDroidApp.ssid)); } return b.build(); } diff --git a/src/org/fdroid/fdroid/WifiStateChangeReceiver.java b/src/org/fdroid/fdroid/WifiStateChangeReceiver.java new file mode 100644 index 000000000..ad2a856dc --- /dev/null +++ b/src/org/fdroid/fdroid/WifiStateChangeReceiver.java @@ -0,0 +1,21 @@ + +package org.fdroid.fdroid; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.NetworkInfo; +import android.net.wifi.WifiManager; + +import org.fdroid.fdroid.net.WifiStateChangeService; + +public class WifiStateChangeReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + NetworkInfo ni = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); + if (ni.isConnected()) { + context.startService(new Intent(context, WifiStateChangeService.class)); + } + } +} diff --git a/src/org/fdroid/fdroid/net/WifiStateChangeService.java b/src/org/fdroid/fdroid/net/WifiStateChangeService.java new file mode 100644 index 000000000..afab55923 --- /dev/null +++ b/src/org/fdroid/fdroid/net/WifiStateChangeService.java @@ -0,0 +1,88 @@ + +package org.fdroid.fdroid.net; + +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; +import android.os.IBinder; +import android.preference.PreferenceManager; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; + +import org.fdroid.fdroid.FDroidApp; + +import java.util.Locale; + +public class WifiStateChangeService extends Service { + public static final String BROADCAST = "org.fdroid.fdroid.action.WIFI_CHANGE"; + + private Context context; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + context = this; + new WaitForWifiAsyncTask().execute(); + return START_NOT_STICKY; + } + + public class WaitForWifiAsyncTask extends AsyncTask { + private static final String TAG = "WaitForWifiAsyncTask"; + private WifiManager wifiManager; + + @Override + protected Void doInBackground(Void... params) { + wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); + try { + while (!wifiManager.isWifiEnabled()) { + Log.i(TAG, "waiting for the wifi to be enabled..."); + Thread.sleep(3000); + } + FDroidApp.ipAddress = wifiManager.getConnectionInfo().getIpAddress(); + while (FDroidApp.ipAddress == 0) { + Log.i(TAG, "waiting for an IP address..."); + Thread.sleep(3000); + FDroidApp.ipAddress = wifiManager.getConnectionInfo().getIpAddress(); + } + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + FDroidApp.ipAddress = wifiInfo.getIpAddress(); + FDroidApp.ipAddressString = String.format(Locale.ENGLISH, "%d.%d.%d.%d", + (FDroidApp.ipAddress & 0xff), + (FDroidApp.ipAddress >> 8 & 0xff), + (FDroidApp.ipAddress >> 16 & 0xff), + (FDroidApp.ipAddress >> 24 & 0xff)); + + FDroidApp.ssid = wifiInfo.getSSID().replaceAll("^\"(.*)\"$", "$1"); + FDroidApp.bssid = wifiInfo.getBSSID(); + + String scheme; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (prefs.getBoolean("use_https", false)) + scheme = "https"; + else + scheme = "http"; + FDroidApp.repo.address = String.format(Locale.ENGLISH, "%s://%s:%d/fdroid/repo", + scheme, FDroidApp.ipAddressString, FDroidApp.port); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void result) { + Intent intent = new Intent(BROADCAST); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + WifiStateChangeService.this.stopSelf(); + } + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + +}