aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java59
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java192
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java249
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java214
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityOld.java744
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java25
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java30
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java35
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java17
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java48
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java102
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java17
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java41
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java83
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java114
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java155
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java52
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java82
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java45
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java40
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java90
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java46
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java111
30 files changed, 1226 insertions, 1421 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
index 7ac229b91..467e0c14a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
+import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -37,12 +38,11 @@ import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
@@ -52,10 +52,12 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.OperationResultParcel;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.util.ArrayList;
@@ -64,7 +66,8 @@ import java.util.ArrayList;
*/
public class CertifyKeyActivity extends ActionBarActivity implements
SelectSecretKeyLayoutFragment.SelectSecretKeyCallback, LoaderManager.LoaderCallbacks<Cursor> {
- private View mSignButton;
+ private View mCertifyButton;
+ private ImageView mActionCertifyImage;
private CheckBox mUploadKeyCheckbox;
private Spinner mSelectKeyserverSpinner;
@@ -88,10 +91,19 @@ public class CertifyKeyActivity extends ActionBarActivity implements
mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getSupportFragmentManager()
.findFragmentById(R.id.sign_key_select_key_fragment);
+ mSelectKeyserverSpinner = (Spinner) findViewById(R.id.upload_key_keyserver);
+ mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox);
+ mCertifyButton = findViewById(R.id.certify_key_certify_button);
+ mActionCertifyImage = (ImageView) findViewById(R.id.certify_key_action_certify_image);
+ mUserIds = (ListView) findViewById(R.id.view_key_user_ids);
+
+ // make certify image gray, like action icons
+ mActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
+ PorterDuff.Mode.SRC_IN);
+
mSelectKeyFragment.setCallback(this);
mSelectKeyFragment.setFilterCertify(true);
- mSelectKeyserverSpinner = (Spinner) findViewById(R.id.upload_key_keyserver);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, Preferences.getPreferences(this)
.getKeyServers()
@@ -99,7 +111,6 @@ public class CertifyKeyActivity extends ActionBarActivity implements
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSelectKeyserverSpinner.setAdapter(adapter);
- mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox);
if (!mUploadKeyCheckbox.isChecked()) {
mSelectKeyserverSpinner.setEnabled(false);
} else {
@@ -118,16 +129,17 @@ public class CertifyKeyActivity extends ActionBarActivity implements
}
});
- mSignButton = findViewById(R.id.sign_key_sign_button);
- mSignButton.setOnClickListener(new OnClickListener() {
+ mCertifyButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mPubKeyId != 0) {
if (mMasterKeyId == 0) {
mSelectKeyFragment.setError(getString(R.string.select_key_to_certify));
+ Notify.showNotify(CertifyKeyActivity.this, getString(R.string.select_key_to_certify),
+ Notify.Style.ERROR);
} else {
- initiateSigning();
+ initiateCertifying();
}
}
}
@@ -141,7 +153,6 @@ public class CertifyKeyActivity extends ActionBarActivity implements
}
Log.e(Constants.TAG, "uri: " + mDataUri);
- mUserIds = (ListView) findViewById(R.id.view_key_user_ids);
mUserIdsAdapter = new UserIdsAdapter(this, null, 0, true);
mUserIds.setAdapter(mUserIdsAdapter);
@@ -218,7 +229,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
/**
* handles the UI bits of the signing process on the UI thread
*/
- private void initiateSigning() {
+ private void initiateCertifying() {
// get the user's passphrase for this key (if required)
String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId);
if (passphrase == null) {
@@ -227,27 +238,27 @@ public class CertifyKeyActivity extends ActionBarActivity implements
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- startSigning();
+ startCertifying();
}
}
- });
+ }
+ );
// bail out; need to wait until the user has entered the passphrase before trying again
return;
} else {
- startSigning();
+ startCertifying();
}
}
/**
* kicks off the actual signing process on a background thread
*/
- private void startSigning() {
-
+ private void startCertifying() {
// Bail out if there is not at least one user id selected
ArrayList<String> userIds = mUserIdsAdapter.getSelectedUserIds();
if (userIds.isEmpty()) {
- AppMsg.makeText(CertifyKeyActivity.this, "No User IDs to sign selected!",
- AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(CertifyKeyActivity.this, "No identities selected!",
+ Notify.Style.ERROR);
return;
}
@@ -267,15 +278,15 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// Message is received after signing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_signing), ProgressDialog.STYLE_SPINNER) {
+ getString(R.string.progress_certifying), ProgressDialog.STYLE_SPINNER) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- AppMsg.makeText(CertifyKeyActivity.this, R.string.key_certify_success,
- AppMsg.STYLE_INFO).show();
+ Notify.showNotify(CertifyKeyActivity.this, R.string.key_certify_success,
+ Notify.Style.INFO);
// check if we need to send the key to the server or not
if (mUploadKeyCheckbox.isChecked()) {
@@ -321,14 +332,16 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// Message is received after uploading is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_uploading), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- AppMsg.makeText(CertifyKeyActivity.this, R.string.key_send_success,
- AppMsg.STYLE_INFO).show();
+ Intent intent = new Intent();
+ intent.putExtra(OperationResultParcel.EXTRA_RESULT, message.getData());
+ Notify.showNotify(CertifyKeyActivity.this, R.string.key_send_success,
+ Notify.Style.INFO);
setResult(RESULT_OK);
finish();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
index d2073d9a7..534ac5811 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
@@ -17,171 +17,69 @@
package org.sufficientlysecure.keychain.ui;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.Patterns;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.AutoCompleteTextView;
-import android.widget.Button;
-import android.widget.EditText;
-import org.spongycastle.bcpg.sig.KeyFlags;
-import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ContactHelper;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
-
-import java.util.regex.Matcher;
public class CreateKeyActivity extends ActionBarActivity {
- AutoCompleteTextView nameEdit;
- AutoCompleteTextView emailEdit;
- EditText passphraseEdit;
- Button createButton;
+ public static final String EXTRA_NAME = "name";
+ public static final String EXTRA_EMAIL = "email";
+
+ public static final int FRAG_ACTION_START = 0;
+ public static final int FRAG_ACTION_TO_RIGHT = 1;
+ public static final int FRAG_ACTION_TO_LEFT = 2;
@Override
- protected void onCreate(Bundle savedInstanceState) {
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create_key_activity);
- nameEdit = (AutoCompleteTextView) findViewById(R.id.name);
- emailEdit = (AutoCompleteTextView) findViewById(R.id.email);
- passphraseEdit = (EditText) findViewById(R.id.passphrase);
- createButton = (Button) findViewById(R.id.create_key_button);
-
- emailEdit.setThreshold(1); // Start working from first character
- emailEdit.setAdapter(
- new ArrayAdapter<String>
- (this, android.R.layout.simple_spinner_dropdown_item,
- ContactHelper.getPossibleUserEmails(this)
- )
- );
- emailEdit.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
- }
-
- @Override
- public void afterTextChanged(Editable editable) {
- String email = editable.toString();
- if (email.length() > 0) {
- Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email);
- if (emailMatcher.matches()) {
- emailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0,
- R.drawable.uid_mail_ok, 0);
- } else {
- emailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0,
- R.drawable.uid_mail_bad, 0);
- }
- } else {
- // remove drawable if email is empty
- emailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
- }
- }
- });
- nameEdit.setThreshold(1); // Start working from first character
- nameEdit.setAdapter(
- new ArrayAdapter<String>
- (this, android.R.layout.simple_spinner_dropdown_item,
- ContactHelper.getPossibleUserNames(this)
- )
- );
-
- createButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- createKeyCheck();
- }
- });
-
+ // pass extras into fragment
+ CreateKeyInputFragment frag =
+ CreateKeyInputFragment.newInstance(
+ getIntent().getStringExtra(EXTRA_NAME),
+ getIntent().getStringExtra(EXTRA_EMAIL)
+ );
+ loadFragment(null, frag, FRAG_ACTION_START);
}
- private void createKeyCheck() {
- if (isEditTextNotEmpty(this, nameEdit)
- && isEditTextNotEmpty(this, emailEdit)
- && isEditTextNotEmpty(this, passphraseEdit)) {
- createKey();
+ public void loadFragment(Bundle savedInstanceState, Fragment fragment, int action) {
+ // However, if we're being restored from a previous state,
+ // then we don't need to do anything and should return or else
+ // we could end up with overlapping fragments.
+ if (savedInstanceState != null) {
+ return;
}
- }
-
- private void createKey() {
- Intent intent = new Intent(this, KeychainIntentService.class);
- intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
-
- // Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this,
- getString(R.string.progress_importing),
- ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- CreateKeyActivity.this.finish();
- }
- }
- };
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+
+ switch (action) {
+ case FRAG_ACTION_START:
+ transaction.setCustomAnimations(0, 0);
+ transaction.replace(R.id.create_key_fragment_container, fragment)
+ .commitAllowingStateLoss();
+ break;
+ case FRAG_ACTION_TO_LEFT:
+ getSupportFragmentManager().popBackStackImmediate();
+ break;
+ case FRAG_ACTION_TO_RIGHT:
+ transaction.setCustomAnimations(R.anim.frag_slide_in_from_right, R.anim.frag_slide_out_to_left,
+ R.anim.frag_slide_in_from_left, R.anim.frag_slide_out_to_right);
+ transaction.addToBackStack(null);
+ transaction.replace(R.id.create_key_fragment_container, fragment)
+ .commitAllowingStateLoss();
+ break;
- // fill values for this action
- Bundle data = new Bundle();
-
- SaveKeyringParcel parcel = new SaveKeyringParcel();
- parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.CERTIFY_OTHER, null));
- parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.SIGN_DATA, null));
- parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, null));
- String userId = nameEdit.getText().toString() + " <" + emailEdit.getText().toString() + ">";
- parcel.mAddUserIds.add(userId);
- parcel.mNewPassphrase = passphraseEdit.getText().toString();
-
- // get selected key entries
- data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, parcel);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- saveHandler.showProgressDialog(this);
-
- startService(intent);
- }
-
- /**
- * Checks if text of given EditText is not empty. If it is empty an error is
- * set and the EditText gets the focus.
- *
- * @param context
- * @param editText
- * @return true if EditText is not empty
- */
- private static boolean isEditTextNotEmpty(Context context, EditText editText) {
- boolean output = true;
- if (editText.getText().toString().length() == 0) {
- editText.setError("empty!");
- editText.requestFocus();
- output = false;
- } else {
- editText.setError(null);
}
-
- return output;
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
}
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
new file mode 100644
index 000000000..f9ed16cba
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 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;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Message;
+import android.os.Messenger;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.TextView;
+
+import org.spongycastle.bcpg.sig.KeyFlags;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.helper.Preferences;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.service.KeychainIntentService;
+import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.OperationResultParcel;
+import org.sufficientlysecure.keychain.service.OperationResults;
+import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
+import org.sufficientlysecure.keychain.util.Notify;
+
+public class CreateKeyFinalFragment extends Fragment {
+
+ CreateKeyActivity mCreateKeyActivity;
+
+ TextView mNameEdit;
+ TextView mEmailEdit;
+ CheckBox mUploadCheckbox;
+ View mBackButton;
+ View mCreateButton;
+
+ public static final String ARG_NAME = "name";
+ public static final String ARG_EMAIL = "email";
+ public static final String ARG_PASSPHRASE = "passphrase";
+
+ String mName;
+ String mEmail;
+ String mPassphrase;
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static CreateKeyFinalFragment newInstance(String name, String email, String passphrase) {
+ CreateKeyFinalFragment frag = new CreateKeyFinalFragment();
+
+ Bundle args = new Bundle();
+ args.putString(ARG_NAME, name);
+ args.putString(ARG_EMAIL, email);
+ args.putString(ARG_PASSPHRASE, passphrase);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.create_key_final_fragment, container, false);
+
+ mNameEdit = (TextView) view.findViewById(R.id.name);
+ mEmailEdit = (TextView) view.findViewById(R.id.email);
+ mUploadCheckbox = (CheckBox) view.findViewById(R.id.create_key_upload);
+ mBackButton = view.findViewById(R.id.create_key_back_button);
+ mCreateButton = view.findViewById(R.id.create_key_create_button);
+
+ // get args
+ mName = getArguments().getString(ARG_NAME);
+ mEmail = getArguments().getString(ARG_EMAIL);
+ mPassphrase = getArguments().getString(ARG_PASSPHRASE);
+
+ // set values
+ mNameEdit.setText(mName);
+ mEmailEdit.setText(mEmail);
+
+ mCreateButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ createKey();
+ }
+ });
+
+ mBackButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCreateKeyActivity.loadFragment(null, null, CreateKeyActivity.FRAG_ACTION_TO_LEFT);
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mCreateKeyActivity = (CreateKeyActivity) getActivity();
+ }
+
+ private void createKey() {
+ Intent intent = new Intent(getActivity(), KeychainIntentService.class);
+ intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
+
+ // Message is received after importing is done in KeychainIntentService
+ KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ getActivity(),
+ getString(R.string.progress_importing),
+ ProgressDialog.STYLE_HORIZONTAL) {
+ public void handleMessage(Message message) {
+ // handle messages by standard KeychainIntentServiceHandler first
+ super.handleMessage(message);
+
+ if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
+ // get returned data bundle
+ Bundle returnData = message.getData();
+ if (returnData == null) {
+ return;
+ }
+ final OperationResults.EditKeyResult result =
+ returnData.getParcelable(OperationResultParcel.EXTRA_RESULT);
+ if (result == null) {
+ return;
+ }
+
+ if (result.getResult() == OperationResultParcel.RESULT_OK) {
+ if (mUploadCheckbox.isChecked()) {
+ // result will be displayed after upload
+ uploadKey(result);
+ } else {
+ // TODO: return result
+ result.createNotify(getActivity());
+
+ getActivity().setResult(Activity.RESULT_OK);
+ getActivity().finish();
+ }
+ } else {
+ // display result on error without finishing activity
+ result.createNotify(getActivity());
+ }
+ }
+ }
+ };
+
+ // fill values for this action
+ Bundle data = new Bundle();
+
+ SaveKeyringParcel parcel = new SaveKeyringParcel();
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.CERTIFY_OTHER, null));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.SIGN_DATA, null));
+ parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, null));
+ String userId = mName + " <" + mEmail + ">";
+ parcel.mAddUserIds.add(userId);
+ parcel.mNewPassphrase = mPassphrase;
+
+ // get selected key entries
+ data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, parcel);
+
+ intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(saveHandler);
+ intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
+
+ saveHandler.showProgressDialog(getActivity());
+
+ getActivity().startService(intent);
+ }
+
+ private void uploadKey(final OperationResults.EditKeyResult editKeyResult) {
+ // Send all information needed to service to upload key in other thread
+ final Intent intent = new Intent(getActivity(), KeychainIntentService.class);
+
+ intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING);
+
+ // set data uri as path to keyring
+ Uri blobUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(
+ editKeyResult.mRingMasterKeyId);
+ intent.setData(blobUri);
+
+ // fill values for this action
+ Bundle data = new Bundle();
+
+ // upload to favorite keyserver
+ String keyserver = Preferences.getPreferences(getActivity()).getKeyServers()[0];
+ data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, keyserver);
+
+ intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
+
+ // Message is received after uploading is done in KeychainIntentService
+ KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
+ getString(R.string.progress_uploading), ProgressDialog.STYLE_HORIZONTAL) {
+ public void handleMessage(Message message) {
+ // handle messages by standard KeychainIntentServiceHandler first
+ super.handleMessage(message);
+
+ if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
+ // TODO: not supported by upload?
+// if (result.getResult() == OperationResultParcel.RESULT_OK) {
+ // TODO: return result
+ editKeyResult.createNotify(getActivity());
+
+ Notify.showNotify(getActivity(), R.string.key_send_success,
+ Notify.Style.INFO);
+
+ getActivity().setResult(Activity.RESULT_OK);
+ getActivity().finish();
+// } else {
+// // display result on error without finishing activity
+// editKeyResult.createNotify(getActivity());
+// }
+ }
+ }
+ };
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(saveHandler);
+ intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
+
+ // show progress dialog
+ saveHandler.showProgressDialog(getActivity());
+
+ // start service with intent
+ getActivity().startService(intent);
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
new file mode 100644
index 000000000..ef5a3b145
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 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;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Patterns;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.EditText;
+
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.helper.ContactHelper;
+
+import java.util.regex.Matcher;
+
+public class CreateKeyInputFragment extends Fragment {
+
+ CreateKeyActivity mCreateKeyActivity;
+
+ AutoCompleteTextView mNameEdit;
+ AutoCompleteTextView mEmailEdit;
+ EditText mPassphraseEdit;
+ EditText mPassphraseEditAgain;
+ View mCreateButton;
+
+ public static final String ARG_NAME = "name";
+ public static final String ARG_EMAIL = "email";
+
+ /**
+ * Creates new instance of this fragment
+ */
+ public static CreateKeyInputFragment newInstance(String name, String email) {
+ CreateKeyInputFragment frag = new CreateKeyInputFragment();
+
+ Bundle args = new Bundle();
+ args.putString(ARG_NAME, name);
+ args.putString(ARG_EMAIL, email);
+
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.create_key_input_fragment, container, false);
+
+ mNameEdit = (AutoCompleteTextView) view.findViewById(R.id.name);
+ mEmailEdit = (AutoCompleteTextView) view.findViewById(R.id.email);
+ mPassphraseEdit = (EditText) view.findViewById(R.id.passphrase);
+ mPassphraseEditAgain = (EditText) view.findViewById(R.id.passphrase_again);
+ mCreateButton = view.findViewById(R.id.create_key_button);
+
+ // initial values
+ String name = getArguments().getString(ARG_NAME);
+ String email = getArguments().getString(ARG_EMAIL);
+ mNameEdit.setText(name);
+ mEmailEdit.setText(email);
+
+ // focus non-empty edit fields
+ if (name != null && email != null) {
+ mPassphraseEdit.requestFocus();
+ } else if (name != null) {
+ mEmailEdit.requestFocus();
+ }
+
+ mEmailEdit.setThreshold(1); // Start working from first character
+ mEmailEdit.setAdapter(
+ new ArrayAdapter<String>
+ (getActivity(), android.R.layout.simple_spinner_dropdown_item,
+ ContactHelper.getPossibleUserEmails(getActivity())
+ )
+ );
+ mEmailEdit.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ String email = editable.toString();
+ if (email.length() > 0) {
+ Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email);
+ if (emailMatcher.matches()) {
+ mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0,
+ R.drawable.uid_mail_ok, 0);
+ } else {
+ mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0,
+ R.drawable.uid_mail_bad, 0);
+ }
+ } else {
+ // remove drawable if email is empty
+ mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ }
+ });
+
+ mNameEdit.setThreshold(1); // Start working from first character
+ mNameEdit.setAdapter(
+ new ArrayAdapter<String>
+ (getActivity(), android.R.layout.simple_spinner_dropdown_item,
+ ContactHelper.getPossibleUserNames(getActivity())
+ )
+ );
+
+ mCreateButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ createKeyCheck();
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mCreateKeyActivity = (CreateKeyActivity) getActivity();
+ }
+
+ private void createKeyCheck() {
+ if (isEditTextNotEmpty(getActivity(), mNameEdit)
+ && isEditTextNotEmpty(getActivity(), mEmailEdit)
+ && isEditTextNotEmpty(getActivity(), mPassphraseEdit)
+ && areEditTextsEqual(getActivity(), mPassphraseEdit, mPassphraseEditAgain)) {
+
+ CreateKeyFinalFragment frag =
+ CreateKeyFinalFragment.newInstance(
+ mNameEdit.getText().toString(),
+ mEmailEdit.getText().toString(),
+ mPassphraseEdit.getText().toString()
+ );
+
+ hideKeyboard();
+ mCreateKeyActivity.loadFragment(null, frag, CreateKeyActivity.FRAG_ACTION_TO_RIGHT);
+ }
+ }
+
+ private void hideKeyboard() {
+ InputMethodManager inputManager = (InputMethodManager) getActivity()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ //check if no view has focus:
+ View v = getActivity().getCurrentFocus();
+ if (v == null)
+ return;
+
+ inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
+ }
+
+ /**
+ * Checks if text of given EditText is not empty. If it is empty an error is
+ * set and the EditText gets the focus.
+ *
+ * @param context
+ * @param editText
+ * @return true if EditText is not empty
+ */
+ private static boolean isEditTextNotEmpty(Context context, EditText editText) {
+ boolean output = true;
+ if (editText.getText().toString().length() == 0) {
+ editText.setError(context.getString(R.string.create_key_empty));
+ editText.requestFocus();
+ output = false;
+ } else {
+ editText.setError(null);
+ }
+
+ return output;
+ }
+
+ private static boolean areEditTextsEqual(Context context, EditText editText1, EditText editText2) {
+ boolean output = true;
+ if (!editText1.getText().toString().equals(editText2.getText().toString())) {
+ editText2.setError(context.getString(R.string.create_key_passphrases_not_equal));
+ editText2.requestFocus();
+ output = false;
+ } else {
+ editText2.setError(null);
+ }
+
+ return output;
+ }
+
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
index c12b5b7be..56dfdbd95 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java
@@ -34,8 +34,6 @@ import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.FileHelper;
@@ -129,7 +127,6 @@ public class DecryptFileFragment extends DecryptFragment {
}
if (mInputFilename.equals("")) {
- //AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
Notify.showNotify(getActivity(), R.string.no_file_selected, Notify.Style.ERROR);
return;
}
@@ -137,11 +134,8 @@ public class DecryptFileFragment extends DecryptFragment {
if (mInputUri == null && mInputFilename.startsWith("file")) {
File file = new File(mInputFilename);
if (!file.exists() || !file.isFile()) {
- AppMsg.makeText(
- getActivity(),
- getString(R.string.error_message,
- getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT)
- .show();
+ Notify.showNotify(getActivity(), getString(R.string.error_message,
+ getString(R.string.error_file_not_found)), Notify.Style.ERROR);
return;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
index 6b8358538..d4235b82b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
@@ -132,7 +132,7 @@ public class DecryptFragment extends Fragment {
mResultText.setText(R.string.decrypt_result_decrypted_and_signature_certified);
}
- mResultLayout.setBackgroundColor(getResources().getColor(R.color.result_green));
+ mResultLayout.setBackgroundColor(getResources().getColor(R.color.android_green_light));
mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
mSignatureLayout.setVisibility(View.VISIBLE);
mLookupKey.setVisibility(View.GONE);
@@ -146,7 +146,7 @@ public class DecryptFragment extends Fragment {
mResultText.setText(R.string.decrypt_result_decrypted_and_signature_uncertified);
}
- mResultLayout.setBackgroundColor(getResources().getColor(R.color.result_orange));
+ mResultLayout.setBackgroundColor(getResources().getColor(R.color.android_orange_light));
mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
mSignatureLayout.setVisibility(View.VISIBLE);
mLookupKey.setVisibility(View.GONE);
@@ -160,7 +160,7 @@ public class DecryptFragment extends Fragment {
mResultText.setText(R.string.decrypt_result_decrypted_unknown_pub_key);
}
- mResultLayout.setBackgroundColor(getResources().getColor(R.color.result_orange));
+ mResultLayout.setBackgroundColor(getResources().getColor(R.color.android_orange_light));
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
mSignatureLayout.setVisibility(View.VISIBLE);
mLookupKey.setVisibility(View.VISIBLE);
@@ -170,7 +170,7 @@ public class DecryptFragment extends Fragment {
case OpenPgpSignatureResult.SIGNATURE_ERROR: {
mResultText.setText(R.string.decrypt_result_invalid_signature);
- mResultLayout.setBackgroundColor(getResources().getColor(R.color.result_red));
+ mResultLayout.setBackgroundColor(getResources().getColor(R.color.android_red_light));
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
mSignatureLayout.setVisibility(View.GONE);
mLookupKey.setVisibility(View.GONE);
@@ -180,7 +180,7 @@ public class DecryptFragment extends Fragment {
default: {
mResultText.setText(R.string.error);
- mResultLayout.setBackgroundColor(getResources().getColor(R.color.result_red));
+ mResultLayout.setBackgroundColor(getResources().getColor(R.color.android_red_light));
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
mSignatureLayout.setVisibility(View.GONE);
mLookupKey.setVisibility(View.GONE);
@@ -192,7 +192,7 @@ public class DecryptFragment extends Fragment {
mLookupKey.setVisibility(View.GONE);
// successful decryption-only
- mResultLayout.setBackgroundColor(getResources().getColor(R.color.result_purple));
+ mResultLayout.setBackgroundColor(getResources().getColor(R.color.android_purple_light));
mResultText.setText(R.string.decrypt_result_decrypted);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
index 46462f924..cf7a0b4b8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java
@@ -28,8 +28,6 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.EditText;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
@@ -38,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.util.regex.Matcher;
@@ -107,12 +106,10 @@ public class DecryptMessageFragment extends DecryptFragment {
mCiphertext = matcher.group(1);
decryptStart(null);
} else {
- AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_ALERT)
- .show();
+ Notify.showNotify(getActivity(), R.string.error_invalid_data, Notify.Style.ERROR);
}
} else {
- AppMsg.makeText(getActivity(), R.string.error_invalid_data, AppMsg.STYLE_ALERT)
- .show();
+ Notify.showNotify(getActivity(), R.string.error_invalid_data, Notify.Style.ERROR);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
index d80425c3c..6ddaec17f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
@@ -33,7 +33,7 @@ public class EditKeyActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.edit_key_activity_new);
+ setContentView(R.layout.edit_key_activity);
Uri dataUri = getIntent().getData();
if (dataUri == null) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityOld.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityOld.java
deleted file mode 100644
index 70ccb8800..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivityOld.java
+++ /dev/null
@@ -1,744 +0,0 @@
-/*
- * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
- * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
- *
- * 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;
-
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.support.v4.app.ActivityCompat;
-import android.support.v7.app.ActionBarActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.LinearLayout;
-import android.widget.Toast;
-
-import com.devspark.appmsg.AppMsg;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.helper.ExportHelper;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.pgp.UncachedSecretKey;
-import org.sufficientlysecure.keychain.pgp.WrappedSecretKey;
-import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.PassphraseCacheService;
-import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
-import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
-import org.sufficientlysecure.keychain.ui.widget.Editor;
-import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener;
-import org.sufficientlysecure.keychain.ui.widget.KeyEditor;
-import org.sufficientlysecure.keychain.ui.widget.SectionView;
-import org.sufficientlysecure.keychain.ui.widget.UserIdEditor;
-import org.sufficientlysecure.keychain.util.Log;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Vector;
-
-public class EditKeyActivityOld extends ActionBarActivity implements EditorListener {
-
- // Actions for internal use only:
- public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY";
- public static final String ACTION_EDIT_KEY = Constants.INTENT_PREFIX + "EDIT_KEY";
-
- // possible extra keys
- public static final String EXTRA_USER_IDS = "user_ids";
- public static final String EXTRA_NO_PASSPHRASE = "no_passphrase";
- public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generate_default_keys";
-
- // EDIT
- private Uri mDataUri;
-
- private SectionView mUserIdsView;
- private SectionView mKeysView;
-
- private String mCurrentPassphrase = null;
- private String mNewPassphrase = null;
- private String mSavedNewPassphrase = null;
- private boolean mIsPassphraseSet;
- private boolean mNeedsSaving;
- private boolean mIsBrandNewKeyring = false;
-
- private Button mChangePassphrase;
-
- private CheckBox mNoPassphrase;
-
- Vector<String> mUserIds;
- Vector<UncachedSecretKey> mKeys;
- Vector<Integer> mKeysUsages;
- boolean mMasterCanSign = true;
-
- ExportHelper mExportHelper;
-
- public boolean needsSaving() {
- mNeedsSaving = (mUserIdsView == null) ? false : mUserIdsView.needsSaving();
- mNeedsSaving |= (mKeysView == null) ? false : mKeysView.needsSaving();
- mNeedsSaving |= hasPassphraseChanged();
- mNeedsSaving |= mIsBrandNewKeyring;
- return mNeedsSaving;
- }
-
-
- public void somethingChanged() {
- ActivityCompat.invalidateOptionsMenu(this);
- }
-
- public void onDeleted(Editor e, boolean wasNewItem) {
- somethingChanged();
- }
-
- public void onEdited() {
- somethingChanged();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mExportHelper = new ExportHelper(this);
-
- // Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setTwoButtonView(getSupportActionBar(),
- R.string.btn_save, R.drawable.ic_action_save,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Save
- saveClicked();
- }
- }, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // Cancel
- cancelClicked();
- }
- }
- );
-
- mUserIds = new Vector<String>();
- mKeys = new Vector<UncachedSecretKey>();
- mKeysUsages = new Vector<Integer>();
-
- // Catch Intents opened from other apps
- Intent intent = getIntent();
- String action = intent.getAction();
- if (ACTION_CREATE_KEY.equals(action)) {
- handleActionCreateKey(intent);
- } else if (ACTION_EDIT_KEY.equals(action)) {
- handleActionEditKey(intent);
- }
- }
-
- /**
- * Handle intent action to create new key
- *
- * @param intent
- */
- private void handleActionCreateKey(Intent intent) {
- Bundle extras = intent.getExtras();
-
- mCurrentPassphrase = "";
- mIsBrandNewKeyring = true;
-
- if (extras != null) {
- // if userId is given, prefill the fields
- if (extras.containsKey(EXTRA_USER_IDS)) {
- Log.d(Constants.TAG, "UserIds are given!");
- mUserIds.add(extras.getString(EXTRA_USER_IDS));
- }
-
- // if no passphrase is given
- if (extras.containsKey(EXTRA_NO_PASSPHRASE)) {
- boolean noPassphrase = extras.getBoolean(EXTRA_NO_PASSPHRASE);
- if (noPassphrase) {
- // check "no passphrase" checkbox and remove button
- mNoPassphrase.setChecked(true);
- mChangePassphrase.setVisibility(View.GONE);
- }
- }
-
- // generate key
- if (extras.containsKey(EXTRA_GENERATE_DEFAULT_KEYS)) {
- /*
- boolean generateDefaultKeys = extras.getBoolean(EXTRA_GENERATE_DEFAULT_KEYS);
- if (generateDefaultKeys) {
-
- // fill values for this action
- Bundle data = new Bundle();
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE,
- mCurrentPassphrase);
-
- serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after generating is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this, getResources().getQuantityString(R.plurals.progress_generating, 1),
- ProgressDialog.STYLE_HORIZONTAL, true,
-
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- // Stop key generation on cancel
- stopService(serviceIntent);
- EditKeyActivity.this.setResult(Activity.RESULT_CANCELED);
- EditKeyActivity.this.finish();
- }
- }) {
-
- @Override
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get new key from data bundle returned from service
- Bundle data = message.getDataAsStringList();
-
- ArrayList<UncachedSecretKey> newKeys =
- PgpConversionHelper.BytesToPGPSecretKeyList(data
- .getByteArray(KeychainIntentService.RESULT_NEW_KEY));
-
- ArrayList<Integer> keyUsageFlags = data.getIntegerArrayList(
- KeychainIntentService.RESULT_KEY_USAGES);
-
- if (newKeys.size() == keyUsageFlags.size()) {
- for (int i = 0; i < newKeys.size(); ++i) {
- mKeys.add(newKeys.get(i));
- mKeysUsages.add(keyUsageFlags.get(i));
- }
- }
-
- buildLayout(true);
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- serviceIntent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(serviceIntent);
- }
- */
- }
- } else {
- buildLayout(false);
- }
- }
-
- /**
- * Handle intent action to edit existing key
- *
- * @param intent
- */
- private void handleActionEditKey(Intent intent) {
- mDataUri = intent.getData();
- if (mDataUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
- finish();
- } else {
- Log.d(Constants.TAG, "uri: " + mDataUri);
-
- try {
- Uri secretUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
- WrappedSecretKeyRing keyRing = new ProviderHelper(this).getWrappedSecretKeyRing(secretUri);
-
- mMasterCanSign = keyRing.getSecretKey().canCertify();
- for (WrappedSecretKey key : keyRing.secretKeyIterator()) {
- // Turn into uncached instance
- mKeys.add(key.getUncached());
- mKeysUsages.add(key.getKeyUsage()); // get usage when view is created
- }
-
- boolean isSet = false;
- for (String userId : keyRing.getSecretKey().getUserIds()) {
- Log.d(Constants.TAG, "Added userId " + userId);
- if (!isSet) {
- isSet = true;
- String[] parts = KeyRing.splitUserId(userId);
- if (parts[0] != null) {
- setTitle(parts[0]);
- }
- }
- mUserIds.add(userId);
- }
-
- buildLayout(false);
-
- mCurrentPassphrase = "";
- mIsPassphraseSet = keyRing.hasPassphrase();
- if (!mIsPassphraseSet) {
- // check "no passphrase" checkbox and remove button
- mNoPassphrase.setChecked(true);
- mChangePassphrase.setVisibility(View.GONE);
- }
-
- } catch (ProviderHelper.NotFoundException e) {
- Log.e(Constants.TAG, "Keyring not found: " + e.getMessage(), e);
- Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_SHORT).show();
- finish();
- }
-
- }
- }
-
- /**
- * Shows the dialog to set a new passphrase
- */
- private void showSetPassphraseDialog() {
- // Message is received after passphrase is cached
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == SetPassphraseDialogFragment.MESSAGE_OKAY) {
- Bundle data = message.getData();
-
- // set new returned passphrase!
- mNewPassphrase = data
- .getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE);
-
- updatePassphraseButtonText();
- somethingChanged();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- // set title based on isPassphraseSet()
- int title;
- if (isPassphraseSet()) {
- title = R.string.title_change_passphrase;
- } else {
- title = R.string.title_set_passphrase;
- }
-
- SetPassphraseDialogFragment setPassphraseDialog = SetPassphraseDialogFragment.newInstance(
- messenger, null, title);
-
- setPassphraseDialog.show(getSupportFragmentManager(), "setPassphraseDialog");
- }
-
- /**
- * Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user
- * id and key.
- *
- * @param newKeys
- */
- private void buildLayout(boolean newKeys) {
- setContentView(R.layout.edit_key_activity);
-
- // find views
- mChangePassphrase = (Button) findViewById(R.id.edit_key_btn_change_passphrase);
- mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
- // Build layout based on given userIds and keys
-
- LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container);
- if (mIsPassphraseSet) {
- mChangePassphrase.setText(getString(R.string.btn_change_passphrase));
- }
- mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
- mUserIdsView.setType(SectionView.TYPE_USER_ID);
- mUserIdsView.setCanBeEdited(mMasterCanSign);
- mUserIdsView.setUserIds(mUserIds);
- mUserIdsView.setEditorListener(this);
- container.addView(mUserIdsView);
- mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
- mKeysView.setType(SectionView.TYPE_KEY);
- mKeysView.setCanBeEdited(mMasterCanSign);
- mKeysView.setKeys(mKeys, mKeysUsages, newKeys);
- mKeysView.setEditorListener(this);
- container.addView(mKeysView);
-
- updatePassphraseButtonText();
-
- mChangePassphrase.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- showSetPassphraseDialog();
- }
- });
-
- // disable passphrase when no passphrase checkbox is checked!
- mNoPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- // remove passphrase
- mSavedNewPassphrase = mNewPassphrase;
- mNewPassphrase = "";
- mChangePassphrase.setVisibility(View.GONE);
- } else {
- mNewPassphrase = mSavedNewPassphrase;
- mChangePassphrase.setVisibility(View.VISIBLE);
- }
- somethingChanged();
- }
- });
- }
-
- private long getMasterKeyId() {
- if (mKeysView.getEditors().getChildCount() == 0) {
- return 0;
- }
- return ((KeyEditor) mKeysView.getEditors().getChildAt(0)).getValue().getKeyId();
- }
-
- public boolean isPassphraseSet() {
- if (mNoPassphrase.isChecked()) {
- return true;
- } else if ((mIsPassphraseSet)
- || (mNewPassphrase != null && !mNewPassphrase.equals(""))) {
- return true;
- } else {
- return false;
- }
- }
-
- public boolean hasPassphraseChanged() {
- if (mNoPassphrase != null) {
- if (mNoPassphrase.isChecked()) {
- return mIsPassphraseSet;
- } else {
- return (mNewPassphrase != null && !mNewPassphrase.equals(""));
- }
- } else {
- return false;
- }
- }
-
- private void saveClicked() {
- final long masterKeyId = getMasterKeyId();
- if (needsSaving()) { //make sure, as some versions don't support invalidateOptionsMenu
- try {
- if (!isPassphraseSet()) {
- throw new PgpGeneralException(this.getString(R.string.set_a_passphrase));
- }
-
- String passphrase;
- if (mIsPassphraseSet) {
- passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
- } else {
- passphrase = "";
- }
- if (passphrase == null) {
- PassphraseDialogFragment.show(this, masterKeyId,
- new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(
- EditKeyActivityOld.this, masterKeyId);
- checkEmptyIDsWanted();
- }
- }
- });
- } else {
- mCurrentPassphrase = passphrase;
- checkEmptyIDsWanted();
- }
- } catch (PgpGeneralException e) {
- AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
- AppMsg.STYLE_ALERT).show();
- }
- } else {
- AppMsg.makeText(this, R.string.error_change_something_first, AppMsg.STYLE_ALERT).show();
- }
- }
-
- private void checkEmptyIDsWanted() {
- try {
- ArrayList<String> userIDs = getUserIds(mUserIdsView);
- List<Boolean> newIDs = mUserIdsView.getNewIDFlags();
- ArrayList<String> originalIDs = mUserIdsView.getOriginalIDs();
- int curID = 0;
- for (String userID : userIDs) {
- if (userID.equals("") && (!userID.equals(originalIDs.get(curID)) || newIDs.get(curID))) {
- CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(
- EditKeyActivityOld.this);
-
- alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
- alert.setTitle(R.string.warning);
- alert.setMessage(EditKeyActivityOld.this.getString(R.string.ask_empty_id_ok));
-
- alert.setPositiveButton(EditKeyActivityOld.this.getString(android.R.string.yes),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- finallySaveClicked();
- }
- }
- );
- alert.setNegativeButton(this.getString(android.R.string.no),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- }
- }
- );
- alert.setCancelable(false);
- alert.show();
- return;
- }
- curID++;
- }
- } catch (PgpGeneralException e) {
- Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
- AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.STYLE_ALERT).show();
- }
- finallySaveClicked();
- }
-
- private boolean[] toPrimitiveArray(final List<Boolean> booleanList) {
- final boolean[] primitives = new boolean[booleanList.size()];
- int index = 0;
- for (Boolean object : booleanList) {
- primitives[index++] = object;
- }
- return primitives;
- }
-
- private void finallySaveClicked() {
- /*
- try {
- // Send all information needed to service to edit key in other thread
- Intent intent = new Intent(this, KeychainIntentService.class);
-
- intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
-
- OldSaveKeyringParcel saveParams = new OldSaveKeyringParcel();
- saveParams.userIds = getUserIds(mUserIdsView);
- saveParams.originalIDs = mUserIdsView.getOriginalIDs();
- saveParams.deletedIDs = mUserIdsView.getDeletedIDs();
- saveParams.newIDs = toPrimitiveArray(mUserIdsView.getNewIDFlags());
- saveParams.primaryIDChanged = mUserIdsView.primaryChanged();
- saveParams.moddedKeys = toPrimitiveArray(mKeysView.getNeedsSavingArray());
- saveParams.deletedKeys = mKeysView.getDeletedKeys();
- saveParams.keysExpiryDates = getKeysExpiryDates(mKeysView);
- saveParams.keysUsages = getKeysUsages(mKeysView);
- saveParams.mNewPassphrase = mNewPassphrase;
- saveParams.oldPassphrase = mCurrentPassphrase;
- saveParams.newKeys = toPrimitiveArray(mKeysView.getNewKeysArray());
- saveParams.keys = getKeys(mKeysView);
- saveParams.originalPrimaryID = mUserIdsView.getOriginalPrimaryID();
-
- // fill values for this action
- Bundle data = new Bundle();
- data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, mMasterCanSign);
- data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, saveParams);
-
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
-
- // Message is received after saving is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard KeychainIntentServiceHandler first
- super.handleMessage(message);
-
- if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- Intent data = new Intent();
-
- // return uri pointing to new created key
- Uri uri = KeyRings.buildGenericKeyRingUri(getMasterKeyId());
- data.setData(uri);
-
- setResult(RESULT_OK, data);
- finish();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
-
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- } catch (PgpGeneralException e) {
- Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
- AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
- AppMsg.STYLE_ALERT).show();
- }
- */
- }
-
- private void cancelClicked() {
- if (needsSaving()) { //ask if we want to save
- CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(
- EditKeyActivityOld.this);
-
- alert.setIcon(R.drawable.ic_dialog_alert_holo_light);
- alert.setTitle(R.string.warning);
- alert.setMessage(EditKeyActivityOld.this.getString(R.string.ask_save_changed_key));
-
- alert.setPositiveButton(EditKeyActivityOld.this.getString(android.R.string.yes),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- saveClicked();
- }
- });
- alert.setNegativeButton(this.getString(android.R.string.no),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- setResult(RESULT_CANCELED);
- finish();
- }
- });
- alert.setCancelable(false);
- alert.show();
- } else {
- setResult(RESULT_CANCELED);
- finish();
- }
- }
-
- /**
- * Returns user ids from the SectionView
- *
- * @param userIdsView
- * @return
- */
- private ArrayList<String> getUserIds(SectionView userIdsView) throws PgpGeneralException {
- ArrayList<String> userIds = new ArrayList<String>();
-
- ViewGroup userIdEditors = userIdsView.getEditors();
-
- boolean gotMainUserId = false;
- for (int i = 0; i < userIdEditors.getChildCount(); ++i) {
- UserIdEditor editor = (UserIdEditor) userIdEditors.getChildAt(i);
- String userId;
- userId = editor.getValue();
-
- if (editor.isMainUserId()) {
- userIds.add(0, userId);
- gotMainUserId = true;
- } else {
- userIds.add(userId);
- }
- }
-
- if (userIds.size() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_a_user_id));
- }
-
- if (!gotMainUserId) {
- throw new PgpGeneralException(getString(R.string.error_main_user_id_must_not_be_empty));
- }
-
- return userIds;
- }
-
- /**
- * Returns keys from the SectionView
- *
- * @param keysView
- * @return
- */
- private ArrayList<UncachedSecretKey> getKeys(SectionView keysView) throws PgpGeneralException {
- ArrayList<UncachedSecretKey> keys = new ArrayList<UncachedSecretKey>();
-
- ViewGroup keyEditors = keysView.getEditors();
-
- if (keyEditors.getChildCount() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
- }
-
- for (int i = 0; i < keyEditors.getChildCount(); ++i) {
- KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
- keys.add(editor.getValue());
- }
-
- return keys;
- }
-
- /**
- * Returns usage selections of keys from the SectionView
- *
- * @param keysView
- * @return
- */
- private ArrayList<Integer> getKeysUsages(SectionView keysView) throws PgpGeneralException {
- ArrayList<Integer> keysUsages = new ArrayList<Integer>();
-
- ViewGroup keyEditors = keysView.getEditors();
-
- if (keyEditors.getChildCount() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
- }
-
- for (int i = 0; i < keyEditors.getChildCount(); ++i) {
- KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
- keysUsages.add(editor.getUsage());
- }
-
- return keysUsages;
- }
-
- private ArrayList<Calendar> getKeysExpiryDates(SectionView keysView) throws PgpGeneralException {
- ArrayList<Calendar> keysExpiryDates = new ArrayList<Calendar>();
-
- ViewGroup keyEditors = keysView.getEditors();
-
- if (keyEditors.getChildCount() == 0) {
- throw new PgpGeneralException(getString(R.string.error_key_needs_master_key));
- }
-
- for (int i = 0; i < keyEditors.getChildCount(); ++i) {
- KeyEditor editor = (KeyEditor) keyEditors.getChildAt(i);
- keysExpiryDates.add(editor.getExpiryDate());
- }
-
- return keysExpiryDates;
- }
-
- private void updatePassphraseButtonText() {
- mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
- : getString(R.string.btn_set_passphrase));
- }
-
-}
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 b41871a39..9083d1567 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
@@ -42,12 +42,13 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
-import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.OperationResults;
+import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
@@ -167,8 +168,8 @@ public class EditKeyFragment extends LoaderFragment implements
try {
Uri secretUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
- WrappedSecretKeyRing keyRing =
- new ProviderHelper(getActivity()).getWrappedSecretKeyRing(secretUri);
+ CanonicalizedSecretKeyRing keyRing =
+ new ProviderHelper(getActivity()).getCanonicalizedSecretKeyRing(secretUri);
mSaveKeyringParcel = new SaveKeyringParcel(keyRing.getMasterKeyId(),
keyRing.getUncachedKeyRing().getFingerprint());
@@ -466,26 +467,30 @@ public class EditKeyFragment extends LoaderFragment implements
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- getActivity().finish();
- // TODO below
// get returned data bundle
Bundle returnData = message.getData();
if (returnData == null) {
return;
}
- final OperationResults.SaveKeyringResult result =
- returnData.getParcelable(KeychainIntentService.RESULT);
+ final OperationResults.EditKeyResult result =
+ returnData.getParcelable(EditKeyResult.EXTRA_RESULT);
if (result == null) {
return;
}
- // if good -> finish, return result to showkey and display there!
// if bad -> display here!
+ if (!result.success()) {
+ result.createNotify(getActivity()).show();
+ return;
+ }
-// result.displayNotify(ImportKeysActivity.this);
+ // if good -> finish, return result to showkey and display there!
+ Intent intent = new Intent();
+ intent.putExtra(EditKeyResult.EXTRA_RESULT, result);
+ getActivity().setResult(EditKeyActivity.RESULT_OK, intent);
+ getActivity().finish();
-// getActivity().finish();
}
}
};
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
index dc0510189..eb807792b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java
@@ -31,11 +31,14 @@ import android.widget.Button;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.KeyRing;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.util.Vector;
@@ -195,22 +198,23 @@ public class EncryptAsymmetricFragment extends Fragment {
mMainUserIdRest.setText("");
} else {
// See if we can get a user_id from a unified query
- String[] userId;
try {
- userId = mProviderHelper.getCachedPublicKeyRing(
+ String[] userIdSplit = mProviderHelper.getCachedPublicKeyRing(
KeyRings.buildUnifiedKeyRingUri(mSecretKeyId)).getSplitPrimaryUserIdWithFallback();
+
+ if (userIdSplit[0] != null) {
+ mMainUserId.setText(userIdSplit[0]);
+ } else {
+ mMainUserId.setText(R.string.user_id_no_name);
+ }
+ if (userIdSplit[1] != null) {
+ mMainUserIdRest.setText(userIdSplit[1]);
+ } else {
+ mMainUserIdRest.setText(getString(R.string.label_key_id) + ": "
+ + PgpKeyHelper.convertKeyIdToHex(mSecretKeyId));
+ }
} catch (PgpGeneralException e) {
- userId = null;
- }
- if (userId != null && userId[0] != null) {
- mMainUserId.setText(String.format("%#16x", Long.parseLong(userId[0])));
- } else {
- mMainUserId.setText(getResources().getString(R.string.user_id_no_name));
- }
- if (userId != null && userId[1] != null) {
- mMainUserIdRest.setText(userId[1]);
- } else {
- mMainUserIdRest.setText("");
+ Notify.showNotify(getActivity(), "Key not found! This is a bug!", Notify.Style.ERROR);
}
mSign.setChecked(true);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
index f5d89d186..345e38a0e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java
@@ -37,8 +37,6 @@ import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.FileHelper;
@@ -51,6 +49,7 @@ import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Choice;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.io.File;
@@ -58,7 +57,7 @@ public class EncryptFileFragment extends Fragment {
public static final String ARG_FILENAME = "filename";
public static final String ARG_ASCII_ARMOR = "ascii_armor";
- private static final int RESULT_CODE_FILE = 0x00007003;
+ private static final int REQUEST_CODE_FILE = 0x00007003;
private EncryptActivityInterface mEncryptInterface;
@@ -109,10 +108,10 @@ public class EncryptFileFragment extends Fragment {
mBrowse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (Constants.KITKAT) {
- FileHelper.openDocument(EncryptFileFragment.this, mInputUri, "*/*", RESULT_CODE_FILE);
+ FileHelper.openDocument(EncryptFileFragment.this, mInputUri, "*/*", REQUEST_CODE_FILE);
} else {
FileHelper.openFile(EncryptFileFragment.this, mFilename.getText().toString(), "*/*",
- RESULT_CODE_FILE);
+ REQUEST_CODE_FILE);
}
}
});
@@ -218,18 +217,18 @@ public class EncryptFileFragment extends Fragment {
}
if (mInputFilename.equals("")) {
- AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.no_file_selected, Notify.Style.ERROR);
return;
}
if (mInputUri == null && !mInputFilename.startsWith("content")) {
File file = new File(mInputFilename);
if (!file.exists() || !file.isFile()) {
- AppMsg.makeText(
+ Notify.showNotify(
getActivity(),
getString(R.string.error_message,
- getString(R.string.error_file_not_found)), AppMsg.STYLE_ALERT)
- .show();
+ getString(R.string.error_file_not_found)), Notify.Style.ERROR
+ );
return;
}
}
@@ -240,13 +239,13 @@ public class EncryptFileFragment extends Fragment {
boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null
&& mEncryptInterface.getPassphrase().length() != 0);
if (!gotPassphrase) {
- AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
- .show();
+ Notify.showNotify(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)
+ ;
return;
}
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
- AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR);
return;
}
} else {
@@ -256,13 +255,13 @@ public class EncryptFileFragment extends Fragment {
&& mEncryptInterface.getEncryptionKeys().length > 0);
if (!gotEncryptionKeys) {
- AppMsg.makeText(getActivity(), R.string.select_encryption_key, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.select_encryption_key, Notify.Style.ERROR);
return;
}
if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
- AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
- AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.select_encryption_or_signature_key,
+ Notify.Style.ERROR);
return;
}
@@ -345,8 +344,8 @@ public class EncryptFileFragment extends Fragment {
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- AppMsg.makeText(getActivity(), R.string.encrypt_sign_successful,
- AppMsg.STYLE_INFO).show();
+ Notify.showNotify(getActivity(), R.string.encrypt_sign_successful,
+ Notify.Style.INFO);
if (mDeleteAfter.isChecked()) {
// Create and show dialog to delete original file
@@ -390,7 +389,7 @@ public class EncryptFileFragment extends Fragment {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
- case RESULT_CODE_FILE: {
+ case REQUEST_CODE_FILE: {
if (resultCode == Activity.RESULT_OK && data != null) {
if (Constants.KITKAT) {
mInputUri = data.getData();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
index 8a6103b16..e1760b4ed 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptMessageFragment.java
@@ -30,8 +30,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
@@ -41,6 +39,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
public class EncryptMessageFragment extends Fragment {
public static final String ARG_TEXT = "text";
@@ -126,13 +125,12 @@ public class EncryptMessageFragment extends Fragment {
boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null
&& mEncryptInterface.getPassphrase().length() != 0);
if (!gotPassphrase) {
- AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
- .show();
+ Notify.showNotify(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR);
return;
}
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
- AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR);
return;
}
@@ -143,8 +141,8 @@ public class EncryptMessageFragment extends Fragment {
&& mEncryptInterface.getEncryptionKeys().length > 0);
if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
- AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
- AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.select_encryption_or_signature_key,
+ Notify.Style.ERROR);
return;
}
@@ -226,9 +224,8 @@ public class EncryptMessageFragment extends Fragment {
if (toClipboard) {
ClipboardReflection.copyToClipboard(getActivity(), output);
- AppMsg.makeText(getActivity(),
- R.string.encrypt_sign_clipboard_successful, AppMsg.STYLE_INFO)
- .show();
+ Notify.showNotify(getActivity(),
+ R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO);
} else {
Intent sendIntent = new Intent(Intent.ACTION_SEND);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java
index aa4120d2c..5f3f170a1 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java
@@ -22,15 +22,19 @@ import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.Window;
-import android.widget.Button;
+import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.helper.Preferences;
+import org.sufficientlysecure.keychain.util.Log;
public class FirstTimeActivity extends ActionBarActivity {
- Button mCreateKey;
- Button mImportKey;
- Button mSkipSetup;
+ View mCreateKey;
+ View mImportKey;
+ View mSkipSetup;
+
+ public static final int REQUEST_CODE_CREATE_OR_IMPORT_KEY = 0x00007012;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -40,16 +44,14 @@ public class FirstTimeActivity extends ActionBarActivity {
setContentView(R.layout.first_time_activity);
- mCreateKey = (Button) findViewById(R.id.first_time_create_key);
- mImportKey = (Button) findViewById(R.id.first_time_import_key);
- mSkipSetup = (Button) findViewById(R.id.first_time_cancel);
+ mCreateKey = findViewById(R.id.first_time_create_key);
+ mImportKey = findViewById(R.id.first_time_import_key);
+ mSkipSetup = findViewById(R.id.first_time_cancel);
mSkipSetup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- Intent intent = new Intent(FirstTimeActivity.this, KeyListActivity.class);
- startActivity(intent);
- finish();
+ finishSetup();
}
});
@@ -58,8 +60,7 @@ public class FirstTimeActivity extends ActionBarActivity {
public void onClick(View v) {
Intent intent = new Intent(FirstTimeActivity.this, ImportKeysActivity.class);
intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN);
- startActivity(intent);
- finish();
+ startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY);
}
});
@@ -67,11 +68,30 @@ public class FirstTimeActivity extends ActionBarActivity {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstTimeActivity.this, CreateKeyActivity.class);
- startActivity(intent);
- finish();
+ startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY);
}
});
}
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if (requestCode == REQUEST_CODE_CREATE_OR_IMPORT_KEY) {
+ if (resultCode == RESULT_OK) {
+ finishSetup();
+ }
+ } else {
+ Log.e(Constants.TAG, "No valid request code!");
+ }
+ }
+
+ private void finishSetup() {
+ Preferences prefs = Preferences.getPreferences(this);
+ prefs.setFirstTime(false);
+ Intent intent = new Intent(FirstTimeActivity.this, KeyListActivity.class);
+ startActivity(intent);
+ finish();
+ }
}
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 3ff3b56bf..dbc557f9a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -40,17 +40,19 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
+import org.sufficientlysecure.keychain.keyimport.FileImportCache;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.OperationResults.ImportResult;
+import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Notify;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale;
@@ -98,6 +100,7 @@ public class ImportKeysActivity extends ActionBarActivity {
public static final int VIEW_PAGER_HEIGHT = 64; // dp
+ private static final int ALL_TABS = -1;
private static final int TAB_KEYSERVER = 0;
private static final int TAB_QR_CODE = 1;
private static final int TAB_FILE = 2;
@@ -150,7 +153,7 @@ public class ImportKeysActivity extends ActionBarActivity {
}
Bundle serverBundle = null;
- boolean serverOnly = false;
+ int showTabOnly = ALL_TABS;
if (ACTION_IMPORT_KEY.equals(action)) {
/* Keychain's own Actions */
@@ -214,7 +217,7 @@ public class ImportKeysActivity extends ActionBarActivity {
serverBundle.putString(ImportKeysServerFragment.ARG_QUERY, query);
serverBundle.putBoolean(ImportKeysServerFragment.ARG_DISABLE_QUERY_EDIT, true);
// display server tab only
- serverOnly = true;
+ showTabOnly = TAB_KEYSERVER;
mSwitchToTab = TAB_KEYSERVER;
// action: search immediately
@@ -227,13 +230,20 @@ public class ImportKeysActivity extends ActionBarActivity {
);
return;
}
- } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)
- || ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(action)) {
+ } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
// NOTE: this only displays the appropriate fragment, no actions are taken
mSwitchToTab = TAB_FILE;
// no immediate actions!
startListFragment(savedInstanceState, null, null, null);
+ } else if (ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(action)) {
+ // NOTE: this only displays the appropriate fragment, no actions are taken
+ mSwitchToTab = TAB_FILE;
+ // display file tab only
+ showTabOnly = TAB_FILE;
+
+ // no immediate actions!
+ startListFragment(savedInstanceState, null, null, null);
} else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) {
// also exposed in AndroidManifest
@@ -259,10 +269,10 @@ public class ImportKeysActivity extends ActionBarActivity {
startListFragment(savedInstanceState, null, null, null);
}
- initTabs(serverBundle, serverOnly);
+ initTabs(serverBundle, showTabOnly);
}
- private void initTabs(Bundle serverBundle, boolean serverOnly) {
+ private void initTabs(Bundle serverBundle, int showTabOnly) {
mTabsAdapter = new PagerTabStripAdapter(this);
mViewPager.setAdapter(mTabsAdapter);
mSlidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@@ -285,15 +295,34 @@ public class ImportKeysActivity extends ActionBarActivity {
}
});
- mTabsAdapter.addTab(ImportKeysServerFragment.class,
- serverBundle, getString(R.string.import_tab_keyserver));
- if (!serverOnly) {
- mTabsAdapter.addTab(ImportKeysQrCodeFragment.class,
- null, getString(R.string.import_tab_qr_code));
- mTabsAdapter.addTab(ImportKeysFileFragment.class,
- null, getString(R.string.import_tab_direct));
- mTabsAdapter.addTab(ImportKeysKeybaseFragment.class,
- null, getString(R.string.import_tab_keybase));
+ switch (showTabOnly) {
+ case ALL_TABS:
+ // show all tabs
+ mTabsAdapter.addTab(ImportKeysServerFragment.class,
+ serverBundle, getString(R.string.import_tab_keyserver));
+ mTabsAdapter.addTab(ImportKeysQrCodeFragment.class,
+ null, getString(R.string.import_tab_qr_code));
+ mTabsAdapter.addTab(ImportKeysFileFragment.class,
+ null, getString(R.string.import_tab_direct));
+ mTabsAdapter.addTab(ImportKeysKeybaseFragment.class,
+ null, getString(R.string.import_tab_keybase));
+ break;
+ case TAB_KEYSERVER:
+ mTabsAdapter.addTab(ImportKeysServerFragment.class,
+ serverBundle, getString(R.string.import_tab_keyserver));
+ break;
+ case TAB_QR_CODE:
+ mTabsAdapter.addTab(ImportKeysQrCodeFragment.class,
+ null, getString(R.string.import_tab_qr_code));
+ break;
+ case TAB_FILE:
+ mTabsAdapter.addTab(ImportKeysFileFragment.class,
+ null, getString(R.string.import_tab_direct));
+ break;
+ case TAB_KEYBASE:
+ mTabsAdapter.addTab(ImportKeysKeybaseFragment.class,
+ null, getString(R.string.import_tab_keybase));
+ break;
}
// update layout after operations
@@ -354,9 +383,8 @@ public class ImportKeysActivity extends ActionBarActivity {
ImportKeysServerFragment f = (ImportKeysServerFragment)
getActiveFragment(mViewPager, TAB_KEYSERVER);
- // TODO: Currently it simply uses keyserver nr 0
- String keyserver = Preferences.getPreferences(ImportKeysActivity.this)
- .getKeyServers()[0];
+ // ask favorite keyserver
+ String keyserver = Preferences.getPreferences(ImportKeysActivity.this).getKeyServers()[0];
// set fields of ImportKeysServerFragment
f.setQueryAndKeyserver(query, keyserver);
@@ -427,15 +455,15 @@ public class ImportKeysActivity extends ActionBarActivity {
if (returnData == null) {
return;
}
- final ImportResult result =
- returnData.getParcelable(KeychainIntentService.RESULT);
+ final ImportKeyResult result =
+ returnData.getParcelable(KeychainIntentService.RESULT_IMPORT);
if (result == null) {
return;
}
if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(getIntent().getAction())) {
Intent intent = new Intent();
- intent.putExtra(EXTRA_RESULT, result);
+ intent.putExtra(ImportKeyResult.EXTRA_RESULT, result);
ImportKeysActivity.this.setResult(RESULT_OK, intent);
ImportKeysActivity.this.finish();
return;
@@ -451,7 +479,7 @@ public class ImportKeysActivity extends ActionBarActivity {
return;
}
- result.displayNotify(ImportKeysActivity.this);
+ result.createNotify(ImportKeysActivity.this).show();
}
}
};
@@ -470,19 +498,29 @@ public class ImportKeysActivity extends ActionBarActivity {
// get DATA from selected key entries
ArrayList<ParcelableKeyRing> selectedEntries = mListFragment.getSelectedData();
- data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries);
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
+ // instead of given the entries by Intent extra, cache them into a file
+ // to prevent Java Binder problems on heavy imports
+ // read FileImportCache for more info.
+ try {
+ FileImportCache cache = new FileImportCache(this);
+ cache.writeCache(selectedEntries);
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
+ intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- // show progress dialog
- saveHandler.showProgressDialog(this);
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(saveHandler);
+ intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
- // start service with intent
- startService(intent);
+ // show progress dialog
+ saveHandler.showProgressDialog(this);
+
+ // start service with intent
+ startService(intent);
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "Problem writing cache file", e);
+ Notify.showNotify(this, "Problem writing cache file!", Notify.Style.ERROR);
+ }
} else if (ls instanceof ImportKeysListFragment.KeyserverLoaderState) {
ImportKeysListFragment.KeyserverLoaderState sls = (ImportKeysListFragment.KeyserverLoaderState) ls;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
index 9a39b6cc3..fde0f5f23 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
@@ -35,7 +35,6 @@ import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.Keyserver;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListKeybaseLoader;
@@ -288,13 +287,13 @@ public class ImportKeysListFragment extends ListFragment implements
if (error == null) {
// No error
mCachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings();
- } else if (error instanceof ImportKeysListLoader.FileHasNoContent) {
- Notify.showNotify(getActivity(), R.string.error_import_file_no_content, Notify.Style.ERROR);
- } else if (error instanceof ImportKeysListLoader.NonPgpPart) {
+ } else if (error instanceof ImportKeysListLoader.NoValidKeysException) {
+ Notify.showNotify(getActivity(), R.string.error_import_no_valid_keys, Notify.Style.ERROR);
+ } else if (error instanceof ImportKeysListLoader.NonPgpPartException) {
Notify.showNotify(getActivity(),
- ((ImportKeysListLoader.NonPgpPart) error).getCount() + " " + getResources().
+ ((ImportKeysListLoader.NonPgpPartException) error).getCount() + " " + getResources().
getQuantityString(R.plurals.error_import_non_pgp_part,
- ((ImportKeysListLoader.NonPgpPart) error).getCount()),
+ ((ImportKeysListLoader.NonPgpPartException) error).getCount()),
Notify.Style.OK
);
} else {
@@ -308,9 +307,11 @@ public class ImportKeysListFragment extends ListFragment implements
if (error == null) {
// No error
} else if (error instanceof Keyserver.QueryTooShortException) {
- Notify.showNotify(getActivity(), R.string.error_keyserver_insufficient_query, Notify.Style.ERROR);
+ Notify.showNotify(getActivity(), R.string.error_query_too_short, Notify.Style.ERROR);
} else if (error instanceof Keyserver.TooManyResponsesException) {
- Notify.showNotify(getActivity(), R.string.error_keyserver_too_many_responses, Notify.Style.ERROR);
+ Notify.showNotify(getActivity(), R.string.error_too_many_responses, Notify.Style.ERROR);
+ } else if (error instanceof Keyserver.QueryTooShortOrTooManyResponsesException) {
+ Notify.showNotify(getActivity(), R.string.error_too_short_or_too_many_responses, Notify.Style.ERROR);
} else if (error instanceof Keyserver.QueryFailedException) {
Log.d(Constants.TAG,
"Unrecoverable keyserver query error: " + error.getLocalizedMessage());
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
index 9cc623c83..50ff5c753 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
@@ -17,29 +17,19 @@
package org.sufficientlysecure.keychain.ui;
-import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
import android.view.Menu;
import android.view.MenuItem;
-import com.devspark.appmsg.AppMsg;
-
-import org.spongycastle.bcpg.sig.KeyFlags;
import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Constants.choice.algorithm;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
-import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
-import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.io.IOException;
@@ -51,11 +41,10 @@ public class KeyListActivity extends DrawerActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ // if this is the first time show first time activity
Preferences prefs = Preferences.getPreferences(this);
- if (prefs.getFirstTime()) {
- prefs.setFirstTime(false);
- Intent intent = new Intent(this, FirstTimeActivity.class);
- startActivity(intent);
+ if (prefs.isFirstTime()) {
+ startActivity(new Intent(this, FirstTimeActivity.class));
finish();
return;
}
@@ -85,7 +74,7 @@ public class KeyListActivity extends DrawerActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
- case R.id.menu_key_list_import:
+ case R.id.menu_key_list_add:
importKeys();
return true;
@@ -93,6 +82,12 @@ public class KeyListActivity extends DrawerActivity {
createKey();
return true;
+ case R.id.menu_key_list_import_existing_key:
+ Intent intentImportExisting = new Intent(this, ImportKeysActivity.class);
+ intentImportExisting.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN);
+ startActivityForResult(intentImportExisting, 0);
+ return true;
+
case R.id.menu_key_list_export:
mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE, true);
return true;
@@ -100,25 +95,27 @@ public class KeyListActivity extends DrawerActivity {
case R.id.menu_key_list_debug_read:
try {
KeychainDatabase.debugRead(this);
- AppMsg.makeText(this, "Restored from backup", AppMsg.STYLE_CONFIRM).show();
+ Notify.showNotify(this, "Restored Notify.Style backup", Notify.Style.INFO);
getContentResolver().notifyChange(KeychainContract.KeyRings.CONTENT_URI, null);
} catch (IOException e) {
Log.e(Constants.TAG, "IO Error", e);
- AppMsg.makeText(this, "IO Error: " + e.getMessage(), AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(this, "IO Notify.Style: " + e.getMessage(), Notify.Style.ERROR);
}
return true;
case R.id.menu_key_list_debug_write:
try {
KeychainDatabase.debugWrite(this);
- AppMsg.makeText(this, "Backup successful", AppMsg.STYLE_CONFIRM).show();
- } catch (IOException e) {
+ Notify.showNotify(this, "Backup Notify.Style", Notify.Style.INFO);
+ } catch(IOException e) {
Log.e(Constants.TAG, "IO Error", e);
- AppMsg.makeText(this, "IO Error: " + e.getMessage(), AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(this, "IO Notify.Style: " + e.getMessage(), Notify.Style.ERROR);
}
return true;
case R.id.menu_key_list_debug_first_time:
+ Preferences prefs = Preferences.getPreferences(this);
+ prefs.setFirstTime(true);
Intent intent = new Intent(this, FirstTimeActivity.class);
startActivity(intent);
finish();
@@ -139,4 +136,4 @@ public class KeyListActivity extends DrawerActivity {
startActivity(intent);
}
-} \ No newline at end of file
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index 9d0a80406..aa17aea3d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
+import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -46,14 +47,11 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
-import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Button;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ExportHelper;
@@ -62,6 +60,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.util.Highlighter;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.util.Date;
import java.util.HashMap;
@@ -86,6 +85,7 @@ public class KeyListFragment extends LoaderFragment
private Button mButtonEmptyCreate;
private Button mButtonEmptyImport;
+ public static final int REQUEST_CODE_CREATE_OR_IMPORT_KEY = 0x00007012;
/**
* Load custom layout with StickyListView from library
@@ -104,11 +104,8 @@ public class KeyListFragment extends LoaderFragment
@Override
public void onClick(View v) {
- Intent intent = new Intent(getActivity(), EditKeyActivityOld.class);
- intent.setAction(EditKeyActivityOld.ACTION_CREATE_KEY);
- intent.putExtra(EditKeyActivityOld.EXTRA_GENERATE_DEFAULT_KEYS, true);
- intent.putExtra(EditKeyActivityOld.EXTRA_USER_IDS, ""); // show user id view
- startActivityForResult(intent, 0);
+ Intent intent = new Intent(getActivity(), CreateKeyActivity.class);
+ startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY);
}
});
mButtonEmptyImport = (Button) view.findViewById(R.id.key_list_empty_button_import);
@@ -117,8 +114,8 @@ public class KeyListFragment extends LoaderFragment
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE);
- startActivityForResult(intent, 0);
+ intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN);
+ startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY);
}
});
@@ -339,8 +336,8 @@ public class KeyListFragment extends LoaderFragment
public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds, boolean hasSecret) {
// Can only work on singular secret keys
if(hasSecret && masterKeyIds.length > 1) {
- AppMsg.makeText(getActivity(), R.string.secret_cannot_multiple,
- AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.secret_cannot_multiple,
+ Notify.Style.ERROR);
return;
}
@@ -437,9 +434,7 @@ public class KeyListFragment extends LoaderFragment
private class ItemViewHolder {
TextView mMainUserId;
TextView mMainUserIdRest;
- FrameLayout mStatusLayout;
- TextView mRevoked;
- ImageView mVerified;
+ ImageView mStatus;
}
@Override
@@ -448,9 +443,7 @@ public class KeyListFragment extends LoaderFragment
ItemViewHolder holder = new ItemViewHolder();
holder.mMainUserId = (TextView) view.findViewById(R.id.mainUserId);
holder.mMainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- holder.mStatusLayout = (FrameLayout) view.findViewById(R.id.status_layout);
- holder.mRevoked = (TextView) view.findViewById(R.id.revoked);
- holder.mVerified = (ImageView) view.findViewById(R.id.verified);
+ holder.mStatus = (ImageView) view.findViewById(R.id.status_image);
view.setTag(holder);
return view;
}
@@ -482,30 +475,40 @@ public class KeyListFragment extends LoaderFragment
}
}
- { // set edit button and revoked info, specific by key type
-
- if (cursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {
- // this is a secret key
- h.mStatusLayout.setVisibility(View.VISIBLE);
- h.mRevoked.setVisibility(View.GONE);
- h.mVerified.setVisibility(View.GONE);
- } else {
- // this is a public key - show if it's revoked
-
- boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
- boolean isExpired = !cursor.isNull(INDEX_EXPIRY)
- && new Date(cursor.getLong(INDEX_EXPIRY)*1000).before(new Date());
- if(isRevoked || isExpired) {
- h.mStatusLayout.setVisibility(View.VISIBLE);
- h.mRevoked.setVisibility(View.VISIBLE);
- h.mVerified.setVisibility(View.GONE);
- h.mRevoked.setText(isRevoked ? R.string.revoked : R.string.expired);
+ { // set edit button and status, specific by key type
+
+ boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
+ boolean isExpired = !cursor.isNull(INDEX_EXPIRY)
+ && new Date(cursor.getLong(INDEX_EXPIRY)*1000).before(new Date());
+ boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0;
+
+ // Note: order is important!
+ if (isRevoked) {
+ h.mStatus.setImageDrawable(
+ getResources().getDrawable(R.drawable.status_signature_revoked_cutout));
+ h.mStatus.setColorFilter(getResources().getColor(R.color.android_red_dark),
+ PorterDuff.Mode.SRC_ATOP);
+ h.mStatus.setVisibility(View.VISIBLE);
+ } else if (isExpired) {
+ h.mStatus.setImageDrawable(
+ getResources().getDrawable(R.drawable.status_signature_expired_cutout));
+ h.mStatus.setColorFilter(getResources().getColor(R.color.android_orange_dark),
+ PorterDuff.Mode.SRC_ATOP);
+ h.mStatus.setVisibility(View.VISIBLE);
+ } else if (isVerified) {
+ if (cursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {
+ // this is a secret key
+ h.mStatus.setVisibility(View.GONE);
} else {
- boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0;
- h.mStatusLayout.setVisibility(isVerified ? View.VISIBLE : View.GONE);
- h.mRevoked.setVisibility(View.GONE);
- h.mVerified.setVisibility(isVerified ? View.VISIBLE : View.GONE);
+ // this is a public key - show if it's verified
+ h.mStatus.setImageDrawable(
+ getResources().getDrawable(R.drawable.status_signature_verified_cutout));
+ h.mStatus.setColorFilter(getResources().getColor(R.color.android_green_dark),
+ PorterDuff.Mode.SRC_ATOP);
+ h.mStatus.setVisibility(View.VISIBLE);
}
+ } else {
+ h.mStatus.setVisibility(View.GONE);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
index 75c967c60..43de6774b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/LogDisplayFragment.java
@@ -178,9 +178,11 @@ public class LogDisplayFragment extends ListFragment implements OnTouchListener
if (entry.mParameters != null && entry.mParameters.length > 0
&& entry.mParameters[0] instanceof Integer) {
ih.mText.setText(getResources().getQuantityString(entry.mType.getMsgId(),
- (Integer) entry.mParameters[0], entry.mParameters));
+ (Integer) entry.mParameters[0],
+ entry.mParameters));
} else {
- ih.mText.setText(getResources().getString(entry.mType.getMsgId(), entry.mParameters));
+ ih.mText.setText(getResources().getString(entry.mType.getMsgId(),
+ entry.mParameters));
}
ih.mText.setTextColor(entry.mLevel == LogLevel.DEBUG ? Color.GRAY : Color.BLACK);
convertView.setPadding((entry.mIndent) * dipFactor, 0, 0, 0);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java
new file mode 100644
index 000000000..a906dfa97
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 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;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.view.View;
+import android.widget.ImageView;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.helper.ActionBarHelper;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
+import org.sufficientlysecure.keychain.util.Notify.Style;
+import org.sufficientlysecure.keychain.util.QrCodeUtils;
+
+public class QrCodeActivity extends ActionBarActivity {
+
+ private ImageView mFingerprintQrCode;
+
+ private static final int QR_CODE_SIZE = 1000;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Inflate a "Done" custom action bar
+ ActionBarHelper.setOneButtonView(getSupportActionBar(),
+ R.string.btn_okay, R.drawable.ic_action_done,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // "Done"
+ finish();
+ }
+ }
+ );
+
+ setContentView(R.layout.qr_code_activity);
+
+ Uri dataUri = getIntent().getData();
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ finish();
+ return;
+ }
+
+ mFingerprintQrCode = (ImageView) findViewById(R.id.qr_code_image);
+
+ mFingerprintQrCode.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+
+ ProviderHelper providerHelper = new ProviderHelper(this);
+ try {
+ byte[] blob = (byte[]) providerHelper.getGenericData(
+ KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
+ KeychainContract.KeyRings.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
+ if (blob == null) {
+ Log.e(Constants.TAG, "key not found!");
+ Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR);
+ finish();
+ }
+
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
+ String qrCodeContent = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
+ mFingerprintQrCode.setImageBitmap(QrCodeUtils.getQRCodeBitmap(qrCodeContent, QR_CODE_SIZE));
+ } catch (ProviderHelper.NotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR);
+ finish();
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // custom activity transition to get zoom in effect
+ this.overridePendingTransition(R.anim.qr_code_zoom_enter, android.R.anim.fade_out);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // custom activity transition to get zoom out effect
+ this.overridePendingTransition(0, R.anim.qr_code_zoom_exit);
+ }
+
+} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
index dbd1b7507..57bfc7bd5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
@@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.util.Log;
@@ -92,7 +93,7 @@ public class UploadKeyActivity extends ActionBarActivity {
intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING);
// set data uri as path to keyring
- Uri blobUri = KeychainContract.KeyRingData.buildPublicKeyRingUri(mDataUri);
+ Uri blobUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
intent.setData(blobUri);
// fill values for this action
@@ -105,7 +106,7 @@ public class UploadKeyActivity extends ActionBarActivity {
// Message is received after uploading is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_uploading), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
index cfdea0611..5201b5df8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java
@@ -35,7 +35,7 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.pgp.WrappedPublicKeyRing;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.WrappedSignature;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
@@ -143,16 +143,16 @@ public class ViewCertActivity extends ActionBarActivity
try {
ProviderHelper providerHelper = new ProviderHelper(this);
- WrappedPublicKeyRing signeeRing =
- providerHelper.getWrappedPublicKeyRing(data.getLong(INDEX_MASTER_KEY_ID));
- WrappedPublicKeyRing signerRing =
- providerHelper.getWrappedPublicKeyRing(sig.getKeyId());
+ CanonicalizedPublicKeyRing signeeRing =
+ providerHelper.getCanonicalizedPublicKeyRing(data.getLong(INDEX_MASTER_KEY_ID));
+ CanonicalizedPublicKeyRing signerRing =
+ providerHelper.getCanonicalizedPublicKeyRing(sig.getKeyId());
try {
sig.init(signerRing.getPublicKey());
if (sig.verifySignature(signeeRing.getPublicKey(), signeeUid)) {
mStatus.setText(R.string.cert_verify_ok);
- mStatus.setTextColor(getResources().getColor(R.color.result_green));
+ mStatus.setTextColor(getResources().getColor(R.color.android_green_light));
} else {
mStatus.setText(R.string.cert_verify_failed);
mStatus.setTextColor(getResources().getColor(R.color.alert));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index a9cd0976b..44a51a75f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -19,9 +19,9 @@
package org.sufficientlysecure.keychain.ui;
import android.annotation.TargetApi;
-import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
+import android.graphics.PorterDuff;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
@@ -43,8 +43,9 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
-
-import com.devspark.appmsg.AppMsg;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@@ -54,11 +55,12 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.OperationResults.ImportResult;
+import org.sufficientlysecure.keychain.service.OperationResultParcel;
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout.TabColorizer;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout;
+import org.sufficientlysecure.keychain.util.Notify;
import java.util.Date;
import java.util.HashMap;
@@ -81,11 +83,11 @@ public class ViewKeyActivity extends ActionBarActivity implements
private ViewPager mViewPager;
private SlidingTabLayout mSlidingTabLayout;
private PagerTabStripAdapter mTabsAdapter;
- private View mStatusDivider;
- private View mStatusRevoked;
- private View mStatusExpired;
- public static final int REQUEST_CODE_LOOKUP_KEY = 0x00007006;
+ private LinearLayout mStatusLayout;
+ private TextView mStatusText;
+ private ImageView mStatusImage;
+ private View mStatusDivider;
// NFC
private NfcAdapter mNfcAdapter;
@@ -115,9 +117,10 @@ public class ViewKeyActivity extends ActionBarActivity implements
setContentView(R.layout.view_key_activity);
- mStatusDivider = findViewById(R.id.status_divider);
- mStatusRevoked = findViewById(R.id.view_key_revoked);
- mStatusExpired = findViewById(R.id.view_key_expired);
+ mStatusLayout = (LinearLayout) findViewById(R.id.view_key_status_layout);
+ mStatusText = (TextView) findViewById(R.id.view_key_status_text);
+ mStatusImage = (ImageView) findViewById(R.id.view_key_status_image);
+ mStatusDivider = findViewById(R.id.view_key_status_divider);
mViewPager = (ViewPager) findViewById(R.id.view_key_pager);
mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.view_key_sliding_tab_layout);
@@ -140,20 +143,27 @@ public class ViewKeyActivity extends ActionBarActivity implements
switchToTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
}
- Uri dataUri = getDataUri();
- if (dataUri == null) {
- Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ mDataUri = getIntent().getData();
+ if (mDataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be uri of key!");
finish();
return;
}
+ if (mDataUri.getHost().equals(ContactsContract.AUTHORITY)) {
+ mDataUri = ContactHelper.dataUriFromContactUri(this, mDataUri);
+ }
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
- loadData(dataUri);
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
- initNfc(dataUri);
+ initNfc(mDataUri);
mShowAdvancedTabs = false;
- initTabs(dataUri);
+ initTabs(mDataUri);
// switch to tab selected by extra
mViewPager.setCurrentItem(switchToTab);
@@ -230,24 +240,6 @@ public class ViewKeyActivity extends ActionBarActivity implements
mSlidingTabLayout.setViewPager(mViewPager);
}
- private Uri getDataUri() {
- Uri dataUri = getIntent().getData();
- if (dataUri != null && dataUri.getHost().equals(ContactsContract.AUTHORITY)) {
- dataUri = ContactHelper.dataUriFromContactUri(this, dataUri);
- }
- return dataUri;
- }
-
- private void loadData(Uri dataUri) {
- mDataUri = dataUri;
-
- Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
-
- // Prepare the loaders. Either re-connect with an existing ones,
- // or start new ones.
- getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
- }
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
@@ -268,14 +260,6 @@ public class ViewKeyActivity extends ActionBarActivity implements
startActivity(homeIntent);
return true;
}
- case R.id.menu_key_view_update: {
- updateFromKeyserver(mDataUri, mProviderHelper);
- return true;
- }
- case R.id.menu_key_view_export_keyserver: {
- uploadToKeyserver(mDataUri);
- return true;
- }
case R.id.menu_key_view_export_file: {
exportToFile(mDataUri, mExportHelper, mProviderHelper);
return true;
@@ -295,7 +279,7 @@ public class ViewKeyActivity extends ActionBarActivity implements
}
}
} catch (ProviderHelper.NotFoundException e) {
- AppMsg.makeText(this, R.string.error_key_not_found, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR);
Log.e(Constants.TAG, "Key not found", e);
}
return super.onOptionsItemSelected(item);
@@ -317,26 +301,6 @@ public class ViewKeyActivity extends ActionBarActivity implements
);
}
- private void uploadToKeyserver(Uri dataUri) throws ProviderHelper.NotFoundException {
- Intent uploadIntent = new Intent(this, UploadKeyActivity.class);
- uploadIntent.setData(dataUri);
- startActivityForResult(uploadIntent, 0);
- }
-
- private void updateFromKeyserver(Uri dataUri, ProviderHelper providerHelper)
- throws ProviderHelper.NotFoundException {
- byte[] blob = (byte[]) providerHelper.getGenericData(
- KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
- KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
-
- Intent queryIntent = new Intent(this, ImportKeysActivity.class);
- queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT);
- queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint);
-
- startActivityForResult(queryIntent, REQUEST_CODE_LOOKUP_KEY);
- }
-
private void deleteKey(Uri dataUri, ExportHelper exportHelper) {
// Message is received after key is deleted
Handler returnHandler = new Handler() {
@@ -352,22 +316,11 @@ public class ViewKeyActivity extends ActionBarActivity implements
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_LOOKUP_KEY: {
- if (resultCode == Activity.RESULT_OK) {
- ImportResult result = data.getParcelableExtra(ImportKeysActivity.EXTRA_RESULT);
- if (result != null) {
- result.displayNotify(this);
- }
- }
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
-
- break;
- }
+ if (data != null && data.hasExtra(OperationResultParcel.EXTRA_RESULT)) {
+ OperationResultParcel result = data.getParcelableExtra(OperationResultParcel.EXTRA_RESULT);
+ result.createNotify(this).show();
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
}
}
@@ -455,8 +408,8 @@ public class ViewKeyActivity extends ActionBarActivity implements
public void handleMessage(Message msg) {
switch (msg.what) {
case NFC_SENT:
- AppMsg.makeText(ViewKeyActivity.this, R.string.nfc_successful,
- AppMsg.STYLE_INFO).show();
+ Notify.showNotify(
+ ViewKeyActivity.this, R.string.nfc_successful, Notify.Style.INFO);
break;
}
}
@@ -515,22 +468,32 @@ public class ViewKeyActivity extends ActionBarActivity implements
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(masterKeyId);
getSupportActionBar().setSubtitle(keyIdStr);
- // If this key is revoked, it cannot be used for anything!
- if (data.getInt(INDEX_UNIFIED_IS_REVOKED) != 0) {
+ boolean isRevoked = data.getInt(INDEX_UNIFIED_IS_REVOKED) > 0;
+ boolean isExpired = !data.isNull(INDEX_UNIFIED_EXPIRY)
+ && new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000).before(new Date());
+
+ // Note: order is important
+ if (isRevoked) {
+ mStatusText.setText(R.string.view_key_revoked);
+ mStatusText.setTextColor(getResources().getColor(R.color.android_red_dark));
+ mStatusImage.setImageDrawable(
+ getResources().getDrawable(R.drawable.status_signature_revoked_cutout));
+ mStatusImage.setColorFilter(getResources().getColor(R.color.android_red_dark),
+ PorterDuff.Mode.SRC_ATOP);
+ mStatusDivider.setVisibility(View.VISIBLE);
+ mStatusLayout.setVisibility(View.VISIBLE);
+ } else if (isExpired) {
+ mStatusText.setText(R.string.view_key_expired);
+ mStatusText.setTextColor(getResources().getColor(R.color.android_orange_dark));
+ mStatusImage.setImageDrawable(
+ getResources().getDrawable(R.drawable.status_signature_expired_cutout));
+ mStatusImage.setColorFilter(getResources().getColor(R.color.android_orange_dark),
+ PorterDuff.Mode.SRC_ATOP);
mStatusDivider.setVisibility(View.VISIBLE);
- mStatusRevoked.setVisibility(View.VISIBLE);
- mStatusExpired.setVisibility(View.GONE);
+ mStatusLayout.setVisibility(View.VISIBLE);
} else {
- mStatusRevoked.setVisibility(View.GONE);
-
- Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
- if (!data.isNull(INDEX_UNIFIED_EXPIRY) && expiryDate.before(new Date())) {
- mStatusDivider.setVisibility(View.VISIBLE);
- mStatusExpired.setVisibility(View.VISIBLE);
- } else {
- mStatusDivider.setVisibility(View.GONE);
- mStatusExpired.setVisibility(View.GONE);
- }
+ mStatusDivider.setVisibility(View.GONE);
+ mStatusLayout.setVisibility(View.GONE);
}
break;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
index f0636cf2c..370a7312f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
@@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.database.Cursor;
+import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
@@ -27,19 +28,21 @@ import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.ListView;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import java.util.Date;
@@ -52,7 +55,9 @@ public class ViewKeyMainFragment extends LoaderFragment implements
private View mActionEditDivider;
private View mActionEncrypt;
private View mActionCertify;
- private View mActionCertifyDivider;
+ private View mActionCertifyText;
+ private ImageView mActionCertifyImage;
+ private View mActionUpdate;
private ListView mUserIds;
@@ -76,7 +81,12 @@ public class ViewKeyMainFragment extends LoaderFragment implements
mActionEditDivider = view.findViewById(R.id.view_key_action_edit_divider);
mActionEncrypt = view.findViewById(R.id.view_key_action_encrypt);
mActionCertify = view.findViewById(R.id.view_key_action_certify);
- mActionCertifyDivider = view.findViewById(R.id.view_key_action_certify_divider);
+ mActionCertifyText = view.findViewById(R.id.view_key_action_certify_text);
+ mActionCertifyImage = (ImageView) view.findViewById(R.id.view_key_action_certify_image);
+ // make certify image gray, like action icons
+ mActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
+ PorterDuff.Mode.SRC_IN);
+ mActionUpdate = view.findViewById(R.id.view_key_action_update);
return root;
}
@@ -116,6 +126,15 @@ public class ViewKeyMainFragment extends LoaderFragment implements
editKey(mDataUri);
}
});
+ mActionUpdate.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ try {
+ updateFromKeyserver(mDataUri, new ProviderHelper(getActivity()));
+ } catch (NotFoundException e) {
+ Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR);
+ }
+ }
+ });
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0);
mUserIds.setAdapter(mUserIdsAdapter);
@@ -182,6 +201,7 @@ public class ViewKeyMainFragment extends LoaderFragment implements
if (data.getInt(INDEX_UNIFIED_IS_REVOKED) != 0) {
mActionEdit.setEnabled(false);
mActionCertify.setEnabled(false);
+ mActionCertifyText.setEnabled(false);
mActionEncrypt.setEnabled(false);
} else {
mActionEdit.setEnabled(true);
@@ -189,9 +209,11 @@ public class ViewKeyMainFragment extends LoaderFragment implements
Date expiryDate = new Date(data.getLong(INDEX_UNIFIED_EXPIRY) * 1000);
if (!data.isNull(INDEX_UNIFIED_EXPIRY) && expiryDate.before(new Date())) {
mActionCertify.setEnabled(false);
+ mActionCertifyText.setEnabled(false);
mActionEncrypt.setEnabled(false);
} else {
mActionCertify.setEnabled(true);
+ mActionCertifyText.setEnabled(true);
mActionEncrypt.setEnabled(true);
}
}
@@ -225,7 +247,7 @@ public class ViewKeyMainFragment extends LoaderFragment implements
private void encrypt(Uri dataUri) {
// If there is no encryption key, don't bother.
if (!mHasEncrypt) {
- AppMsg.makeText(getActivity(), R.string.error_no_encrypt_subkey, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.error_no_encrypt_subkey, Notify.Style.ERROR);
return;
}
try {
@@ -243,18 +265,30 @@ public class ViewKeyMainFragment extends LoaderFragment implements
}
}
+ private void updateFromKeyserver(Uri dataUri, ProviderHelper providerHelper)
+ throws ProviderHelper.NotFoundException {
+ byte[] blob = (byte[]) providerHelper.getGenericData(
+ KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
+ KeychainContract.Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
+
+ Intent queryIntent = new Intent(getActivity(), ImportKeysActivity.class);
+ queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT);
+ queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint);
+
+ startActivityForResult(queryIntent, 0);
+ }
+
private void certify(Uri dataUri) {
Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
signIntent.setData(dataUri);
- startActivity(signIntent);
+ startActivityForResult(signIntent, 0);
}
private void editKey(Uri dataUri) {
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri));
-// editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
-// startActivityForResult(editIntent, 0);
- startActivity(editIntent);
+ startActivityForResult(editIntent, 0);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java
index 52b573f47..54ab76464 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyShareFragment.java
@@ -20,7 +20,14 @@ package org.sufficientlysecure.keychain.ui;
import android.annotation.TargetApi;
import android.content.Intent;
import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
@@ -33,8 +40,6 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
-import com.devspark.appmsg.AppMsg;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
@@ -44,9 +49,10 @@ import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Notify;
import org.sufficientlysecure.keychain.util.QrCodeUtils;
import java.io.IOException;
@@ -65,6 +71,7 @@ public class ViewKeyShareFragment extends LoaderFragment implements
private View mKeyClipboardButton;
private View mNfcHelpButton;
private View mNfcPrefsButton;
+ private View mKeyUploadButton;
ProviderHelper mProviderHelper;
@@ -89,6 +96,7 @@ public class ViewKeyShareFragment extends LoaderFragment implements
mKeyClipboardButton = view.findViewById(R.id.view_key_action_key_clipboard);
mNfcHelpButton = view.findViewById(R.id.view_key_action_nfc_help);
mNfcPrefsButton = view.findViewById(R.id.view_key_action_nfc_prefs);
+ mKeyUploadButton = view.findViewById(R.id.view_key_action_upload);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mNfcPrefsButton.setVisibility(View.VISIBLE);
@@ -139,6 +147,12 @@ public class ViewKeyShareFragment extends LoaderFragment implements
showNfcPrefs();
}
});
+ mKeyUploadButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ uploadToKeyserver();
+ }
+ });
return root;
}
@@ -152,7 +166,7 @@ public class ViewKeyShareFragment extends LoaderFragment implements
KeyRings.buildUnifiedKeyRingUri(dataUri),
Keys.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
String fingerprint = PgpKeyHelper.convertFingerprintToHex(data);
- if(!toClipboard){
+ if (!toClipboard) {
content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
} else {
content = fingerprint;
@@ -171,13 +185,13 @@ public class ViewKeyShareFragment extends LoaderFragment implements
} else {
message = getResources().getString(R.string.key_copied_to_clipboard);
}
- AppMsg.makeText(getActivity(), message, AppMsg.STYLE_INFO).show();
+ Notify.showNotify(getActivity(), message, Notify.Style.OK);
} else {
// Android will fail with android.os.TransactionTooLargeException if key is too big
// see http://www.lonestarprod.com/?p=34
if (content.length() >= 86389) {
- AppMsg.makeText(getActivity(), R.string.key_too_big_for_sharing,
- AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.key_too_big_for_sharing,
+ Notify.Style.ERROR);
return;
}
@@ -195,19 +209,20 @@ public class ViewKeyShareFragment extends LoaderFragment implements
}
} catch (PgpGeneralException e) {
Log.e(Constants.TAG, "error processing key!", e);
- AppMsg.makeText(getActivity(), R.string.error_key_processing, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.error_key_processing, Notify.Style.ERROR);
} catch (IOException e) {
Log.e(Constants.TAG, "error processing key!", e);
- AppMsg.makeText(getActivity(), R.string.error_key_processing, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.error_key_processing, Notify.Style.ERROR);
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "key not found!", e);
- AppMsg.makeText(getActivity(), R.string.error_key_not_found, AppMsg.STYLE_ALERT).show();
+ Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR);
}
}
private void showQrCodeDialog() {
- ShareQrCodeDialogFragment dialog = ShareQrCodeDialogFragment.newInstance(mDataUri);
- dialog.show(ViewKeyShareFragment.this.getActivity().getSupportFragmentManager(), "shareQrCodeDialog");
+ Intent qrCodeIntent = new Intent(getActivity(), QrCodeActivity.class);
+ qrCodeIntent.setData(mDataUri);
+ startActivity(qrCodeIntent);
}
private void showNfcHelpDialog() {
@@ -292,10 +307,7 @@ public class ViewKeyShareFragment extends LoaderFragment implements
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
- String qrCodeContent = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
- mFingerprintQrCode.setImageBitmap(
- QrCodeUtils.getQRCodeBitmap(qrCodeContent, QR_CODE_SIZE)
- );
+ loadQrCode(fingerprint);
break;
}
@@ -311,4 +323,42 @@ public class ViewKeyShareFragment extends LoaderFragment implements
*/
public void onLoaderReset(Loader<Cursor> loader) {
}
+
+ /**
+ * Load QR Code asynchronously and with a fade in animation
+ *
+ * @param fingerprint
+ */
+ private void loadQrCode(final String fingerprint) {
+ AsyncTask<Void, Void, Bitmap> loadTask =
+ new AsyncTask<Void, Void, Bitmap>() {
+ protected Bitmap doInBackground(Void... unused) {
+ String qrCodeContent = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
+ return QrCodeUtils.getQRCodeBitmap(qrCodeContent, QR_CODE_SIZE);
+ }
+
+ protected void onPostExecute(Bitmap qrCode) {
+ mFingerprintQrCode.setImageBitmap(qrCode);
+
+ // Transition drawable with a transparent drawable and the final bitmap
+ final TransitionDrawable td =
+ new TransitionDrawable(new Drawable[]{
+ new ColorDrawable(Color.TRANSPARENT),
+ new BitmapDrawable(getResources(), qrCode)
+ });
+
+ mFingerprintQrCode.setImageDrawable(td);
+ td.startTransition(200);
+ }
+ };
+
+ loadTask.execute();
+ }
+
+ private void uploadToKeyserver() {
+ Intent uploadIntent = new Intent(getActivity(), UploadKeyActivity.class);
+ uploadIntent.setData(mDataUri);
+ startActivityForResult(uploadIntent, 0);
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
index 99f959035..4971c535c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
@@ -30,20 +30,21 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
import java.io.BufferedInputStream;
+import java.io.IOException;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
public class ImportKeysListLoader
extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
- public static class FileHasNoContent extends Exception {
-
+ public static class NoValidKeysException extends Exception {
}
- public static class NonPgpPart extends Exception {
+ public static class NonPgpPartException extends Exception {
private int mCount;
- public NonPgpPart(int count) {
+ public NonPgpPartException(int count) {
this.mCount = count;
}
@@ -67,7 +68,6 @@ public class ImportKeysListLoader
@Override
public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
-
// This has already been loaded! nvm any further, just return
if (mEntryListWrapper != null) {
return mEntryListWrapper;
@@ -119,9 +119,6 @@ public class ImportKeysListLoader
* @return
*/
private void generateListOfKeyrings(InputData inputData) {
-
- boolean isEmpty = true;
-
PositionAwareInputStream progressIn = new PositionAwareInputStream(
inputData.getInputStream());
@@ -130,27 +127,23 @@ public class ImportKeysListLoader
// armor blocks
BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
try {
-
- // read all available blocks... (asc files can contain many blocks with BEGIN END)
- while (bufferedInput.available() > 0) {
- // TODO: deal with non-keyring objects?
- List<UncachedKeyRing> rings = UncachedKeyRing.fromStream(bufferedInput);
- for(UncachedKeyRing key : rings) {
- ImportKeysListEntry item = new ImportKeysListEntry(getContext(), key);
- mData.add(item);
- mParcelableRings.put(item.hashCode(), new ParcelableKeyRing(key.getEncoded()));
- isEmpty = false;
- }
+ // parse all keyrings
+ Iterator<UncachedKeyRing> it = UncachedKeyRing.fromStream(bufferedInput);
+ while (it.hasNext()) {
+ UncachedKeyRing ring = it.next();
+ ImportKeysListEntry item = new ImportKeysListEntry(getContext(), ring);
+ mData.add(item);
+ mParcelableRings.put(item.hashCode(), new ParcelableKeyRing(ring.getEncoded()));
}
- } catch (Exception e) {
- Log.e(Constants.TAG, "Exception on parsing key file!", e);
- mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, e);
- }
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException on parsing key file! Return NoValidKeysException!", e);
- if (isEmpty) {
- Log.e(Constants.TAG, "File has no content!", new FileHasNoContent());
+ NoValidKeysException e1 = new NoValidKeysException();
mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
- (mData, new FileHasNoContent());
+ (mData, e1);
+ } catch (Exception e) {
+ Log.e(Constants.TAG, "Other Exception on parsing key file!", e);
+ mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, e);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
index 18312660a..6d46f3c8f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java
@@ -19,6 +19,8 @@ package org.sufficientlysecure.keychain.ui.adapter;
import android.content.Context;
import android.database.Cursor;
+import android.graphics.PorterDuff;
+import android.graphics.Typeface;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
@@ -156,7 +158,10 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
if (isRevoked) {
// set revocation icon (can this even be primary?)
- vVerified.setImageResource(R.drawable.key_certify_revoke);
+ vVerified.setImageResource(R.drawable.status_signature_revoked_cutout);
+ vVerified.setColorFilter(
+ mContext.getResources().getColor(R.color.bg_gray),
+ PorterDuff.Mode.SRC_IN);
// disable and strike through text for revoked user ids
vName.setEnabled(false);
@@ -170,22 +175,33 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
vAddress.setEnabled(true);
vComment.setEnabled(true);
- // verified: has been verified
- // isPrimary: show small star icon for primary user ids
- int verified = cursor.getInt(INDEX_VERIFIED);
- switch (verified) {
+ if (isPrimary) {
+ vName.setTypeface(null, Typeface.BOLD);
+ vAddress.setTypeface(null, Typeface.BOLD);
+ } else {
+ vName.setTypeface(null, Typeface.NORMAL);
+ vAddress.setTypeface(null, Typeface.NORMAL);
+ }
+
+ int isVerified = cursor.getInt(INDEX_VERIFIED);
+ switch (isVerified) {
case Certs.VERIFIED_SECRET:
- vVerified.setImageResource(isPrimary
- ? R.drawable.key_certify_primary_ok_depth0
- : R.drawable.key_certify_ok_depth0);
+ vVerified.setImageResource(R.drawable.status_signature_verified_cutout);
+ vVerified.setColorFilter(
+ mContext.getResources().getColor(R.color.android_green_dark),
+ PorterDuff.Mode.SRC_IN);
break;
case Certs.VERIFIED_SELF:
- vVerified.setImageResource(isPrimary
- ? R.drawable.key_certify_primary_ok_self
- : R.drawable.key_certify_ok_self);
+ vVerified.setImageResource(R.drawable.status_signature_unverified_cutout);
+ vVerified.setColorFilter(
+ mContext.getResources().getColor(R.color.bg_gray),
+ PorterDuff.Mode.SRC_IN);
break;
default:
- vVerified.setImageResource(R.drawable.key_certify_error);
+ vVerified.setImageResource(R.drawable.status_signature_invalid_cutout);
+ vVerified.setColorFilter(
+ mContext.getResources().getColor(R.color.android_red_dark),
+ PorterDuff.Mode.SRC_IN);
break;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
index d723f88af..ef2659cf8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
@@ -33,8 +33,8 @@ import android.support.v4.app.FragmentActivity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.WindowManager.LayoutParams;
import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
@@ -44,8 +44,8 @@ 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.WrappedSecretKey;
-import org.sufficientlysecure.keychain.pgp.WrappedSecretKeyRing;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
@@ -62,7 +62,6 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
private Messenger mMessenger;
private EditText mPassphraseEditText;
- private boolean mCanKB;
/**
* Shows passphrase dialog to cache a new passphrase the user enters for using it later for
@@ -102,10 +101,10 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
// check if secret key has a passphrase
if (!(secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none)) {
try {
- if (!new ProviderHelper(context).getWrappedSecretKeyRing(secretKeyId).hasPassphrase()) {
+ if (!new ProviderHelper(context).getCanonicalizedSecretKeyRing(secretKeyId).hasPassphrase()) {
throw new PgpGeneralException("No passphrase! No passphrase dialog needed!");
}
- } catch(ProviderHelper.NotFoundException e) {
+ } catch (ProviderHelper.NotFoundException e) {
throw new PgpGeneralException("Error: Key not found!", e);
}
}
@@ -120,11 +119,6 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
return frag;
}
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
/**
* Creates dialog
*/
@@ -138,7 +132,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
alert.setTitle(R.string.title_authentication);
- final WrappedSecretKeyRing secretRing;
+ final CanonicalizedSecretKeyRing secretRing;
String userId;
if (secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none) {
@@ -147,7 +141,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
} else {
try {
ProviderHelper helper = new ProviderHelper(activity);
- secretRing = helper.getWrappedSecretKeyRing(secretKeyId);
+ secretRing = helper.getCanonicalizedSecretKeyRing(secretKeyId);
// yes the inner try/catch block is necessary, otherwise the final variable
// above can't be statically verified to have been set in all cases because
// the catch clause doesn't return.
@@ -165,7 +159,6 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
}
});
alert.setCancelable(false);
- mCanKB = false;
return alert.create();
}
@@ -190,7 +183,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
// Early breakout if we are dealing with a symmetric key
if (secretRing == null) {
PassphraseCacheService.addCachedPassphrase(activity, Constants.key.symmetric,
- passphrase, getString(R.string.passp_cache_notif_pwd));
+ passphrase, getString(R.string.passp_cache_notif_pwd));
// also return passphrase back to activity
Bundle data = new Bundle();
data.putString(MESSAGE_DATA_PASSPHRASE, passphrase);
@@ -198,9 +191,9 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
return;
}
- WrappedSecretKey unlockedSecretKey = null;
+ CanonicalizedSecretKey unlockedSecretKey = null;
- for(WrappedSecretKey clickSecretKey : secretRing.secretKeyIterator()) {
+ for (CanonicalizedSecretKey clickSecretKey : secretRing.secretKeyIterator()) {
try {
boolean unlocked = clickSecretKey.unlock(passphrase);
if (unlocked) {
@@ -232,9 +225,9 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
try {
PassphraseCacheService.addCachedPassphrase(activity, masterKeyId, passphrase,
- secretRing.getPrimaryUserIdWithFallback());
- } catch(PgpGeneralException e) {
- Log.e(Constants.TAG, "adding of a passhrase failed", e);
+ secretRing.getPrimaryUserIdWithFallback());
+ } catch (PgpGeneralException e) {
+ Log.e(Constants.TAG, "adding of a passphrase failed", e);
}
if (unlockedSecretKey.getKeyId() != masterKeyId) {
@@ -258,20 +251,30 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
}
});
- mCanKB = true;
- return alert.show();
- }
+ // Hack to open keyboard.
+ // This is the only method that I found to work across all Android versions
+ // http://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/
+ // Notes: * onCreateView can't be used because we want to add buttons to the dialog
+ // * opening in onActivityCreated does not work on Android 4.4
+ mPassphraseEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ mPassphraseEditText.post(new Runnable() {
+ @Override
+ public void run() {
+ InputMethodManager imm = (InputMethodManager) getActivity()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(mPassphraseEditText, InputMethodManager.SHOW_IMPLICIT);
+ }
+ });
+ }
+ });
+ mPassphraseEditText.requestFocus();
- @Override
- public void onActivityCreated(Bundle arg0) {
- super.onActivityCreated(arg0);
- if (mCanKB) {
- // request focus and open soft keyboard
- mPassphraseEditText.requestFocus();
- getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
-
- mPassphraseEditText.setOnEditorActionListener(this);
- }
+ mPassphraseEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE);
+ mPassphraseEditText.setOnEditorActionListener(this);
+
+ return alert.show();
}
@Override
@@ -282,6 +285,27 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
sendMessageToHandler(MESSAGE_CANCEL);
}
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ Log.d(Constants.TAG, "onDismiss");
+
+ // hide keyboard on dismiss
+ hideKeyboard();
+ }
+
+ private void hideKeyboard() {
+ InputMethodManager inputManager = (InputMethodManager) getActivity()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ //check if no view has focus:
+ View v = getActivity().getCurrentFocus();
+ if (v == null)
+ return;
+
+ inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
+ }
+
/**
* Associate the "done" button on the soft keyboard with the okay button in the view
*/
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
index 93da48b75..1386ed098 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui.dialog;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Message;
@@ -32,6 +33,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager.LayoutParams;
import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
@@ -164,18 +166,50 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
}
});
+ // Hack to open keyboard.
+ // This is the only method that I found to work across all Android versions
+ // http://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/
+ // Notes: * onCreateView can't be used because we want to add buttons to the dialog
+ // * opening in onActivityCreated does not work on Android 4.4
+ mPassphraseEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ mPassphraseEditText.post(new Runnable() {
+ @Override
+ public void run() {
+ InputMethodManager imm = (InputMethodManager) getActivity()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(mPassphraseEditText, InputMethodManager.SHOW_IMPLICIT);
+ }
+ });
+ }
+ });
+ mPassphraseEditText.requestFocus();
+
+ mPassphraseAgainEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE);
+ mPassphraseAgainEditText.setOnEditorActionListener(this);
+
return alert.show();
}
@Override
- public void onActivityCreated(Bundle arg0) {
- super.onActivityCreated(arg0);
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
- // request focus and open soft keyboard
- mPassphraseEditText.requestFocus();
- getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ // hide keyboard on dismiss
+ hideKeyboard();
+ }
- mPassphraseAgainEditText.setOnEditorActionListener(this);
+ private void hideKeyboard() {
+ InputMethodManager inputManager = (InputMethodManager) getActivity()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ //check if no view has focus:
+ View v = getActivity().getCurrentFocus();
+ if (v == null)
+ return;
+
+ inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
/**
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
deleted file mode 100644
index 24608784b..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareQrCodeDialogFragment.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.net.Uri;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.devspark.appmsg.AppMsg;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.QrCodeUtils;
-
-public class ShareQrCodeDialogFragment extends DialogFragment {
- private static final String ARG_KEY_URI = "uri";
-
- private ImageView mImage;
- private TextView mText;
-
- private static final int QR_CODE_SIZE = 1000;
-
- /**
- * Creates new instance of this dialog fragment
- */
- public static ShareQrCodeDialogFragment newInstance(Uri dataUri) {
- ShareQrCodeDialogFragment frag = new ShareQrCodeDialogFragment();
- Bundle args = new Bundle();
- args.putParcelable(ARG_KEY_URI, dataUri);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity activity = getActivity();
-
- Uri dataUri = getArguments().getParcelable(ARG_KEY_URI);
-
- CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(getActivity());
- alert.setTitle(R.string.share_qr_code_dialog_title);
-
- LayoutInflater inflater = activity.getLayoutInflater();
- View view = inflater.inflate(R.layout.share_qr_code_dialog, null);
- alert.setView(view);
-
- mImage = (ImageView) view.findViewById(R.id.share_qr_code_dialog_image);
- mText = (TextView) view.findViewById(R.id.share_qr_code_dialog_text);
-
- ProviderHelper providerHelper = new ProviderHelper(getActivity());
- String content;
- try {
- alert.setPositiveButton(R.string.btn_okay, null);
-
- byte[] blob = (byte[]) providerHelper.getGenericData(
- KeyRings.buildUnifiedKeyRingUri(dataUri),
- KeyRings.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
- if (blob == null) {
- Log.e(Constants.TAG, "key not found!");
- AppMsg.makeText(getActivity(), R.string.error_key_not_found, AppMsg.STYLE_ALERT).show();
- return null;
- }
-
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);
- mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint);
- content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
- setQrCode(content);
- } catch (ProviderHelper.NotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
- AppMsg.makeText(getActivity(), R.string.error_key_not_found, AppMsg.STYLE_ALERT).show();
- return null;
- }
-
- return alert.show();
- }
-
- private void setQrCode(String data) {
- mImage.setImageBitmap(QrCodeUtils.getQRCodeBitmap(data, QR_CODE_SIZE));
- }
-
-}