Merge pull request #1424 from open-keychain/import-proxy

Shifted proxy logic to ImportKeysListCloudLoader
This commit is contained in:
Dominik Schürmann 2015-07-08 11:41:46 +02:00
commit 7b35f9b07a
9 changed files with 126 additions and 67 deletions

View file

@ -20,7 +20,9 @@ package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
public class GetKeyResult extends OperationResult {
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
public class GetKeyResult extends InputPendingResult {
public int mNonPgpPartsCount;
@ -36,6 +38,10 @@ public class GetKeyResult extends OperationResult {
super(result, log);
}
public GetKeyResult(OperationLog log, RequiredInputParcel requiredInput) {
super(log, requiredInput);
}
public static final int RESULT_ERROR_NO_VALID_KEYS = RESULT_ERROR + 8;
public static final int RESULT_ERROR_NO_PGP_PARTS = RESULT_ERROR + 16;
public static final int RESULT_ERROR_QUERY_TOO_SHORT = RESULT_ERROR + 32;

View file

@ -42,9 +42,7 @@ import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.NfcListenerFragment;
import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
public class CreateYubiKeyImportFragment
@ -134,18 +132,7 @@ public class CreateYubiKeyImportFragment
view.findViewById(R.id.button_search).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final Preferences.ProxyPrefs proxyPrefs = Preferences.getPreferences(getActivity()).getProxyPrefs();
Runnable ignoreTor = new Runnable() {
@Override
public void run() {
refreshSearch(new ParcelableProxy(null, -1, null));
}
};
if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs,
getActivity())) {
refreshSearch(proxyPrefs.parcelableProxy);
}
refreshSearch();
}
});
@ -184,10 +171,9 @@ public class CreateYubiKeyImportFragment
}
}
public void refreshSearch(ParcelableProxy parcelableProxy) {
// TODO: PHILIP verify proxy implementation in YubiKey parts
public void refreshSearch() {
mListFragment.loadNew(new ImportKeysListFragment.CloudLoaderState("0x" + mNfcFingerprint,
Preferences.getPreferences(getActivity()).getCloudSearchPrefs()), parcelableProxy);
Preferences.getPreferences(getActivity()).getCloudSearchPrefs()));
}
public void importKey() {
@ -226,19 +212,7 @@ public class CreateYubiKeyImportFragment
setData();
Preferences.ProxyPrefs proxyPrefs = Preferences.getPreferences(getActivity()).getProxyPrefs();
Runnable ignoreTor = new Runnable() {
@Override
public void run() {
refreshSearch(new ParcelableProxy(null, -1, null));
}
};
if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs,
getActivity())) {
refreshSearch(proxyPrefs.parcelableProxy);
}
refreshSearch();
}
@Override

View file

@ -53,9 +53,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
public abstract class DecryptFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

View file

@ -44,7 +44,6 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
import java.io.IOException;
import java.util.ArrayList;
@ -90,16 +89,12 @@ public class ImportKeysActivity extends BaseNfcActivity
private ArrayList<ParcelableKeyRing> mKeyList;
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mOperationHelper;
private Preferences.ProxyPrefs mProxyPrefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setFullScreenDialogClose(Activity.RESULT_CANCELED, true);
mProxyPrefs = Preferences.getPreferences(this).getProxyPrefs();
mImportButton = findViewById(R.id.import_import);
mImportButton.setOnClickListener(new OnClickListener() {
@Override
@ -233,8 +228,8 @@ public class ImportKeysActivity extends BaseNfcActivity
// we just set the keyserver
startCloudFragment(savedInstanceState, null, false, keyserver);
// we don't set the keyserver for ImportKeysListFragment since
// it'll be taken care of by ImportKeysCloudFragment when the user clicks
// the search button
// it'll be set in the cloudSearchPrefs of ImportKeysCloudFragment
// which is used when the user clicks on the search button
startListFragment(savedInstanceState, null, null, null, null);
} else {
// we allow our users to edit the query if they wish
@ -356,23 +351,7 @@ public class ImportKeysActivity extends BaseNfcActivity
}
public void loadCallback(final ImportKeysListFragment.LoaderState loaderState) {
if (loaderState instanceof ImportKeysListFragment.CloudLoaderState) {
// do the tor check
// this handle will set tor to be ignored whenever a message is received
Runnable ignoreTor = new Runnable() {
@Override
public void run() {
// disables Tor until Activity is recreated
mProxyPrefs = new Preferences.ProxyPrefs(false, false, null, -1, null);
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
}
};
if (OrbotHelper.putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, mProxyPrefs, this)) {
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
}
} else if (loaderState instanceof ImportKeysListFragment.BytesLoaderState) { // must always be true
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
}
mListFragment.loadNew(loaderState);
}
private void handleMessage(Message message) {

View file

@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
@ -34,6 +35,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListCloudLoader;
@ -43,6 +45,7 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
@ -63,9 +66,9 @@ public class ImportKeysListFragment extends ListFragment implements
private Activity mActivity;
private ImportKeysAdapter mAdapter;
private ParcelableProxy mParcelableProxy;
private LoaderState mLoaderState;
private ParcelableProxy mProxy;
private static final int LOADER_ID_BYTES = 0;
private static final int LOADER_ID_CLOUD = 1;
@ -73,6 +76,8 @@ public class ImportKeysListFragment extends ListFragment implements
private LongSparseArray<ParcelableKeyRing> mCachedKeyData;
private boolean mNonInteractive;
private boolean mShowingOrbotDialog;
public LoaderState getLoaderState() {
return mLoaderState;
}
@ -261,8 +266,7 @@ public class ImportKeysListFragment extends ListFragment implements
mAdapter.notifyDataSetChanged();
}
public void loadNew(LoaderState loaderState, ParcelableProxy proxy) {
mProxy = proxy;
public void loadNew(LoaderState loaderState) {
mLoaderState = loaderState;
@ -306,7 +310,8 @@ public class ImportKeysListFragment extends ListFragment implements
}
case LOADER_ID_CLOUD: {
CloudLoaderState ls = (CloudLoaderState) mLoaderState;
return new ImportKeysListCloudLoader(getActivity(), ls.mServerQuery, ls.mCloudPrefs, mProxy);
return new ImportKeysListCloudLoader(getActivity(), ls.mServerQuery, ls.mCloudPrefs,
mParcelableProxy);
}
default:
@ -354,6 +359,46 @@ public class ImportKeysListFragment extends ListFragment implements
if (getKeyResult.success()) {
// No error
} else if (getKeyResult.isPending()) {
if (getKeyResult.getRequiredInputParcel().mType ==
RequiredInputParcel.RequiredInputType.ENABLE_ORBOT) {
if (mShowingOrbotDialog) {
// to prevent dialogs stacking
return;
}
// this is because we can't commit fragment dialogs in onLoadFinished
Runnable showOrbotDialog = new Runnable() {
@Override
public void run() {
final Runnable ignoreTor = new Runnable() {
@Override
public void run() {
mParcelableProxy = ParcelableProxy
.getForNoProxy();
mShowingOrbotDialog = false;
restartLoaders();
}
};
final Runnable dialogDismiss = new Runnable() {
@Override
public void run() {
mShowingOrbotDialog = false;
}
};
if (OrbotHelper.putOrbotInRequiredState(
ignoreTor, dialogDismiss, getActivity())) {
// looks like we didn't have to show the
// dialog after all
restartLoaders();
}
}
};
new Handler().post(showOrbotDialog );
mShowingOrbotDialog = true;
}
} else {
getKeyResult.createNotify(getActivity()).show();
}

View file

@ -44,9 +44,7 @@ import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
import java.util.ArrayList;
import java.util.Locale;

View file

@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.ui.base.BaseActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
/**
* Sends the selected public key to a keyserver

View file

@ -18,6 +18,7 @@
package org.sufficientlysecure.keychain.ui.adapter;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.content.AsyncTaskLoader;
import org.sufficientlysecure.keychain.Constants;
@ -26,9 +27,11 @@ import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.Keyserver;
import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
import java.util.ArrayList;
@ -44,13 +47,21 @@ public class ImportKeysListCloudLoader
private ArrayList<ImportKeysListEntry> mEntryList = new ArrayList<>();
private AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper;
/**
* Pass a parcelableProxy to specify an explicit proxy, otherwise will fetch from preferences
*
* @param context
* @param serverQuery
* @param cloudPrefs
* @param parcelableProxy
*/
public ImportKeysListCloudLoader(Context context, String serverQuery, Preferences.CloudSearchPrefs cloudPrefs,
ParcelableProxy proxy) {
@Nullable ParcelableProxy parcelableProxy) {
super(context);
mContext = context;
mServerQuery = serverQuery;
mCloudPrefs = cloudPrefs;
mParcelableProxy = proxy;
mParcelableProxy = parcelableProxy;
}
@Override
@ -99,11 +110,30 @@ public class ImportKeysListCloudLoader
* Query keyserver
*/
private void queryServer(boolean enforceFingerprint) {
ParcelableProxy parcelableProxy;
if (mParcelableProxy == null) {
// no explicit proxy specified, fetch from preferences
if (OrbotHelper.isOrbotInRequiredState(mContext)) {
parcelableProxy = Preferences.getPreferences(mContext).getProxyPrefs()
.parcelableProxy;
} else {
// user needs to enable/install orbot
mEntryList.clear();
GetKeyResult pendingResult = new GetKeyResult(null,
RequiredInputParcel.createOrbotRequiredOperation());
mEntryListWrapper = new AsyncTaskResultWrapper<>(mEntryList, pendingResult);
return;
}
} else {
parcelableProxy = mParcelableProxy;
}
try {
ArrayList<ImportKeysListEntry> searchResult = CloudSearch.search(
mServerQuery,
mCloudPrefs,
mParcelableProxy != null ? mParcelableProxy.getProxy() : null
parcelableProxy.getProxy()
);
mEntryList.clear();

View file

@ -130,6 +130,13 @@ public class OrbotHelper {
return intent;
}
/**
* checks preferences to see if Orbot is required, and if yes, if it is installed and running
*
* @param context used to retrieve preferences
* @return false if Tor is selected proxy and Orbot is not installed or running, true
* otherwise
*/
public static boolean isOrbotInRequiredState(Context context) {
Preferences.ProxyPrefs proxyPrefs = Preferences.getPreferences(context).getProxyPrefs();
if (!proxyPrefs.torEnabled) {
@ -219,4 +226,27 @@ public class OrbotHelper {
return putOrbotInRequiredState(middleButton, middleButtonRunnable, emptyRunnable,
proxyPrefs, fragmentActivity);
}
/**
* generates a standard Orbot install/enable dialog if necessary, based on proxy settings in
* preferences
*
* @param ignoreTorRunnable run when the "Ignore Tor" button is pressed
* @param fragmentActivity used to start the activ
* @return
*/
public static boolean putOrbotInRequiredState(Runnable ignoreTorRunnable,
FragmentActivity fragmentActivity) {
return putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTorRunnable,
Preferences.getPreferences(fragmentActivity).getProxyPrefs(), fragmentActivity);
}
public static boolean putOrbotInRequiredState(Runnable ignoreTorRunnable,
Runnable dismissDialogRunnable,
FragmentActivity fragmentActivity) {
return putOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTorRunnable,
dismissDialogRunnable,
Preferences.getPreferences(fragmentActivity).getProxyPrefs(),
fragmentActivity);
}
}