diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml
index 75d94ae69..171267933 100644
--- a/OpenKeychain/src/main/AndroidManifest.xml
+++ b/OpenKeychain/src/main/AndroidManifest.xml
@@ -672,6 +672,9 @@
android:name=".ui.LogDisplayActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_log_display" />
+
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
index d3ec0f2cc..f395699a2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
@@ -145,7 +145,7 @@ public class EditKeyFragment extends NewCryptoOperationFragment(this) {
+ new OperationHelper(this, R.string.progress_building_key) {
@Override
public SaveKeyringParcel createOperationInput() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index f3c11a785..874128f95 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -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 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 keys = new ArrayList<>();
+ keyList = new ArrayList<>();
{
// change the format into ParcelableKeyRing
ArrayList 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
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java
index 25fab7938..117f2fef4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/OrbotRequiredDialogActivity.java
@@ -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();
+ }
+ }
+ });
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java
index 4736eddca..4da2db15d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/OrbotStartDialogFragment.java
@@ -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() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java
index 4898e7f1a..36d9564dd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableProxy.java
@@ -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();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/ImportOperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/ImportOperationHelper.java
index 7b3af0af5..4c3747f47 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/ImportOperationHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/ImportOperationHelper.java
@@ -29,8 +29,9 @@ public abstract class ImportOperationHelper extends OperationHelper mKeyList;
private String mKeyserver;
- public ImportOperationHelper(FragmentActivity activity, ArrayList keyList, String keyserver) {
- super(activity);
+ public ImportOperationHelper(FragmentActivity activity, int progressMessageString,
+ ArrayList keyList, String keyserver) {
+ super(activity, progressMessageString);
mKeyList = keyList;
mKeyserver = keyserver;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/OperationHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/OperationHelper.java
index 1f7e1bbd4..7587d86c8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/OperationHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/operation/OperationHelper.java
@@ -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