Merge remote-tracking branch 'origin/master' into dev
This commit is contained in:
commit
4c7bb196dd
@ -52,4 +52,5 @@ dependencies {
|
||||
compile 'com.android.support:palette-v7:22.2.0'
|
||||
compile 'com.android.support:appcompat-v7:22.2.0'
|
||||
compile 'org.jsoup:jsoup:1.8.1'
|
||||
compile 'net.i2p.android:client:0.7@aar'
|
||||
}
|
||||
|
@ -77,3 +77,9 @@
|
||||
# Don't warn about those in case this app is linking against an older
|
||||
# platform version. We know about them, and they are safe.
|
||||
-dontwarn android.support.**
|
||||
|
||||
# The I2P Java API bundled inside the I2P Android client library contains
|
||||
# references to javax.naming classes that Android doesn't have. But those
|
||||
# classes are never used on Android, and it is safe to ignore the warnings.
|
||||
-dontwarn net.i2p.crypto.CertUtil
|
||||
-dontwarn org.apache.http.conn.ssl.DefaultHostnameVerifier
|
||||
|
@ -10,7 +10,11 @@ import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.*;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.database.Cursor;
|
||||
@ -36,15 +40,26 @@ import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v4.widget.DrawerLayout.DrawerListener;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.*;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnFocusChangeListener;
|
||||
import android.view.View.OnKeyListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.Animation.AnimationListener;
|
||||
import android.view.animation.AnimationUtils;
|
||||
@ -52,41 +67,68 @@ import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.Transformation;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.webkit.*;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.CookieSyncManager;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebChromeClient.CustomViewCallback;
|
||||
import android.webkit.WebIconDatabase;
|
||||
import android.webkit.WebStorage;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebView.HitTestResult;
|
||||
import android.widget.*;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.webkit.WebViewDatabase;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
import android.widget.Toast;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import acr.browser.lightning.view.AnimatedProgressBar;
|
||||
import acr.browser.lightning.database.BookmarkManager;
|
||||
import acr.browser.lightning.constant.BookmarkPage;
|
||||
import acr.browser.lightning.controller.BrowserController;
|
||||
import acr.browser.lightning.object.ClickHandler;
|
||||
import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.object.DrawerArrowDrawable;
|
||||
import acr.browser.lightning.database.HistoryDatabase;
|
||||
import acr.browser.lightning.database.HistoryItem;
|
||||
import acr.browser.lightning.constant.HistoryPage;
|
||||
import acr.browser.lightning.view.LightningView;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.object.SearchAdapter;
|
||||
import acr.browser.lightning.utils.Utils;
|
||||
import info.guardianproject.onionkit.ui.OrbotHelper;
|
||||
import info.guardianproject.onionkit.web.WebkitProxy;
|
||||
import net.i2p.android.ui.I2PAndroidHelper;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.constant.BookmarkPage;
|
||||
import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.constant.HistoryPage;
|
||||
import acr.browser.lightning.controller.BrowserController;
|
||||
import acr.browser.lightning.database.BookmarkManager;
|
||||
import acr.browser.lightning.database.HistoryDatabase;
|
||||
import acr.browser.lightning.database.HistoryItem;
|
||||
import acr.browser.lightning.object.ClickHandler;
|
||||
import acr.browser.lightning.object.DrawerArrowDrawable;
|
||||
import acr.browser.lightning.object.SearchAdapter;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
import acr.browser.lightning.utils.Utils;
|
||||
import acr.browser.lightning.view.AnimatedProgressBar;
|
||||
import acr.browser.lightning.view.LightningView;
|
||||
import info.guardianproject.onionkit.ui.OrbotHelper;
|
||||
import info.guardianproject.onionkit.web.WebkitProxy;
|
||||
|
||||
public class BrowserActivity extends ThemableActivity implements BrowserController, OnClickListener {
|
||||
|
||||
@ -140,6 +182,11 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
private Drawable mDeleteIcon, mRefreshIcon, mCopyIcon, mIcon;
|
||||
private DrawerArrowDrawable mArrowDrawable;
|
||||
|
||||
// Helper
|
||||
private I2PAndroidHelper mI2PHelper;
|
||||
private boolean mI2PHelperBound;
|
||||
private boolean mI2PProxyInitialized;
|
||||
|
||||
// Constant
|
||||
private static final int API = android.os.Build.VERSION.SDK_INT;
|
||||
private static final LayoutParams MATCH_PARENT = new LayoutParams(LayoutParams.MATCH_PARENT,
|
||||
@ -222,6 +269,8 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
R.id.arrow_button);
|
||||
arrowButton.setOnClickListener(this);
|
||||
|
||||
mI2PHelper = new I2PAndroidHelper(this);
|
||||
|
||||
RelativeLayout back = (RelativeLayout) findViewById(R.id.action_back);
|
||||
back.setOnClickListener(this);
|
||||
|
||||
@ -305,7 +354,7 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath());
|
||||
}
|
||||
|
||||
checkForTor();
|
||||
checkForProxy();
|
||||
}
|
||||
|
||||
private class SearchClass {
|
||||
@ -495,56 +544,106 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
}
|
||||
|
||||
/*
|
||||
* If Orbot/Tor is installed, prompt the user if they want to enable
|
||||
* If Orbot/Tor or I2P is installed, prompt the user if they want to enable
|
||||
* proxying for this session
|
||||
*/
|
||||
private boolean checkForTor() {
|
||||
private void checkForProxy() {
|
||||
boolean useProxy = mPreferences.getUseProxy();
|
||||
|
||||
OrbotHelper oh = new OrbotHelper(this);
|
||||
if (oh.isOrbotInstalled() && !mPreferences.getCheckedForTor()) {
|
||||
mPreferences.setCheckedForTor(true);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
mPreferences.setUseProxy(true);
|
||||
initializeTor();
|
||||
break;
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
mPreferences.setUseProxy(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
final boolean orbotInstalled = oh.isOrbotInstalled();
|
||||
boolean orbotChecked = mPreferences.getCheckedForTor();
|
||||
boolean orbot = orbotInstalled && !orbotChecked;
|
||||
|
||||
boolean i2pInstalled = mI2PHelper.isI2PAndroidInstalled();
|
||||
boolean i2pChecked = mPreferences.getCheckedForI2P();
|
||||
boolean i2p = i2pInstalled && !i2pChecked;
|
||||
|
||||
// TODO Is the idea to show this per-session, or only once?
|
||||
if (!useProxy && (orbot || i2p)) {
|
||||
if (orbot) mPreferences.setCheckedForTor(true);
|
||||
if (i2p) mPreferences.setCheckedForI2P(true);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setMessage(R.string.use_tor_prompt)
|
||||
.setPositiveButton(R.string.yes, dialogClickListener)
|
||||
.setNegativeButton(R.string.no, dialogClickListener).show();
|
||||
|
||||
return true;
|
||||
} else if (oh.isOrbotInstalled() & useProxy) {
|
||||
return true;
|
||||
} else {
|
||||
mPreferences.setUseProxy(false);
|
||||
return false;
|
||||
if (orbotInstalled && i2pInstalled) {
|
||||
String[] proxyChoices = this.getResources().getStringArray(R.array.proxy_choices_array);
|
||||
builder.setTitle(getResources().getString(R.string.http_proxy))
|
||||
.setSingleChoiceItems(proxyChoices, mPreferences.getProxyChoice(),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mPreferences.setProxyChoice(which);
|
||||
}
|
||||
})
|
||||
.setNeutralButton(getResources().getString(R.string.action_ok),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (mPreferences.getUseProxy())
|
||||
initializeProxy();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
mPreferences.setProxyChoice(orbotInstalled ?
|
||||
Constants.PROXY_ORBOT : Constants.PROXY_I2P);
|
||||
initializeProxy();
|
||||
break;
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
mPreferences.setProxyChoice(Constants.NO_PROXY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
builder.setMessage(orbotInstalled ? R.string.use_tor_prompt : R.string.use_i2p_prompt)
|
||||
.setPositiveButton(R.string.yes, dialogClickListener)
|
||||
.setNegativeButton(R.string.no, dialogClickListener);
|
||||
}
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize WebKit Proxying for Tor
|
||||
* Initialize WebKit Proxying
|
||||
*/
|
||||
private void initializeTor() {
|
||||
private void initializeProxy() {
|
||||
String host;
|
||||
int port;
|
||||
|
||||
OrbotHelper oh = new OrbotHelper(this);
|
||||
if (!oh.isOrbotRunning()) {
|
||||
oh.requestOrbotStart(this);
|
||||
switch (mPreferences.getProxyChoice()) {
|
||||
case Constants.NO_PROXY:
|
||||
// We shouldn't be here
|
||||
return;
|
||||
|
||||
case Constants.PROXY_ORBOT:
|
||||
OrbotHelper oh = new OrbotHelper(this);
|
||||
if (!oh.isOrbotRunning()) {
|
||||
oh.requestOrbotStart(this);
|
||||
}
|
||||
host = "localhost";
|
||||
port = 8118;
|
||||
break;
|
||||
|
||||
case Constants.PROXY_I2P:
|
||||
mI2PProxyInitialized = true;
|
||||
if (mI2PHelperBound && !mI2PHelper.isI2PAndroidRunning()) {
|
||||
mI2PHelper.requestI2PAndroidStart(this);
|
||||
}
|
||||
host = "localhost";
|
||||
port = 4444;
|
||||
break;
|
||||
|
||||
default:
|
||||
host = mPreferences.getProxyHost();
|
||||
port = mPreferences.getProxyPort();
|
||||
}
|
||||
|
||||
try {
|
||||
String host = mPreferences.getProxyHost();
|
||||
int port = mPreferences.getProxyPort();
|
||||
WebkitProxy.setProxy(BrowserApp.class.getName(), getApplicationContext(),
|
||||
host, port);
|
||||
} catch (Exception e) {
|
||||
@ -553,6 +652,20 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
|
||||
}
|
||||
|
||||
public boolean isProxyReady() {
|
||||
if (mPreferences.getProxyChoice() == Constants.PROXY_I2P) {
|
||||
if (!mI2PHelper.isI2PAndroidRunning()) {
|
||||
Utils.showToast(this, getString(R.string.i2p_not_running));
|
||||
return false;
|
||||
} else if (!mI2PHelper.areTunnelsActive()) {
|
||||
Utils.showToast(this, getString(R.string.i2p_tunnels_not_ready));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isTablet() {
|
||||
return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
|
||||
}
|
||||
@ -705,7 +818,7 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
|
||||
updateCookiePreference();
|
||||
if (mPreferences.getUseProxy()) {
|
||||
initializeTor();
|
||||
initializeProxy();
|
||||
} else {
|
||||
try {
|
||||
WebkitProxy.resetProxy(BrowserApp.class.getName(),
|
||||
@ -713,6 +826,7 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
mI2PProxyInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1370,6 +1484,13 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mI2PHelper.unbind();
|
||||
mI2PHelperBound = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(Constants.TAG, "onDestroy");
|
||||
@ -1379,6 +1500,22 @@ public class BrowserActivity extends ThemableActivity implements BrowserControll
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
if (mPreferences.getProxyChoice() == Constants.PROXY_I2P) {
|
||||
// Try to bind to I2P Android
|
||||
mI2PHelper.bind(new I2PAndroidHelper.Callback() {
|
||||
@Override
|
||||
public void onI2PAndroidBound() {
|
||||
mI2PHelperBound = true;
|
||||
if (mI2PProxyInitialized && !mI2PHelper.isI2PAndroidRunning())
|
||||
mI2PHelper.requestI2PAndroidStart(BrowserActivity.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
@ -22,11 +22,15 @@ import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.i2p.android.ui.I2PAndroidHelper;
|
||||
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.utils.Utils;
|
||||
import info.guardianproject.onionkit.ui.OrbotHelper;
|
||||
|
||||
@ -36,6 +40,8 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
private PreferenceManager mPreferences;
|
||||
private Context mContext;
|
||||
private Activity mActivity;
|
||||
private CharSequence[] mProxyChoices;
|
||||
private TextView mProxyChoiceName;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -69,7 +75,7 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
layoutBlockAds.setEnabled(Constants.FULL_VERSION);
|
||||
RelativeLayout layoutImages = (RelativeLayout) findViewById(R.id.layoutImages);
|
||||
RelativeLayout layoutEnableJS = (RelativeLayout) findViewById(R.id.layoutEnableJS);
|
||||
RelativeLayout layoutOrbot = (RelativeLayout) findViewById(R.id.layoutUseOrbot);
|
||||
LinearLayout layoutProxyChoice = (LinearLayout) findViewById(R.id.layoutProxyChoice);
|
||||
RelativeLayout layoutColor = (RelativeLayout) findViewById(R.id.layoutColorMode);
|
||||
RelativeLayout layoutBookmarks = (RelativeLayout) findViewById(R.id.layoutBookmarks);
|
||||
|
||||
@ -89,12 +95,19 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
boolean imagesBool = mPreferences.getBlockImagesEnabled();
|
||||
boolean enableJSBool = mPreferences.getJavaScriptEnabled();
|
||||
|
||||
mProxyChoiceName = (TextView) findViewById(R.id.proxyChoiceName);
|
||||
mProxyChoices = this.getResources().getStringArray(R.array.proxy_choices_array);
|
||||
int choice = mPreferences.getProxyChoice();
|
||||
if (choice == Constants.PROXY_MANUAL)
|
||||
mProxyChoiceName.setText(mPreferences.getProxyHost() + ":" + mPreferences.getProxyPort());
|
||||
else
|
||||
mProxyChoiceName.setText(mProxyChoices[choice]);
|
||||
|
||||
CheckBox flash = (CheckBox) findViewById(R.id.cbFlash);
|
||||
CheckBox adblock = (CheckBox) findViewById(R.id.cbAdblock);
|
||||
adblock.setEnabled(Constants.FULL_VERSION);
|
||||
CheckBox images = (CheckBox) findViewById(R.id.cbImageBlock);
|
||||
CheckBox enablejs = (CheckBox) findViewById(R.id.cbJavascript);
|
||||
CheckBox orbot = (CheckBox) findViewById(R.id.cbOrbot);
|
||||
CheckBox color = (CheckBox) findViewById(R.id.cbColorMode);
|
||||
|
||||
images.setChecked(imagesBool);
|
||||
@ -105,12 +118,11 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
flash.setChecked(false);
|
||||
}
|
||||
adblock.setChecked(mPreferences.getAdBlockEnabled());
|
||||
orbot.setChecked(mPreferences.getUseProxy());
|
||||
color.setChecked(mPreferences.getColorModeEnabled());
|
||||
|
||||
initCheckBox(flash, adblock, images, enablejs, orbot, color);
|
||||
initCheckBox(flash, adblock, images, enablejs, color);
|
||||
clickListenerForCheckBoxes(layoutFlash, layoutBlockAds, layoutImages, layoutEnableJS,
|
||||
layoutOrbot, layoutColor, flash, adblock, images, enablejs, orbot, color);
|
||||
layoutProxyChoice, layoutColor, flash, adblock, images, enablejs, color);
|
||||
|
||||
RelativeLayout general = (RelativeLayout) findViewById(R.id.layoutGeneral);
|
||||
RelativeLayout display = (RelativeLayout) findViewById(R.id.layoutDisplay);
|
||||
@ -127,9 +139,9 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
|
||||
public void clickListenerForCheckBoxes(RelativeLayout layoutFlash,
|
||||
RelativeLayout layoutBlockAds, RelativeLayout layoutImages,
|
||||
RelativeLayout layoutEnableJS, RelativeLayout layoutOrbot, RelativeLayout layoutColor,
|
||||
RelativeLayout layoutEnableJS, LinearLayout layoutProxyChoice, RelativeLayout layoutColor,
|
||||
final CheckBox flash, final CheckBox adblock, final CheckBox images,
|
||||
final CheckBox enablejs, final CheckBox orbot, final CheckBox color) {
|
||||
final CheckBox enablejs, final CheckBox color) {
|
||||
layoutFlash.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
@ -168,17 +180,12 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
}
|
||||
|
||||
});
|
||||
layoutOrbot.setOnClickListener(new OnClickListener() {
|
||||
layoutProxyChoice.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (orbot.isEnabled()) {
|
||||
orbot.setChecked(!orbot.isChecked());
|
||||
} else {
|
||||
Utils.showToast(mContext, getResources().getString(R.string.install_orbot));
|
||||
}
|
||||
public void onClick(View view) {
|
||||
proxyChoicePicker();
|
||||
}
|
||||
|
||||
});
|
||||
layoutColor.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@ -191,7 +198,7 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
}
|
||||
|
||||
public void initCheckBox(CheckBox flash, CheckBox adblock, CheckBox images, CheckBox enablejs,
|
||||
CheckBox orbot, CheckBox color) {
|
||||
CheckBox color) {
|
||||
flash.setEnabled(API < 19);
|
||||
flash.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
|
||||
@ -253,20 +260,7 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
}
|
||||
|
||||
});
|
||||
OrbotHelper oh = new OrbotHelper(this);
|
||||
if (!oh.isOrbotInstalled()) {
|
||||
orbot.setEnabled(false);
|
||||
}
|
||||
|
||||
orbot.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
mPreferences.setUseProxy(isChecked);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
color.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
|
||||
@Override
|
||||
@ -309,6 +303,77 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
alert.show();
|
||||
}
|
||||
|
||||
private void proxyChoicePicker() {
|
||||
AlertDialog.Builder picker = new AlertDialog.Builder(mContext);
|
||||
picker.setTitle(getResources().getString(R.string.http_proxy));
|
||||
picker.setSingleChoiceItems(mProxyChoices, mPreferences.getProxyChoice(),
|
||||
new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setProxyChoice(which);
|
||||
}
|
||||
});
|
||||
picker.setNeutralButton(getResources().getString(R.string.action_ok),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
});
|
||||
picker.show();
|
||||
}
|
||||
|
||||
private void setProxyChoice(int choice) {
|
||||
switch (choice) {
|
||||
case Constants.PROXY_ORBOT:
|
||||
OrbotHelper oh = new OrbotHelper(this);
|
||||
if (!oh.isOrbotInstalled()) {
|
||||
choice = Constants.NO_PROXY;
|
||||
Utils.showToast(mContext, getResources().getString(R.string.install_orbot));
|
||||
}
|
||||
break;
|
||||
|
||||
case Constants.PROXY_I2P:
|
||||
I2PAndroidHelper ih = new I2PAndroidHelper(this);
|
||||
if (!ih.isI2PAndroidInstalled()) {
|
||||
choice = Constants.NO_PROXY;
|
||||
ih.promptToInstall(this);
|
||||
}
|
||||
break;
|
||||
|
||||
case Constants.PROXY_MANUAL:
|
||||
manualProxyPicker();
|
||||
break;
|
||||
}
|
||||
|
||||
mPreferences.setProxyChoice(choice);
|
||||
if (choice < mProxyChoices.length)
|
||||
mProxyChoiceName.setText(mProxyChoices[choice]);
|
||||
}
|
||||
|
||||
public void manualProxyPicker() {
|
||||
View v = getLayoutInflater().inflate(R.layout.picker_manual_proxy, null);
|
||||
final EditText eProxyHost = (EditText) v.findViewById(R.id.proxyHost);
|
||||
final EditText eProxyPort = (EditText) v.findViewById(R.id.proxyPort);
|
||||
eProxyHost.setText(mPreferences.getProxyHost());
|
||||
eProxyPort.setText(Integer.toString(mPreferences.getProxyPort()));
|
||||
|
||||
new AlertDialog.Builder(mActivity)
|
||||
.setTitle(R.string.manual_proxy)
|
||||
.setView(v)
|
||||
.setPositiveButton(R.string.action_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
String proxyHost = eProxyHost.getText().toString();
|
||||
int proxyPort = Integer.parseInt(eProxyPort.getText().toString());
|
||||
mPreferences.setProxyHost(proxyHost);
|
||||
mPreferences.setProxyPort(proxyPort);
|
||||
mProxyChoiceName.setText(proxyHost + ":" + proxyPort);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
public void agentPicker() {
|
||||
final AlertDialog.Builder agentStringPicker = new AlertDialog.Builder(mActivity);
|
||||
|
||||
|
@ -40,4 +40,10 @@ public final class Constants {
|
||||
public static final String FILE = "file://";
|
||||
public static final String FOLDER = "folder://";
|
||||
public static final String TAG = "Lightning";
|
||||
|
||||
// These should match the order of @array/proxy_choices_array
|
||||
public static final int NO_PROXY = 0;
|
||||
public static final int PROXY_ORBOT = 1;
|
||||
public static final int PROXY_I2P = 2;
|
||||
public static final int PROXY_MANUAL = 3;
|
||||
}
|
||||
|
@ -54,5 +54,7 @@ public interface BrowserController {
|
||||
|
||||
boolean isIncognito();
|
||||
|
||||
boolean isProxyReady();
|
||||
|
||||
int getMenu();
|
||||
}
|
||||
|
@ -49,9 +49,11 @@ public class PreferenceManager {
|
||||
public static final String DEFAULT_BOOKMARKS = "defaultBookmarks";
|
||||
|
||||
public static final String USE_PROXY = "useProxy";
|
||||
public static final String PROXY_CHOICE = "proxyChoice";
|
||||
public static final String USE_PROXY_HOST = "useProxyHost";
|
||||
public static final String USE_PROXY_PORT = "useProxyPort";
|
||||
public static final String INITIAL_CHECK_FOR_TOR = "checkForTor";
|
||||
public static final String INITIAL_CHECK_FOR_I2P = "checkForI2P";
|
||||
}
|
||||
|
||||
private static PreferenceManager mInstance;
|
||||
@ -86,6 +88,10 @@ public class PreferenceManager {
|
||||
return mPrefs.getBoolean(Name.INITIAL_CHECK_FOR_TOR, false);
|
||||
}
|
||||
|
||||
public boolean getCheckedForI2P() {
|
||||
return mPrefs.getBoolean(Name.INITIAL_CHECK_FOR_I2P, false);
|
||||
}
|
||||
|
||||
public boolean getClearCacheExit() {
|
||||
return mPrefs.getBoolean(Name.CLEAR_CACHE_EXIT, false);
|
||||
}
|
||||
@ -226,6 +232,10 @@ public class PreferenceManager {
|
||||
return mPrefs.getBoolean(Name.USE_PROXY, false);
|
||||
}
|
||||
|
||||
public int getProxyChoice() {
|
||||
return mPrefs.getInt(Name.PROXY_CHOICE, Constants.NO_PROXY);
|
||||
}
|
||||
|
||||
public int getUserAgentChoice() {
|
||||
return mPrefs.getInt(Name.USER_AGENT, 1);
|
||||
}
|
||||
@ -266,6 +276,10 @@ public class PreferenceManager {
|
||||
putBoolean(Name.INITIAL_CHECK_FOR_TOR, check);
|
||||
}
|
||||
|
||||
public void setCheckedForI2P(boolean check) {
|
||||
putBoolean(Name.INITIAL_CHECK_FOR_I2P, check);
|
||||
}
|
||||
|
||||
public void setClearCacheExit(boolean enable) {
|
||||
putBoolean(Name.CLEAR_CACHE_EXIT, enable);
|
||||
}
|
||||
@ -394,8 +408,27 @@ public class PreferenceManager {
|
||||
putInt(Name.THEME, theme);
|
||||
}
|
||||
|
||||
public void setUseProxy(boolean enable) {
|
||||
putBoolean(Name.USE_PROXY, enable);
|
||||
/**
|
||||
* Valid choices:
|
||||
* <ul>
|
||||
* <li>{@link Constants#NO_PROXY}</li>
|
||||
* <li>{@link Constants#PROXY_ORBOT}</li>
|
||||
* <li>{@link Constants#PROXY_I2P}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param choice the proxy to use.
|
||||
*/
|
||||
public void setProxyChoice(int choice) {
|
||||
putBoolean(Name.USE_PROXY, choice != Constants.NO_PROXY);
|
||||
putInt(Name.PROXY_CHOICE, choice);
|
||||
}
|
||||
|
||||
public void setProxyHost(String proxyHost) {
|
||||
putString(Name.USE_PROXY_HOST, proxyHost);
|
||||
}
|
||||
|
||||
public void setProxyPort(int proxyPort) {
|
||||
putInt(Name.USE_PROXY_PORT, proxyPort);
|
||||
}
|
||||
|
||||
public void setUserAgentChoice(int choice) {
|
||||
|
@ -526,6 +526,12 @@ public class LightningView {
|
||||
}
|
||||
|
||||
public synchronized void reload() {
|
||||
// Check if configured proxy is available
|
||||
if (!mBrowserController.isProxyReady()) {
|
||||
// User has been notified
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWebView != null) {
|
||||
mWebView.reload();
|
||||
}
|
||||
@ -611,6 +617,12 @@ public class LightningView {
|
||||
}
|
||||
|
||||
public synchronized void loadUrl(String url) {
|
||||
// Check if configured proxy is available
|
||||
if (!mBrowserController.isProxyReady()) {
|
||||
// User has been notified
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWebView != null) {
|
||||
mWebView.loadUrl(url);
|
||||
}
|
||||
@ -815,6 +827,12 @@ public class LightningView {
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
// Check if configured proxy is available
|
||||
if (!mBrowserController.isProxyReady()) {
|
||||
// User has been notified
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mBrowserController.isIncognito()) {
|
||||
return super.shouldOverrideUrlLoading(view, url);
|
||||
}
|
||||
|
43
app/src/main/res/layout/picker_manual_proxy.xml
Normal file
43
app/src/main/res/layout/picker_manual_proxy.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingStart="4dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/host"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/proxyHost"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:inputType="text"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/port"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/proxyPort"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:inputType="number"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include layout="@layout/toolbar_settings" />
|
||||
|
||||
@ -159,33 +160,32 @@
|
||||
android:layout_marginRight="10dp"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/layoutUseOrbot"
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutProxyChoice"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/listChoiceBackgroundIndicator"
|
||||
android:minHeight="60dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingTop="10dp" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="60dp"
|
||||
android:text="@string/enable_orbot"
|
||||
android:text="@string/http_proxy"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbOrbot"
|
||||
<TextView
|
||||
android:id="@+id/proxyChoiceName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true" />
|
||||
</RelativeLayout>
|
||||
android:paddingLeft="16dp"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/light"
|
||||
tools:text="Disabled" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -158,9 +158,21 @@
|
||||
<string name="powered_by_google">Powered by Google</string>
|
||||
<string name="title_adblock">AdBlock</string>
|
||||
<string name="message_adblock">AdBlock is currently only available in the browser\'s paid version, Lightning Browser+. It is available to download on Google Play.</string>
|
||||
<string name="enable_orbot">Enable Orbot</string>
|
||||
<string name="http_proxy">HTTP proxy</string>
|
||||
<string-array name="proxy_choices_array">
|
||||
<item>None</item>
|
||||
<item>Orbot</item>
|
||||
<item>I2P</item>
|
||||
<item>Manual</item>
|
||||
</string-array>
|
||||
<string name="manual_proxy">Manual proxy</string>
|
||||
<string name="host">Host:</string>
|
||||
<string name="port">Port:</string>
|
||||
<string name="use_tor_prompt">It looks like you have Orbot installed. Do you want to use Tor?</string>
|
||||
<string name="use_i2p_prompt">It looks like you have I2P installed. Do you want to use I2P?</string>
|
||||
<string name="install_orbot">Please install Orbot in order to proxy with Tor.</string>
|
||||
<string name="i2p_not_running">I2P is not running.</string>
|
||||
<string name="i2p_tunnels_not_ready">I2P tunnels are not ready yet.</string>
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="clear_cookies_exit">Clear cookies on exit</string>
|
||||
|
Loading…
Reference in New Issue
Block a user