From 191fa26cf3c96736650f6b59cc84079f67871fec Mon Sep 17 00:00:00 2001 From: M66B Date: Wed, 3 Feb 2016 11:54:17 +0100 Subject: [PATCH] Hosts file download option --- .../faircode/netguard/ActivitySettings.java | 72 +++++++-- .../eu/faircode/netguard/DownloadTask.java | 143 ++++++++++++++++++ app/src/main/res/values/strings.xml | 4 + app/src/main/res/xml-v14/preferences.xml | 8 + app/src/main/res/xml-v21/preferences.xml | 8 + checkprefs.sh | 3 + 6 files changed, 226 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/eu/faircode/netguard/DownloadTask.java create mode 100644 checkprefs.sh diff --git a/app/src/main/java/eu/faircode/netguard/ActivitySettings.java b/app/src/main/java/eu/faircode/netguard/ActivitySettings.java index 68473b3d..caee9599 100644 --- a/app/src/main/java/eu/faircode/netguard/ActivitySettings.java +++ b/app/src/main/java/eu/faircode/netguard/ActivitySettings.java @@ -74,6 +74,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -114,7 +116,7 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); - PreferenceScreen screen = getPreferenceScreen(); + final PreferenceScreen screen = getPreferenceScreen(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); // Handle auto enable @@ -197,19 +199,25 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere } }); - // Handle hosts import - // https://github.com/Free-Software-for-Android/AdAway/wiki/HostsSources + // Hosts file settings Preference pref_hosts = screen.findPreference("hosts"); Preference pref_block_domains = screen.findPreference("use_hosts"); - pref_block_domains.setEnabled(new File(getFilesDir(), "hosts.txt").exists()); + EditTextPreference pref_hosts_url = (EditTextPreference) screen.findPreference("hosts_url"); + Preference pref_hosts_download = screen.findPreference("hosts_download"); if (Util.isPlayStoreInstall(this)) { - PreferenceCategory pref_backup = (PreferenceCategory) screen.findPreference("category_backup"); - pref_backup.removePreference(pref_hosts); PreferenceCategory pref_category = (PreferenceCategory) screen.findPreference("category_advanced_options"); pref_category.removePreference(pref_block_domains); + PreferenceCategory pref_backup = (PreferenceCategory) screen.findPreference("category_backup"); + pref_backup.removePreference(pref_hosts); + pref_backup.removePreference(pref_hosts_url); + pref_backup.removePreference(pref_hosts_download); } else { + pref_block_domains.setEnabled(new File(getFilesDir(), "hosts.txt").exists()); + + // Handle hosts import + // https://github.com/Free-Software-for-Android/AdAway/wiki/HostsSources pref_hosts.setEnabled(getIntentOpenHosts().resolveActivity(getPackageManager()) != null); pref_hosts.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override @@ -218,10 +226,47 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere return true; } }); + + // Handle hosts file download + pref_hosts_url.setSummary(pref_hosts_url.getText()); + pref_hosts_download.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + final File hosts = new File(getFilesDir(), "hosts.txt"); + EditTextPreference pref_hosts_url = (EditTextPreference) screen.findPreference("hosts_url"); + try { + new DownloadTask(ActivitySettings.this, new URL(pref_hosts_url.getText()), hosts, new DownloadTask.Listener() { + @Override + public void onCompleted() { + Toast.makeText(ActivitySettings.this, R.string.msg_downloaded, Toast.LENGTH_LONG).show(); + SinkholeService.reload(null, "hosts file download", ActivitySettings.this); + } + + @Override + public void onCancelled() { + if (hosts.exists()) + hosts.delete(); + SinkholeService.reload(null, "hosts file download", ActivitySettings.this); + } + + @Override + public void onException(Throwable ex) { + if (hosts.exists()) + hosts.delete(); + SinkholeService.reload(null, "hosts file download", ActivitySettings.this); + Toast.makeText(ActivitySettings.this, ex.getMessage(), Toast.LENGTH_LONG).show(); + } + }).execute(); + } catch (MalformedURLException ex) { + Toast.makeText(ActivitySettings.this, ex.toString(), Toast.LENGTH_LONG).show(); + } + return true; + } + }); } + // Development if (!(Util.isDebuggable(this) || Util.getSelfVersionName(this).contains("beta"))) { - // Development screen.removePreference(screen.findPreference("category_development")); prefs.edit().remove("loglevel").apply(); } @@ -508,19 +553,22 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere } getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_dns, prefs.getString("dns", Util.getDefaultDNS(this)))); - } else if ("show_stats".equals(name)) { + } else if ("show_stats".equals(name)) SinkholeService.reloadStats("changed " + name, this); - } else if ("stats_base".equals(name)) { + else if ("stats_base".equals(name)) getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_base, prefs.getString(name, "5"))); - } else if ("stats_frequency".equals(name)) { + else if ("stats_frequency".equals(name)) getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_frequency, prefs.getString(name, "1000"))); - } else if ("stats_samples".equals(name)) { + else if ("stats_samples".equals(name)) getPreferenceScreen().findPreference(name).setTitle(getString(R.string.setting_stats_samples, prefs.getString(name, "90"))); - } else if ("loglevel".equals(name)) + else if ("hosts_url".equals(name)) + getPreferenceScreen().findPreference(name).setSummary(prefs.getString(name, "http://www.netguard.me/hosts")); + + else if ("loglevel".equals(name)) SinkholeService.reload(null, "changed " + name, this); } diff --git a/app/src/main/java/eu/faircode/netguard/DownloadTask.java b/app/src/main/java/eu/faircode/netguard/DownloadTask.java new file mode 100644 index 00000000..d711693e --- /dev/null +++ b/app/src/main/java/eu/faircode/netguard/DownloadTask.java @@ -0,0 +1,143 @@ +package eu.faircode.netguard; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.AsyncTask; +import android.os.PowerManager; +import android.util.Log; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +public class DownloadTask extends AsyncTask { + private static final String TAG = "NetGuard.Download"; + + private Context context; + private URL url; + private File file; + private Listener listener; + ProgressDialog progressDialog; + private PowerManager.WakeLock wakeLock; + + public interface Listener { + void onCompleted(); + + void onCancelled(); + + void onException(Throwable ex); + } + + public DownloadTask(Context context, URL url, File file, Listener listener) { + this.context = context; + this.url = url; + this.file = file; + this.listener = listener; + } + + @Override + protected void onPreExecute() { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName()); + wakeLock.acquire(); + + progressDialog = new ProgressDialog(context); + progressDialog.setIcon(R.mipmap.ic_launcher); + progressDialog.setTitle(R.string.app_name); + progressDialog.setMessage(context.getString(R.string.msg_downloading, url.toString())); + progressDialog.setIndeterminate(true); + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + progressDialog.setCancelable(true); + progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + DownloadTask.this.cancel(true); + } + }); + progressDialog.show(); + } + + @Override + protected Object doInBackground(Object... args) { + Log.i(TAG, "Downloading " + url + " into " + file); + + InputStream in = null; + OutputStream out = null; + HttpURLConnection connection = null; + try { + connection = (HttpURLConnection) url.openConnection(); + connection.connect(); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) + throw new IOException(connection.getResponseCode() + " " + connection.getResponseMessage()); + + int contentLength = connection.getContentLength(); + Log.i(TAG, "Content length=" + contentLength); + in = connection.getInputStream(); + out = new FileOutputStream(file); + + long size = 0; + byte buffer[] = new byte[4096]; + int bytes; + while (!isCancelled() && (bytes = in.read(buffer)) != -1) { + out.write(buffer, 0, bytes); + + size += bytes; + if (contentLength > 0) + publishProgress((int) (size * 100 / contentLength)); + } + + Log.i(TAG, "Downloaded size=" + size); + return null; + } catch (Throwable ex) { + return ex; + } finally { + try { + if (out != null) + out.close(); + } catch (IOException ex) { + Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); + } + try { + if (in != null) + in.close(); + } catch (IOException ex) { + Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); + } + + if (connection != null) + connection.disconnect(); + } + } + + @Override + protected void onProgressUpdate(Integer... progress) { + super.onProgressUpdate(progress); + progressDialog.setIndeterminate(false); + progressDialog.setMax(100); + progressDialog.setProgress(progress[0]); + } + + @Override + protected void onCancelled() { + super.onCancelled(); + Log.i(TAG, "Cancelled"); + listener.onCancelled(); + } + + @Override + protected void onPostExecute(Object result) { + wakeLock.release(); + progressDialog.dismiss(); + if (result instanceof Throwable) { + Log.e(TAG, result.toString() + "\n" + Log.getStackTraceString((Throwable) result)); + listener.onException((Throwable) result); + } else + listener.onCompleted(); + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f7d01570..af87e91d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -72,6 +72,8 @@ however it is impossible to guarantee NetGuard will work correctly on every devi Export settings Import settings Import hosts file + Hosts file download URL + Download hosts file Technical information General @@ -124,6 +126,8 @@ Your internet traffic is not being sent to a remote VPN server. Traffic logging is disabled, use the switch above to enable logging. Traffic logging might result in extra battery usage. This will reset the rules and conditions to their default values This will delete access attempt log lines without allow/block rules + Downloading\n%1s + Hosts file downloaded Conditions Allow Wi-Fi when screen is on diff --git a/app/src/main/res/xml-v14/preferences.xml b/app/src/main/res/xml-v14/preferences.xml index eec8cd97..c9a36fef 100644 --- a/app/src/main/res/xml-v14/preferences.xml +++ b/app/src/main/res/xml-v14/preferences.xml @@ -176,6 +176,14 @@ android:key="hosts" android:summary="@string/summary_hosts" android:title="@string/setting_hosts" /> + + + +