Added Disconnect category selection

pull/212/head
M66B 1 year ago
parent 06e840747a
commit 547c5c2e77

@ -45,9 +45,11 @@ import javax.net.ssl.HttpsURLConnection;
public class DisconnectBlacklist {
private static final Map<String, List<String>> map = new HashMap<>();
private static final List<String> all = new ArrayList<>();
private final static int FETCH_TIMEOUT = 20 * 1000; // milliseconds
private final static String LIST = "https://raw.githubusercontent.com/disconnectme/disconnect-tracking-protection/master/services.json";
final static String URI_CATEGORIES = "https://disconnect.me/trackerprotection#categories-of-trackers";
static void init(Context context) {
final File file = getFile(context);
@ -70,6 +72,7 @@ public class DisconnectBlacklist {
long start = SystemClock.elapsedRealtime();
map.clear();
all.clear();
String json = Helper.readText(file);
JSONObject jdisconnect = new JSONObject(json);
@ -77,6 +80,7 @@ public class DisconnectBlacklist {
Iterator<String> categories = jcategories.keys();
while (categories.hasNext()) {
String category = categories.next();
all.add(category);
JSONArray jcategory = jcategories.getJSONArray(category);
for (int c = 0; c < jcategory.length(); c++) {
JSONObject jblock = (JSONObject) jcategory.get(c);
@ -135,15 +139,34 @@ public class DisconnectBlacklist {
init(file);
}
static List<String> getCategories() {
synchronized (all) {
return new ArrayList<>(all);
}
}
static boolean isEnabled(Context context, String category) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean("disconnect_" + category, !"Content".equals(category));
}
static void setEnabled(Context context, String category, boolean value) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putBoolean("disconnect_" + category, value).apply();
}
static List<String> getCategories(String domain) {
return _getCategories(domain);
}
static boolean isTracking(String host) {
static boolean isTrackingImage(Context context, String host) {
List<String> categories = _getCategories(host);
if (categories == null || categories.size() == 0)
return false;
return !categories.contains("Content");
for (String category : categories)
if (isEnabled(context, category))
return true;
return false;
}
private static List<String> _getCategories(String domain) {

@ -36,6 +36,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.Spinner;
@ -47,11 +48,14 @@ import androidx.annotation.Nullable;
import androidx.appcompat.widget.SwitchCompat;
import androidx.constraintlayout.widget.Group;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.webkit.WebViewFeature;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
public class FragmentOptionsPrivacy extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -92,6 +96,9 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer
private SwitchCompat swDisconnectAutoUpdate;
private SwitchCompat swDisconnectLinks;
private SwitchCompat swDisconnectImages;
private RecyclerView rvDisconnect;
private ImageButton ibDisconnectCategories;
private AdapterDisconnect adapter;
private SwitchCompat swMnemonic;
private Button btnClearAll;
private TextView tvMnemonic;
@ -158,6 +165,8 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer
swDisconnectAutoUpdate = view.findViewById(R.id.swDisconnectAutoUpdate);
swDisconnectLinks = view.findViewById(R.id.swDisconnectLinks);
swDisconnectImages = view.findViewById(R.id.swDisconnectImages);
rvDisconnect = view.findViewById(R.id.rvDisconnect);
ibDisconnectCategories = view.findViewById(R.id.ibDisconnectCategories);
swMnemonic = view.findViewById(R.id.swMnemonic);
btnClearAll = view.findViewById(R.id.btnClearAll);
tvMnemonic = view.findViewById(R.id.tvMnemonic);
@ -484,6 +493,19 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("disconnect_images", checked).apply();
rvDisconnect.setAlpha(checked ? 1.0f : Helper.LOW_LIGHT);
}
});
rvDisconnect.setHasFixedSize(false);
rvDisconnect.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new AdapterDisconnect(getContext(), DisconnectBlacklist.getCategories());
rvDisconnect.setAdapter(adapter);
ibDisconnectCategories.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(DisconnectBlacklist.URI_CATEGORIES), true);
}
});
@ -626,6 +648,7 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer
swDisconnectAutoUpdate.setChecked(prefs.getBoolean("disconnect_auto_update", false));
swDisconnectLinks.setChecked(prefs.getBoolean("disconnect_links", true));
swDisconnectImages.setChecked(prefs.getBoolean("disconnect_images", false));
rvDisconnect.setAlpha(swDisconnectImages.isChecked() ? 1.0f : Helper.LOW_LIGHT);
String mnemonic = prefs.getString("wipe_mnemonic", null);
swMnemonic.setChecked(mnemonic != null);
@ -634,4 +657,70 @@ public class FragmentOptionsPrivacy extends FragmentBase implements SharedPrefer
Log.e(ex);
}
}
public static class AdapterDisconnect extends RecyclerView.Adapter<AdapterDisconnect.ViewHolder> {
private Context context;
private LayoutInflater inflater;
private List<String> items;
public class ViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener {
private CheckBox cbEnabled;
ViewHolder(View itemView) {
super(itemView);
cbEnabled = itemView.findViewById(R.id.cbEnabled);
}
private void wire() {
cbEnabled.setOnCheckedChangeListener(this);
}
private void unwire() {
cbEnabled.setOnCheckedChangeListener(null);
}
private void bindTo(String category) {
cbEnabled.setText(category);
cbEnabled.setChecked(DisconnectBlacklist.isEnabled(context, category));
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int pos = getAdapterPosition();
if (pos == RecyclerView.NO_POSITION)
return;
String category = items.get(pos);
DisconnectBlacklist.setEnabled(context, category, isChecked);
}
}
AdapterDisconnect(Context context, List<String> items) {
this.context = context;
this.inflater = LayoutInflater.from(context);
setHasStableIds(false);
this.items = items;
}
@Override
public int getItemCount() {
return items.size();
}
@Override
@NonNull
public AdapterDisconnect.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new AdapterDisconnect.ViewHolder(inflater.inflate(R.layout.item_disconnect_enabled, parent, false));
}
@Override
public void onBindViewHolder(@NonNull AdapterDisconnect.ViewHolder holder, int position) {
holder.unwire();
String category = items.get(position);
holder.bindTo(category);
holder.wire();
}
}
}

@ -57,7 +57,6 @@ import android.text.style.TypefaceSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.util.Base64;
import android.util.Pair;
import android.util.Patterns;
import android.view.View;
@ -2287,7 +2286,7 @@ public class HtmlHelper {
Uri uri = Uri.parse(img.attr("src"));
String host = uri.getHost();
if (host != null && !hosts.contains(host) &&
!isTrackingHost(host, disconnect_images))
!isTrackingHost(context, host, disconnect_images))
hosts.add(host);
}
}
@ -2305,7 +2304,7 @@ public class HtmlHelper {
if (host == null || hosts.contains(host))
continue;
if (isTrackingPixel(img) || isTrackingHost(host, disconnect_images)) {
if (isTrackingPixel(img) || isTrackingHost(context, host, disconnect_images)) {
img.attr("src", sb.toString());
img.attr("alt", context.getString(R.string.title_legend_tracking_pixel));
img.attr("height", "24");
@ -2340,10 +2339,10 @@ public class HtmlHelper {
}
}
private static boolean isTrackingHost(String host, boolean disconnect_images) {
private static boolean isTrackingHost(Context context, String host, boolean disconnect_images) {
if (TRACKING_HOSTS.contains(host))
return true;
if (disconnect_images && DisconnectBlacklist.isTracking(host))
if (disconnect_images && DisconnectBlacklist.isTrackingImage(context, host))
return true;
return false;
}

@ -691,6 +691,29 @@
app:layout_constraintTop_toBottomOf="@+id/swDisconnectLinks"
app:switchPadding="12dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDisconnect"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swDisconnectImages" />
<ImageButton
android:id="@+id/ibDisconnectCategories"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="12dp"
android:contentDescription="@string/title_info"
android:tooltipText="@string/title_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rvDisconnect"
app:srcCompat="@drawable/twotone_info_24" />
<Button
android:id="@+id/btnClearAll"
style="?android:attr/buttonStyleSmall"
@ -701,7 +724,7 @@
android:drawablePadding="6dp"
android:text="@string/title_advanced_clear_all"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swDisconnectImages" />
app:layout_constraintTop_toBottomOf="@id/ibDisconnectCategories" />
<TextView
android:id="@+id/tvClearAllHint"

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clItem"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/cbEnabled"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="blocklist"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
Loading…
Cancel
Save