mirror of
https://github.com/moparisthebest/open-keychain
synced 2025-02-19 20:31:52 -05:00
orbot dialog fragments added
This commit is contained in:
parent
87d68702a9
commit
5726698763
@ -21,6 +21,7 @@ import android.app.ProgressDialog;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
@ -28,7 +29,6 @@ import android.view.View;
|
|||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import info.guardianproject.onionkit.ui.OrbotHelper;
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
||||||
@ -39,13 +39,14 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
|||||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||||
import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity;
|
import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity;
|
||||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||||
|
import org.sufficientlysecure.keychain.ui.dialog.InstallDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
|
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
|
||||||
import org.sufficientlysecure.keychain.util.ParcelableProxy;
|
|
||||||
import org.sufficientlysecure.keychain.util.Preferences;
|
import org.sufficientlysecure.keychain.util.Preferences;
|
||||||
|
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
@ -348,18 +349,33 @@ public class ImportKeysActivity extends BaseNfcActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadCallback(ImportKeysListFragment.LoaderState loaderState) {
|
public void loadCallback(final ImportKeysListFragment.LoaderState loaderState) {
|
||||||
if (loaderState instanceof ImportKeysListFragment.CloudLoaderState) {
|
if (loaderState instanceof ImportKeysListFragment.CloudLoaderState) {
|
||||||
// do the tor check
|
// do the tor check
|
||||||
OrbotHelper helper = new OrbotHelper(this);
|
// this handle will set tor to be ignored whenever a message is received
|
||||||
// TODO: Add callbacks by modifying OrbotHelper so we know if the user wants to not use Tor
|
Handler ignoreTorHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
// disables Tor until Activity is recreated
|
||||||
|
mProxyPrefs = new Preferences.ProxyPrefs(false, false, null, -1, null);
|
||||||
|
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(mProxyPrefs.torEnabled && !OrbotHelper.isOrbotInstalled(this)) {
|
||||||
|
|
||||||
|
OrbotHelper.getInstallDialogFragmentWithThirdButton(
|
||||||
|
new Messenger(ignoreTorHandler),
|
||||||
|
R.string.orbot_install_dialog_ignore_tor
|
||||||
|
).show(getSupportFragmentManager(), "orbotInstallDialog");
|
||||||
|
|
||||||
if(mProxyPrefs.torEnabled && !helper.isOrbotInstalled()) {
|
|
||||||
helper.promptToInstall(this);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(mProxyPrefs.torEnabled && !helper.isOrbotRunning()) {
|
|
||||||
helper.requestOrbotStart(this);
|
if(mProxyPrefs.torEnabled && !OrbotHelper.isOrbotRunning()) {
|
||||||
|
OrbotHelper.getOrbotStartDialogFragment(new Messenger(ignoreTorHandler),
|
||||||
|
R.string.orbot_install_dialog_ignore_tor)
|
||||||
|
.show(getSupportFragmentManager(), "orbotStartDialog");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,13 +383,6 @@ public class ImportKeysActivity extends BaseNfcActivity {
|
|||||||
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
|
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* disables use of Tor as proxy for this session
|
|
||||||
*/
|
|
||||||
private void disableTorForSession() {
|
|
||||||
mProxyPrefs = new Preferences.ProxyPrefs(false, false, null, -1, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMessage(Message message) {
|
private void handleMessage(Message message) {
|
||||||
if (message.arg1 == ServiceProgressHandler.MessageStatus.OKAY.ordinal()) {
|
if (message.arg1 == ServiceProgressHandler.MessageStatus.OKAY.ordinal()) {
|
||||||
// get returned data bundle
|
// get returned data bundle
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -35,7 +36,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import info.guardianproject.onionkit.ui.OrbotHelper;
|
|
||||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify;
|
|||||||
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
|
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Preferences;
|
import org.sufficientlysecure.keychain.util.Preferences;
|
||||||
|
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
|
|
||||||
public static final String ACTION_PREFS_CLOUD = "org.sufficientlysecure.keychain.ui.PREFS_CLOUD";
|
public static final String ACTION_PREFS_CLOUD = "org.sufficientlysecure.keychain.ui.PREFS_CLOUD";
|
||||||
public static final String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
|
public static final String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
|
||||||
|
public static final String ACTION_PREFS_PROXY = "org.sufficientlysecure.keychain.ui.PREFS_PROXY";
|
||||||
|
|
||||||
public static final int REQUEST_CODE_KEYSERVER_PREF = 0x00007005;
|
public static final int REQUEST_CODE_KEYSERVER_PREF = 0x00007005;
|
||||||
|
|
||||||
@ -64,61 +66,74 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
setupToolbar();
|
setupToolbar();
|
||||||
|
|
||||||
String action = getIntent().getAction();
|
String action = getIntent().getAction();
|
||||||
|
if (action == null) return;
|
||||||
|
|
||||||
if (action != null && action.equals(ACTION_PREFS_CLOUD)) {
|
switch(action) {
|
||||||
addPreferencesFromResource(R.xml.cloud_search_prefs);
|
case ACTION_PREFS_CLOUD: {
|
||||||
|
addPreferencesFromResource(R.xml.cloud_search_prefs);
|
||||||
|
|
||||||
mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
|
mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
|
||||||
mKeyServerPreference.setSummary(keyserverSummary(this));
|
mKeyServerPreference.setSummary(keyserverSummary(this));
|
||||||
mKeyServerPreference
|
mKeyServerPreference
|
||||||
.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
Intent intent = new Intent(SettingsActivity.this,
|
Intent intent = new Intent(SettingsActivity.this,
|
||||||
SettingsKeyServerActivity.class);
|
SettingsKeyServerActivity.class);
|
||||||
intent.putExtra(SettingsKeyServerActivity.EXTRA_KEY_SERVERS,
|
intent.putExtra(SettingsKeyServerActivity.EXTRA_KEY_SERVERS,
|
||||||
sPreferences.getKeyServers());
|
sPreferences.getKeyServers());
|
||||||
startActivityForResult(intent, REQUEST_CODE_KEYSERVER_PREF);
|
startActivityForResult(intent, REQUEST_CODE_KEYSERVER_PREF);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
initializeSearchKeyserver(
|
initializeSearchKeyserver(
|
||||||
(CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYSERVER)
|
(CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYSERVER)
|
||||||
);
|
);
|
||||||
initializeSearchKeybase(
|
initializeSearchKeybase(
|
||||||
(CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYBASE)
|
(CheckBoxPreference) findPreference(Constants.Pref.SEARCH_KEYBASE)
|
||||||
);
|
);
|
||||||
|
|
||||||
} else if (action != null && action.equals(ACTION_PREFS_ADV)) {
|
break;
|
||||||
addPreferencesFromResource(R.xml.adv_preferences);
|
|
||||||
|
|
||||||
initializePassphraseCacheSubs(
|
|
||||||
(CheckBoxPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_SUBS));
|
|
||||||
|
|
||||||
initializePassphraseCacheTtl(
|
|
||||||
(IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
|
|
||||||
|
|
||||||
int[] valueIds = new int[]{
|
|
||||||
CompressionAlgorithmTags.UNCOMPRESSED,
|
|
||||||
CompressionAlgorithmTags.ZIP,
|
|
||||||
CompressionAlgorithmTags.ZLIB,
|
|
||||||
CompressionAlgorithmTags.BZIP2,
|
|
||||||
};
|
|
||||||
String[] entries = new String[]{
|
|
||||||
getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
|
|
||||||
"ZIP (" + getString(R.string.compression_fast) + ")",
|
|
||||||
"ZLIB (" + getString(R.string.compression_fast) + ")",
|
|
||||||
"BZIP2 (" + getString(R.string.compression_very_slow) + ")",};
|
|
||||||
String[] values = new String[valueIds.length];
|
|
||||||
for (int i = 0; i < values.length; ++i) {
|
|
||||||
values[i] = "" + valueIds[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeUseDefaultYubiKeyPin(
|
case ACTION_PREFS_ADV: {
|
||||||
(CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
|
addPreferencesFromResource(R.xml.adv_preferences);
|
||||||
|
|
||||||
initializeUseNumKeypadForYubiKeyPin(
|
initializePassphraseCacheSubs(
|
||||||
(CheckBoxPreference) findPreference(Constants.Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN));
|
(CheckBoxPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_SUBS));
|
||||||
|
|
||||||
|
initializePassphraseCacheTtl(
|
||||||
|
(IntegerListPreference) findPreference(Constants.Pref.PASSPHRASE_CACHE_TTL));
|
||||||
|
|
||||||
|
int[] valueIds = new int[]{
|
||||||
|
CompressionAlgorithmTags.UNCOMPRESSED,
|
||||||
|
CompressionAlgorithmTags.ZIP,
|
||||||
|
CompressionAlgorithmTags.ZLIB,
|
||||||
|
CompressionAlgorithmTags.BZIP2,
|
||||||
|
};
|
||||||
|
String[] entries = new String[]{
|
||||||
|
getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
|
||||||
|
"ZIP (" + getString(R.string.compression_fast) + ")",
|
||||||
|
"ZLIB (" + getString(R.string.compression_fast) + ")",
|
||||||
|
"BZIP2 (" + getString(R.string.compression_very_slow) + ")",};
|
||||||
|
String[] values = new String[valueIds.length];
|
||||||
|
for (int i = 0; i < values.length; ++i) {
|
||||||
|
values[i] = "" + valueIds[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeUseDefaultYubiKeyPin(
|
||||||
|
(CheckBoxPreference) findPreference(Constants.Pref.USE_DEFAULT_YUBIKEY_PIN));
|
||||||
|
|
||||||
|
initializeUseNumKeypadForYubiKeyPin(
|
||||||
|
(CheckBoxPreference) findPreference(Constants.Pref.USE_NUMKEYPAD_FOR_YUBIKEY_PIN));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ACTION_PREFS_PROXY: {
|
||||||
|
new ProxyPrefsFragment.Initializer(this).initialize();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,163 +292,199 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class ProxyPrefsFragment extends PreferenceFragment {
|
public static class ProxyPrefsFragment extends PreferenceFragment {
|
||||||
private CheckBoxPreference mUseTor;
|
|
||||||
private CheckBoxPreference mUseNormalProxy;
|
|
||||||
private EditTextPreference mProxyHost;
|
|
||||||
private EditTextPreference mProxyPort;
|
|
||||||
private ListPreference mProxyType;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
// makes android's preference framework write to our file instead of default
|
|
||||||
// This allows us to use the "persistent" attribute to simplify code
|
|
||||||
sPreferences.setPreferenceManagerFileAndMode(getPreferenceManager());
|
|
||||||
|
|
||||||
// Load the preferences from an XML resource
|
new Initializer(this).initialize();
|
||||||
addPreferencesFromResource(R.xml.proxy_prefs);
|
|
||||||
|
|
||||||
mUseTor = (CheckBoxPreference) findPreference(Constants.Pref.USE_TOR_PROXY);
|
|
||||||
mUseNormalProxy = (CheckBoxPreference) findPreference(Constants.Pref.USE_NORMAL_PROXY);
|
|
||||||
mProxyHost = (EditTextPreference) findPreference(Constants.Pref.PROXY_HOST);
|
|
||||||
mProxyPort = (EditTextPreference) findPreference(Constants.Pref.PROXY_PORT);
|
|
||||||
mProxyType = (ListPreference) findPreference(Constants.Pref.PROXY_TYPE);
|
|
||||||
|
|
||||||
initializeUseTorPref();
|
|
||||||
initializeUseNormalProxyPref();
|
|
||||||
initializeEditTextPreferences();
|
|
||||||
initializeProxyTypePreference();
|
|
||||||
|
|
||||||
if (mUseTor.isChecked()) disableNormalProxyPrefs();
|
|
||||||
else if (mUseNormalProxy.isChecked()) disableUseTorPrefs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeUseTorPref() {
|
public static class Initializer {
|
||||||
mUseTor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
private CheckBoxPreference mUseTor;
|
||||||
@Override
|
private CheckBoxPreference mUseNormalProxy;
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
private EditTextPreference mProxyHost;
|
||||||
if ((Boolean)newValue) {
|
private EditTextPreference mProxyPort;
|
||||||
OrbotHelper orbotHelper = new OrbotHelper(ProxyPrefsFragment.this.getActivity());
|
private ListPreference mProxyType;
|
||||||
boolean installed = orbotHelper.isOrbotInstalled();
|
private PreferenceActivity mActivity;
|
||||||
if (!installed) {
|
private PreferenceFragment mFragment;
|
||||||
Log.d(Constants.TAG, "Prompting to install Tor");
|
|
||||||
orbotHelper.promptToInstall(ProxyPrefsFragment.this.getActivity());
|
public Initializer(PreferenceFragment fragment) {
|
||||||
// don't let the user check the box until he's installed orbot
|
mFragment = fragment;
|
||||||
return false;
|
}
|
||||||
} else {
|
|
||||||
disableNormalProxyPrefs();
|
public Initializer(PreferenceActivity activity) {
|
||||||
// let the enable tor box be checked
|
mActivity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Preference automaticallyFindPreference(String key) {
|
||||||
|
if(mFragment != null) {
|
||||||
|
return mFragment.findPreference(key);
|
||||||
|
} else {
|
||||||
|
return mActivity.findPreference(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize() {
|
||||||
|
// makes android's preference framework write to our file instead of default
|
||||||
|
// This allows us to use the "persistent" attribute to simplify code
|
||||||
|
if (mFragment != null) {
|
||||||
|
Preferences.setPreferenceManagerFileAndMode(mFragment.getPreferenceManager());
|
||||||
|
// Load the preferences from an XML resource
|
||||||
|
mFragment.addPreferencesFromResource(R.xml.proxy_prefs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Preferences.setPreferenceManagerFileAndMode(mActivity.getPreferenceManager());
|
||||||
|
// Load the preferences from an XML resource
|
||||||
|
mActivity.addPreferencesFromResource(R.xml.proxy_prefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
mUseTor = (CheckBoxPreference) automaticallyFindPreference(Constants.Pref.USE_TOR_PROXY);
|
||||||
|
mUseNormalProxy = (CheckBoxPreference) automaticallyFindPreference(Constants.Pref.USE_NORMAL_PROXY);
|
||||||
|
mProxyHost = (EditTextPreference) automaticallyFindPreference(Constants.Pref.PROXY_HOST);
|
||||||
|
mProxyPort = (EditTextPreference) automaticallyFindPreference(Constants.Pref.PROXY_PORT);
|
||||||
|
mProxyType = (ListPreference) automaticallyFindPreference(Constants.Pref.PROXY_TYPE);
|
||||||
|
initializeUseTorPref();
|
||||||
|
initializeUseNormalProxyPref();
|
||||||
|
initializeEditTextPreferences();
|
||||||
|
initializeProxyTypePreference();
|
||||||
|
|
||||||
|
if (mUseTor.isChecked()) disableNormalProxyPrefs();
|
||||||
|
else if (mUseNormalProxy.isChecked()) disableUseTorPrefs();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeUseTorPref() {
|
||||||
|
mUseTor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
Activity activity = mFragment != null ? mFragment.getActivity() : mActivity;
|
||||||
|
if ((Boolean)newValue) {
|
||||||
|
boolean installed = OrbotHelper.isOrbotInstalled(activity);
|
||||||
|
if (!installed) {
|
||||||
|
Log.d(Constants.TAG, "Prompting to install Tor");
|
||||||
|
OrbotHelper.getPreferenceInstallDialogFragment().show(activity.getFragmentManager(),
|
||||||
|
"installDialog");
|
||||||
|
// don't let the user check the box until he's installed orbot
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
disableNormalProxyPrefs();
|
||||||
|
// let the enable tor box be checked
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we're unchecking Tor, so enable other proxy
|
||||||
|
enableNormalProxyPrefs();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
});
|
||||||
// we're unchecking Tor, so enable other proxy
|
}
|
||||||
enableNormalProxyPrefs();
|
|
||||||
|
private void initializeUseNormalProxyPref() {
|
||||||
|
mUseNormalProxy.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
if ((Boolean) newValue) {
|
||||||
|
disableUseTorPrefs();
|
||||||
|
} else {
|
||||||
|
enableUseTorPrefs();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeUseNormalProxyPref() {
|
private void initializeEditTextPreferences() {
|
||||||
mUseNormalProxy.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
mProxyHost.setSummary(mProxyHost.getText());
|
||||||
@Override
|
mProxyPort.setSummary(mProxyPort.getText());
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
if ((Boolean) newValue) {
|
|
||||||
disableUseTorPrefs();
|
|
||||||
} else {
|
|
||||||
enableUseTorPrefs();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeEditTextPreferences() {
|
mProxyHost.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
mProxyHost.setSummary(mProxyHost.getText());
|
@Override
|
||||||
mProxyPort.setSummary(mProxyPort.getText());
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
Activity activity = mFragment != null ? mFragment.getActivity() : mActivity;
|
||||||
mProxyHost.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
if (TextUtils.isEmpty((String) newValue)) {
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
if (TextUtils.isEmpty((String) newValue)) {
|
|
||||||
Notify.create(
|
|
||||||
ProxyPrefsFragment.this.getActivity(),
|
|
||||||
R.string.pref_proxy_host_err_invalid,
|
|
||||||
Notify.Style.ERROR
|
|
||||||
).show();
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
mProxyHost.setSummary((CharSequence) newValue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mProxyPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
try {
|
|
||||||
int port = Integer.parseInt((String) newValue);
|
|
||||||
if(port < 0 || port > 65535) {
|
|
||||||
Notify.create(
|
Notify.create(
|
||||||
ProxyPrefsFragment.this.getActivity(),
|
activity,
|
||||||
|
R.string.pref_proxy_host_err_invalid,
|
||||||
|
Notify.Style.ERROR
|
||||||
|
).show();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
mProxyHost.setSummary((CharSequence) newValue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mProxyPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
Activity activity = mFragment != null ? mFragment.getActivity() : mActivity;
|
||||||
|
try {
|
||||||
|
int port = Integer.parseInt((String) newValue);
|
||||||
|
if(port < 0 || port > 65535) {
|
||||||
|
Notify.create(
|
||||||
|
activity,
|
||||||
|
R.string.pref_proxy_port_err_invalid,
|
||||||
|
Notify.Style.ERROR
|
||||||
|
).show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// no issues, save port
|
||||||
|
mProxyPort.setSummary("" + port);
|
||||||
|
return true;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Notify.create(
|
||||||
|
activity,
|
||||||
R.string.pref_proxy_port_err_invalid,
|
R.string.pref_proxy_port_err_invalid,
|
||||||
Notify.Style.ERROR
|
Notify.Style.ERROR
|
||||||
).show();
|
).show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// no issues, save port
|
|
||||||
mProxyPort.setSummary("" + port);
|
|
||||||
return true;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Notify.create(
|
|
||||||
ProxyPrefsFragment.this.getActivity(),
|
|
||||||
R.string.pref_proxy_port_err_invalid,
|
|
||||||
Notify.Style.ERROR
|
|
||||||
).show();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
private void initializeProxyTypePreference() {
|
||||||
|
mProxyType.setSummary(mProxyType.getEntry());
|
||||||
|
|
||||||
|
mProxyType.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
CharSequence entry = mProxyType.getEntries()[mProxyType.findIndexOfValue((String) newValue)];
|
||||||
|
mProxyType.setSummary(entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableNormalProxyPrefs() {
|
||||||
|
mUseNormalProxy.setChecked(false);
|
||||||
|
mUseNormalProxy.setEnabled(false);
|
||||||
|
mProxyHost.setEnabled(false);
|
||||||
|
mProxyPort.setEnabled(false);
|
||||||
|
mProxyType.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableNormalProxyPrefs() {
|
||||||
|
mUseNormalProxy.setEnabled(true);
|
||||||
|
mProxyHost.setEnabled(true);
|
||||||
|
mProxyPort.setEnabled(true);
|
||||||
|
mProxyType.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableUseTorPrefs() {
|
||||||
|
mUseTor.setChecked(false);
|
||||||
|
mUseTor.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableUseTorPrefs() {
|
||||||
|
mUseTor.setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeProxyTypePreference() {
|
|
||||||
mProxyType.setSummary(mProxyType.getEntry());
|
|
||||||
|
|
||||||
mProxyType.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
CharSequence entry = mProxyType.getEntries()[mProxyType.findIndexOfValue((String) newValue)];
|
|
||||||
mProxyType.setSummary(entry);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableNormalProxyPrefs() {
|
|
||||||
mUseNormalProxy.setChecked(false);
|
|
||||||
mUseNormalProxy.setEnabled(false);
|
|
||||||
mProxyHost.setEnabled(false);
|
|
||||||
mProxyPort.setEnabled(false);
|
|
||||||
mProxyType.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enableNormalProxyPrefs() {
|
|
||||||
mUseNormalProxy.setEnabled(true);
|
|
||||||
mProxyHost.setEnabled(true);
|
|
||||||
mProxyPort.setEnabled(true);
|
|
||||||
mProxyType.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableUseTorPrefs() {
|
|
||||||
mUseTor.setChecked(false);
|
|
||||||
mUseTor.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enableUseTorPrefs() {
|
|
||||||
mUseTor.setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.ui.dialog;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
public class InstallDialogFragment extends DialogFragment {
|
||||||
|
private static final String ARG_MESSENGER = "messenger";
|
||||||
|
private static final String ARG_TITLE = "title";
|
||||||
|
private static final String ARG_MESSAGE = "message";
|
||||||
|
private static final String ARG_MIDDLE_BUTTON = "middleButton";
|
||||||
|
private static final String ARG_INSTALL_PATH = "installPath";
|
||||||
|
private static final String ARG_USE_MIDDLE_BUTTON = "useMiddleButton";
|
||||||
|
|
||||||
|
public static final String PLAY_STORE_PATH = "market://search?q=pname:";
|
||||||
|
|
||||||
|
public static final int MESSAGE_MIDDLE_CLICKED = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a dialog which prompts the user to install an application. Consists of two default buttons ("Install"
|
||||||
|
* and "Cancel") and an optional third button. Callbacks are provided only for the middle button, if set.
|
||||||
|
*
|
||||||
|
* @param messenger required only for callback from middle button if it has been set
|
||||||
|
* @param title
|
||||||
|
* @param message content of dialog
|
||||||
|
* @param packageToInstall package name of application to install
|
||||||
|
* @param middleButton if not null, adds a third button to the app with a call back
|
||||||
|
* @return The dialog to display
|
||||||
|
*/
|
||||||
|
public static InstallDialogFragment newInstance(Messenger messenger, int title, int message,
|
||||||
|
String packageToInstall, int middleButton, boolean useMiddleButton) {
|
||||||
|
InstallDialogFragment frag = new InstallDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putParcelable(ARG_MESSENGER, messenger);
|
||||||
|
|
||||||
|
args.putInt(ARG_TITLE, title);
|
||||||
|
args.putInt(ARG_MESSAGE, message);
|
||||||
|
args.putInt(ARG_MIDDLE_BUTTON, middleButton);
|
||||||
|
args.putString(ARG_INSTALL_PATH, PLAY_STORE_PATH + packageToInstall);
|
||||||
|
args.putBoolean(ARG_USE_MIDDLE_BUTTON, useMiddleButton);
|
||||||
|
|
||||||
|
frag.setArguments(args);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To create a DialogFragment with only two buttons
|
||||||
|
*
|
||||||
|
* @param title
|
||||||
|
* @param message
|
||||||
|
* @param packageToInstall
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static InstallDialogFragment newInstance(int title, int message,
|
||||||
|
String packageToInstall) {
|
||||||
|
return newInstance(null, title, message, packageToInstall, -1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
|
||||||
|
final Messenger messenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||||
|
|
||||||
|
final int title = getArguments().getInt(ARG_TITLE);
|
||||||
|
final int message = getArguments().getInt(ARG_MESSAGE);
|
||||||
|
final int middleButton = getArguments().getInt(ARG_MIDDLE_BUTTON);
|
||||||
|
final String installPath = getArguments().getString(ARG_INSTALL_PATH);
|
||||||
|
final boolean useMiddleButton = getArguments().getBoolean(ARG_USE_MIDDLE_BUTTON);
|
||||||
|
|
||||||
|
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(activity);
|
||||||
|
|
||||||
|
builder.setTitle(title).setMessage(message);
|
||||||
|
|
||||||
|
builder.setNegativeButton(R.string.orbot_install_dialog_cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setPositiveButton(R.string.orbot_install_dialog_install,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Uri uri = Uri.parse(installPath);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
activity.startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (useMiddleButton) {
|
||||||
|
builder.setNeutralButton(middleButton,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what=MESSAGE_MIDDLE_CLICKED;
|
||||||
|
try {
|
||||||
|
messenger.send(msg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.show();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.ui.dialog;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* displays a dialog asking the user to enable Tor
|
||||||
|
*/
|
||||||
|
public class OrbotStartDialogFragment extends DialogFragment {
|
||||||
|
private static final String ARG_MESSENGER = "messenger";
|
||||||
|
private static final String ARG_TITLE = "title";
|
||||||
|
private static final String ARG_MESSAGE = "message";
|
||||||
|
private static final String ARG_MIDDLE_BUTTON = "middleButton";
|
||||||
|
|
||||||
|
public static final int MESSAGE_MIDDLE_BUTTON = 1;
|
||||||
|
|
||||||
|
public static OrbotStartDialogFragment newInstance(Messenger messenger, int title, int message, int middleButton) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putParcelable(ARG_MESSENGER, messenger);
|
||||||
|
args.putInt(ARG_TITLE, title);
|
||||||
|
args.putInt(ARG_MESSAGE, message);
|
||||||
|
args.putInt(ARG_MIDDLE_BUTTON, middleButton);
|
||||||
|
|
||||||
|
OrbotStartDialogFragment fragment = new OrbotStartDialogFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
final Messenger messenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||||
|
int title = getArguments().getInt(ARG_TITLE);
|
||||||
|
final int message = getArguments().getInt(ARG_MESSAGE);
|
||||||
|
int middleButton = getArguments().getInt(ARG_MIDDLE_BUTTON);
|
||||||
|
|
||||||
|
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(getActivity());
|
||||||
|
builder.setTitle(title).setMessage(message);
|
||||||
|
|
||||||
|
builder.setNegativeButton(R.string.orbot_start_dialog_cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setPositiveButton(R.string.orbot_start_dialog_start, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
getActivity().startActivityForResult(OrbotHelper.getOrbotStartIntent(), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setNeutralButton(middleButton, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = MESSAGE_MIDDLE_BUTTON;
|
||||||
|
try {
|
||||||
|
messenger.send(msg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return builder.show();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.ui.dialog;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.app.DialogFragment;
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
public class PreferenceInstallDialogFragment extends DialogFragment {
|
||||||
|
private static final String ARG_MESSENGER = "messenger";
|
||||||
|
private static final String ARG_TITLE = "title";
|
||||||
|
private static final String ARG_MESSAGE = "message";
|
||||||
|
private static final String ARG_MIDDLE_BUTTON = "middleButton";
|
||||||
|
private static final String ARG_INSTALL_PATH = "installPath";
|
||||||
|
private static final String ARG_USE_MIDDLE_BUTTON = "installPath";
|
||||||
|
|
||||||
|
public static final String PLAY_STORE_PATH = "market://search?q=pname:";
|
||||||
|
|
||||||
|
public static final int MESSAGE_MIDDLE_CLICKED = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a dialog which prompts the user to install an application. Consists of two default buttons ("Install"
|
||||||
|
* and "Cancel") and an optional third button. Callbacks are provided only for the middle button, if set.
|
||||||
|
*
|
||||||
|
* @param messenger required only for callback from middle button if it has been set
|
||||||
|
* @param title
|
||||||
|
* @param message content of dialog
|
||||||
|
* @param packageToInstall package name of application to install
|
||||||
|
* @param middleButton if not null, adds a third button to the app with a call back
|
||||||
|
* @return The dialog to display
|
||||||
|
*/
|
||||||
|
public static PreferenceInstallDialogFragment newInstance(Messenger messenger, int title, int message,
|
||||||
|
String packageToInstall, int middleButton, boolean useMiddleButton) {
|
||||||
|
PreferenceInstallDialogFragment frag = new PreferenceInstallDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putParcelable(ARG_MESSENGER, messenger);
|
||||||
|
|
||||||
|
args.putInt(ARG_TITLE, title);
|
||||||
|
args.putInt(ARG_MESSAGE, message);
|
||||||
|
args.putInt(ARG_MIDDLE_BUTTON, middleButton);
|
||||||
|
args.putString(ARG_INSTALL_PATH, PLAY_STORE_PATH + packageToInstall);
|
||||||
|
args.putBoolean(ARG_USE_MIDDLE_BUTTON, useMiddleButton);
|
||||||
|
|
||||||
|
frag.setArguments(args);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To create a DialogFragment with only two buttons
|
||||||
|
*
|
||||||
|
* @param title
|
||||||
|
* @param message
|
||||||
|
* @param packageToInstall
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static PreferenceInstallDialogFragment newInstance(int title, int message,
|
||||||
|
String packageToInstall) {
|
||||||
|
return newInstance(null, title, message, packageToInstall, -1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
|
||||||
|
final Messenger messenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||||
|
|
||||||
|
final String title = getArguments().getString(ARG_TITLE);
|
||||||
|
final String message = getArguments().getString(ARG_MESSAGE);
|
||||||
|
final String installPath = getArguments().getString(ARG_INSTALL_PATH);
|
||||||
|
final String middleButton = getArguments().getString(ARG_MIDDLE_BUTTON);
|
||||||
|
final boolean useMiddleButton = getArguments().getBoolean(ARG_USE_MIDDLE_BUTTON);
|
||||||
|
|
||||||
|
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(activity);
|
||||||
|
|
||||||
|
builder.setTitle(title).setMessage(message);
|
||||||
|
|
||||||
|
builder.setNegativeButton(R.string.orbot_install_dialog_cancel,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setPositiveButton(R.string.orbot_install_dialog_install,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Uri uri = Uri.parse(installPath);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||||
|
activity.startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (useMiddleButton) {
|
||||||
|
builder.setNeutralButton(middleButton,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what=MESSAGE_MIDDLE_CLICKED;
|
||||||
|
try {
|
||||||
|
messenger.send(msg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.show();
|
||||||
|
}
|
||||||
|
}
|
@ -36,6 +36,9 @@ public class ParcelableProxy implements Parcelable {
|
|||||||
|
|
||||||
public ParcelableProxy(String hostName, int port, Proxy.Type type) {
|
public ParcelableProxy(String hostName, int port, Proxy.Type type) {
|
||||||
mProxyHost = hostName;
|
mProxyHost = hostName;
|
||||||
|
|
||||||
|
if (hostName == null) return; // represents a null proxy
|
||||||
|
|
||||||
mProxyPort = port;
|
mProxyPort = port;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -51,6 +54,8 @@ public class ParcelableProxy implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Proxy getProxy() {
|
public Proxy getProxy() {
|
||||||
|
if(mProxyHost == null) return null;
|
||||||
|
|
||||||
Proxy.Type type = null;
|
Proxy.Type type = null;
|
||||||
switch (mProxyType) {
|
switch (mProxyType) {
|
||||||
case TYPE_HTTP:
|
case TYPE_HTTP:
|
||||||
|
@ -23,12 +23,10 @@ import android.content.SharedPreferences;
|
|||||||
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import info.guardianproject.onionkit.ui.OrbotHelper;
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Constants.Pref;
|
import org.sufficientlysecure.keychain.Constants.Pref;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -65,7 +63,7 @@ public class Preferences {
|
|||||||
updateSharedPreferences(context);
|
updateSharedPreferences(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPreferenceManagerFileAndMode(PreferenceManager manager) {
|
public static void setPreferenceManagerFileAndMode(PreferenceManager manager) {
|
||||||
manager.setSharedPreferencesName(PREF_FILE_NAME);
|
manager.setSharedPreferencesName(PREF_FILE_NAME);
|
||||||
manager.setSharedPreferencesMode(PREF_FILE_MODE);
|
manager.setSharedPreferencesMode(PREF_FILE_MODE);
|
||||||
}
|
}
|
||||||
@ -245,32 +243,14 @@ public class Preferences {
|
|||||||
return mSharedPreferences.getBoolean(Constants.Pref.USE_NORMAL_PROXY, false);
|
return mSharedPreferences.getBoolean(Constants.Pref.USE_NORMAL_PROXY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUseNormalProxy(boolean use) {
|
|
||||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
|
||||||
editor.putBoolean(Constants.Pref.USE_NORMAL_PROXY, use);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getUseTorProxy() {
|
public boolean getUseTorProxy() {
|
||||||
return mSharedPreferences.getBoolean(Constants.Pref.USE_TOR_PROXY, false);
|
return mSharedPreferences.getBoolean(Constants.Pref.USE_TOR_PROXY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUseTorProxy(boolean use) {
|
|
||||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
|
||||||
editor.putBoolean(Constants.Pref.USE_TOR_PROXY, use);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProxyHost() {
|
public String getProxyHost() {
|
||||||
return mSharedPreferences.getString(Constants.Pref.PROXY_HOST, null);
|
return mSharedPreferences.getString(Constants.Pref.PROXY_HOST, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProxyHost(String host) {
|
|
||||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
|
||||||
editor.putString(Constants.Pref.PROXY_HOST, host);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* we store port as String for easy interfacing with EditTextPreference, but return it as an integer
|
* we store port as String for easy interfacing with EditTextPreference, but return it as an integer
|
||||||
*
|
*
|
||||||
@ -334,7 +314,7 @@ public class Preferences {
|
|||||||
public ProxyPrefs(boolean torEnabled, boolean normalPorxyEnabled, String hostName, int port, Proxy.Type type) {
|
public ProxyPrefs(boolean torEnabled, boolean normalPorxyEnabled, String hostName, int port, Proxy.Type type) {
|
||||||
this.torEnabled = torEnabled;
|
this.torEnabled = torEnabled;
|
||||||
this.normalPorxyEnabled = normalPorxyEnabled;
|
this.normalPorxyEnabled = normalPorxyEnabled;
|
||||||
if(!torEnabled && !normalPorxyEnabled) this.parcelableProxy = null;
|
if(!torEnabled && !normalPorxyEnabled) this.parcelableProxy = new ParcelableProxy(null, -1, null);
|
||||||
else this.parcelableProxy = new ParcelableProxy(hostName, port, type);
|
else this.parcelableProxy = new ParcelableProxy(hostName, port, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,53 @@
|
|||||||
|
/* This is the license for Orlib, a free software project to
|
||||||
|
provide anonymity on the Internet from a Google Android smartphone.
|
||||||
|
|
||||||
package info.guardianproject.onionkit.ui;
|
For more information about Orlib, see https://guardianproject.info/
|
||||||
|
|
||||||
|
If you got this file as a part of a larger bundle, there may be other
|
||||||
|
license terms that you should be aware of.
|
||||||
|
===============================================================================
|
||||||
|
Orlib is distributed under this license (aka the 3-clause BSD license)
|
||||||
|
|
||||||
|
Copyright (c) 2009-2010, Nathan Freitas, The Guardian Project
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
* Neither the names of the copyright owners nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*****
|
||||||
|
Orlib contains a binary distribution of the JSocks library:
|
||||||
|
http://code.google.com/p/jsocks-mirror/
|
||||||
|
which is licensed under the GNU Lesser General Public License:
|
||||||
|
http://www.gnu.org/licenses/lgpl.html
|
||||||
|
|
||||||
|
*****
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.util.orbot;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
@ -7,42 +55,37 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.os.Messenger;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
import info.guardianproject.onionkit.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.ui.dialog.InstallDialogFragment;
|
||||||
|
import org.sufficientlysecure.keychain.ui.dialog.OrbotStartDialogFragment;
|
||||||
|
import org.sufficientlysecure.keychain.ui.dialog.PreferenceInstallDialogFragment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is taken from the NetCipher library: https://github.com/guardianproject/NetCipher/
|
||||||
|
*/
|
||||||
public class OrbotHelper {
|
public class OrbotHelper {
|
||||||
|
|
||||||
private final static int REQUEST_CODE_STATUS = 100;
|
|
||||||
|
|
||||||
public final static String ORBOT_PACKAGE_NAME = "org.torproject.android";
|
public final static String ORBOT_PACKAGE_NAME = "org.torproject.android";
|
||||||
public final static String TOR_BIN_PATH = "/data/data/org.torproject.android/app_bin/tor";
|
public final static String TOR_BIN_PATH = "/data/data/org.torproject.android/app_bin/tor";
|
||||||
|
|
||||||
public final static String ACTION_START_TOR = "org.torproject.android.START_TOR";
|
public final static String ACTION_START_TOR = "org.torproject.android.START_TOR";
|
||||||
public final static String ACTION_REQUEST_HS = "org.torproject.android.REQUEST_HS_PORT";
|
|
||||||
public final static int HS_REQUEST_CODE = 9999;
|
|
||||||
|
|
||||||
private Context mContext = null;
|
public static boolean isOrbotRunning()
|
||||||
|
|
||||||
public OrbotHelper(Context context)
|
|
||||||
{
|
|
||||||
mContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOrbotRunning()
|
|
||||||
{
|
{
|
||||||
int procId = TorServiceUtils.findProcessId(TOR_BIN_PATH);
|
int procId = TorServiceUtils.findProcessId(TOR_BIN_PATH);
|
||||||
|
|
||||||
return (procId != -1);
|
return (procId != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOrbotInstalled()
|
public static boolean isOrbotInstalled(Context context)
|
||||||
{
|
{
|
||||||
return isAppInstalled(ORBOT_PACKAGE_NAME);
|
return isAppInstalled(ORBOT_PACKAGE_NAME, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAppInstalled(String uri) {
|
private static boolean isAppInstalled(String uri, Context context) {
|
||||||
PackageManager pm = mContext.getPackageManager();
|
PackageManager pm = context.getPackageManager();
|
||||||
boolean installed = false;
|
boolean installed = false;
|
||||||
try {
|
try {
|
||||||
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
|
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
|
||||||
@ -53,66 +96,32 @@ public class OrbotHelper {
|
|||||||
return installed;
|
return installed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void promptToInstall(Activity activity)
|
/**
|
||||||
|
* hack to get around teh fact that PreferenceActivity still supports only android.app.DialogFragment
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static android.app.DialogFragment getPreferenceInstallDialogFragment()
|
||||||
{
|
{
|
||||||
String uriMarket = activity.getString(R.string.market_orbot);
|
return PreferenceInstallDialogFragment.newInstance(R.string.orbot_install_dialog_title,
|
||||||
// show dialog - install from market, f-droid or direct APK
|
R.string.orbot_install_dialog_content, ORBOT_PACKAGE_NAME);
|
||||||
showDownloadDialog(activity, activity.getString(R.string.install_orbot_),
|
|
||||||
activity.getString(R.string.you_must_have_orbot),
|
|
||||||
activity.getString(R.string.yes), activity.getString(R.string.no), uriMarket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AlertDialog showDownloadDialog(final Activity activity,
|
public static DialogFragment getInstallDialogFragment()
|
||||||
CharSequence stringTitle, CharSequence stringMessage, CharSequence stringButtonYes,
|
{
|
||||||
CharSequence stringButtonNo, final String uriString) {
|
return InstallDialogFragment.newInstance(R.string.orbot_install_dialog_title,
|
||||||
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
|
R.string.orbot_install_dialog_content, ORBOT_PACKAGE_NAME);
|
||||||
downloadDialog.setTitle(stringTitle);
|
|
||||||
downloadDialog.setMessage(stringMessage);
|
|
||||||
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
Uri uri = Uri.parse(uriString);
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
|
||||||
activity.startActivity(intent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return downloadDialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestOrbotStart(final Activity activity)
|
public static DialogFragment getInstallDialogFragmentWithThirdButton(Messenger messenger, int middleButton)
|
||||||
{
|
{
|
||||||
|
return InstallDialogFragment.newInstance(messenger, R.string.orbot_install_dialog_title,
|
||||||
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
|
R.string.orbot_install_dialog_content, ORBOT_PACKAGE_NAME, middleButton, true);
|
||||||
downloadDialog.setTitle(R.string.start_orbot_);
|
|
||||||
downloadDialog
|
|
||||||
.setMessage(R.string.orbot_doesn_t_appear_to_be_running_would_you_like_to_start_it_up_and_connect_to_tor_);
|
|
||||||
downloadDialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
activity.startActivityForResult(getOrbotStartIntent(), 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
downloadDialog.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialogInterface, int i) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
downloadDialog.show();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestHiddenServiceOnPort(Activity activity, int port)
|
public static DialogFragment getOrbotStartDialogFragment(Messenger messenger, int middleButton) {
|
||||||
{
|
return OrbotStartDialogFragment.newInstance(messenger, R.string.orbot_start_dialog_title, R.string.orbot_start_dialog_content,
|
||||||
Intent intent = new Intent(ACTION_REQUEST_HS);
|
middleButton);
|
||||||
intent.setPackage(ORBOT_PACKAGE_NAME);
|
|
||||||
intent.putExtra("hs_port", port);
|
|
||||||
|
|
||||||
activity.startActivityForResult(intent, HS_REQUEST_CODE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Intent getOrbotStartIntent() {
|
public static Intent getOrbotStartIntent() {
|
||||||
|
@ -1,86 +1,73 @@
|
|||||||
/* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */
|
/* This is the license for Orlib, a free software project to
|
||||||
/* See LICENSE for licensing information */
|
provide anonymity on the Internet from a Google Android smartphone.
|
||||||
|
|
||||||
package info.guardianproject.onionkit.ui;
|
For more information about Orlib, see https://guardianproject.info/
|
||||||
|
|
||||||
|
If you got this file as a part of a larger bundle, there may be other
|
||||||
|
license terms that you should be aware of.
|
||||||
|
===============================================================================
|
||||||
|
Orlib is distributed under this license (aka the 3-clause BSD license)
|
||||||
|
|
||||||
|
Copyright (c) 2009-2010, Nathan Freitas, The Guardian Project
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
* Neither the names of the copyright owners nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*****
|
||||||
|
Orlib contains a binary distribution of the JSocks library:
|
||||||
|
http://code.google.com/p/jsocks-mirror/
|
||||||
|
which is licensed under the GNU Lesser General Public License:
|
||||||
|
http://www.gnu.org/licenses/lgpl.html
|
||||||
|
|
||||||
|
*****
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.util.orbot;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is taken from the NetCipher library: https://github.com/guardianproject/NetCipher/
|
||||||
|
*/
|
||||||
|
|
||||||
public class TorServiceUtils {
|
public class TorServiceUtils {
|
||||||
|
|
||||||
private final static String TAG = "TorUtils";
|
private final static String TAG = "TorUtils";
|
||||||
// various console cmds
|
// various console cmds
|
||||||
public final static String SHELL_CMD_CHMOD = "chmod";
|
|
||||||
public final static String SHELL_CMD_KILL = "kill -9";
|
|
||||||
public final static String SHELL_CMD_RM = "rm";
|
|
||||||
public final static String SHELL_CMD_PS = "ps";
|
public final static String SHELL_CMD_PS = "ps";
|
||||||
public final static String SHELL_CMD_PIDOF = "pidof";
|
public final static String SHELL_CMD_PIDOF = "pidof";
|
||||||
|
|
||||||
public final static String CHMOD_EXE_VALUE = "700";
|
|
||||||
|
|
||||||
public static boolean isRootPossible()
|
|
||||||
{
|
|
||||||
|
|
||||||
StringBuilder log = new StringBuilder();
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// Check if Superuser.apk exists
|
|
||||||
File fileSU = new File("/system/app/Superuser.apk");
|
|
||||||
if (fileSU.exists())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
fileSU = new File("/system/app/superuser.apk");
|
|
||||||
if (fileSU.exists())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
fileSU = new File("/system/bin/su");
|
|
||||||
if (fileSU.exists())
|
|
||||||
{
|
|
||||||
String[] cmd = {
|
|
||||||
"su"
|
|
||||||
};
|
|
||||||
int exitCode = TorServiceUtils.doShellCommand(cmd, log, false, true);
|
|
||||||
if (exitCode != 0)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for 'su' binary
|
|
||||||
String[] cmd = {
|
|
||||||
"which su"
|
|
||||||
};
|
|
||||||
int exitCode = TorServiceUtils.doShellCommand(cmd, log, false, true);
|
|
||||||
|
|
||||||
if (exitCode == 0) {
|
|
||||||
Log.d(TAG, "root exists, but not sure about permissions");
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
// this means that there is no root to be had (normally) so we won't
|
|
||||||
// log anything
|
|
||||||
Log.e(TAG, "Error checking for root access", e);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Error checking for root access", e);
|
|
||||||
// this means that there is no root to be had (normally)
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.e(TAG, "Could not acquire root permissions");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int findProcessId(String command)
|
public static int findProcessId(String command)
|
||||||
{
|
{
|
||||||
int procId = -1;
|
int procId = -1;
|
||||||
@ -175,60 +162,4 @@ public class TorServiceUtils {
|
|||||||
return procId;
|
return procId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int doShellCommand(String[] cmds, StringBuilder log, boolean runAsRoot,
|
|
||||||
boolean waitFor) throws Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
Process proc = null;
|
|
||||||
int exitCode = -1;
|
|
||||||
|
|
||||||
if (runAsRoot)
|
|
||||||
proc = Runtime.getRuntime().exec("su");
|
|
||||||
else
|
|
||||||
proc = Runtime.getRuntime().exec("sh");
|
|
||||||
|
|
||||||
OutputStreamWriter out = new OutputStreamWriter(proc.getOutputStream());
|
|
||||||
|
|
||||||
for (int i = 0; i < cmds.length; i++)
|
|
||||||
{
|
|
||||||
// TorService.logMessage("executing shell cmd: " + cmds[i] +
|
|
||||||
// "; runAsRoot=" + runAsRoot + ";waitFor=" + waitFor);
|
|
||||||
|
|
||||||
out.write(cmds[i]);
|
|
||||||
out.write("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
out.flush();
|
|
||||||
out.write("exit\n");
|
|
||||||
out.flush();
|
|
||||||
|
|
||||||
if (waitFor)
|
|
||||||
{
|
|
||||||
|
|
||||||
final char buf[] = new char[10];
|
|
||||||
|
|
||||||
// Consume the "stdout"
|
|
||||||
InputStreamReader reader = new InputStreamReader(proc.getInputStream());
|
|
||||||
int read = 0;
|
|
||||||
while ((read = reader.read(buf)) != -1) {
|
|
||||||
if (log != null)
|
|
||||||
log.append(buf, 0, read);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consume the "stderr"
|
|
||||||
reader = new InputStreamReader(proc.getErrorStream());
|
|
||||||
read = 0;
|
|
||||||
while ((read = reader.read(buf)) != -1) {
|
|
||||||
if (log != null)
|
|
||||||
log.append(buf, 0, read);
|
|
||||||
}
|
|
||||||
|
|
||||||
exitCode = proc.waitFor();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return exitCode;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -167,21 +167,38 @@
|
|||||||
<string name="pref_keybase_summary">"Search keys on keybase.io"</string>
|
<string name="pref_keybase_summary">"Search keys on keybase.io"</string>
|
||||||
|
|
||||||
<!-- Proxy Preferences -->
|
<!-- Proxy Preferences -->
|
||||||
<string name="pref_proxy_tor_label">"Enable Tor"</string>
|
<string name="pref_proxy_tor_title">"Enable Tor"</string>
|
||||||
<string name="pref_proxy_tor_summary">"Requires Orbot to be installed"</string>
|
<string name="pref_proxy_tor_summary">"Requires Orbot to be installed"</string>
|
||||||
<string name="pref_proxy_normal">"Enable other proxy"</string>
|
<string name="pref_proxy_normal_title">"Enable other proxy"</string>
|
||||||
<string name="pref_proxy_host_label">"Proxy Host"</string>
|
<string name="pref_proxy_host_title">"Proxy Host"</string>
|
||||||
<string name="pref_proxy_host_err_invalid">"Proxy host cannot be empty"</string>
|
<string name="pref_proxy_host_err_invalid">"Proxy host cannot be empty"</string>
|
||||||
<string name="pref_proxy_port_label">"Proxy Port"</string>
|
<string name="pref_proxy_port_title">"Proxy Port"</string>
|
||||||
<string name="pref_proxy_port_err_invalid">"Invalid port number entered"</string>
|
<string name="pref_proxy_port_err_invalid">"Invalid port number entered"</string>
|
||||||
<string name="pref_proxy_type_label">"Proxy Type"</string>
|
<string name="pref_proxy_type_title">"Proxy Type"</string>
|
||||||
|
|
||||||
<!-- proxy type choices -->
|
<!-- proxy type choices and values -->
|
||||||
<string name="pref_proxy_type_choice_http">"HTTP"</string>
|
<string name="pref_proxy_type_choice_http">"HTTP"</string>
|
||||||
<string name="pref_proxy_type_choice_socks">"SOCKS"</string>
|
<string name="pref_proxy_type_choice_socks">"SOCKS"</string>
|
||||||
<string name="pref_proxy_type_value_http">"proxyHttp"</string>
|
<string name="pref_proxy_type_value_http">"proxyHttp"</string>
|
||||||
<string name="pref_proxy_type_value_socks">"proxySocks"</string>
|
<string name="pref_proxy_type_value_socks">"proxySocks"</string>
|
||||||
|
|
||||||
|
<!-- OrbotHelper strings -->
|
||||||
|
<!-- InstallDialogFragment strings -->
|
||||||
|
<string name="orbot_install_dialog_title">Install Orbot to use Tor?</string>
|
||||||
|
<string name="orbot_install_dialog_install">"Install"</string>
|
||||||
|
<string name="orbot_install_dialog_content">You must have Orbot installed and activated to proxy traffic through it. Would you like to install it?</string>
|
||||||
|
<string name="orbot_install_dialog_cancel">"Cancel"</string>
|
||||||
|
<string name="orbot_install_dialog_ignore_tor">"Don\'t use Tor"</string>
|
||||||
|
|
||||||
|
<!-- StartOrbotDialogFragment strings -->
|
||||||
|
<string name="orbot_start_dialog_title">Start Orbot?</string>
|
||||||
|
<string name="orbot_start_dialog_content">"Orbot doesn\'t appear to be running. Would you like to start it up and connect to Tor?"</string>
|
||||||
|
<string name="orbot_start_btn">"Start Orbot"</string>
|
||||||
|
<string name="orbot_start_dialog_start">"Start Orbot"</string>
|
||||||
|
<string name="orbot_start_dialog_cancel">"Cancel"</string>
|
||||||
|
<string name="orbot_start_dialog_ignore_tor">"Don\'t use Tor"</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="user_id_no_name">"<no name>"</string>
|
<string name="user_id_no_name">"<no name>"</string>
|
||||||
<string name="none">"<none>"</string>
|
<string name="none">"<none>"</string>
|
||||||
|
|
||||||
|
@ -3,17 +3,17 @@
|
|||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="useTorProxy"
|
android:key="useTorProxy"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:title="@string/pref_proxy_tor_label"
|
android:title="@string/pref_proxy_tor_title"
|
||||||
android:summary="@string/pref_proxy_tor_summary" />
|
android:summary="@string/pref_proxy_tor_summary" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="useNormalProxy"
|
android:key="useNormalProxy"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:title="@string/pref_proxy_normal" />
|
android:title="@string/pref_proxy_normal_title" />
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:key="proxyHost"
|
android:key="proxyHost"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:defaultValue="127.0.0.1"
|
android:defaultValue="127.0.0.1"
|
||||||
android:title="@string/pref_proxy_host_label"
|
android:title="@string/pref_proxy_host_title"
|
||||||
android:cursorVisible="true"
|
android:cursorVisible="true"
|
||||||
android:textCursorDrawable="@null"
|
android:textCursorDrawable="@null"
|
||||||
android:inputType="textEmailAddress"/>
|
android:inputType="textEmailAddress"/>
|
||||||
@ -21,7 +21,7 @@
|
|||||||
android:key="proxyPort"
|
android:key="proxyPort"
|
||||||
android:defaultValue="8118"
|
android:defaultValue="8118"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:title="@string/pref_proxy_port_label"
|
android:title="@string/pref_proxy_port_title"
|
||||||
android:textCursorDrawable="@null"
|
android:textCursorDrawable="@null"
|
||||||
android:inputType="number" />
|
android:inputType="number" />
|
||||||
<ListPreference
|
<ListPreference
|
||||||
@ -30,5 +30,5 @@
|
|||||||
android:defaultValue="@string/pref_proxy_type_value_http"
|
android:defaultValue="@string/pref_proxy_type_value_http"
|
||||||
android:key="proxyType"
|
android:key="proxyType"
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:title="@string/pref_proxy_type_label" />
|
android:title="@string/pref_proxy_type_title" />
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user