Lightning browser with I2P configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

182 lines
6.7 KiB

package acr.browser.lightning.utils;
import android.content.Context;
import android.content.res.AssetManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.preference.PreferenceManager;
@Singleton
public class AdBlock {
private static final String TAG = "AdBlock";
private static final String BLOCKED_DOMAINS_LIST_FILE_NAME = "hosts.txt";
private static final String LOCAL_IP_V4 = "127.0.0.1";
private static final String LOCAL_IP_V4_ALT = "0.0.0.0";
private static final String LOCAL_IP_V6 = "::1";
private static final String LOCALHOST = "localhost";
private static final String COMMENT = "#";
private static final String TAB = "\t";
private static final String SPACE = " ";
private static final String EMPTY = "";
private final Set<String> mBlockedDomainsList = new HashSet<>();
private boolean mBlockAds;
@Inject PreferenceManager mPreferenceManager;
@Inject
public AdBlock(@NonNull Context context) {
BrowserApp.getAppComponent().inject(this);
if (mBlockedDomainsList.isEmpty() && Constants.FULL_VERSION) {
loadHostsFile(context);
}
mBlockAds = mPreferenceManager.getAdBlockEnabled();
}
public void updatePreference() {
mBlockAds = mPreferenceManager.getAdBlockEnabled();
}
private void loadBlockedDomainsList(@NonNull final Context context) {
BrowserApp.getTaskThread().execute(new Runnable() {
@Override
public void run() {
AssetManager asset = context.getAssets();
BufferedReader reader = null;
try {
//noinspection IOResourceOpenedButNotSafelyClosed
reader = new BufferedReader(new InputStreamReader(
asset.open(BLOCKED_DOMAINS_LIST_FILE_NAME)));
String line;
while ((line = reader.readLine()) != null) {
mBlockedDomainsList.add(line.trim());
}
} catch (IOException e) {
Log.wtf(TAG, "Reading blocked domains list from file '"
+ BLOCKED_DOMAINS_LIST_FILE_NAME + "' failed.", e);
} finally {
Utils.close(reader);
}
}
});
}
/**
* a method that determines if the given URL is an ad or not. It performs
* a search of the URL's domain on the blocked domain hash set.
*
* @param url the URL to check for being an ad
* @return true if it is an ad, false if it is not an ad
*/
public boolean isAd(@Nullable String url) {
if (!mBlockAds || url == null) {
return false;
}
String domain;
try {
domain = getDomainName(url);
} catch (URISyntaxException e) {
Log.d(TAG, "URL '" + url + "' is invalid", e);
return false;
}
boolean isOnBlacklist = mBlockedDomainsList.contains(domain);
if (isOnBlacklist) {
Log.d(TAG, "URL '" + url + "' is an ad");
}
return isOnBlacklist;
}
/**
* Returns the probable domain name for a given URL
*
* @param url the url to parse
* @return returns the domain
* @throws URISyntaxException throws an exception if the string cannot form a URI
*/
@NonNull
private static String getDomainName(@NonNull String url) throws URISyntaxException {
int index = url.indexOf('/', 8);
if (index != -1) {
url = url.substring(0, index);
}
URI uri = new URI(url);
String domain = uri.getHost();
if (domain == null) {
return url;
}
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
/**
* This method reads through a hosts file and extracts the domains that should
* be redirected to localhost (a.k.a. IP address 127.0.0.1). It can handle files that
* simply have a list of hostnames to block, or it can handle a full blown hosts file.
* It will strip out comments, references to the base IP address and just extract the
* domains to be used
*
* @param context the context needed to read the file
*/
private void loadHostsFile(@NonNull final Context context) {
BrowserApp.getTaskThread().execute(new Runnable() {
@Override
public void run() {
AssetManager asset = context.getAssets();
BufferedReader reader = null;
try {
//noinspection IOResourceOpenedButNotSafelyClosed
reader = new BufferedReader(new InputStreamReader(
asset.open(BLOCKED_DOMAINS_LIST_FILE_NAME)));
String line;
while ((line = reader.readLine()) != null) {
if (!line.isEmpty() && !line.startsWith(COMMENT)) {
line = line.replace(LOCAL_IP_V4, EMPTY)
.replace(LOCAL_IP_V4_ALT, EMPTY)
.replace(LOCAL_IP_V6, EMPTY)
.replace(TAB, EMPTY);
int comment = line.indexOf(COMMENT);
if (comment >= 0) {
line = line.substring(0, comment);
}
line = line.trim();
if (!line.isEmpty() && !line.equals(LOCALHOST)) {
while (line.contains(SPACE)) {
int space = line.indexOf(SPACE);
String host = line.substring(0, space);
mBlockedDomainsList.add(host.trim());
line = line.substring(space, line.length()).trim();
}
mBlockedDomainsList.add(line.trim());
}
}
}
} catch (IOException e) {
Log.wtf(TAG, "Reading blocked domains list from file '"
+ BLOCKED_DOMAINS_LIST_FILE_NAME + "' failed.", e);
} finally {
Utils.close(reader);
}
}
});
}
}