added OperationHelper to ImportKeysActivity

This commit is contained in:
Adithya Abraham Philip 2015-06-21 00:12:33 +05:30
parent 1ce2877b41
commit de50b3becb
9 changed files with 153 additions and 94 deletions

View File

@ -672,6 +672,9 @@
android:name=".ui.LogDisplayActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_log_display" />
<activity
android:name=".ui.OrbotRequiredDialogActivity"
android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".ui.ConsolidateDialogActivity"
android:theme="@android:style/Theme.NoDisplay" />

View File

@ -145,7 +145,7 @@ public class EditKeyFragment extends NewCryptoOperationFragment<SaveKeyringParce
super.onActivityCreated(savedInstanceState);
super.setOperationHelper(
new OperationHelper<SaveKeyringParcel, OperationResult>(this) {
new OperationHelper<SaveKeyringParcel, OperationResult>(this, R.string.progress_building_key) {
@Override
public SaveKeyringParcel createOperationInput() {

View File

@ -47,6 +47,8 @@ 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.operation.ImportOperationHelper;
import org.sufficientlysecure.keychain.util.operation.OperationHelper;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
import java.io.IOException;
@ -87,14 +89,14 @@ public class ImportKeysActivity extends BaseNfcActivity {
private Fragment mTopFragment;
private View mImportButton;
private Preferences.ProxyPrefs mProxyPrefs;
private Preferences.ProxyPrefs mProxyPrefs; // set only when an explicit proxy is to be used
private OperationHelper mImportOperationHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mProxyPrefs = Preferences.getPreferences(this).getProxyPrefs();
mImportButton = findViewById(R.id.import_import);
mImportButton.setOnClickListener(new OnClickListener() {
@Override
@ -111,6 +113,12 @@ public class ImportKeysActivity extends BaseNfcActivity {
setContentView(R.layout.import_keys_activity);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mImportOperationHelper != null) mImportOperationHelper.handleActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
protected void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction();
Bundle extras = intent.getExtras();
@ -351,6 +359,8 @@ public class ImportKeysActivity extends BaseNfcActivity {
public void loadCallback(final ImportKeysListFragment.LoaderState loaderState) {
if (loaderState instanceof ImportKeysListFragment.CloudLoaderState) {
Preferences.ProxyPrefs proxyPrefs =
mProxyPrefs == null ? Preferences.getPreferences(this).getProxyPrefs() : mProxyPrefs;
// do the tor check
// this handle will set tor to be ignored whenever a message is received
Runnable ignoreTor = new Runnable() {
@ -361,22 +371,15 @@ public class ImportKeysActivity extends BaseNfcActivity {
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
}
};
if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, mProxyPrefs, this)) {
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor, proxyPrefs, this)) {
mListFragment.loadNew(loaderState, proxyPrefs.parcelableProxy);
}
} else if (loaderState instanceof ImportKeysListFragment.BytesLoaderState) { // must always be true
mListFragment.loadNew(loaderState, mProxyPrefs.parcelableProxy);
}
}
private void handleMessage(Message message) {
if (message.arg1 == ServiceProgressHandler.MessageStatus.OKAY.ordinal()) {
// get returned data bundle
Bundle returnData = message.getData();
if (returnData == null) {
return;
}
final ImportKeyResult result = returnData.getParcelable(OperationResult.EXTRA_RESULT);
private void handleResult(ImportKeyResult result) {
if (result == null) {
Log.e(Constants.TAG, "result == null");
return;
@ -398,7 +401,6 @@ public class ImportKeysActivity extends BaseNfcActivity {
result.createNotify(ImportKeysActivity.this)
.show((ViewGroup) findViewById(R.id.import_snackbar));
}
}
/**
@ -412,20 +414,9 @@ public class ImportKeysActivity extends BaseNfcActivity {
return;
}
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(this) {
@Override
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
ImportKeysActivity.this.handleMessage(message);
}
};
// Send all information needed to service to import key in other thread
Intent intent = new Intent(this, KeychainNewService.class);
ImportKeyringParcel operationInput = null;
CryptoInputParcel cryptoInput = null;
ArrayList<ParcelableKeyRing> keyList = null;
String keyserver = null;
CryptoInputParcel cryptoInput = new CryptoInputParcel();
ImportKeysListFragment.LoaderState ls = mListFragment.getLoaderState();
if (ls instanceof ImportKeysListFragment.BytesLoaderState) {
@ -444,9 +435,6 @@ public class ImportKeysActivity extends BaseNfcActivity {
new ParcelableFileCache<>(this, "key_import.pcl");
cache.writeCache(selectedEntries);
operationInput = new ImportKeyringParcel(null, null);
cryptoInput = new CryptoInputParcel();
} catch (IOException e) {
Log.e(Constants.TAG, "Problem writing cache file", e);
Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR)
@ -456,40 +444,32 @@ public class ImportKeysActivity extends BaseNfcActivity {
ImportKeysListFragment.CloudLoaderState sls = (ImportKeysListFragment.CloudLoaderState) ls;
// get selected key entries
ArrayList<ParcelableKeyRing> keys = new ArrayList<>();
keyList = new ArrayList<>();
{
// change the format into ParcelableKeyRing
ArrayList<ImportKeysListEntry> entries = mListFragment.getSelectedEntries();
for (ImportKeysListEntry entry : entries) {
keys.add(new ParcelableKeyRing(
keyList.add(new ParcelableKeyRing(
entry.getFingerprintHex(), entry.getKeyIdHex(), entry.getExtraData())
);
}
}
operationInput = new ImportKeyringParcel(keys, sls.mCloudPrefs.keyserver);
keyserver = sls.mCloudPrefs.keyserver;
if (mProxyPrefs != null) { // if not null means we have specified an explicit proxy
cryptoInput = new CryptoInputParcel(mProxyPrefs.parcelableProxy);
} else {
cryptoInput = new CryptoInputParcel();
}
}
intent.putExtra(KeychainNewService.EXTRA_OPERATION_INPUT, operationInput);
intent.putExtra(KeychainNewService.EXTRA_CRYPTO_INPUT, cryptoInput);
mImportOperationHelper = new ImportOperationHelper(this, R.string.progress_importing, keyList, keyserver) {
@Override
protected void onCryptoOperationSuccess(ImportKeyResult result) {
handleResult(result);
}
};
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(serviceHandler);
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
// show progress dialog
serviceHandler.showProgressDialog(
getString(R.string.progress_importing),
ProgressDialog.STYLE_HORIZONTAL, true
);
// start service with intent
startService(intent);
mImportOperationHelper.cryptoOperation(cryptoInput);
}
@Override

View File

@ -18,10 +18,46 @@
package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Messenger;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.text.InputType;
import android.text.method.PasswordTransformationMethod;
import android.view.*;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.remote.CryptoInputParcelCacheService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.dialog.OrbotStartDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
@ -30,24 +66,40 @@ import org.sufficientlysecure.keychain.util.orbot.OrbotHelper;
*/
public class OrbotRequiredDialogActivity extends FragmentActivity {
public final static String RESULT_IGNORE_TOR = "ignore_tor";
public static final String RESULT_IGNORE_TOR = "result_ignore_tor";
@Override
public void onCreate(Bundle savedInstanceState) {
Runnable ignoreTor = new Runnable() {
@Override
public void run() {
Intent data = new Intent();
data.putExtra(RESULT_IGNORE_TOR, true);
setResult(RESULT_OK, data);
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showDialog();
}
if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor,
Preferences.getPreferences(this).getProxyPrefs(), this)) {
Intent data = new Intent();
data.putExtra(RESULT_IGNORE_TOR, false);
setResult(RESULT_OK, data);
}
/**
* Shows passphrase dialog to cache a new passphrase the user enters for using it later for
* encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks
* for a symmetric passphrase
*/
public void showDialog() {
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
public void run() {
Runnable ignoreTor = new Runnable() {
@Override
public void run() {
Intent intent = new Intent();
intent.putExtra(RESULT_IGNORE_TOR, true);
setResult(RESULT_OK, intent);
finish();
}
};
if (OrbotHelper.isOrbotInRequiredState(R.string.orbot_ignore_tor, ignoreTor,
OrbotRequiredDialogActivity.this)) {
// no action required after all
Intent intent = new Intent();
intent.putExtra(RESULT_IGNORE_TOR, true);
setResult(RESULT_OK, intent);
finish();
}
}
});
}
}

View File

@ -18,6 +18,7 @@
package org.sufficientlysecure.keychain.ui.dialog;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
@ -26,6 +27,7 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.view.ContextThemeWrapper;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;
@ -62,8 +64,14 @@ public class OrbotStartDialogFragment extends DialogFragment {
int title = getArguments().getInt(ARG_TITLE);
final int message = getArguments().getInt(ARG_MESSAGE);
int middleButton = getArguments().getInt(ARG_MIDDLE_BUTTON);
final Activity activity = getActivity();
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(getActivity());
// if the dialog is displayed from the application class, design is missing.
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
ContextThemeWrapper theme = new ContextThemeWrapper(activity,
R.style.Theme_AppCompat_Light_Dialog);
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(theme);
builder.setTitle(title).setMessage(message);
builder.setNegativeButton(R.string.orbot_start_dialog_cancel, new DialogInterface.OnClickListener() {

View File

@ -68,6 +68,10 @@ public class ParcelableProxy implements Parcelable {
return new Proxy(type, new InetSocketAddress(mProxyHost, mProxyPort));
}
public static ParcelableProxy getForNoProxy() {
return new ParcelableProxy(null, -1, null);
}
protected ParcelableProxy(Parcel in) {
mProxyHost = in.readString();
mProxyPort = in.readInt();

View File

@ -29,8 +29,9 @@ public abstract class ImportOperationHelper extends OperationHelper<ImportKeyrin
private ArrayList<ParcelableKeyRing> mKeyList;
private String mKeyserver;
public ImportOperationHelper(FragmentActivity activity, ArrayList<ParcelableKeyRing> keyList, String keyserver) {
super(activity);
public ImportOperationHelper(FragmentActivity activity, int progressMessageString,
ArrayList<ParcelableKeyRing> keyList, String keyserver) {
super(activity, progressMessageString);
mKeyList = keyList;
mKeyserver = keyserver;
}

View File

@ -41,6 +41,7 @@ import org.sufficientlysecure.keychain.ui.OrbotRequiredDialogActivity;
import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableProxy;
/**
* Designed to be intergrated into activities or fragments used for CryptoOperations.
@ -54,6 +55,8 @@ public abstract class OperationHelper<T extends Parcelable, S extends OperationR
public static final int REQUEST_CODE_NFC = 0x00008002;
public static final int REQUEST_ENABLE_ORBOT = 0x00008004;
private int mProgressMessageString;
private FragmentActivity mActivity;
private Fragment mFragment;
@ -64,9 +67,10 @@ public abstract class OperationHelper<T extends Parcelable, S extends OperationR
*
* @param activity
*/
public OperationHelper(FragmentActivity activity) {
public OperationHelper(FragmentActivity activity, int progressMessageString) {
mActivity = activity;
mUseFragment = false;
mProgressMessageString = progressMessageString;
}
/**
@ -74,10 +78,11 @@ public abstract class OperationHelper<T extends Parcelable, S extends OperationR
*
* @param fragment
*/
public OperationHelper(Fragment fragment) {
public OperationHelper(Fragment fragment, int progressMessageString) {
mFragment = fragment;
mActivity = fragment.getActivity();
mUseFragment = true;
mProgressMessageString = progressMessageString;
}
private void initiateInputActivity(RequiredInputParcel requiredInput) {
@ -124,7 +129,7 @@ public abstract class OperationHelper<T extends Parcelable, S extends OperationR
}
/**
* Attempts the result of an activity started by this helper. Returns true if request code is recognized,
* Attempts the result of an activity started by this helper. Returns true if requestCode is recognized,
* false otherwise.
*
* @param requestCode
@ -163,7 +168,7 @@ public abstract class OperationHelper<T extends Parcelable, S extends OperationR
case REQUEST_ENABLE_ORBOT: {
if (resultCode == Activity.RESULT_OK && data != null) {
if (data.getBooleanExtra(OrbotRequiredDialogActivity.RESULT_IGNORE_TOR, false)) {
cryptoOperation(new CryptoInputParcel());
cryptoOperation(new CryptoInputParcel(ParcelableProxy.getForNoProxy()));
}
return true;
}
@ -226,14 +231,14 @@ public abstract class OperationHelper<T extends Parcelable, S extends OperationR
}
};
saveHandler.showProgressDialog(
mActivity.getString(mProgressMessageString),
ProgressDialog.STYLE_HORIZONTAL, false);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
saveHandler.showProgressDialog(
mActivity.getString(R.string.progress_building_key),
ProgressDialog.STYLE_HORIZONTAL, false);
mActivity.startService(intent);
}

View File

@ -135,7 +135,9 @@ public class OrbotHelper {
}
/**
* checks if Tor is enabled and if it is, that Orbot is installed and runnign. Generates appropriate dialogs.
* checks if Tor is enabled and if it is, that Orbot is installed and running. Generates appropriate dialogs.
* Convenience function for isOrbotinRequiredState(int, Runnable, FragmentActivity) by checking for tor being
* enabled internally
*
* @param middleButton resourceId of string to display as the middle button of install and enable dialogs
* @param middleButtonRunnable runnable to be executed if the user clicks on the middle button
@ -145,6 +147,25 @@ public class OrbotHelper {
*/
public static boolean isOrbotInRequiredState(int middleButton, final Runnable middleButtonRunnable,
Preferences.ProxyPrefs proxyPrefs, FragmentActivity fragmentActivity) {
if (!proxyPrefs.torEnabled) {
return true;
} else {
return isOrbotInRequiredState(middleButton, middleButtonRunnable, fragmentActivity);
}
}
/**
* checks if Orbot is installed and running. Generates appropriate dialogs.
*
* @param middleButton resourceId of string to display as the middle button of install and enable dialogs
* @param middleButtonRunnable runnable to be executed if the user clicks on the middle button
* @param fragmentActivity
* @return true if Tor is not enabled or Tor is enabled and Orbot is installed and running, else false
*/
public static boolean isOrbotInRequiredState(int middleButton, final Runnable middleButtonRunnable,
FragmentActivity fragmentActivity) {
Handler ignoreTorHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@ -153,10 +174,6 @@ public class OrbotHelper {
}
};
if (!proxyPrefs.torEnabled) {
return true;
}
if (!OrbotHelper.isOrbotInstalled(fragmentActivity)) {
OrbotHelper.getInstallDialogFragmentWithThirdButton(
@ -176,15 +193,4 @@ public class OrbotHelper {
return true;
}
}
// TODO: PHILIP return an Intent to required dialog activity
public static Intent getRequiredIntent(Context context) {
if (!isOrbotInstalled(context)) {
}
if (!isOrbotRunning()) {
}
return null;
}
}