aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui
diff options
context:
space:
mode:
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SignKeyActivity.java)26
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java211
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java)13
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java91
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java)19
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java186
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java17
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java15
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java20
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java82
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java42
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java371
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java92
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java313
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java17
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java39
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java12
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java84
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java13
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java99
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java136
27 files changed, 1062 insertions, 858 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SignKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
index d9fb294d5..aab6b81d9 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SignKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
@@ -56,7 +56,7 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
/**
* Signs the specified public key with the specified secret master key
*/
-public class SignKeyActivity extends ActionBarActivity implements
+public class CertifyKeyActivity extends ActionBarActivity implements
SelectSecretKeyLayoutFragment.SelectSecretKeyCallback {
private BootstrapButton mSignButton;
private CheckBox mUploadKeyCheckbox;
@@ -72,7 +72,7 @@ public class SignKeyActivity extends ActionBarActivity implements
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.sign_key_activity);
+ setContentView(R.layout.certify_key_activity);
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(true);
@@ -164,8 +164,8 @@ public class SignKeyActivity extends ActionBarActivity implements
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
} catch (PgpGeneralException e) {
- Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
- // send message to handler to start encryption directly
+ Log.d(Constants.TAG, "No passphrase for this secret key!");
+ // send message to handler to start certification directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
}
}
@@ -196,8 +196,8 @@ public class SignKeyActivity extends ActionBarActivity implements
String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId);
if (passphrase == null) {
showPassphraseDialog(mMasterKeyId);
- return; // bail out; need to wait until the user has entered the passphrase
- // before trying again
+ // bail out; need to wait until the user has entered the passphrase before trying again
+ return;
} else {
startSigning();
}
@@ -218,13 +218,13 @@ public class SignKeyActivity extends ActionBarActivity implements
// Send all information needed to service to sign key in other thread
Intent intent = new Intent(this, KeychainIntentService.class);
- intent.setAction(KeychainIntentService.ACTION_SIGN_KEYRING);
+ intent.setAction(KeychainIntentService.ACTION_CERTIFY_KEYRING);
// fill values for this action
Bundle data = new Bundle();
- data.putLong(KeychainIntentService.SIGN_KEY_MASTER_KEY_ID, mMasterKeyId);
- data.putLong(KeychainIntentService.SIGN_KEY_PUB_KEY_ID, mPubKeyId);
+ data.putLong(KeychainIntentService.CERTIFY_KEY_MASTER_KEY_ID, mMasterKeyId);
+ data.putLong(KeychainIntentService.CERTIFY_KEY_PUB_KEY_ID, mPubKeyId);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@@ -237,14 +237,12 @@ public class SignKeyActivity extends ActionBarActivity implements
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- Toast.makeText(SignKeyActivity.this, R.string.key_sign_success,
+ Toast.makeText(CertifyKeyActivity.this, R.string.key_sign_success,
Toast.LENGTH_SHORT).show();
// check if we need to send the key to the server or not
if (mUploadKeyCheckbox.isChecked()) {
- /*
- * upload the newly signed key to the key server
- */
+ // upload the newly signed key to the keyserver
uploadKey();
} else {
setResult(RESULT_OK);
@@ -291,7 +289,7 @@ public class SignKeyActivity extends ActionBarActivity implements
super.handleMessage(message);
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- Toast.makeText(SignKeyActivity.this, R.string.key_send_success,
+ Toast.makeText(CertifyKeyActivity.this, R.string.key_send_success,
Toast.LENGTH_SHORT).show();
setResult(RESULT_OK);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
index 26657479f..652310cd2 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
@@ -34,7 +34,7 @@ import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.FileHelper;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.pgp.PgpOperation;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
@@ -43,7 +43,6 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.LookupUnknownKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
@@ -61,7 +60,7 @@ import android.view.animation.AnimationUtils;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
@@ -78,14 +77,20 @@ public class DecryptActivity extends DrawerActivity {
/* EXTRA keys for input */
public static final String EXTRA_TEXT = "text";
+ private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
+ private static final int RESULT_CODE_FILE = 0x00007003;
+
private long mSignatureKeyId = 0;
private boolean mReturnResult = false;
+
+ // TODO: replace signed only checks with something more intelligent
+ // PgpDecryptVerify should handle all automatically!!!
private boolean mSignedOnly = false;
private boolean mAssumeSymmetricEncryption = false;
private EditText mMessage = null;
- private LinearLayout mSignatureLayout = null;
+ private RelativeLayout mSignatureLayout = null;
private ImageView mSignatureStatusImage = null;
private TextView mUserId = null;
private TextView mUserIdRest = null;
@@ -100,6 +105,7 @@ public class DecryptActivity extends DrawerActivity {
private EditText mFilename = null;
private CheckBox mDeleteAfter = null;
private BootstrapButton mBrowse = null;
+ private BootstrapButton mLookupKey = null;
private String mInputFilename = null;
private String mOutputFilename = null;
@@ -107,14 +113,10 @@ public class DecryptActivity extends DrawerActivity {
private Uri mContentUri = null;
private boolean mReturnBinary = false;
- private long mUnknownSignatureKeyId = 0;
-
private long mSecretKeyId = Id.key.none;
private FileDialogFragment mFileDialog;
- private boolean mLookupUnknownKey = true;
-
private boolean mDecryptImmediately = false;
private BootstrapButton mDecryptButton;
@@ -154,7 +156,7 @@ public class DecryptActivity extends DrawerActivity {
mSourceLabel.setOnClickListener(nextSourceClickListener);
mMessage = (EditText) findViewById(R.id.message);
- mSignatureLayout = (LinearLayout) findViewById(R.id.signature);
+ mSignatureLayout = (RelativeLayout) findViewById(R.id.signature);
mSignatureStatusImage = (ImageView) findViewById(R.id.ic_signature_status);
mUserId = (TextView) findViewById(R.id.mainUserId);
mUserIdRest = (TextView) findViewById(R.id.mainUserIdRest);
@@ -171,7 +173,15 @@ public class DecryptActivity extends DrawerActivity {
mBrowse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*",
- Id.request.filename);
+ RESULT_CODE_FILE);
+ }
+ });
+
+ mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key);
+ mLookupKey.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ lookupUnknownKey(mSignatureKeyId);
}
});
@@ -239,7 +249,7 @@ public class DecryptActivity extends DrawerActivity {
DecryptActivity.this, mSignatureKeyId);
if (key != null) {
Intent intent = new Intent(DecryptActivity.this, ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER);
+ intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER);
intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, mSignatureKeyId);
startActivity(intent);
}
@@ -263,14 +273,14 @@ public class DecryptActivity extends DrawerActivity {
if (mDecryptImmediately
|| (mSource.getCurrentView().getId() == R.id.sourceMessage && (mMessage.getText()
- .length() > 0 || mContentUri != null))) {
+ .length() > 0 || mContentUri != null))) {
decryptClicked();
}
}
/**
* Handles all actions with this intent
- *
+ *
* @param intent
*/
private void handleActions(Intent intent) {
@@ -287,13 +297,13 @@ public class DecryptActivity extends DrawerActivity {
* Android's Action
*/
if (Intent.ACTION_SEND.equals(action) && type != null) {
- // When sending to Keychain Encrypt via share menu
+ // When sending to Keychain Decrypt via share menu
if ("text/plain".equals(type)) {
// Plain text
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// handle like normal text decryption, override action and extras to later
- // execute ACTION_DECRYPT in main actions
+ // executeServiceMethod ACTION_DECRYPT in main actions
extras.putString(EXTRA_TEXT, sharedText);
action = ACTION_DECRYPT;
}
@@ -375,21 +385,21 @@ public class DecryptActivity extends DrawerActivity {
private void updateSource() {
switch (mSource.getCurrentView().getId()) {
- case R.id.sourceFile: {
- mSourceLabel.setText(R.string.label_file);
- mDecryptButton.setText(getString(R.string.btn_decrypt));
- break;
- }
+ case R.id.sourceFile: {
+ mSourceLabel.setText(R.string.label_file);
+ mDecryptButton.setText(getString(R.string.btn_decrypt));
+ break;
+ }
- case R.id.sourceMessage: {
- mSourceLabel.setText(R.string.label_message);
- mDecryptButton.setText(getString(R.string.btn_decrypt));
- break;
- }
+ case R.id.sourceMessage: {
+ mSourceLabel.setText(R.string.label_message);
+ mDecryptButton.setText(getString(R.string.btn_decrypt));
+ break;
+ }
- default: {
- break;
- }
+ default: {
+ break;
+ }
}
}
@@ -449,7 +459,7 @@ public class DecryptActivity extends DrawerActivity {
} else {
if (mDecryptTarget == Id.target.file) {
askForOutputFilename();
- } else {
+ } else { // mDecryptTarget == Id.target.message
decryptStart();
}
}
@@ -527,7 +537,7 @@ public class DecryptActivity extends DrawerActivity {
try {
if (inStream.markSupported()) {
inStream.mark(200); // should probably set this to the max size of two pgpF
- // objects, if it even needs to be anything other than 0.
+ // objects, if it even needs to be anything other than 0.
}
mSecretKeyId = PgpHelper.getDecryptionKeyId(this, inStream);
if (mSecretKeyId == Id.key.none) {
@@ -539,7 +549,7 @@ public class DecryptActivity extends DrawerActivity {
inStream.reset();
}
mSecretKeyId = Id.key.symmetric;
- if (!PgpOperation.hasSymmetricEncryption(this, inStream)) {
+ if (!PgpDecryptVerify.hasSymmetricEncryption(this, inStream)) {
throw new PgpGeneralException(
getString(R.string.error_no_known_encryption_found));
}
@@ -559,7 +569,7 @@ public class DecryptActivity extends DrawerActivity {
data = "\n\n" + data;
intent.putExtra(EncryptActivity.EXTRA_TEXT, data);
intent.putExtra(EncryptActivity.EXTRA_SIGNATURE_KEY_ID, mSecretKeyId);
- intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, new long[] { mSignatureKeyId });
+ intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, new long[]{mSignatureKeyId});
startActivity(intent);
}
@@ -587,28 +597,10 @@ public class DecryptActivity extends DrawerActivity {
}
private void lookupUnknownKey(long unknownKeyId) {
- // Message is received after passphrase is cached
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == LookupUnknownKeyDialogFragment.MESSAGE_OKAY) {
- // the result is handled by onActivityResult() as LookupUnknownKeyDialogFragment
- // starts a new Intent which then returns data
- } else if (message.what == LookupUnknownKeyDialogFragment.MESSAGE_CANCEL) {
- // decrypt again, but don't lookup unknown keys!
- mLookupUnknownKey = false;
- decryptStart();
- }
- }
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(returnHandler);
-
- LookupUnknownKeyDialogFragment lookupKeyDialog = LookupUnknownKeyDialogFragment
- .newInstance(messenger, unknownKeyId);
-
- lookupKeyDialog.show(getSupportFragmentManager(), "unknownKeyDialog");
+ Intent intent = new Intent(this, ImportKeysActivity.class);
+ intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER);
+ intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId);
+ startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY);
}
private void decryptStart() {
@@ -644,8 +636,6 @@ public class DecryptActivity extends DrawerActivity {
data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId);
- data.putBoolean(KeychainIntentService.DECRYPT_SIGNED_ONLY, mSignedOnly);
- data.putBoolean(KeychainIntentService.DECRYPT_LOOKUP_UNKNOWN_KEY, mLookupUnknownKey);
data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary);
data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption);
@@ -662,15 +652,6 @@ public class DecryptActivity extends DrawerActivity {
// get returned data bundle
Bundle returnData = message.getData();
- // if key is unknown show lookup dialog
- if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_LOOKUP_KEY)
- && mLookupUnknownKey) {
- mUnknownSignatureKeyId = returnData
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
- lookupUnknownKey(mUnknownSignatureKeyId);
- return;
- }
-
mSignatureKeyId = 0;
mSignatureLayout.setVisibility(View.GONE);
@@ -685,26 +666,26 @@ public class DecryptActivity extends DrawerActivity {
}
switch (mDecryptTarget) {
- case Id.target.message:
- String decryptedMessage = returnData
- .getString(KeychainIntentService.RESULT_DECRYPTED_STRING);
- mMessage.setText(decryptedMessage);
- mMessage.setHorizontallyScrolling(false);
-
- break;
-
- case Id.target.file:
- if (mDeleteAfter.isChecked()) {
- // Create and show dialog to delete original file
- DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
- .newInstance(mInputFilename);
- deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
- }
- break;
-
- default:
- // shouldn't happen
- break;
+ case Id.target.message:
+ String decryptedMessage = returnData
+ .getString(KeychainIntentService.RESULT_DECRYPTED_STRING);
+ mMessage.setText(decryptedMessage);
+ mMessage.setHorizontallyScrolling(false);
+
+ break;
+
+ case Id.target.file:
+ if (mDeleteAfter.isChecked()) {
+ // Create and show dialog to delete original file
+ DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
+ .newInstance(mInputFilename);
+ deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
+ }
+ break;
+
+ default:
+ // shouldn't happen
+ break;
}
@@ -727,19 +708,24 @@ public class DecryptActivity extends DrawerActivity {
if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) {
mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
+ mLookupKey.setVisibility(View.GONE);
} else if (returnData
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.VISIBLE);
Toast.makeText(DecryptActivity.this,
- R.string.unknown_signature_key_touch_to_look_up,
+ R.string.unknown_signature,
Toast.LENGTH_LONG).show();
} else {
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.GONE);
}
mSignatureLayout.setVisibility(View.VISIBLE);
}
}
- };
+ }
+
+ ;
};
// Create a new Messenger for the communication back
@@ -756,36 +742,37 @@ public class DecryptActivity extends DrawerActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
- case Id.request.filename: {
- if (resultCode == RESULT_OK && data != null) {
- try {
- String path = FileHelper.getPath(this, data.getData());
- Log.d(Constants.TAG, "path=" + path);
-
- mFilename.setText(path);
- } catch (NullPointerException e) {
- Log.e(Constants.TAG, "Nullpointer while retrieving path!");
+ case RESULT_CODE_FILE: {
+ if (resultCode == RESULT_OK && data != null) {
+ try {
+ String path = FileHelper.getPath(this, data.getData());
+ Log.d(Constants.TAG, "path=" + path);
+
+ mFilename.setText(path);
+ } catch (NullPointerException e) {
+ Log.e(Constants.TAG, "Nullpointer while retrieving path!");
+ }
}
+ return;
}
- return;
- }
- // this request is returned after LookupUnknownKeyDialogFragment started
- // ImportKeysActivity and user looked uo key
- case Id.request.look_up_key_id: {
- Log.d(Constants.TAG, "Returning from Lookup Key...");
- // decrypt again without lookup
- mLookupUnknownKey = false;
- decryptStart();
- return;
- }
+ // this request is returned after LookupUnknownKeyDialogFragment started
+ // ImportKeysActivity and user looked uo key
+ case RESULT_CODE_LOOKUP_KEY: {
+ Log.d(Constants.TAG, "Returning from Lookup Key...");
+ if (resultCode == RESULT_OK) {
+ // decrypt again
+ decryptStart();
+ }
+ return;
+ }
- default: {
- break;
- }
- }
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
- super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index 81446db99..85bfba224 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -173,7 +173,7 @@ public class EncryptActivity extends DrawerActivity {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// handle like normal text encryption, override action and extras to later
- // execute ACTION_ENCRYPT in main actions
+ // executeServiceMethod ACTION_ENCRYPT in main actions
extras.putString(EXTRA_TEXT, sharedText);
extras.putBoolean(EXTRA_ASCII_ARMOR, true);
action = ACTION_ENCRYPT;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
index be7c50dbb..12d689274 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
@@ -33,18 +33,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
-public class HelpFragmentAbout extends Fragment {
-
- /**
- * Workaround for Android Bug. See
- * http://stackoverflow.com/questions/8748064/starting-activity-from
- * -fragment-causes-nullpointerexception
- */
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- setUserVisibleHint(true);
- }
+public class HelpAboutFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
index 2fe7c56e6..9ccd7e088 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
@@ -20,12 +20,13 @@ package org.sufficientlysecure.keychain.ui;
import java.util.ArrayList;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
@@ -37,8 +38,6 @@ public class HelpActivity extends ActionBarActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
- TextView tabCenter;
- TextView tabText;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -63,93 +62,21 @@ public class HelpActivity extends ActionBarActivity {
}
Bundle startBundle = new Bundle();
- startBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_start);
+ startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
- HelpFragmentHtml.class, startBundle, (selectedTab == 0 ? true : false));
+ HelpHtmlFragment.class, startBundle, (selectedTab == 0 ? true : false));
Bundle nfcBundle = new Bundle();
- nfcBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_nfc_beam);
+ nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
- HelpFragmentHtml.class, nfcBundle, (selectedTab == 1 ? true : false));
+ HelpHtmlFragment.class, nfcBundle, (selectedTab == 1 ? true : false));
Bundle changelogBundle = new Bundle();
- changelogBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_changelog);
+ changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
- HelpFragmentHtml.class, changelogBundle, (selectedTab == 2 ? true : false));
+ HelpHtmlFragment.class, changelogBundle, (selectedTab == 2 ? true : false));
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
- HelpFragmentAbout.class, null, (selectedTab == 3 ? true : false));
- }
-
- public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener,
- ViewPager.OnPageChangeListener {
- private final Context mContext;
- private final ActionBar mActionBar;
- private final ViewPager mViewPager;
- private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
-
- static final class TabInfo {
- private final Class<?> clss;
- private final Bundle args;
-
- TabInfo(Class<?> _class, Bundle _args) {
- clss = _class;
- args = _args;
- }
- }
-
- public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
- super(activity.getSupportFragmentManager());
- mContext = activity;
- mActionBar = activity.getSupportActionBar();
- mViewPager = pager;
- mViewPager.setAdapter(this);
- mViewPager.setOnPageChangeListener(this);
- }
-
- public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, boolean selected) {
- TabInfo info = new TabInfo(clss, args);
- tab.setTag(info);
- tab.setTabListener(this);
- mTabs.add(info);
- mActionBar.addTab(tab, selected);
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return mTabs.size();
- }
-
- @Override
- public Fragment getItem(int position) {
- TabInfo info = mTabs.get(position);
- return Fragment.instantiate(mContext, info.clss.getName(), info.args);
- }
-
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
-
- public void onPageSelected(int position) {
- mActionBar.setSelectedNavigationItem(position);
- }
-
- public void onPageScrollStateChanged(int state) {
- }
-
- public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
- Object tag = tab.getTag();
- for (int i = 0; i < mTabs.size(); i++) {
- if (mTabs.get(i) == tag) {
- mViewPager.setCurrentItem(i);
- }
- }
- }
-
- public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
- }
-
- public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
- }
+ HelpAboutFragment.class, null, (selectedTab == 3 ? true : false));
}
} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java
index fb6747db0..3afb5bbe0 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java
@@ -28,7 +28,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
-public class HelpFragmentHtml extends Fragment {
+public class HelpHtmlFragment extends Fragment {
private Activity mActivity;
private int htmlFile;
@@ -36,10 +36,10 @@ public class HelpFragmentHtml extends Fragment {
public static final String ARG_HTML_FILE = "htmlFile";
/**
- * Create a new instance of HelpFragmentHtml, providing "htmlFile" as an argument.
+ * Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument.
*/
- static HelpFragmentHtml newInstance(int htmlFile) {
- HelpFragmentHtml f = new HelpFragmentHtml();
+ static HelpHtmlFragment newInstance(int htmlFile) {
+ HelpHtmlFragment f = new HelpHtmlFragment();
// Supply html raw file input as an argument.
Bundle args = new Bundle();
@@ -49,17 +49,6 @@ public class HelpFragmentHtml extends Fragment {
return f;
}
- /**
- * Workaround for Android Bug. See
- * http://stackoverflow.com/questions/8748064/starting-activity-from
- * -fragment-causes-nullpointerexception
- */
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- setUserVisibleHint(true);
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mActivity = getActivity();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index dc3a07def..a5027ac1c 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2011 Senecaso
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,16 +47,19 @@ import android.support.v7.app.ActionBar;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
-import android.widget.Toast;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import com.devspark.appmsg.AppMsg;
public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNavigationListener {
public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY";
public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
+ "IMPORT_KEY_FROM_QR_CODE";
- public static final String ACTION_IMPORT_KEY_FROM_KEY_SERVER = Constants.INTENT_PREFIX
- + "IMPORT_KEY_FROM_KEY_SERVER";
+ public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = Constants.INTENT_PREFIX
+ + "IMPORT_KEY_FROM_KEYSERVER";
+ // TODO: implement:
+ public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN = Constants.INTENT_PREFIX
+ + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN";
// Actions for internal use only:
public static final String ACTION_IMPORT_KEY_FROM_FILE = Constants.INTENT_PREFIX
@@ -67,7 +70,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
// only used by ACTION_IMPORT_KEY
public static final String EXTRA_KEY_BYTES = "key_bytes";
- // only used by ACTION_IMPORT_KEY_FROM_KEY_SERVER
+ // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER
public static final String EXTRA_QUERY = "query";
public static final String EXTRA_KEY_ID = "key_id";
public static final String EXTRA_FINGERPRINT = "fingerprint";
@@ -78,6 +81,16 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
private Fragment mCurrentFragment;
private BootstrapButton mImportButton;
+ private static final Class[] NAVIGATION_CLASSES = new Class[]{
+ ImportKeysServerFragment.class,
+ ImportKeysFileFragment.class,
+ ImportKeysQrCodeFragment.class,
+ ImportKeysClipboardFragment.class,
+ ImportKeysNFCFragment.class
+ };
+
+ private int mCurrentNavPostition = -1;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -107,6 +120,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
handleActions(savedInstanceState, getIntent());
}
+
protected void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction();
Bundle extras = intent.getExtras();
@@ -125,24 +139,23 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
if (scheme != null && scheme.toLowerCase(Locale.ENGLISH).equals(Constants.FINGERPRINT_SCHEME)) {
/* Scanning a fingerprint directly with Barcode Scanner */
- getSupportActionBar().setSelectedNavigationItem(0);
- loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[0]);
- loadFromFingerprintUri(dataUri);
+ loadFromFingerprintUri(savedInstanceState, dataUri);
} else if (ACTION_IMPORT_KEY.equals(action)) {
/* Keychain's own Actions */
- getSupportActionBar().setSelectedNavigationItem(1);
- loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
+
+ // display file fragment
+ loadNavFragment(1, null);
if (dataUri != null) {
- // directly load data
+ // action: directly load data
startListFragment(savedInstanceState, null, dataUri, null);
} else if (extras.containsKey(EXTRA_KEY_BYTES)) {
byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES);
- // directly load data
+ // action: directly load data
startListFragment(savedInstanceState, importData, null, null);
}
- } else if (ACTION_IMPORT_KEY_FROM_KEY_SERVER.equals(action)) {
+ } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) {
String query = null;
if (extras.containsKey(EXTRA_QUERY)) {
query = extras.getString(EXTRA_QUERY);
@@ -161,82 +174,97 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
return;
}
- // search directly
- getSupportActionBar().setSelectedNavigationItem(0);
+ // display keyserver fragment with query
Bundle args = new Bundle();
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
- loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]);
+ loadNavFragment(0, args);
+ // action: search immediately
startListFragment(savedInstanceState, null, null, query);
- } else {
- // Other actions
+ } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
+
+ // NOTE: this only displays the appropriate fragment, no actions are taken
+ loadNavFragment(1, null);
+
+ // no immediate actions!
startListFragment(savedInstanceState, null, null, null);
+ } else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) {
+ // also exposed in AndroidManifest
- if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
- getSupportActionBar().setSelectedNavigationItem(1);
- loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
- } else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) {
- // also exposed in AndroidManifest
- getSupportActionBar().setSelectedNavigationItem(2);
- loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[2]);
- } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
- getSupportActionBar().setSelectedNavigationItem(3);
- loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[3]);
- }
+ // NOTE: this only displays the appropriate fragment, no actions are taken
+ loadNavFragment(2, null);
+
+ // no immediate actions!
+ startListFragment(savedInstanceState, null, null, null);
+ } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
+
+ // NOTE: this only displays the appropriate fragment, no actions are taken
+ loadNavFragment(3, null);
+
+ // no immediate actions!
+ startListFragment(savedInstanceState, null, null, null);
+ } else {
+ startListFragment(savedInstanceState, null, null, null);
}
}
private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri, String serverQuery) {
- // Check that the activity is using the layout version with
- // the fragment_container FrameLayout
- if (findViewById(R.id.import_keys_list_container) != null) {
-
- // 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;
- }
+ // 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;
+ }
- // Create an instance of the fragment
- mListFragment = ImportKeysListFragment.newInstance(bytes, dataUri, serverQuery);
+ // Create an instance of the fragment
+ mListFragment = ImportKeysListFragment.newInstance(bytes, dataUri, serverQuery);
- // Add the fragment to the 'fragment_container' FrameLayout
- // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.import_keys_list_container, mListFragment)
- .commitAllowingStateLoss();
- // do it immediately!
- getSupportFragmentManager().executePendingTransactions();
- }
+ // Add the fragment to the 'fragment_container' FrameLayout
+ // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.import_keys_list_container, mListFragment)
+ .commitAllowingStateLoss();
+ // do it immediately!
+ getSupportFragmentManager().executePendingTransactions();
}
+ /**
+ * "Basically, when using a list navigation, onNavigationItemSelected() is automatically
+ * called when your activity is created/re-created, whether you like it or not. To prevent
+ * your Fragment's onCreateView() from being called twice, this initial automatic call to
+ * onNavigationItemSelected() should check whether the Fragment is already in existence
+ * inside your Activity."
+ * <p/>
+ * from http://stackoverflow.com/questions/10983396/fragment-oncreateview-and-onactivitycreated-called-twice/14295474#14295474
+ *
+ * In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint,
+ * the fragment would be loaded twice resulting in the query being empty after the second load.
+ *
+ * Our solution:
+ * To prevent that a fragment will be loaded again even if it was already loaded loadNavFragment
+ * checks against mCurrentNavPostition.
+ *
+ * @param itemPosition
+ * @param itemId
+ * @return
+ */
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
- // Create new fragment from our own Fragment class
- switch (itemPosition) {
- case 0:
- loadFragment(ImportKeysServerFragment.class, null, mNavigationStrings[itemPosition]);
- break;
- case 1:
- loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[itemPosition]);
- break;
- case 2:
- loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]);
- break;
- case 3:
- loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]);
- break;
- case 4:
- loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]);
- break;
-
- default:
- break;
- }
+ Log.d(Constants.TAG, "onNavigationItemSelected");
+
+ loadNavFragment(itemPosition, null);
+
return true;
}
+ private void loadNavFragment(int itemPosition, Bundle args) {
+ if (mCurrentNavPostition != itemPosition) {
+ getSupportActionBar().setSelectedNavigationItem(itemPosition);
+ loadFragment(NAVIGATION_CLASSES[itemPosition], args, mNavigationStrings[itemPosition]);
+ mCurrentNavPostition = itemPosition;
+ }
+ }
+
private void loadFragment(Class<?> clss, Bundle args, String tag) {
mCurrentFragment = Fragment.instantiate(this, clss.getName(), args);
@@ -248,26 +276,26 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
ft.commit();
}
- public void loadFromFingerprintUri(Uri dataUri) {
+ public void loadFromFingerprintUri(Bundle savedInstanceState, Uri dataUri) {
String fingerprint = dataUri.toString().split(":")[1].toLowerCase(Locale.ENGLISH);
Log.d(Constants.TAG, "fingerprint: " + fingerprint);
if (fingerprint.length() < 16) {
- Toast.makeText(this, R.string.import_qr_code_too_short_fingerprint,
- Toast.LENGTH_LONG).show();
+ AppMsg.makeText(this, R.string.import_qr_code_too_short_fingerprint,
+ AppMsg.STYLE_ALERT).show();
return;
}
String query = "0x" + fingerprint;
- // search directly
- getSupportActionBar().setSelectedNavigationItem(0);
+ // display keyserver fragment with query
Bundle args = new Bundle();
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
- loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]);
+ loadNavFragment(0, args);
- startListFragment(null, null, null, query);
+ // action: search directly
+ startListFragment(savedInstanceState, null, null, query);
}
public void loadCallback(byte[] importData, Uri dataUri, String serverQuery, String keyServer) {
@@ -364,7 +392,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
} else {
toastMessage = getString(R.string.no_keys_added_or_updated);
}
- Toast.makeText(ImportKeysActivity.this, toastMessage, Toast.LENGTH_SHORT)
+ AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
.show();
if (bad > 0) {
AlertDialog.Builder alert = new AlertDialog.Builder(
@@ -446,7 +474,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
// start service with intent
startService(intent);
} else {
- Toast.makeText(this, R.string.error_nothing_import, Toast.LENGTH_LONG).show();
+ AppMsg.makeText(this, R.string.error_nothing_import, AppMsg.STYLE_ALERT).show();
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
index 68d318491..b52de5bc9 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
@@ -122,7 +122,7 @@ public class ImportKeysListFragment extends ListFragment implements
mKeyBytes = getArguments().getByteArray(ARG_BYTES);
mServerQuery = getArguments().getString(ARG_SERVER_QUERY);
- // TODO: this is used when scanning QR Code. Currently it simply uses key server nr 0
+ // TODO: this is used when scanning QR Code. Currently it simply uses keyserver nr 0
mKeyServer = Preferences.getPreferences(getActivity())
.getKeyServers()[0];
@@ -136,7 +136,7 @@ public class ImportKeysListFragment extends ListFragment implements
getLoaderManager().initLoader(LOADER_ID_BYTES, null, this);
}
- if (mServerQuery != null) {
+ if (mServerQuery != null && mKeyServer != null) {
// Start out with a progress indicator.
setListShown(false);
@@ -165,14 +165,19 @@ public class ImportKeysListFragment extends ListFragment implements
mServerQuery = serverQuery;
mKeyServer = keyServer;
- // Start out with a progress indicator.
- setListShown(false);
+ if (mKeyBytes != null || mDataUri != null) {
+ // Start out with a progress indicator.
+ setListShown(false);
- if (mKeyBytes != null || mDataUri != null)
getLoaderManager().restartLoader(LOADER_ID_BYTES, null, this);
+ }
+
+ if (mServerQuery != null && mKeyServer != null) {
+ // Start out with a progress indicator.
+ setListShown(false);
- if (mServerQuery != null && mKeyServer != null)
getLoaderManager().restartLoader(LOADER_ID_SERVER_QUERY, null, this);
+ }
}
@Override
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java
index 63727ad26..ee91b2434 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java
@@ -98,22 +98,29 @@ public class ImportKeysQrCodeFragment extends Fragment {
IntentResult scanResult = IntentIntegratorSupportV4.parseActivityResult(requestCode,
resultCode, data);
if (scanResult != null && scanResult.getFormatName() != null) {
+ String scannedContent = scanResult.getContents();
- Log.d(Constants.TAG, "scanResult content: " + scanResult.getContents());
+ Log.d(Constants.TAG, "scannedContent: " + scannedContent);
// look if it's fingerprint only
- if (scanResult.getContents().toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) {
+ if (scannedContent.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) {
importFingerprint(Uri.parse(scanResult.getContents()));
return;
}
// look if it is the whole key
- String[] parts = scanResult.getContents().split(",");
+ String[] parts = scannedContent.split(",");
if (parts.length == 3) {
importParts(parts);
return;
}
+ // is this a full key encoded as qr code?
+ if (scannedContent.startsWith("-----BEGIN PGP")) {
+ mImportActivity.loadCallback(scannedContent.getBytes(), null, null, null);
+ return;
+ }
+
// fail...
Toast.makeText(getActivity(), R.string.import_qr_code_wrong, Toast.LENGTH_LONG)
.show();
@@ -130,7 +137,7 @@ public class ImportKeysQrCodeFragment extends Fragment {
}
public void importFingerprint(Uri dataUri) {
- mImportActivity.loadFromFingerprintUri(dataUri);
+ mImportActivity.loadFromFingerprintUri(null, dataUri);
}
private void importParts(String[] parts) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
index 2e0956d8b..d77015aa7 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java
@@ -127,21 +127,21 @@ public class ImportKeysServerFragment extends Fragment {
mImportActivity = (ImportKeysActivity) getActivity();
// set displayed values
- if (getArguments() != null && getArguments().containsKey(ARG_QUERY)) {
- String query = getArguments().getString(ARG_QUERY);
- mQueryEditText.setText(query, TextView.BufferType.EDITABLE);
+ if (getArguments() != null) {
+ if (getArguments().containsKey(ARG_QUERY)) {
+ String query = getArguments().getString(ARG_QUERY);
+ mQueryEditText.setText(query, TextView.BufferType.EDITABLE);
+
+ Log.d(Constants.TAG, "query: " + query);
+ }
- String keyServer = null;
if (getArguments().containsKey(ARG_KEY_SERVER)) {
- keyServer = getArguments().getString(ARG_KEY_SERVER);
+ String keyServer = getArguments().getString(ARG_KEY_SERVER);
int keyServerPos = mServerAdapter.getPosition(keyServer);
mServerSpinner.setSelection(keyServerPos);
- } else {
- keyServer = (String) mServerSpinner.getSelectedItem();
- }
- Log.d(Constants.TAG, "query: " + query);
- Log.d(Constants.TAG, "keyServer: " + keyServer);
+ Log.d(Constants.TAG, "keyServer: " + keyServer);
+ }
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
index 6ae2b9bf9..c28d57627 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
@@ -17,6 +17,7 @@
package org.sufficientlysecure.keychain.ui;
+import java.util.ArrayList;
import java.util.Set;
import org.sufficientlysecure.keychain.Id;
@@ -30,12 +31,16 @@ import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
+
import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
@@ -50,6 +55,7 @@ import android.view.ViewGroup;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.ListView;
+import android.widget.Toast;
import com.beardedhen.androidbootstrap.BootstrapButton;
@@ -63,7 +69,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
private KeyListPublicAdapter mAdapter;
private StickyListHeadersListView mStickyList;
- // empty layout
+ // empty list layout
private BootstrapButton mButtonEmptyCreate;
private BootstrapButton mButtonEmptyImport;
@@ -92,9 +98,9 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
@Override
public void onClick(View v) {
- Intent intentImportFromFile = new Intent(getActivity(), ImportKeysActivity.class);
- intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE);
- startActivityForResult(intentImportFromFile, 0);
+ Intent intent = new Intent(getActivity(), ImportKeysActivity.class);
+ intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE);
+ startActivityForResult(intent, 0);
}
});
@@ -109,7 +115,6 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- // mKeyListPublicActivity = (KeyListPublicActivity) getActivity();
mStickyList = (StickyListHeadersListView) getActivity().findViewById(R.id.list);
mStickyList.setOnItemClickListener(this);
@@ -159,18 +164,16 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
}
switch (item.getItemId()) {
- case R.id.menu_key_list_public_multi_encrypt: {
- encrypt(ids);
-
- break;
- }
- case R.id.menu_key_list_public_multi_delete: {
- showDeleteKeyDialog(ids);
-
- break;
- }
+ case R.id.menu_key_list_public_multi_encrypt: {
+ encrypt(mode, ids);
+ break;
+ }
+ case R.id.menu_key_list_public_multi_delete: {
+ showDeleteKeyDialog(mode, ids);
+ break;
+ }
}
- return false;
+ return true;
}
@Override
@@ -181,7 +184,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
- boolean checked) {
+ boolean checked) {
if (checked) {
count++;
mAdapter.setNewSelection(position, checked);
@@ -212,8 +215,12 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
}
// These are the rows that we will retrieve.
- static final String[] PROJECTION = new String[] { KeyRings._ID, KeyRings.MASTER_KEY_ID,
- UserIds.USER_ID };
+ static final String[] PROJECTION = new String[]{
+ KeychainContract.KeyRings._ID,
+ KeychainContract.KeyRings.MASTER_KEY_ID,
+ KeychainContract.UserIds.USER_ID,
+ KeychainContract.Keys.IS_REVOKED
+ };
static final int USER_ID_INDEX = 2;
@@ -270,7 +277,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
startActivity(viewIntent);
}
- public void encrypt(long[] keyRingRowIds) {
+ public void encrypt(ActionMode mode, long[] keyRingRowIds) {
// get master key ids from row ids
long[] keyRingIds = new long[keyRingRowIds.length];
for (int i = 0; i < keyRingRowIds.length; i++) {
@@ -282,15 +289,44 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte
intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, keyRingIds);
// used instead of startActivity set actionbar based on callingPackage
startActivityForResult(intent, 0);
+
+ mode.finish();
}
/**
* Show dialog to delete key
- *
+ *
* @param keyRingRowIds
*/
- public void showDeleteKeyDialog(long[] keyRingRowIds) {
- DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(null,
+ public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) {
+ // Message is received after key is deleted
+ Handler returnHandler = new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
+ Bundle returnData = message.getData();
+ if (returnData != null
+ && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) {
+ ArrayList<String> notDeleted =
+ returnData.getStringArrayList(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED);
+ String notDeletedMsg = "";
+ for (String userId : notDeleted) {
+ notDeletedMsg += userId + "\n";
+ }
+ Toast.makeText(getActivity(), getString(R.string.error_can_not_delete_contacts, notDeletedMsg)
+ + getResources().getQuantityString(R.plurals.error_can_not_delete_info, notDeleted.size()),
+ Toast.LENGTH_LONG).show();
+
+ mode.finish();
+ }
+ }
+ }
+ };
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(returnHandler);
+
+ DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
keyRingRowIds, Id.type.public_key);
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
index f2e6131f6..f9d267f27 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java
@@ -17,6 +17,7 @@
package org.sufficientlysecure.keychain.ui;
+import java.util.ArrayList;
import java.util.Set;
import org.sufficientlysecure.keychain.Id;
@@ -33,6 +34,9 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
@@ -45,6 +49,7 @@ import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Toast;
public class KeyListSecretFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener {
@@ -103,13 +108,12 @@ public class KeyListSecretFragment extends ListFragment implements
}
switch (item.getItemId()) {
- case R.id.menu_key_list_public_multi_delete: {
- showDeleteKeyDialog(ids);
-
- break;
- }
+ case R.id.menu_key_list_public_multi_delete: {
+ showDeleteKeyDialog(mode, ids);
+ break;
+ }
}
- return false;
+ return true;
}
@Override
@@ -120,7 +124,7 @@ public class KeyListSecretFragment extends ListFragment implements
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
- boolean checked) {
+ boolean checked) {
if (checked) {
count++;
mAdapter.setNewSelection(position, checked);
@@ -153,8 +157,8 @@ public class KeyListSecretFragment extends ListFragment implements
}
// These are the rows that we will retrieve.
- static final String[] PROJECTION = new String[] { KeyRings._ID, KeyRings.MASTER_KEY_ID,
- UserIds.USER_ID };
+ static final String[] PROJECTION = new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID,
+ UserIds.USER_ID};
static final String SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC";
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@@ -202,13 +206,27 @@ public class KeyListSecretFragment extends ListFragment implements
/**
* Show dialog to delete key
- *
+ *
* @param keyRingRowIds
*/
- public void showDeleteKeyDialog(long[] keyRingRowIds) {
- DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(null,
+ public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) {
+ // Message is received after key is deleted
+ Handler returnHandler = new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
+ mode.finish();
+ }
+ }
+ };
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(returnHandler);
+
+ DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
keyRingRowIds, Id.type.secret_key);
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
}
+
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
index e3881503b..550d3047d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
@@ -40,7 +40,7 @@ import android.widget.Toast;
import com.beardedhen.androidbootstrap.BootstrapButton;
/**
- * Sends the selected public key to a key server
+ * Sends the selected public key to a keyserver
*/
public class UploadKeyActivity extends ActionBarActivity {
private BootstrapButton mUploadButton;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index 99d93fbbd..0a452bc8a 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -18,8 +18,17 @@
package org.sufficientlysecure.keychain.ui;
-import java.util.ArrayList;
-import java.util.Date;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -27,63 +36,27 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
-import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v7.app.ActionBarActivity;
-import android.text.format.DateFormat;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
+import java.util.ArrayList;
-public class ViewKeyActivity extends ActionBarActivity implements
- LoaderManager.LoaderCallbacks<Cursor> {
+public class ViewKeyActivity extends ActionBarActivity {
ExportHelper mExportHelper;
protected Uri mDataUri;
- private TextView mName;
- private TextView mEmail;
- private TextView mComment;
- private TextView mAlgorithm;
- private TextView mKeyId;
- private TextView mExpiry;
- private TextView mCreation;
- private TextView mFingerprint;
- private BootstrapButton mActionEncrypt;
-
- private ListView mUserIds;
- private ListView mKeys;
-
- private static final int LOADER_ID_KEYRING = 0;
- private static final int LOADER_ID_USER_IDS = 1;
- private static final int LOADER_ID_KEYS = 2;
- private ViewKeyUserIdsAdapter mUserIdsAdapter;
- private ViewKeyKeysAdapter mKeysAdapter;
+ public static final String EXTRA_SELECTED_TAB = "selectedTab";
+
+ ViewPager mViewPager;
+ TabsAdapter mTabsAdapter;
+
+ private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -91,25 +64,36 @@ public class ViewKeyActivity extends ActionBarActivity implements
mExportHelper = new ExportHelper(this);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setIcon(android.R.color.transparent);
- getSupportActionBar().setHomeButtonEnabled(true);
+ // let the actionbar look like Android's contact app
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setIcon(android.R.color.transparent);
+ actionBar.setHomeButtonEnabled(true);
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
setContentView(R.layout.view_key_activity);
- mName = (TextView) findViewById(R.id.name);
- mEmail = (TextView) findViewById(R.id.email);
- mComment = (TextView) findViewById(R.id.comment);
- mKeyId = (TextView) findViewById(R.id.key_id);
- mAlgorithm = (TextView) findViewById(R.id.algorithm);
- mCreation = (TextView) findViewById(R.id.creation);
- mExpiry = (TextView) findViewById(R.id.expiry);
- mFingerprint = (TextView) findViewById(R.id.fingerprint);
- mActionEncrypt = (BootstrapButton) findViewById(R.id.action_encrypt);
- mUserIds = (ListView) findViewById(R.id.user_ids);
- mKeys = (ListView) findViewById(R.id.keys);
-
- loadData(getIntent());
+ mViewPager = (ViewPager) findViewById(R.id.pager);
+
+ mTabsAdapter = new TabsAdapter(this, mViewPager);
+
+ int selectedTab = 0;
+ Intent intent = getIntent();
+ if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
+ selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
+ }
+
+ mDataUri = getIntent().getData();
+
+ Bundle mainBundle = new Bundle();
+ mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
+ mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_main)),
+ ViewKeyMainFragment.class, mainBundle, (selectedTab == 0 ? true : false));
+
+ Bundle certBundle = new Bundle();
+ certBundle.putParcelable(ViewKeyCertsFragment.ARG_DATA_URI, mDataUri);
+ mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_certs)),
+ ViewKeyCertsFragment.class, certBundle, (selectedTab == 1 ? true : false));
}
@Override
@@ -130,9 +114,6 @@ public class ViewKeyActivity extends ActionBarActivity implements
case R.id.menu_key_view_update:
updateFromKeyserver(mDataUri);
return true;
- case R.id.menu_key_view_sign:
- signKey(mDataUri);
- return true;
case R.id.menu_key_view_export_keyserver:
uploadToKeyserver(mDataUri);
return true;
@@ -159,230 +140,13 @@ public class ViewKeyActivity extends ActionBarActivity implements
copyToClipboard(mDataUri);
return true;
case R.id.menu_key_view_delete: {
- // Message is received after key is deleted
- Handler returnHandler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
- setResult(RESULT_CANCELED);
- finish();
- }
- }
- };
-
- mExportHelper.deleteKey(mDataUri, Id.type.public_key, returnHandler);
+ deleteKey(mDataUri);
return true;
}
}
return super.onOptionsItemSelected(item);
}
- private void loadData(Intent intent) {
- if (intent.getData().equals(mDataUri)) {
- Log.d(Constants.TAG, "Same URI, no need to load the data again!");
- return;
- }
-
- mDataUri = intent.getData();
- if (mDataUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
- finish();
- return;
- }
-
- Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
-
- mActionEncrypt.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- long keyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, mDataUri);
-
- long[] encryptionKeyIds = new long[]{keyId};
- Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class);
- intent.setAction(EncryptActivity.ACTION_ENCRYPT);
- intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
- // used instead of startActivity set actionbar based on callingPackage
- startActivityForResult(intent, 0);
- }
- });
-
- mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0);
-
- mUserIds.setAdapter(mUserIdsAdapter);
- // mUserIds.setEmptyView(findViewById(android.R.id.empty));
- // mUserIds.setClickable(true);
- // mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- // @Override
- // public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
- // }
- // });
-
- mKeysAdapter = new ViewKeyKeysAdapter(this, null, 0);
-
- mKeys.setAdapter(mKeysAdapter);
-
- // Prepare the loader. Either re-connect with an existing one,
- // or start a new one.
- getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
- getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
- getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
- }
-
- static final String[] KEYRING_PROJECTION = new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID,
- UserIds.USER_ID};
- static final int KEYRING_INDEX_ID = 0;
- static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
- static final int KEYRING_INDEX_USER_ID = 2;
-
- static final String[] USER_IDS_PROJECTION = new String[]{UserIds._ID, UserIds.USER_ID,
- UserIds.RANK,};
- // not the main user id
- static final String USER_IDS_SELECTION = UserIds.RANK + " > 0 ";
- static final String USER_IDS_SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC";
-
- static final String[] KEYS_PROJECTION = new String[]{Keys._ID, Keys.KEY_ID,
- Keys.IS_MASTER_KEY, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN,
- Keys.CAN_ENCRYPT, Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT};
- static final String KEYS_SORT_ORDER = Keys.RANK + " ASC";
- static final int KEYS_INDEX_ID = 0;
- static final int KEYS_INDEX_KEY_ID = 1;
- static final int KEYS_INDEX_IS_MASTER_KEY = 2;
- static final int KEYS_INDEX_ALGORITHM = 3;
- static final int KEYS_INDEX_KEY_SIZE = 4;
- static final int KEYS_INDEX_CAN_CERTIFY = 5;
- static final int KEYS_INDEX_CAN_SIGN = 6;
- static final int KEYS_INDEX_CAN_ENCRYPT = 7;
- static final int KEYS_INDEX_CREATION = 8;
- static final int KEYS_INDEX_EXPIRY = 9;
- static final int KEYS_INDEX_FINGERPRINT = 10;
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- switch (id) {
- case LOADER_ID_KEYRING: {
- Uri baseUri = mDataUri;
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(this, baseUri, KEYRING_PROJECTION, null, null, null);
- }
- case LOADER_ID_USER_IDS: {
- Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
- USER_IDS_SORT_ORDER);
- }
- case LOADER_ID_KEYS: {
- Uri baseUri = Keys.buildKeysUri(mDataUri);
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(this, baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
- }
-
- default:
- return null;
- }
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- switch (loader.getId()) {
- case LOADER_ID_KEYRING:
- if (data.moveToFirst()) {
- // get name, email, and comment from USER_ID
- String[] mainUserId = PgpKeyHelper.splitUserId(data
- .getString(KEYRING_INDEX_USER_ID));
- if (mainUserId[0] != null) {
- setTitle(mainUserId[0]);
- mName.setText(mainUserId[0]);
- } else {
- setTitle(R.string.user_id_no_name);
- mName.setText(R.string.user_id_no_name);
- }
- mEmail.setText(mainUserId[1]);
- mComment.setText(mainUserId[2]);
- }
-
- break;
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(data);
- break;
- case LOADER_ID_KEYS:
- // the first key here is our master key
- if (data.moveToFirst()) {
- // get key id from MASTER_KEY_ID
- long keyId = data.getLong(KEYS_INDEX_KEY_ID);
-
- String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
- mKeyId.setText(keyIdStr);
-
- // get creation date from CREATION
- if (data.isNull(KEYS_INDEX_CREATION)) {
- mCreation.setText(R.string.none);
- } else {
- Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
-
- mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(
- creationDate));
- }
-
- // get expiry date from EXPIRY
- if (data.isNull(KEYS_INDEX_EXPIRY)) {
- mExpiry.setText(R.string.none);
- } else {
- Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
-
- mExpiry.setText(DateFormat.getDateFormat(getApplicationContext()).format(
- expiryDate));
- }
-
- String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
- data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
- mAlgorithm.setText(algorithmStr);
-
- byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
- if (fingerprintBlob == null) {
- // FALLBACK for old database entries
- fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
- }
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
- fingerprint = fingerprint.replace(" ", "\n");
-
- mFingerprint.setText(fingerprint);
- }
-
- mKeysAdapter.swapCursor(data);
- break;
-
- default:
- break;
- }
- }
-
- /**
- * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
- * We need to make sure we are no longer using it.
- */
- public void onLoaderReset(Loader<Cursor> loader) {
- switch (loader.getId()) {
- case LOADER_ID_KEYRING:
- // No resources need to be freed for this ID
- break;
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(null);
- break;
- case LOADER_ID_KEYS:
- mKeysAdapter.swapCursor(null);
- break;
- default:
- break;
- }
- }
-
private void uploadToKeyserver(Uri dataUri) {
Intent uploadIntent = new Intent(this, UploadKeyActivity.class);
uploadIntent.setData(dataUri);
@@ -398,21 +162,15 @@ public class ViewKeyActivity extends ActionBarActivity implements
}
Intent queryIntent = new Intent(this, ImportKeysActivity.class);
- queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER);
+ queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER);
queryIntent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, updateKeyId);
- // TODO: lookup??
- startActivityForResult(queryIntent, Id.request.look_up_key_id);
- }
-
- private void signKey(Uri dataUri) {
- Intent signIntent = new Intent(this, SignKeyActivity.class);
- signIntent.setData(dataUri);
- startActivity(signIntent);
+ // TODO: lookup with onactivityresult!
+ startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY);
}
private void shareKey(Uri dataUri, boolean fingerprintOnly) {
- String content = null;
+ String content;
if (fingerprintOnly) {
byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);
@@ -465,4 +223,29 @@ public class ViewKeyActivity extends ActionBarActivity implements
dialog.show(getSupportFragmentManager(), "shareNfcDialog");
}
+ private void deleteKey(Uri dataUri) {
+ // Message is received after key is deleted
+ Handler returnHandler = new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
+ Bundle returnData = message.getData();
+ if (returnData != null
+ && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) {
+ // we delete only this key, so MESSAGE_NOT_DELETED will solely contain this key
+ Toast.makeText(ViewKeyActivity.this,
+ getString(R.string.error_can_not_delete_contact)
+ + getResources().getQuantityString(R.plurals.error_can_not_delete_info, 1),
+ Toast.LENGTH_LONG).show();
+ } else {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+ }
+ }
+ };
+
+ mExportHelper.deleteKey(dataUri, Id.type.public_key, returnHandler);
+ }
+
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
index a2e3e4339..59037d9ff 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
@@ -23,7 +23,6 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import android.annotation.TargetApi;
-import android.database.Cursor;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
@@ -35,12 +34,11 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.support.v4.app.LoaderManager;
import android.widget.Toast;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
- OnNdefPushCompleteCallback, LoaderManager.LoaderCallbacks<Cursor> {
+ OnNdefPushCompleteCallback {
// NFC
private NfcAdapter mNfcAdapter;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java
new file mode 100644
index 000000000..36d3e6ace
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java
@@ -0,0 +1,92 @@
+/*
+ * 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.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.beardedhen.androidbootstrap.BootstrapButton;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.util.Log;
+
+
+public class ViewKeyCertsFragment extends Fragment {
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private BootstrapButton mActionCertify;
+
+ private Uri mDataUri;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.view_key_certs_fragment, container, false);
+
+ mActionCertify = (BootstrapButton) view.findViewById(R.id.action_certify);
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ if (dataUri.equals(mDataUri)) {
+ Log.d(Constants.TAG, "Same URI, no need to load the data again!");
+ return;
+ }
+
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ mActionCertify.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ certifyKey(mDataUri);
+ }
+ });
+
+ }
+
+ private void certifyKey(Uri dataUri) {
+ Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
+ signIntent.setData(dataUri);
+ startActivity(signIntent);
+ }
+
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
new file mode 100644
index 000000000..495764eaf
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
@@ -0,0 +1,313 @@
+/*
+ * 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.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.text.format.DateFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.beardedhen.androidbootstrap.BootstrapButton;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.Date;
+
+
+public class ViewKeyMainFragment extends Fragment implements
+ LoaderManager.LoaderCallbacks<Cursor>{
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private TextView mName;
+ private TextView mEmail;
+ private TextView mComment;
+ private TextView mAlgorithm;
+ private TextView mKeyId;
+ private TextView mExpiry;
+ private TextView mCreation;
+ private TextView mFingerprint;
+ private BootstrapButton mActionEncrypt;
+
+ private ListView mUserIds;
+ private ListView mKeys;
+
+ private static final int LOADER_ID_KEYRING = 0;
+ private static final int LOADER_ID_USER_IDS = 1;
+ private static final int LOADER_ID_KEYS = 2;
+
+ private ViewKeyUserIdsAdapter mUserIdsAdapter;
+ private ViewKeyKeysAdapter mKeysAdapter;
+
+ private Uri mDataUri;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.view_key_main_fragment, container, false);
+
+ mName = (TextView) view.findViewById(R.id.name);
+ mEmail = (TextView) view.findViewById(R.id.email);
+ mComment = (TextView) view.findViewById(R.id.comment);
+ mKeyId = (TextView) view.findViewById(R.id.key_id);
+ mAlgorithm = (TextView) view.findViewById(R.id.algorithm);
+ mCreation = (TextView) view.findViewById(R.id.creation);
+ mExpiry = (TextView) view.findViewById(R.id.expiry);
+ mFingerprint = (TextView) view.findViewById(R.id.fingerprint);
+ mUserIds = (ListView) view.findViewById(R.id.user_ids);
+ mKeys = (ListView) view.findViewById(R.id.keys);
+ mActionEncrypt = (BootstrapButton) view.findViewById(R.id.action_encrypt);
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ if (dataUri.equals(mDataUri)) {
+ Log.d(Constants.TAG, "Same URI, no need to load the data again!");
+ return;
+ }
+
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ mActionEncrypt.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ encryptToContact(mDataUri);
+ }
+ });
+
+ mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0);
+ mUserIds.setAdapter(mUserIdsAdapter);
+
+ mKeysAdapter = new ViewKeyKeysAdapter(getActivity(), null, 0);
+ mKeys.setAdapter(mKeysAdapter);
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
+ getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
+ getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
+ }
+
+ static final String[] KEYRING_PROJECTION = new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID,
+ KeychainContract.UserIds.USER_ID};
+ static final int KEYRING_INDEX_ID = 0;
+ static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
+ static final int KEYRING_INDEX_USER_ID = 2;
+
+ static final String[] USER_IDS_PROJECTION = new String[]{KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID,
+ KeychainContract.UserIds.RANK,};
+ // not the main user id
+ static final String USER_IDS_SELECTION = KeychainContract.UserIds.RANK + " > 0 ";
+ static final String USER_IDS_SORT_ORDER = KeychainContract.UserIds.USER_ID + " COLLATE LOCALIZED ASC";
+
+ static final String[] KEYS_PROJECTION = new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
+ KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN,
+ KeychainContract.Keys.CAN_ENCRYPT, KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT};
+ static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC";
+ static final int KEYS_INDEX_ID = 0;
+ static final int KEYS_INDEX_KEY_ID = 1;
+ static final int KEYS_INDEX_IS_MASTER_KEY = 2;
+ static final int KEYS_INDEX_ALGORITHM = 3;
+ static final int KEYS_INDEX_KEY_SIZE = 4;
+ static final int KEYS_INDEX_CAN_CERTIFY = 5;
+ static final int KEYS_INDEX_CAN_SIGN = 6;
+ static final int KEYS_INDEX_CAN_ENCRYPT = 7;
+ static final int KEYS_INDEX_CREATION = 8;
+ static final int KEYS_INDEX_EXPIRY = 9;
+ static final int KEYS_INDEX_FINGERPRINT = 10;
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ switch (id) {
+ case LOADER_ID_KEYRING: {
+ Uri baseUri = mDataUri;
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), baseUri, KEYRING_PROJECTION, null, null, null);
+ }
+ case LOADER_ID_USER_IDS: {
+ Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
+ USER_IDS_SORT_ORDER);
+ }
+ case LOADER_ID_KEYS: {
+ Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri);
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ switch (loader.getId()) {
+ case LOADER_ID_KEYRING:
+ if (data.moveToFirst()) {
+ // get name, email, and comment from USER_ID
+ String[] mainUserId = PgpKeyHelper.splitUserId(data
+ .getString(KEYRING_INDEX_USER_ID));
+ if (mainUserId[0] != null) {
+ getActivity().setTitle(mainUserId[0]);
+ mName.setText(mainUserId[0]);
+ } else {
+ getActivity().setTitle(R.string.user_id_no_name);
+ mName.setText(R.string.user_id_no_name);
+ }
+ mEmail.setText(mainUserId[1]);
+ mComment.setText(mainUserId[2]);
+ }
+
+ break;
+ case LOADER_ID_USER_IDS:
+ mUserIdsAdapter.swapCursor(data);
+ break;
+ case LOADER_ID_KEYS:
+ // the first key here is our master key
+ if (data.moveToFirst()) {
+ // get key id from MASTER_KEY_ID
+ long keyId = data.getLong(KEYS_INDEX_KEY_ID);
+
+ String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
+ mKeyId.setText(keyIdStr);
+
+ // get creation date from CREATION
+ if (data.isNull(KEYS_INDEX_CREATION)) {
+ mCreation.setText(R.string.none);
+ } else {
+ Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
+
+ mCreation.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
+ creationDate));
+ }
+
+ // get expiry date from EXPIRY
+ if (data.isNull(KEYS_INDEX_EXPIRY)) {
+ mExpiry.setText(R.string.none);
+ } else {
+ Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
+
+ mExpiry.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
+ expiryDate));
+ }
+
+ String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
+ data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
+ mAlgorithm.setText(algorithmStr);
+
+ byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
+ if (fingerprintBlob == null) {
+ // FALLBACK for old database entries
+ fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
+ }
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
+ fingerprint = fingerprint.replace(" ", "\n");
+
+ mFingerprint.setText(fingerprint);
+ }
+
+ mKeysAdapter.swapCursor(data);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ switch (loader.getId()) {
+ case LOADER_ID_KEYRING:
+ // No resources need to be freed for this ID
+ break;
+ case LOADER_ID_USER_IDS:
+ mUserIdsAdapter.swapCursor(null);
+ break;
+ case LOADER_ID_KEYS:
+ mKeysAdapter.swapCursor(null);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ private void encryptToContact(Uri dataUri) {
+ long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
+
+ long[] encryptionKeyIds = new long[]{keyId};
+ Intent intent = new Intent(getActivity(), EncryptActivity.class);
+ intent.setAction(EncryptActivity.ACTION_ENCRYPT);
+ intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
+ // used instead of startActivity set actionbar based on callingPackage
+ startActivityForResult(intent, 0);
+ }
+
+ private void certifyKey(Uri dataUri) {
+ Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
+ signIntent.setData(dataUri);
+ startActivity(signIntent);
+ }
+
+
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
index a850fc020..52186b662 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
@@ -90,16 +90,11 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
View view = mInflater.inflate(R.layout.import_keys_list_entry, null);
TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mainUserId.setText(R.string.user_id_no_name);
TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mainUserIdRest.setText("");
TextView keyId = (TextView) view.findViewById(R.id.keyId);
- keyId.setText(R.string.no_key);
TextView fingerprint = (TextView) view.findViewById(R.id.fingerprint);
TextView algorithm = (TextView) view.findViewById(R.id.algorithm);
- algorithm.setText("");
TextView status = (TextView) view.findViewById(R.id.status);
- status.setText("");
// main user id
String userId = entry.userIds.get(0);
@@ -113,6 +108,8 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
mainUserId.setTextColor(Color.RED);
}
mainUserId.setText(userIdSplit[0]);
+ } else {
+ mainUserId.setText(R.string.user_id_no_name);
}
// email
@@ -124,12 +121,18 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
}
keyId.setText(entry.hexKeyId);
- fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
+
+ if (entry.fingerPrint != null) {
+ fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
+ fingerprint.setVisibility(View.VISIBLE);
+ } else {
+ fingerprint.setVisibility(View.GONE);
+ }
algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
if (entry.revoked) {
- status.setText("revoked");
+ status.setText(R.string.revoked);
} else {
status.setVisibility(View.GONE);
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
index 5094e8abd..4a7a9c93a 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
@@ -48,7 +48,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
private boolean selected;
- private byte[] bytes = new byte[] {};
+ private byte[] bytes = new byte[]{};
public ImportKeysListEntry(ImportKeysListEntry b) {
this.userIds = b.userIds;
@@ -167,7 +167,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
.getFingerprint(), true);
- this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
+ this.hexKeyId = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
index 753994450..b3bc39127 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java
@@ -79,7 +79,7 @@ public class ImportKeysListServerLoader extends AsyncTaskLoader<List<ImportKeysL
}
/**
- * Query key server
+ * Query keyserver
*/
private void queryServer(String query, String keyServer) {
HkpKeyServer server = new HkpKeyServer(keyServer);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
index f0e926655..257136cbd 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
@@ -23,10 +23,11 @@ import java.util.Set;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.util.Log;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
+
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
@@ -35,6 +36,7 @@ import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.RelativeLayout;
import android.widget.TextView;
/**
@@ -44,6 +46,7 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
private LayoutInflater mInflater;
private int mSectionColumnIndex;
private int mIndexUserId;
+ private int mIndexIsRevoked;
@SuppressLint("UseSparseArrays")
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
@@ -66,48 +69,59 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
/**
* Get column indexes for performance reasons just once in constructor and swapCursor. For a
* performance comparison see http://stackoverflow.com/a/17999582
- *
+ *
* @param cursor
*/
private void initIndex(Cursor cursor) {
if (cursor != null) {
- mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID);
+ mIndexUserId = cursor.getColumnIndexOrThrow(KeychainContract.UserIds.USER_ID);
+ mIndexIsRevoked = cursor.getColumnIndexOrThrow(KeychainContract.Keys.IS_REVOKED);
}
}
/**
* Bind cursor data to the item list view
- *
+ * <p/>
* NOTE: CursorAdapter already implements the ViewHolder pattern in its getView() method. Thus
* no ViewHolder is required here.
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mainUserId.setText(R.string.user_id_no_name);
TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mainUserIdRest.setText("");
+ TextView revoked = (TextView) view.findViewById(R.id.revoked);
String userId = cursor.getString(mIndexUserId);
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
-
if (userIdSplit[0] != null) {
mainUserId.setText(userIdSplit[0]);
+ } else {
+ mainUserId.setText(R.string.user_id_no_name);
}
if (userIdSplit[1] != null) {
mainUserIdRest.setText(userIdSplit[1]);
+ mainUserIdRest.setVisibility(View.VISIBLE);
+ } else {
+ mainUserIdRest.setVisibility(View.GONE);
+ }
+
+ boolean isRevoked = cursor.getInt(mIndexIsRevoked) > 0;
+ if (isRevoked) {
+ revoked.setVisibility(View.VISIBLE);
+ } else {
+ revoked.setVisibility(View.GONE);
}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.key_list_item, null);
+ return mInflater.inflate(R.layout.key_list_public_item, null);
}
/**
* Creates a new header view and binds the section headers to it. It uses the ViewHolder
* pattern. Most functionality is similar to getView() from Android's CursorAdapter.
- *
+ * <p/>
* NOTE: The variables mDataValid and mCursor are available due to the super class
* CursorAdapter.
*/
@@ -159,8 +173,7 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
}
// return the first character of the name as ID because this is what
- // headers private HashMap<Integer, Boolean> mSelection = new HashMap<Integer,
- // Boolean>();are based upon
+ // headers are based upon
String userId = mCursor.getString(mSectionColumnIndex);
if (userId != null && userId.length() > 0) {
return userId.subSequence(0, 1).charAt(0);
@@ -173,7 +186,9 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
TextView text;
}
- /** -------------------------- MULTI-SELECTION METHODS -------------- */
+ /**
+ * -------------------------- MULTI-SELECTION METHODS --------------
+ */
public void setNewSelection(int position, boolean value) {
mSelection.put(position, value);
notifyDataSetChanged();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java
index ce9b48bff..11d1e8c17 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java
@@ -71,24 +71,26 @@ public class KeyListSecretAdapter extends CursorAdapter {
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mainUserId.setText(R.string.user_id_no_name);
TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mainUserIdRest.setText("");
String userId = cursor.getString(mIndexUserId);
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
if (userIdSplit[0] != null) {
mainUserId.setText(userIdSplit[0]);
+ } else {
+ mainUserId.setText(R.string.user_id_no_name);
}
if (userIdSplit[1] != null) {
mainUserIdRest.setText(userIdSplit[1]);
+ } else {
+ mainUserIdRest.setText("");
}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.key_list_item, null);
+ return mInflater.inflate(R.layout.key_list_secret_item, null);
}
/** -------------------------- MULTI-SELECTION METHODS -------------- */
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
index 7e01faf9b..d44dd5890 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
@@ -96,27 +96,31 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
boolean valid = cursor.getInt(mIndexProjectionValid) > 0;
TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mainUserId.setText(R.string.user_id_no_name);
TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mainUserIdRest.setText("");
TextView keyId = (TextView) view.findViewById(R.id.keyId);
- keyId.setText(R.string.no_key);
TextView status = (TextView) view.findViewById(R.id.status);
- status.setText(R.string.unknown_status);
String userId = cursor.getString(mIndexUserId);
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
if (userIdSplit[0] != null) {
mainUserId.setText(userIdSplit[0]);
+ } else {
+ mainUserId.setText(R.string.user_id_no_name);
}
if (userIdSplit[1] != null) {
mainUserIdRest.setText(userIdSplit[1]);
+ } else {
+ mainUserIdRest.setText("");
}
+ // TODO: needed to key id to no?
+ keyId.setText(R.string.no_key);
long masterKeyId = cursor.getLong(mIndexMasterKeyId);
keyId.setText(PgpKeyHelper.convertKeyIdToHex(masterKeyId));
+ // TODO: needed to set unknown_status?
+ status.setText(R.string.unknown_status);
if (valid) {
if (mKeyType == Id.type.public_key) {
status.setText(R.string.can_encrypt);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
new file mode 100644
index 000000000..924a70897
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
@@ -0,0 +1,84 @@
+package org.sufficientlysecure.keychain.ui.adapter;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentStatePagerAdapter;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+
+import java.util.ArrayList;
+
+public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener,
+ ViewPager.OnPageChangeListener {
+ private final Context mContext;
+ private final ActionBar mActionBar;
+ private final ViewPager mViewPager;
+ private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
+
+ static final class TabInfo {
+ private final Class<?> clss;
+ private final Bundle args;
+
+ TabInfo(Class<?> _class, Bundle _args) {
+ clss = _class;
+ args = _args;
+ }
+ }
+
+ public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
+ super(activity.getSupportFragmentManager());
+ mContext = activity;
+ mActionBar = activity.getSupportActionBar();
+ mViewPager = pager;
+ mViewPager.setAdapter(this);
+ mViewPager.setOnPageChangeListener(this);
+ }
+
+ public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, boolean selected) {
+ TabInfo info = new TabInfo(clss, args);
+ tab.setTag(info);
+ tab.setTabListener(this);
+ mTabs.add(info);
+ mActionBar.addTab(tab, selected);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mTabs.size();
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ TabInfo info = mTabs.get(position);
+ return Fragment.instantiate(mContext, info.clss.getName(), info.args);
+ }
+
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ }
+
+ public void onPageSelected(int position) {
+ mActionBar.setSelectedNavigationItem(position);
+ }
+
+ public void onPageScrollStateChanged(int state) {
+ }
+
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
+ Object tag = tab.getTag();
+ for (int i = 0; i < mTabs.size(); i++) {
+ if (mTabs.get(i) == tag) {
+ mViewPager.setCurrentItem(i);
+ }
+ }
+ }
+
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
+ }
+
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
+ }
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
index d5162c403..54c7eb60e 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
@@ -76,38 +76,39 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
@Override
public void bindView(View view, Context context, Cursor cursor) {
+ TextView keyId = (TextView) view.findViewById(R.id.keyId);
+ TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails);
+ ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
+ ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
+ ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
+ ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
+
String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm),
cursor.getInt(mIndexKeySize));
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
keyId.setText(keyIdStr);
- TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails);
keyDetails.setText("(" + algorithmStr + ")");
- ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
if (cursor.getInt(mIndexIsMasterKey) != 1) {
masterKeyIcon.setVisibility(View.INVISIBLE);
} else {
masterKeyIcon.setVisibility(View.VISIBLE);
}
- ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
if (cursor.getInt(mIndexCanCertify) != 1) {
certifyIcon.setVisibility(View.GONE);
} else {
certifyIcon.setVisibility(View.VISIBLE);
}
- ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
if (cursor.getInt(mIndexCanEncrypt) != 1) {
encryptIcon.setVisibility(View.GONE);
} else {
encryptIcon.setVisibility(View.VISIBLE);
}
- ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
if (cursor.getInt(mIndexCanSign) != 1) {
signIcon.setVisibility(View.GONE);
} else {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
index 109bfe929..3c44bff81 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
@@ -23,12 +23,16 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
@@ -36,6 +40,8 @@ import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
+import java.util.ArrayList;
+
public class DeleteKeyDialogFragment extends DialogFragment {
private static final String ARG_MESSENGER = "messenger";
private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_file";
@@ -43,13 +49,15 @@ public class DeleteKeyDialogFragment extends DialogFragment {
public static final int MESSAGE_OKAY = 1;
+ public static final String MESSAGE_NOT_DELETED = "not_deleted";
+
private Messenger mMessenger;
/**
* Creates new instance of this delete file dialog fragment
*/
public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds,
- int keyType) {
+ int keyType) {
DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
Bundle args = new Bundle();
@@ -77,20 +85,13 @@ public class DeleteKeyDialogFragment extends DialogFragment {
builder.setTitle(R.string.warning);
if (keyRingRowIds.length == 1) {
- // TODO: better way to do this?
- String userId = activity.getString(R.string.user_id_no_name);
-
+ Uri dataUri;
if (keyType == Id.type.public_key) {
- PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByRowId(activity,
- keyRingRowIds[0]);
- userId = PgpKeyHelper.getMainUserIdSafe(activity,
- PgpKeyHelper.getMasterKey(keyRing));
+ dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowIds[0]));
} else {
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByRowId(activity,
- keyRingRowIds[0]);
- userId = PgpKeyHelper.getMainUserIdSafe(activity,
- PgpKeyHelper.getMasterKey(keyRing));
+ dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowIds[0]));
}
+ String userId = ProviderHelper.getUserId(activity, dataUri);
builder.setMessage(getString(
keyType == Id.type.public_key ? R.string.key_deletion_confirmation
@@ -104,9 +105,61 @@ public class DeleteKeyDialogFragment extends DialogFragment {
@Override
public void onClick(DialogInterface dialog, int id) {
+ ArrayList<String> notDeleted = new ArrayList<String>();
+
if (keyType == Id.type.public_key) {
- for (long keyRowId : keyRingRowIds) {
- ProviderHelper.deletePublicKeyRing(activity, keyRowId);
+ Uri queryUri = KeychainContract.KeyRings.buildPublicKeyRingsUri();
+ String[] projection = new String[]{
+ KeychainContract.KeyRings._ID, // 0
+ KeychainContract.KeyRings.MASTER_KEY_ID, // 1
+ KeychainContract.UserIds.USER_ID // 2
+ };
+
+ // make selection with all entries where _ID is one of the given row ids
+ String selection = KeychainDatabase.Tables.KEY_RINGS + "." +
+ KeychainContract.KeyRings._ID + " IN(";
+ String selectionIDs = "";
+ for (int i = 0; i < keyRingRowIds.length; i++) {
+ selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'";
+ if (i+1 < keyRingRowIds.length)
+ selectionIDs += ",";
+ }
+ selection += selectionIDs + ")";
+
+ Cursor cursor = activity.getContentResolver().query(queryUri, projection,
+ selection, null, null);
+
+ long rowId;
+ long masterKeyId;
+ String userId;
+ try {
+ while (cursor != null && cursor.moveToNext()) {
+ rowId = cursor.getLong(0);
+ masterKeyId = cursor.getLong(1);
+ userId = cursor.getString(2);
+
+ Log.d(Constants.TAG, "rowId: " + rowId + ", masterKeyId: " + masterKeyId
+ + ", userId: " + userId);
+
+ // check if a corresponding secret key exists...
+ Cursor secretCursor = activity.getContentResolver().query(
+ KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)),
+ null, null, null, null
+ );
+ if (secretCursor != null && secretCursor.getCount() > 0) {
+ notDeleted.add(userId);
+ } else {
+ // it is okay to delete this key, no secret key found!
+ ProviderHelper.deletePublicKeyRing(activity, rowId);
+ }
+ if (secretCursor != null) {
+ secretCursor.close();
+ }
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
} else {
for (long keyRowId : keyRingRowIds) {
@@ -116,7 +169,13 @@ public class DeleteKeyDialogFragment extends DialogFragment {
dismiss();
- sendMessageToHandler(MESSAGE_OKAY);
+ if (notDeleted.size() > 0) {
+ Bundle data = new Bundle();
+ data.putStringArrayList(MESSAGE_NOT_DELETED, notDeleted);
+ sendMessageToHandler(MESSAGE_OKAY, data);
+ } else {
+ sendMessageToHandler(MESSAGE_OKAY, null);
+ }
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@@ -131,13 +190,15 @@ public class DeleteKeyDialogFragment extends DialogFragment {
/**
* Send message back to handler which is initialized in a activity
- *
- * @param what
- * Message integer you want to send
+ *
+ * @param what Message integer you want to send
*/
- private void sendMessageToHandler(Integer what) {
+ private void sendMessageToHandler(Integer what, Bundle data) {
Message msg = Message.obtain();
msg.what = what;
+ if (data != null) {
+ msg.setData(data);
+ }
try {
mMessenger.send(msg);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java
deleted file mode 100644
index a0592285f..000000000
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2012-2013 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 org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
-import org.sufficientlysecure.keychain.util.Log;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.support.v4.app.DialogFragment;
-
-public class LookupUnknownKeyDialogFragment extends DialogFragment {
- private static final String ARG_MESSENGER = "messenger";
- private static final String ARG_UNKNOWN_KEY_ID = "unknown_key_id";
-
- public static final int MESSAGE_OKAY = 1;
- public static final int MESSAGE_CANCEL = 2;
-
- private Messenger mMessenger;
-
- /**
- * Creates new instance of this dialog fragment
- *
- * @param messenger
- * @param unknownKeyId
- * @return
- */
- public static LookupUnknownKeyDialogFragment newInstance(Messenger messenger, long unknownKeyId) {
- LookupUnknownKeyDialogFragment frag = new LookupUnknownKeyDialogFragment();
- Bundle args = new Bundle();
- args.putLong(ARG_UNKNOWN_KEY_ID, unknownKeyId);
- args.putParcelable(ARG_MESSENGER, messenger);
-
- frag.setArguments(args);
-
- return frag;
- }
-
- /**
- * Creates dialog
- */
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Activity activity = getActivity();
-
- final long unknownKeyId = getArguments().getLong(ARG_UNKNOWN_KEY_ID);
- mMessenger = getArguments().getParcelable(ARG_MESSENGER);
-
- AlertDialog.Builder alert = new AlertDialog.Builder(activity);
-
- alert.setIcon(android.R.drawable.ic_dialog_alert);
- alert.setTitle(R.string.title_unknown_signature_key);
- alert.setMessage(getString(R.string.lookup_unknown_key,
- PgpKeyHelper.convertKeyIdToHex(unknownKeyId)));
-
- alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
-
- sendMessageToHandler(MESSAGE_OKAY);
-
- Intent intent = new Intent(activity, ImportKeysActivity.class);
- intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER);
- intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId);
- startActivityForResult(intent, Id.request.look_up_key_id);
- }
- });
- alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dismiss();
-
- sendMessageToHandler(MESSAGE_CANCEL);
- }
- });
- alert.setCancelable(true);
- alert.setOnCancelListener(new OnCancelListener() {
-
- @Override
- public void onCancel(DialogInterface dialog) {
- sendMessageToHandler(MESSAGE_CANCEL);
- }
- });
-
- return alert.create();
- }
-
- /**
- * Send message back to handler which is initialized in a activity
- *
- * @param what
- * Message integer you want to send
- */
- private void sendMessageToHandler(Integer what) {
- Message msg = Message.obtain();
- msg.what = what;
-
- try {
- mMessenger.send(msg);
- } catch (RemoteException e) {
- Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
- } catch (NullPointerException e) {
- Log.w(Constants.TAG, "Messenger is null!", e);
- }
- }
-} \ No newline at end of file