From 5241f4cb105e51855475087874851190ddcb2f46 Mon Sep 17 00:00:00 2001 From: Schoumi Date: Mon, 29 Jun 2020 17:39:48 +0200 Subject: [PATCH] Add Tracker Page instead of opening external web page --- .../exodusprivacy/MainActivity.java | 20 +- .../exodus_privacy/exodusprivacy/Utils.java | 142 ++++++++++++ .../adapters/TrackerListAdapter.java | 13 +- .../fragments/ReportFragment.java | 10 +- .../fragments/TrackerFragment.java | 155 +++++++++++++ .../main/res/drawable/square_dark_orange.xml | 6 + .../main/res/drawable/square_light_blue.xml | 6 + app/src/main/res/layout/tracker.xml | 213 ++++++++++++++++++ app/src/main/res/values-fr/strings.xml | 7 + app/src/main/res/values/colors.xml | 10 +- app/src/main/res/values/strings.xml | 7 + 11 files changed, 578 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/org/eu/exodus_privacy/exodusprivacy/fragments/TrackerFragment.java create mode 100644 app/src/main/res/drawable/square_dark_orange.xml create mode 100644 app/src/main/res/drawable/square_light_blue.xml create mode 100644 app/src/main/res/layout/tracker.xml diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java index 7f9b800..e44b9cb 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/MainActivity.java @@ -40,12 +40,15 @@ import com.google.android.material.snackbar.Snackbar; import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationListAdapter; import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationViewModel; +import org.eu.exodus_privacy.exodusprivacy.adapters.TrackerListAdapter; import org.eu.exodus_privacy.exodusprivacy.databinding.MainBinding; import org.eu.exodus_privacy.exodusprivacy.fragments.HomeFragment; import org.eu.exodus_privacy.exodusprivacy.fragments.ReportFragment; +import org.eu.exodus_privacy.exodusprivacy.fragments.TrackerFragment; import org.eu.exodus_privacy.exodusprivacy.fragments.Updatable; import org.eu.exodus_privacy.exodusprivacy.listener.NetworkListener; import org.eu.exodus_privacy.exodusprivacy.manager.DatabaseManager; + import java.util.ArrayList; import java.util.List; @@ -57,6 +60,7 @@ public class MainActivity extends AppCompatActivity { private MenuItem settingsMenuItem; private String packageName; private MainBinding binding; + private ApplicationListAdapter.OnAppClickListener onAppClickListener; @Override protected void onCreate(Bundle savedInstanceState) { @@ -100,12 +104,24 @@ public class MainActivity extends AppCompatActivity { } }; - ApplicationListAdapter.OnAppClickListener onAppClickListener = vm -> { + TrackerListAdapter.OnTrackerClickListener onTrackerClickListener = id -> { + TrackerFragment tracker = TrackerFragment.newInstance(id); + tracker.setOnAppClickListener(onAppClickListener); + fragments.add(tracker); + FragmentManager manager = getSupportFragmentManager(); + FragmentTransaction transaction = manager.beginTransaction(); + transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right, R.anim.slide_in_left, R.anim.slide_out_left) + .replace(R.id.fragment_container,tracker) + .addToBackStack(null) + .commit(); + }; + + onAppClickListener = vm -> { try { PackageManager pm = getPackageManager(); PackageInfo packageInfo = pm.getPackageInfo(vm.packageName, PackageManager.GET_PERMISSIONS); - ReportFragment report = ReportFragment.newInstance(pm,vm,packageInfo); + ReportFragment report = ReportFragment.newInstance(pm,vm,packageInfo,onTrackerClickListener); fragments.add(report); FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/Utils.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/Utils.java index bf83b8e..b7da7f2 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/Utils.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/Utils.java @@ -12,6 +12,9 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Utils { @@ -79,4 +82,143 @@ public class Utils { } return str.toString(); } + + /* + Simple and not complete markdownToHtml converter + */ + public static String markdownToHtml(String markdown) { + StringBuilder builder = new StringBuilder(); + String[] lines = markdown.split("\r\n"); + ArrayList listStarter = new ArrayList<>(); + ArrayList formatStarter = new ArrayList<>(); + ArrayList closeTags = new ArrayList<>(); + for(String line : lines) { + if (line.matches("^#{1,5} .*")) { + int nb = line.indexOf(" "); + String hx = ""; + String endhx = ""; + builder.append(hx); + closeTags.add(endhx); + line = line.substring(line.indexOf(" ")+1); + } else if (line.matches("^ *[+\\-*] .*")) { + String starter=""; + if (listStarter.size() > 0 && line.startsWith(listStarter.get(listStarter.size()-1))) { + starter = listStarter.get(listStarter.size()-1); + } else { + Pattern pattern = Pattern.compile("^( *[+\\-*] )"); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + starter = matcher.group(1); + listStarter.add(starter); + builder.append("
    \n"); + + } + } + builder.append("
  • "); + int beginIndex = line.indexOf(starter)+starter.length(); + line = line.substring(beginIndex); + closeTags.add("
  • "); + } else { + while(!listStarter.isEmpty()) { + listStarter.remove(listStarter.size() - 1); + builder.append("
\n"); + } + builder.append("

"); + closeTags.add("

"); + } + while(!line.isEmpty()){ + Pattern pattern = Pattern.compile("^\\[(.+?)(?=\\]\\()\\]\\((http.+?)(?=\\))\\)"); + //Pattern pattern = Pattern.compile("^\\[(.*)\\]\\((http.*)\\)"); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + builder.append(""); + builder.append(matcher.group(1)); + builder.append(""); + line = line.substring(line.indexOf(")")+1); + continue; + } + pattern = Pattern.compile("^(http.*)"); + matcher = pattern.matcher(line); + if (matcher.find()) { + builder.append(""); + builder.append(matcher.group(1)); + builder.append(""); + line = line.substring(matcher.group(1).length()); + continue; + } + pattern = Pattern.compile("^[*_]{2}(.+)[*_]{2}"); + matcher = pattern.matcher(line); + if (matcher.find()) { + if(line.startsWith("*")) { + line = line.replaceFirst("\\*\\*", ""); + formatStarter.add("**"); + } + else { + line = line.replaceFirst("__", ""); + formatStarter.add("__"); + } + continue; + } + pattern = Pattern.compile("^[*_]{1}(.+)"); + matcher = pattern.matcher(line); + if (matcher.find()) { + if(line.startsWith("*")) { + line = line.replaceFirst("\\*", ""); + formatStarter.add("*"); + } + else { + line = line.replaceFirst("_", ""); + formatStarter.add("_"); + } + continue; + } + if(formatStarter.size() > 0) { + String checkFormat; + if(line.contains(" ")) + checkFormat = line.substring(0,line.indexOf(" ")); + else + checkFormat = line; + String lastFormat = formatStarter.get(formatStarter.size()-1); + if (checkFormat.contains(lastFormat)) { + if(lastFormat.length()==2) { + if (lastFormat.contains("*")) + line = line.replaceFirst("\\*\\*", ""); + else + line = line.replaceFirst("__", ""); + } else { + if (lastFormat.contains("*")) + line = line.replaceFirst("\\*", ""); + else + line = line.replaceFirst("_", ""); + } + formatStarter.remove(formatStarter.size()-1); + continue; + } + } + + if(line.contains(" ")) { + builder.append(line.substring(0, line.indexOf(" ") + 1)); + line = line.substring(line.indexOf(" ") + 1); + } else { + builder.append(line); + line = ""; + } + } + //close all unclosed tags starting at the end + while(!closeTags.isEmpty()) { + builder.append(closeTags.remove(closeTags.size()-1)); + } + builder.append("\n"); + + } + while(!listStarter.isEmpty()) { + listStarter.remove(listStarter.size() - 1); + builder.append("\n"); + } + return builder.toString(); + } } diff --git a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/TrackerListAdapter.java b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/TrackerListAdapter.java index 31a12e2..103ea08 100644 --- a/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/TrackerListAdapter.java +++ b/app/src/main/java/org/eu/exodus_privacy/exodusprivacy/adapters/TrackerListAdapter.java @@ -3,7 +3,6 @@ package org.eu.exodus_privacy.exodusprivacy.adapters; import android.content.Intent; import android.net.Uri; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; @@ -24,11 +23,13 @@ import java.util.Set; public class TrackerListAdapter extends RecyclerView.Adapter{ private List trackersList; + private OnTrackerClickListener trackerClickListener; private int layout; - public TrackerListAdapter(Set trackerList, int resource) { + public TrackerListAdapter(Set trackerList, int resource, OnTrackerClickListener listener) { setTrackers(trackerList); layout = resource; + trackerClickListener = listener; } @NonNull @@ -78,9 +79,7 @@ public class TrackerListAdapter extends RecyclerView.Adapter { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse("https://reports.exodus-privacy.eu.org/trackers/" + tracker.id + "/")); - v.getContext().startActivity(intent); + trackerClickListener.onTrackerClick(tracker.id); }); } else @@ -89,5 +88,9 @@ public class TrackerListAdapter extends RecyclerView.Adapter applications; + private AppListFragment appListFragment; + private ApplicationListAdapter.OnAppClickListener onAppClickListener; + + public static TrackerFragment newInstance(long trackerId) { + TrackerFragment fragment = new TrackerFragment(); + fragment.setTrackerId(trackerId); + return fragment; + } + + private void setTrackerId(long id) { + trackerId = id; + } + + @Override + public void onUpdateComplete() { + Context context = trackerBinding.getRoot().getContext(); + Tracker tracker = DatabaseManager.getInstance(context).getTracker(trackerId); + trackerBinding.name.setText(tracker.name); + trackerBinding.codeDetection.setText(tracker.codeSignature); + trackerBinding.networkDetection.setText(tracker.networkSignature); + trackerBinding.description.setText(Html.fromHtml(Utils.markdownToHtml(tracker.description))); + trackerBinding.description.setMovementMethod(LinkMovementMethod.getInstance()); + trackerBinding.description.setClickable(true); + trackerBinding.trackerUrl.setOnClickListener(v -> { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(tracker.website)); + startActivity(intent); + }); + displayAppListAsync(); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + trackerBinding = DataBindingUtil.inflate(inflater, R.layout.tracker,container,false); + if (applications == null) + applications = new ArrayList<>(); + appListFragment = new AppListFragment(); + appListFragment.setFilter(AppListFragment.Type.TRACKER,trackerId); + appListFragment.disableScrollBar(); + appListFragment.setOnAppClickListener(onAppClickListener); + FragmentManager manager = getChildFragmentManager(); + FragmentTransaction transaction = manager.beginTransaction(); + transaction.replace(R.id.applications,appListFragment); + transaction.commit(); + Context context = trackerBinding.getRoot().getContext(); + packageManager = context.getPackageManager(); + onUpdateComplete(); + return trackerBinding.getRoot(); + } + + + @Override + public void onPrepareOptionsMenu(Menu menu) { + MenuItem item = menu.findItem(R.id.action_filter); + item.setVisible(false); + item = menu.findItem(R.id.action_settings); + item.setVisible(false); + + } + + private void displayAppListAsync() { + trackerBinding.noAppFound.setVisibility(View.GONE); + trackerBinding.trackerPresence.setVisibility(View.GONE); + //todo + trackerBinding.trackerPresenceNb.setVisibility(View.GONE); + //todo + trackerBinding.trackerPresenceTitle.setVisibility(View.GONE); + if (applications.isEmpty()) { + trackerBinding.retrieveApp.setVisibility(View.VISIBLE); + } + + new ComputeAppListTask( + new WeakReference<>(packageManager), + new WeakReference<>(DatabaseManager.getInstance(getActivity())), + new WeakReference<>(this) + ).execute(); + } + + @Override + public void onAppsComputed(List apps) { + this.applications = apps; + trackerBinding.retrieveApp.setVisibility(View.GONE); + trackerBinding.noAppFound.setVisibility(apps.isEmpty() ? View.VISIBLE : View.GONE); + trackerBinding.trackerPresence.setVisibility(View.VISIBLE); + trackerBinding.trackerPresenceNb.setVisibility(View.VISIBLE); + trackerBinding.trackerPresenceTitle.setVisibility(View.VISIBLE); + appListFragment.setApplications(apps); + int total = appListFragment.getTotalApps(); + int displayedApps = appListFragment.getDisplayedApps(); + int percent = displayedApps*100/total; + if(percent >=50) + trackerBinding.trackerPresenceNb.setBackgroundResource(R.drawable.square_red); + else if(percent >=33) + trackerBinding.trackerPresenceNb.setBackgroundResource(R.drawable.square_dark_orange); + else if(percent >=20) + trackerBinding.trackerPresenceNb.setBackgroundResource(R.drawable.square_yellow); + else + trackerBinding.trackerPresenceNb.setBackgroundResource(R.drawable.square_light_blue); + + trackerBinding.trackerPresenceNb.setText(percent+"%"); + Context context = trackerBinding.getRoot().getContext(); + String presence = context.getResources().getString(R.string.tracker_presence,displayedApps); + trackerBinding.trackerPresence.setText(presence); + trackerBinding.trackerPresenceTitle.setText(R.string.tracker_presence_in); + } + + public void setOnAppClickListener(ApplicationListAdapter.OnAppClickListener listener) { + onAppClickListener = listener; + } +} diff --git a/app/src/main/res/drawable/square_dark_orange.xml b/app/src/main/res/drawable/square_dark_orange.xml new file mode 100644 index 0000000..f5f9b9b --- /dev/null +++ b/app/src/main/res/drawable/square_dark_orange.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable/square_light_blue.xml b/app/src/main/res/drawable/square_light_blue.xml new file mode 100644 index 0000000..7b6cbb8 --- /dev/null +++ b/app/src/main/res/drawable/square_light_blue.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/layout/tracker.xml b/app/src/main/res/layout/tracker.xml new file mode 100644 index 0000000..b7b24dd --- /dev/null +++ b/app/src/main/res/layout/tracker.xml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 0afb715..a40c758 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -37,6 +37,13 @@ Un pisteur est une partie du logiciel dédiée à la collecte de données sur vous et vos usages. En savoir plus… Les permissions sont les actions que l\'application peut effectuer sur votre téléphone. En savoir plus… L\'icône ! indique un niveau \'Dangereux\' ou \'Spécial\' d\'après les niveaux de protection de Google. + Page web du pisteur ➤ + Règles de détection + Règle de détection(code): + Règle de détection(réseau): + Présent dans %d de vos applications + Présent dans: + Ce pisteur ne semble pas être présent dans vos applications Filtrer diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index b1fe880..695a7ac 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,13 +3,19 @@ #684971 #3d2b43 #684971 + #6fc384 - #e46772 - #ffdb66 #e46772 #ffdb66 + + #17a2b8 + #ffc70f + #ff8c00 + #e61718 + #684971 #343A40 #6C757D #FFFFFF + #E83E8C diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0d34fe3..4058e0e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -37,6 +37,13 @@ A tracker is a piece of software meant to collect data about you or your usages. Learn more… Permissions are actions the application can do on your phone. Learn more… The icon ! indicates a \'Dangerous\' or \'Special\' level according to Google\'s protection levels. + Tracker web page ➤ + Detection Rules + Code detection rule: + Network detection rule: + Present in %d of your applications + Present in: + This tracker seems not be present in your applications Filter