From 58c5750599af523a9deb24284c151003c5b89029 Mon Sep 17 00:00:00 2001 From: M66B Date: Tue, 19 Jul 2016 07:10:07 +0200 Subject: [PATCH] Removed usage data sharing --- FAQ.md | 27 -- README.md | 6 +- app/app.iml | 16 +- app/src/main/AndroidManifest.xml | 5 - .../eu/faircode/netguard/ActivityMain.java | 9 +- .../eu/faircode/netguard/ActivityPro.java | 5 - .../faircode/netguard/ActivitySettings.java | 9 - .../eu/faircode/netguard/AdapterRule.java | 192 ------------- .../java/eu/faircode/netguard/Receiver.java | 5 - .../main/java/eu/faircode/netguard/Rule.java | 17 +- .../java/eu/faircode/netguard/ServiceJob.java | 253 ------------------ .../main/java/eu/faircode/netguard/Util.java | 11 - .../ic_cloud_download_black_24dp.png | Bin 344 -> 0 bytes .../ic_cloud_download_white_24dp.png | Bin 353 -> 0 bytes .../ic_cloud_download_black_24dp.png | Bin 235 -> 0 bytes .../ic_cloud_download_white_24dp.png | Bin 242 -> 0 bytes .../ic_cloud_download_black_24dp.png | Bin 404 -> 0 bytes .../ic_cloud_download_white_24dp.png | Bin 417 -> 0 bytes .../ic_cloud_download_black_24dp.png | Bin 592 -> 0 bytes .../ic_cloud_download_white_24dp.png | Bin 610 -> 0 bytes .../ic_cloud_download_black_24dp.png | Bin 764 -> 0 bytes .../ic_cloud_download_white_24dp.png | Bin 789 -> 0 bytes app/src/main/res/drawable/fetch_black.xml | 5 - .../res/drawable/fetch_disabled_black.xml | 4 - .../res/drawable/fetch_disabled_white.xml | 4 - app/src/main/res/drawable/fetch_white.xml | 5 - app/src/main/res/layout/first.xml | 9 - app/src/main/res/layout/rule.xml | 17 +- app/src/main/res/values/strings.xml | 2 - app/src/main/res/values/styles.xml | 3 - playstore/PLAY-es.md | 3 +- playstore/PLAY-ro.md | 1 + playstore/PLAY.md | 3 +- 33 files changed, 19 insertions(+), 592 deletions(-) delete mode 100644 app/src/main/java/eu/faircode/netguard/ServiceJob.java delete mode 100644 app/src/main/res/drawable-hdpi/ic_cloud_download_black_24dp.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_cloud_download_white_24dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_cloud_download_black_24dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_cloud_download_white_24dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_cloud_download_black_24dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_cloud_download_white_24dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_cloud_download_black_24dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_cloud_download_white_24dp.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_cloud_download_black_24dp.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_cloud_download_white_24dp.png delete mode 100644 app/src/main/res/drawable/fetch_black.xml delete mode 100644 app/src/main/res/drawable/fetch_disabled_black.xml delete mode 100644 app/src/main/res/drawable/fetch_disabled_white.xml delete mode 100644 app/src/main/res/drawable/fetch_white.xml diff --git a/FAQ.md b/FAQ.md index 18c32c53..43f80fed 100644 --- a/FAQ.md +++ b/FAQ.md @@ -363,33 +363,6 @@ On most devices, NetGuard will keep running in the background with its foregroun On some devices (in particular some Samsung models), where there are lots of applications competing for memory, Android may still stop NetGuard as a last resort. Unfortunately this cannot be fixed from NetGuard, and can be considered a shortcoming of the device and/or as a bug in Android. - -**(39) Which usage data will be shared?** - -On Android version 5.0 or newer, NetGuard will share anonymized usage data to help improve how NetGuard protects you, -by understanding how end users work with NetGuard. - -The following data will be shared when changing application settings: - -* The [SHA256](https://en.wikipedia.org/wiki/SHA-2) hashed [Android ID](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID) (needed to prevent multiple records of the same setting) -* The [device name](https://developer.android.com/reference/android/os/Build.html#DEVICE) * -* The [Android version](https://developer.android.com/reference/android/os/Build.VERSION_CODES.html) * -* The [country](https://developer.android.com/reference/java/util/Locale.html#getCountry()) configured when initializing Android * -* The application name, version and [installer](https://developer.android.com/reference/android/content/pm/PackageManager.html#getInstallerPackageName(java.lang.String)) and whether an application is a user installed or a system bundled application -* Whether Wi-Fi and mobile connections will be blocked or allowed and which conditions apply (when screen on, roaming, notify on access, addresses, etc) - -This data cannot be used to identify you, so your privacy is guaranteed. -Data marked with an asterix (*) is being shared by Google in the [Google Play developer console](https://developer.android.com/distribute/googleplay/developer-console.html) as well. - -Usage data will be queued for sending over an unmetered connection (mostly Wi-Fi) when settings are being changed. -Usage data will be anonynized before sending. -Sending usage data can optionally be disabled per application. - -You can see the aggregated data [here](https://crowd.netguard.me). -
**If you didn't find the answer to your question, you can ask your questions [in this forum](http://forum.xda-developers.com/showthread.php?t=3233012) or contact me directly [by e-mail](mailto:marcel+netguard@faircode.eu)**. - -If you want to request a new feature or want to report a bug, please [create an issue on GitHub](https://github.com/M66B/NetGuard/issues/new). - diff --git a/README.md b/README.md index 47a317e1..b3ba60a3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ Features: * Simple to use * No root required * 100% open source -* No tracking and user profiling +* No calling home +* No tracking or analytics * No advertisements * Actively developed and supported * Android 4.0 and later supported @@ -183,9 +184,6 @@ Frequently Asked Questions (FAQ) [**(38) Why did NetGuard stop running?**](https://github.com/M66B/NetGuard/blob/master/FAQ.md#FAQ38) - -[**(39) Which usage data will be shared?**](https://github.com/M66B/NetGuard/blob/master/FAQ.md#FAQ39) - Permissions ----------- diff --git a/app/app.iml b/app/app.iml index 91cca5e5..4e989c04 100644 --- a/app/app.iml +++ b/app/app.iml @@ -104,14 +104,6 @@ - - - - - - - - @@ -120,6 +112,14 @@ + + + + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4e2fe2b9..fd504dae 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -117,11 +117,6 @@ - - = Build.VERSION_CODES.LOLLIPOP ? View.VISIBLE : View.GONE); // Show dialog dialogFirst = new AlertDialog.Builder(this) @@ -349,10 +346,8 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences .setPositiveButton(R.string.app_agree, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (running) { + if (running) prefs.edit().putBoolean("initialized", true).apply(); - prefs.edit().putBoolean("submitting", true).apply(); - } } }) .setNegativeButton(R.string.app_disagree, new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/eu/faircode/netguard/ActivityPro.java b/app/src/main/java/eu/faircode/netguard/ActivityPro.java index 962210da..1afb6063 100644 --- a/app/src/main/java/eu/faircode/netguard/ActivityPro.java +++ b/app/src/main/java/eu/faircode/netguard/ActivityPro.java @@ -21,10 +21,8 @@ package eu.faircode.netguard; import android.app.PendingIntent; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.v4.app.NavUtils; import android.support.v7.app.AppCompatActivity; import android.text.Editable; @@ -35,8 +33,6 @@ import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; @@ -273,7 +269,6 @@ public class ActivityPro extends AppCompatActivity { TextView tvSpeed = (TextView) findViewById(R.id.tvSpeed); TextView tvTheme = (TextView) findViewById(R.id.tvTheme); TextView tvAll = (TextView) findViewById(R.id.tvAll); - CheckBox cbSubmit = (CheckBox) findViewById(R.id.cbSubmit); LinearLayout llChallenge = (LinearLayout) findViewById(R.id.llChallenge); btnLog.setVisibility(IAB.isPurchased(SKU_LOG, this) ? View.GONE : View.VISIBLE); diff --git a/app/src/main/java/eu/faircode/netguard/ActivitySettings.java b/app/src/main/java/eu/faircode/netguard/ActivitySettings.java index d4475795..0aaae09f 100644 --- a/app/src/main/java/eu/faircode/netguard/ActivitySettings.java +++ b/app/src/main/java/eu/faircode/netguard/ActivitySettings.java @@ -1029,10 +1029,6 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere xmlExport(getSharedPreferences("notify", Context.MODE_PRIVATE), serializer); serializer.endTag(null, "notify"); - serializer.startTag(null, "submit"); - xmlExport(getSharedPreferences("submit", Context.MODE_PRIVATE), serializer); - serializer.endTag(null, "submit"); - serializer.startTag(null, "filter"); filterExport(serializer); serializer.endTag(null, "filter"); @@ -1170,7 +1166,6 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere xmlImport(handler.roaming, getSharedPreferences("roaming", Context.MODE_PRIVATE)); xmlImport(handler.apply, getSharedPreferences("apply", Context.MODE_PRIVATE)); xmlImport(handler.notify, getSharedPreferences("notify", Context.MODE_PRIVATE)); - xmlImport(handler.submit, getSharedPreferences("submit", Context.MODE_PRIVATE)); // Upgrade imported settings Receiver.upgrade(true, this); @@ -1218,7 +1213,6 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere public Map roaming = new HashMap<>(); public Map apply = new HashMap<>(); public Map notify = new HashMap<>(); - public Map submit = new HashMap<>(); private Map current = null; public XmlImportHandler(Context context) { @@ -1257,9 +1251,6 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere else if (qName.equals("notify")) current = notify; - else if (qName.equals("submit")) - current = submit; - else if (qName.equals("filter")) { current = null; Log.i(TAG, "Clearing filters"); diff --git a/app/src/main/java/eu/faircode/netguard/AdapterRule.java b/app/src/main/java/eu/faircode/netguard/AdapterRule.java index e0ea2cfc..cfc31fec 100644 --- a/app/src/main/java/eu/faircode/netguard/AdapterRule.java +++ b/app/src/main/java/eu/faircode/netguard/AdapterRule.java @@ -62,21 +62,9 @@ import android.widget.TextView; import com.squareup.picasso.Picasso; -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import java.util.Locale; - -import javax.net.ssl.HttpsURLConnection; public class AdapterRule extends RecyclerView.Adapter implements Filterable { private static final String TAG = "NetGuard.Adapter"; @@ -94,10 +82,6 @@ public class AdapterRule extends RecyclerView.Adapter im private List listAll = new ArrayList<>(); private List listFiltered = new ArrayList<>(); - private static final String cUrl = "https://crowd.netguard.me/"; - private static final int cTimeOutMs = 15000; - private static final double cConfidence = 0.35; - public static class ViewHolder extends RecyclerView.ViewHolder { public View view; @@ -127,7 +111,6 @@ public class AdapterRule extends RecyclerView.Adapter im public CheckBox cbApply; public Button btnRelated; - public ImageButton ibFetch; public ImageButton ibSettings; public ImageButton ibLaunch; @@ -146,7 +129,6 @@ public class AdapterRule extends RecyclerView.Adapter im public ImageButton btnClearAccess; public CheckBox cbNotify; - public CheckBox cbSubmit; public ViewHolder(View itemView) { super(itemView); @@ -178,7 +160,6 @@ public class AdapterRule extends RecyclerView.Adapter im cbApply = (CheckBox) itemView.findViewById(R.id.cbApply); btnRelated = (Button) itemView.findViewById(R.id.btnRelated); - ibFetch = (ImageButton) itemView.findViewById(R.id.ibFetch); ibSettings = (ImageButton) itemView.findViewById(R.id.ibSettings); ibLaunch = (ImageButton) itemView.findViewById(R.id.ibLaunch); @@ -197,7 +178,6 @@ public class AdapterRule extends RecyclerView.Adapter im btnClearAccess = (ImageButton) itemView.findViewById(R.id.btnClearAccess); cbNotify = (CheckBox) itemView.findViewById(R.id.cbNotify); - cbSubmit = (CheckBox) itemView.findViewById(R.id.cbSubmit); final View wifiParent = (View) cbWifi.getParent(); wifiParent.post(new Runnable() { @@ -446,135 +426,6 @@ public class AdapterRule extends RecyclerView.Adapter im } }); - // Fetch settings - holder.ibFetch.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - new AsyncTask() { - @Override - protected void onPreExecute() { - holder.ibFetch.setEnabled(false); - } - - @Override - protected Object doInBackground(Object... args) { - HttpsURLConnection urlConnection = null; - try { - JSONObject json = new JSONObject(); - - json.put("type", "fetch"); - json.put("country", Locale.getDefault().getCountry()); - json.put("netguard", Util.getSelfVersionCode(context)); - json.put("fingerprint", Util.getFingerprint(context)); - - JSONObject pkg = new JSONObject(); - pkg.put("name", rule.info.packageName); - pkg.put("version_code", rule.info.versionCode); - pkg.put("version_name", rule.info.versionName); - - JSONArray pkgs = new JSONArray(); - pkgs.put(pkg); - json.put("package", pkgs); - - urlConnection = (HttpsURLConnection) new URL(cUrl).openConnection(); - urlConnection.setConnectTimeout(cTimeOutMs); - urlConnection.setReadTimeout(cTimeOutMs); - urlConnection.setRequestProperty("Accept", "application/json"); - urlConnection.setRequestProperty("Content-type", "application/json"); - urlConnection.setRequestMethod("POST"); - urlConnection.setDoInput(true); - urlConnection.setDoOutput(true); - - Log.i(TAG, "Request=" + json.toString()); - OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); - out.write(json.toString().getBytes()); // UTF-8 - out.flush(); - - int code = urlConnection.getResponseCode(); - if (code != HttpsURLConnection.HTTP_OK) - throw new IOException("HTTP " + code); - - InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream()); - String response = Util.readString(isr).toString(); - Log.i(TAG, "Response=" + response); - JSONObject jfetched = new JSONObject(response); - JSONArray jpkgs = jfetched.getJSONArray("package"); - for (int i = 0; i < jpkgs.length(); i++) { - JSONObject jpkg = jpkgs.getJSONObject(i); - String name = jpkg.getString("name"); - int wifi = jpkg.getInt("wifi"); - int wifi_screen = jpkg.getInt("wifi_screen"); - int other = jpkg.getInt("other"); - int other_screen = jpkg.getInt("other_screen"); - int roaming = jpkg.getInt("roaming"); - int devices = jpkg.getInt("devices"); - - double conf_wifi; - boolean block_wifi; - if (rule.wifi_default) { - conf_wifi = confidence(devices - wifi, devices); - block_wifi = !(devices - wifi > wifi && conf_wifi > cConfidence); - } else { - conf_wifi = confidence(wifi, devices); - block_wifi = (wifi > devices - wifi && conf_wifi > cConfidence); - } - - boolean allow_wifi_screen = rule.screen_wifi_default; - if (block_wifi) - allow_wifi_screen = (wifi_screen > wifi / 2); - - double conf_other; - boolean block_other; - if (rule.other_default) { - conf_other = confidence(devices - other, devices); - block_other = !(devices - other > other && conf_other > cConfidence); - } else { - conf_other = confidence(other, devices); - block_other = (other > devices - other && conf_other > cConfidence); - } - - boolean allow_other_screen = rule.screen_other_default; - if (block_other) - allow_other_screen = (other_screen > other / 2); - - boolean block_roaming = rule.roaming_default; - if (!block_other || allow_other_screen) - block_roaming = (roaming > (devices - other) / 2); - - Log.i(TAG, "pkg=" + name + - " wifi=" + wifi + "/" + wifi_screen + "=" + block_wifi + "/" + allow_wifi_screen + " " + Math.round(100 * conf_wifi) + "%" + - " other=" + other + "/" + other_screen + "/" + roaming + "=" + block_other + "/" + allow_other_screen + "/" + block_roaming + " " + Math.round(100 * conf_other) + "%" + - " devices=" + devices); - - rule.wifi_blocked = block_wifi; - rule.screen_wifi = allow_wifi_screen; - rule.other_blocked = block_other; - rule.screen_other = allow_other_screen; - rule.roaming = block_roaming; - } - - } catch (Throwable ex) { - Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); - return ex; - - } finally { - if (urlConnection != null) - urlConnection.disconnect(); - } - - return null; - } - - @Override - protected void onPostExecute(Object result) { - holder.ibFetch.setEnabled(true); - updateRule(rule, true, listAll); - } - - }.execute(rule); - } - }); - // Launch application settings final Intent settings = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); settings.setData(Uri.parse("package:" + rule.info.packageName)); @@ -744,8 +595,6 @@ public class AdapterRule extends RecyclerView.Adapter im if (IAB.isPurchased(ActivityPro.SKU_FILTER, context)) { DatabaseHelper.getInstance(context).setAccess(id, 0); ServiceSinkhole.reload("allow host", context); - if (rule.submit) - ServiceJob.submit(rule, version, protocol, daddr, dport, 0, context); } else context.startActivity(new Intent(context, ActivityPro.class)); return true; @@ -754,8 +603,6 @@ public class AdapterRule extends RecyclerView.Adapter im if (IAB.isPurchased(ActivityPro.SKU_FILTER, context)) { DatabaseHelper.getInstance(context).setAccess(id, 1); ServiceSinkhole.reload("block host", context); - if (rule.submit) - ServiceJob.submit(rule, version, protocol, daddr, dport, 1, context); } else context.startActivity(new Intent(context, ActivityPro.class)); return true; @@ -763,8 +610,6 @@ public class AdapterRule extends RecyclerView.Adapter im case R.id.menu_reset: DatabaseHelper.getInstance(context).setAccess(id, -1); ServiceSinkhole.reload("reset host", context); - if (rule.submit) - ServiceJob.submit(rule, version, protocol, daddr, dport, -1, context); return true; } return false; @@ -812,18 +657,6 @@ public class AdapterRule extends RecyclerView.Adapter im updateRule(rule, true, listAll); } }); - - // Usage data sharing - holder.cbSubmit.setVisibility(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? View.VISIBLE : View.GONE); - holder.cbSubmit.setOnCheckedChangeListener(null); - holder.cbSubmit.setChecked(rule.submit); - holder.cbSubmit.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) { - rule.submit = isChecked; - updateRule(rule, true, listAll); - } - }); } private void updateRule(Rule rule, boolean root, List listAll) { @@ -834,8 +667,6 @@ public class AdapterRule extends RecyclerView.Adapter im SharedPreferences screen_other = context.getSharedPreferences("screen_other", Context.MODE_PRIVATE); SharedPreferences roaming = context.getSharedPreferences("roaming", Context.MODE_PRIVATE); SharedPreferences notify = context.getSharedPreferences("notify", Context.MODE_PRIVATE); - SharedPreferences submit = context.getSharedPreferences("submit", Context.MODE_PRIVATE); - SharedPreferences history = context.getSharedPreferences("history", Context.MODE_PRIVATE); if (rule.wifi_blocked == rule.wifi_default) wifi.edit().remove(rule.info.packageName).apply(); @@ -872,14 +703,6 @@ public class AdapterRule extends RecyclerView.Adapter im else notify.edit().putBoolean(rule.info.packageName, rule.notify).apply(); - if (rule.submit) - submit.edit().remove(rule.info.packageName).apply(); - else - submit.edit().putBoolean(rule.info.packageName, rule.submit).apply(); - - rule.last_modified = new Date().getTime(); - history.edit().putLong(rule.info.packageName + ":modified", rule.last_modified).apply(); - rule.updateChanged(context); Log.i(TAG, "Updated " + rule); @@ -910,9 +733,6 @@ public class AdapterRule extends RecyclerView.Adapter im NotificationManagerCompat.from(context).cancel(rule.info.applicationInfo.uid); ServiceSinkhole.reload("rule changed", context); } - - if (rule.submit) - ServiceJob.submit(rule, context); } @Override @@ -959,18 +779,6 @@ public class AdapterRule extends RecyclerView.Adapter im }; } - private double confidence(int count, int total) { - // Agresti-Coull Interval - // http://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Agresti-Coull_Interval - int n = total; - double p = count / (float) n; - double z = 1.96; // 95% - double n1 = n + z * z; - double p1 = (1 / n1) * (count + 0.5 * z * z); - double ci = z * Math.sqrt((1 / n1) * p1 * (1 - p1)); - return 1 - ci; - } - @Override public AdapterRule.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.rule, parent, false)); diff --git a/app/src/main/java/eu/faircode/netguard/Receiver.java b/app/src/main/java/eu/faircode/netguard/Receiver.java index dd2aa3b8..6af59bfc 100644 --- a/app/src/main/java/eu/faircode/netguard/Receiver.java +++ b/app/src/main/java/eu/faircode/netguard/Receiver.java @@ -239,11 +239,6 @@ public class Receiver extends BroadcastReceiver { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) editor.putBoolean("filter", true); // Mandatory - if (Util.isPlayStoreInstall(context)) { - SharedPreferences apply = context.getSharedPreferences("apply", Context.MODE_PRIVATE); - apply.edit().putBoolean(context.getPackageName(), false).apply(); - } - editor.putInt("version", newVersion); editor.apply(); } diff --git a/app/src/main/java/eu/faircode/netguard/Rule.java b/app/src/main/java/eu/faircode/netguard/Rule.java index 37d10877..474a90d1 100644 --- a/app/src/main/java/eu/faircode/netguard/Rule.java +++ b/app/src/main/java/eu/faircode/netguard/Rule.java @@ -71,7 +71,6 @@ public class Rule { public boolean apply = true; public boolean notify = true; - public boolean submit = true; public boolean relateduids = false; public String[] related = null; @@ -81,8 +80,6 @@ public class Rule { public float totalbytes; public boolean changed; - public long last_modified; - public long last_submitted; public boolean expanded = false; @@ -225,8 +222,6 @@ public class Rule { SharedPreferences roaming = context.getSharedPreferences("roaming", Context.MODE_PRIVATE); SharedPreferences apply = context.getSharedPreferences("apply", Context.MODE_PRIVATE); SharedPreferences notify = context.getSharedPreferences("notify", Context.MODE_PRIVATE); - SharedPreferences submit = context.getSharedPreferences("submit", Context.MODE_PRIVATE); - SharedPreferences history = context.getSharedPreferences("history", Context.MODE_PRIVATE); // Get settings boolean default_wifi = prefs.getBoolean("whitelist_wifi", true); @@ -324,10 +319,7 @@ public class Rule { if (pre_system.containsKey(info.packageName)) rule.system = pre_system.get(info.packageName); if (info.applicationInfo.uid == Process.myUid()) - if (Util.isPlayStoreInstall(context) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - continue; - else - rule.system = true; + rule.system = true; if (all || ((rule.system ? show_system : show_user) && @@ -348,13 +340,6 @@ public class Rule { rule.apply = apply.getBoolean(info.packageName, true); rule.notify = notify.getBoolean(info.packageName, true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - rule.submit = submit.getBoolean(info.packageName, true); - else - rule.submit = false; - - rule.last_modified = history.getLong(info.packageName + ":modified", 0); - rule.last_submitted = history.getLong(info.packageName + ":submitted", 0); // Related packages List listPkg = new ArrayList<>(); diff --git a/app/src/main/java/eu/faircode/netguard/ServiceJob.java b/app/src/main/java/eu/faircode/netguard/ServiceJob.java deleted file mode 100644 index 86f73ebe..00000000 --- a/app/src/main/java/eu/faircode/netguard/ServiceJob.java +++ /dev/null @@ -1,253 +0,0 @@ -package eu.faircode.netguard; - -/* - This file is part of NetGuard. - - NetGuard is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - NetGuard is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with NetGuard. If not, see . - - Copyright 2015-2016 by Marcel Bokhorst (M66B) -*/ - -import android.annotation.TargetApi; -import android.app.job.JobInfo; -import android.app.job.JobParameters; -import android.app.job.JobScheduler; -import android.app.job.JobService; -import android.content.ComponentName; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.os.AsyncTask; -import android.os.Build; -import android.os.PersistableBundle; -import android.provider.Settings; -import android.util.Log; - -import org.json.JSONObject; - -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.URL; -import java.util.Date; -import java.util.Locale; - -import javax.net.ssl.HttpsURLConnection; - -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class ServiceJob extends JobService { - private static int id = 0; - private static final String TAG = "NetGuard.Job"; - - private static final String cUrl = "https://crowd.netguard.me/"; - private static final int cTimeOutMs = 15000; - - @Override - public boolean onStartJob(JobParameters params) { - Log.i(TAG, "Start job=" + params.getJobId()); - - new AsyncTask() { - - @Override - protected JobParameters doInBackground(JobParameters... params) { - Log.i(TAG, "Executing job=" + params[0].getJobId()); - - HttpsURLConnection urlConnection = null; - try { - String android_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); - JSONObject json = new JSONObject(); - - json.put("device", Util.sha256(android_id, "")); - json.put("product", Build.DEVICE); - json.put("sdk", Build.VERSION.SDK_INT); - json.put("country", Locale.getDefault().getCountry()); - - json.put("netguard", Util.getSelfVersionCode(ServiceJob.this)); - try { - json.put("store", getPackageManager().getInstallerPackageName(getPackageName())); - } catch (Throwable ex) { - Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); - json.put("store", null); - } - - for (String name : params[0].getExtras().keySet()) - json.put(name, params[0].getExtras().get(name)); - - urlConnection = (HttpsURLConnection) new URL(cUrl).openConnection(); - urlConnection.setConnectTimeout(cTimeOutMs); - urlConnection.setReadTimeout(cTimeOutMs); - urlConnection.setRequestProperty("Accept", "application/json"); - urlConnection.setRequestProperty("Content-type", "application/json"); - urlConnection.setRequestMethod("POST"); - urlConnection.setDoInput(true); - urlConnection.setDoOutput(true); - - OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); - out.write(json.toString().getBytes()); // UTF-8 - out.flush(); - - int code = urlConnection.getResponseCode(); - if (code != HttpsURLConnection.HTTP_OK) - throw new IOException("HTTP " + code); - - InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream()); - Log.i(TAG, "Response=" + Util.readString(isr).toString()); - - jobFinished(params[0], false); - - if ("rule".equals(params[0].getExtras().getString("type"))) { - SharedPreferences history = getSharedPreferences("history", Context.MODE_PRIVATE); - history.edit().putLong(params[0].getExtras().getString("package") + ":submitted", new Date().getTime()).apply(); - } - - } catch (Throwable ex) { - Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); - jobFinished(params[0], true); - - } finally { - if (urlConnection != null) - urlConnection.disconnect(); - - try { - Thread.sleep(1000); - } catch (InterruptedException ignored) { - } - } - - return null; - } - }.execute(params); - - return true; - } - - @Override - public boolean onStopJob(JobParameters params) { - Log.i(TAG, "Stop job=" + params.getJobId()); - return true; - } - - public static void submit(Rule rule, Context context) { - PersistableBundle bundle = new PersistableBundle(); - bundle.putString("type", "rule"); - - bundle.putInt("wifi_default", rule.wifi_default ? 1 : 0); - bundle.putInt("other_default", rule.other_default ? 1 : 0); - bundle.putInt("screen_wifi_default", rule.screen_wifi_default ? 1 : 0); - bundle.putInt("screen_other_default", rule.screen_other_default ? 1 : 0); - bundle.putInt("roaming_default", rule.roaming_default ? 1 : 0); - - bundle.putInt("wifi_blocked", rule.wifi_blocked ? 1 : 0); - bundle.putInt("other_blocked", rule.other_blocked ? 1 : 0); - bundle.putInt("screen_wifi", rule.screen_wifi ? 1 : 0); - bundle.putInt("screen_other", rule.screen_other ? 1 : 0); - bundle.putInt("roaming", rule.roaming ? 1 : 0); - - bundle.putInt("apply", rule.apply ? 1 : 0); - bundle.putInt("notify", rule.notify ? 1 : 0); - - submit(rule, bundle, context); - } - - public static void submit(Rule rule, int version, int protocol, String daddr, int dport, int blocked, Context context) { - PersistableBundle bundle = new PersistableBundle(); - bundle.putString("type", "host"); - - bundle.putInt("version", version); - bundle.putInt("protocol", protocol); - bundle.putString("daddr", daddr); - bundle.putInt("dport", dport); - bundle.putInt("blocked", blocked); - - submit(rule, bundle, context); - } - - private static void submit(Rule rule, PersistableBundle bundle, Context context) { - PackageManager pm = context.getPackageManager(); - JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); - - // Get english application label - String label = null; - try { - Configuration config = new Configuration(); - config.setLocale(new Locale("en")); - Resources res = pm.getResourcesForApplication(rule.info.packageName); - res.updateConfiguration(config, res.getDisplayMetrics()); - label = res.getString(rule.info.applicationInfo.labelRes); - } catch (Throwable ex) { - Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); - CharSequence cs = rule.info.applicationInfo.loadLabel(pm); - if (cs != null) - label = cs.toString(); - } - - // Add application data - bundle.putInt("uid", rule.info.applicationInfo.uid); - bundle.putString("package", rule.info.packageName); - bundle.putInt("version_code", rule.info.versionCode); - bundle.putString("version_name", rule.info.versionName); - bundle.putString("label", label); - bundle.putInt("system", rule.system ? 1 : 0); - try { - bundle.putString("installer", pm.getInstallerPackageName(rule.info.packageName)); - } catch (Throwable ex) { - Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); - bundle.putString("installer", null); - } - - // Cancel overlapping jobs - for (JobInfo pending : scheduler.getAllPendingJobs()) { - String type = pending.getExtras().getString("type"); - if (type != null && type.equals(bundle.getString("type"))) { - if (type.equals("rule")) { - int uid = pending.getExtras().getInt("uid"); - if (uid == bundle.getInt("uid")) { - Log.i(TAG, "Canceling id=" + pending.getId()); - scheduler.cancel(pending.getId()); - } - } else if (type.equals("host")) { - int uid = pending.getExtras().getInt("uid"); - int version = pending.getExtras().getInt("version"); - int protocol = pending.getExtras().getInt("protocol"); - String daddr = pending.getExtras().getString("daddr"); - int dport = pending.getExtras().getInt("dport"); - if (uid == bundle.getInt("uid") && - version == bundle.getInt("version") && - protocol == bundle.getInt("protocol") && - daddr != null && daddr.equals(bundle.getString("daddr")) && - dport == bundle.getInt("dport")) { - Log.i(TAG, "Canceling id=" + pending.getId()); - scheduler.cancel(pending.getId()); - } - } - } - } - - // Schedule job - ComponentName serviceName = new ComponentName(context, ServiceJob.class); - JobInfo job = new JobInfo.Builder(++id, serviceName) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) - .setMinimumLatency(Util.isDebuggable(context) ? 10 * 1000 : 60 * 1000) - .setExtras(bundle) - .setPersisted(true) - .build(); - if (scheduler.schedule(job) == JobScheduler.RESULT_SUCCESS) - Log.i(TAG, "Scheduled job=" + job.getId() + " success"); - else - Log.e(TAG, "Scheduled job=" + job.getId() + " failed"); - } -} diff --git a/app/src/main/java/eu/faircode/netguard/Util.java b/app/src/main/java/eu/faircode/netguard/Util.java index 0153248c..25994b9b 100644 --- a/app/src/main/java/eu/faircode/netguard/Util.java +++ b/app/src/main/java/eu/faircode/netguard/Util.java @@ -107,17 +107,6 @@ public class Util { } } - public static String sha256(String text, String salt) throws NoSuchAlgorithmException, UnsupportedEncodingException { - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - byte[] bytes = (text + salt).getBytes("UTF-8"); - digest.update(bytes, 0, bytes.length); - bytes = digest.digest(); - StringBuilder sb = new StringBuilder(); - for (byte b : bytes) - sb.append(String.format("%02X", b)); - return sb.toString(); - } - public static boolean isConnected(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo ni = (cm == null ? null : cm.getActiveNetworkInfo()); diff --git a/app/src/main/res/drawable-hdpi/ic_cloud_download_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_cloud_download_black_24dp.png deleted file mode 100644 index 1b590a24f2472c1835a80339c7e198a833f70567..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 344 zcmV-e0jK_nP)(*eQ9R{wwA%mw(o%JR6*FPn!?woUuusp_^cfHtN%1n@RAuz%?@5GLN$* zo{^0g7I8F917)Z)MP^6H;SjSiO6+rqT)wO?HAfXigcOmsL!@P1QB*pScE>=ow9wE) zqQNn1jMJ-%yh9Ne%m6?Md4~)S6aaSpL#Bir(Sz3rUFkws4Gma_H{Ds!(`sk%0Imd!2!g#;^aK|14&oK&0Agip;Ro0XVm!fOA$tM8h?s!JLJdM9 zN*;?T%p^0rZ(OjDJpcaJ4D-sk{}n|xIpu*4pENjUiy{)5;NKM6bQrA54%4GRi`)?E zjw{K!!=Loc?S2@V zrwt=R(By=5CV!w9RFJ<*<}6f!To61GA;Mm62oeh7eegQQ&Vh^_b%xsz-tpxUF6Zk^ z_y9c>VBlG}1vO;|^(7pFk}`yA32UID3~AK_;X*+f(yIzWiFP`b$s`oQpH|-!5hB=? zi1}R!(cpz#WuI%h=<3m;MwJ3$q5K;|e+_*DoPSf;fViWX00000NkvXXu0mjf?unJ- diff --git a/app/src/main/res/drawable-mdpi/ic_cloud_download_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_cloud_download_black_24dp.png deleted file mode 100644 index 47cde7099cd32a0c61242ee6a1c836bef1e521ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iO`a}}Ar*{w&l~Ew1WLGnoSzlZ z?4r7narXqxk}^lbxz9qUxFj2Qz2sCp_{P~y;^^`@e~Rzge4TT-_I>@N-#IGmc{*!q zs>^fbf8|L2(Z~)z_p*5PmbjM%i>%}(=gh7=b-ac9;Jk24hKP7R#v31(xi#~b_chGC z#D9sqLWcX0W_+Q93eU&dd5&st_vlmxz%c^|g(Grt*Rn=o{X9IltFJ>${V|Qjop@y7F+@ZfSv)5R%j6|idht{$r%KdvdG=I3 qtrz=sbV9UQ&BW^gfiHaCFdn(ZwdkJK-s?b5FnGH9xvX<)Pd=*}3sG&) za{lWxk#V#*#$~PD7I{Sj+gjQby$sBK_R6}Yqrack3}k$<1^|ty8pwO-1h8sRJ&^YZ z*b;RE1=eBbKMqVR^Fy>sN=l;Dm_t!FQE)yq*@1$IB(lEpT~tpbA#cu(sGLZmWME5F zO(aoZmx~q^6G;?l;Em`wkwl>}teAD0C_g_j0&a-ni6n|`0B}q6?y$si( diff --git a/app/src/main/res/drawable-xhdpi/ic_cloud_download_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_cloud_download_white_24dp.png deleted file mode 100644 index d1a0573af65814d77858c4f04ad4467de81647df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 417 zcmV;S0bc%zP))D*jn?auJVYUT*KKR0m$E(zB|-j;dX+0$g&eYKP9}0PF7g=t!OJ z&jLCMBlSD9It|z{Fs+!J)4Ey?+=01)y)s~%Mu4F&Ufa}~1Ud$_fbzcD_!lT>7=TC4 zjDe2PLI56*fn62^uqnd+0)d{@@Kbq7WGpGK8&1e4DxRm91(4=A&$sY{+C(y|Vc4f8 zk;nmdsYN6?9fT`J)d@*nMF?-HNF=#+Ls&DYL?pTOv_lBD$R?8fwnP~3w&r^>`DEVo zTa)cMI|+o#-WX}3o~^QP%bL4B_-?39Lk9|7ZBYg^wEqfN0!!d8m2gFXs7S&200000 LNkvXXu0mjfq%yl{ diff --git a/app/src/main/res/drawable-xxhdpi/ic_cloud_download_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_cloud_download_black_24dp.png deleted file mode 100644 index 254c20f6761e21d820689d20b2d653e434dde6e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 592 zcmV-W0zP~r{;hg(`&*$^`eE)G97~&lFc*z%< zEb*BaOmdbztS9Eu>|>He)M5=LDAG?X^)td76k)G9+rF2yj@s7t#ZD--Ig{Ku;R>*b97wht zQ4T>4Btwpc1Os3HfFEk`uq267-7azfA%QUI_UIg{KuVwB}BJCocwb7WaA!(%s+Ge;EpsT|Kyg1f+P z<(N*4bBlmg$}pDD=>)WFSIk#8N0Gl2u%D?|Fm*=B60yyUaGe=G(lBN;n5ROS0x5hx epU>y}=lTxDWwZ9(>ZsEI0000MSTYjf}^-3lMOyWom`6O;OJ20xG5q;ks?S25v$}QfCy47Za3Yla;8Af=GPOmsZ#y4mu&xlil9sWQOr|A&4 z4kzjJ0UF>Arrl3^R?dF2@Cxn8RmZSg#Knphlde%l_U$UC?G`AOX<09%zsz zBm#P?1M24qBm{yc6P#feeceGda0t@vB`3)L2~>hqKmczj{SL}9mm&z@EYZ)P!;mrv zt`V(*9`yhSF8ly(g`NPx&^Lp5!uRdLCgq3&qlmDwEA}L7&OC)xP@cz@B!z92UmuD^ zW=XS)YoF3Zrb(+?L~B7pp0Sj^PSpJzvzu9xY@W)$4ptEdm?DW1|&)x#nMux zgMvaSL{Wm5N*wKA=pZ3#ib*6XNxp6eLen%k=XX2syx#x7=OfFqEX%Si%d)I6y6(wc>Is{2z?`V!KpRbZ%R@G_!!M$V2U^WZ9&lG9qPYiJO*w2` z1LnKpKv;EJk2{kryQjG=YQ2y|2Mu?6Afy`S zhs*peYP*m`hfQ)r)N~<GKy2 zXxZV{5-%iCLSxo=%3Mhok|?2ReXMoVN(mQ|D5Yc8@tWw8#$f#mE28mTvCUl_@o(ej z-)}=tx-J^qm~HN9hj-13#x?DjO&f65f@n;OM)ldEJx-ahDr#=Z83Wq3&v764%I{_@ uiHce>W6~wV4(f4-EX%Si%d#xXvi||D=6R8Hd-{C<0000--fBOT!<-Ol0Y&M(CX0zFBHk(aV zRC9rT#)z{>iX3Y!v&cIh)6aSKBh-${$BuG~x8&Ha9J5>_;y*we&snF`ay+BeKY(+@ zanc*kmdI5X_fU~;=w3GK0;5#!s;0nh|12mHYF8~foaDxNe11k6gz6AiJknGzU&<{Qb z04&h9IUr0r5CF(CKfP-WL1%Pov#enM&FaX>w2E+phfQ$bCO%O=H z5;X-tS3m(UQ~<;R3&_%l5WK=!5}|M;P8vW6=D|2Y;;e6k1j}HUAaUMF!5SDPNZb@H z0L&32?wS<*1Y-n=+Y*9#Fhr2J?}y+e7$Hbhv?>?|0|W`G0A1iYL87Xp;4pYhkfuBGtseei%FQQZQe!qZKpwG$-j8$<{S69ugV ziTbjHi+?SC)<}@(D7NwE?g>(w2$G`If7BQ6X4W+jBzo%DY{Ah(P>OA}V(MWX|2IY1 zRscaezwvid?A?CNdYn1@Ta2=u7u^-yCXN4EqNDUvgD^v6@K0HWsoCwZM;(2{$z!?& z1_?Vqw`ri0d%WN)NmlWyRgxr_AW91%^@p#9#{w+C0xZA+EWiRRzyd750u;<&TKF}4 Tehrn800000NkvXXu0mjfJxo+? diff --git a/app/src/main/res/drawable/fetch_black.xml b/app/src/main/res/drawable/fetch_black.xml deleted file mode 100644 index 355ad63c..00000000 --- a/app/src/main/res/drawable/fetch_black.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/fetch_disabled_black.xml b/app/src/main/res/drawable/fetch_disabled_black.xml deleted file mode 100644 index 0166eda1..00000000 --- a/app/src/main/res/drawable/fetch_disabled_black.xml +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/drawable/fetch_disabled_white.xml b/app/src/main/res/drawable/fetch_disabled_white.xml deleted file mode 100644 index 43c77adc..00000000 --- a/app/src/main/res/drawable/fetch_disabled_white.xml +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/drawable/fetch_white.xml b/app/src/main/res/drawable/fetch_white.xml deleted file mode 100644 index 44d35acb..00000000 --- a/app/src/main/res/drawable/fetch_white.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/first.xml b/app/src/main/res/layout/first.xml index 6ccca1cc..0a4b72cf 100644 --- a/app/src/main/res/layout/first.xml +++ b/app/src/main/res/layout/first.xml @@ -44,15 +44,6 @@ android:layout_height="wrap_content" android:text="@string/app_first" android:textAppearance="@style/TextMedium" /> - - \ No newline at end of file diff --git a/app/src/main/res/layout/rule.xml b/app/src/main/res/layout/rule.xml index b70c7dc9..c7027b7f 100644 --- a/app/src/main/res/layout/rule.xml +++ b/app/src/main/res/layout/rule.xml @@ -229,16 +229,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:text="@string/title_related" /> - - + android:text="@string/title_related" /> - - \ 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 6c7b8e1d..31cb02a6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,7 +7,6 @@ Great care has been taken to develop and test NetGuard, however it is impossible to guarantee NetGuard will work correctly on every device. \n\nBy using NetGuard, you agree to the GNU General Public License version 3 - NetGuard will optionally share anonymized usage data to help improve how NetGuard protects you, by understanding how end users work with NetGuard. I agree I disagree @@ -215,7 +214,6 @@ Your internet traffic is not being sent to a remote VPN server. Access rules take precedence over other rules Options Notify internet access attempts - Share settings Rate Allow diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 6c29b94a..568fde14 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -4,7 +4,6 @@ - @@ -18,7 +17,6 @@ @drawable/expander_black @drawable/ic_hourglass_empty_black_24dp @drawable/ic_attach_money_black_24dp - @drawable/fetch_black @drawable/ic_settings_black_24dp @drawable/ic_delete_black_24dp @drawable/ic_launch_black_24dp @@ -29,7 +27,6 @@ @drawable/expander_white @drawable/ic_hourglass_empty_white_24dp @drawable/ic_attach_money_white_24dp - @drawable/fetch_white @drawable/ic_settings_white_24dp @drawable/ic_delete_white_24dp @drawable/ic_launch_white_24dp diff --git a/playstore/PLAY-es.md b/playstore/PLAY-es.md index 621cb38c..adcf052f 100644 --- a/playstore/PLAY-es.md +++ b/playstore/PLAY-es.md @@ -28,7 +28,8 @@ Características: • Simple de usar • No requiere root • 100% código abierto -• Sin seguimiento o perfilado de usuarios +• No calling home +• Sin seguimiento o análisis integrado • Sin publicidad • Desarrollado y soportado activamente • Soporta Android 4.0 o superior diff --git a/playstore/PLAY-ro.md b/playstore/PLAY-ro.md index 35c3456f..b3a48499 100644 --- a/playstore/PLAY-ro.md +++ b/playstore/PLAY-ro.md @@ -28,6 +28,7 @@ Caracteristici: • Simplu de utilizat • Nu necesita acces root • 100% software cu sursa deschisa +• Nu transmite datele nicaieri • Nu urmareste activitatea si nici nu o analizeaza • Fara reclama • Dezvoltare si asistenta continuua diff --git a/playstore/PLAY.md b/playstore/PLAY.md index b0c7493b..aaef5f08 100644 --- a/playstore/PLAY.md +++ b/playstore/PLAY.md @@ -28,7 +28,8 @@ Features: • Simple to use • No root required • 100% open source -• No tracking and user profiling +• No calling home +• No tracking or analytics • No advertisements • Actively developed and supported • Android 4.0 and later supported