aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-01-12 21:33:37 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2014-01-12 21:33:37 +0100
commit100ae50e02ef3dfd0330a6e1e7084726ddea69a0 (patch)
treec5eb870ccab1fc99718f44ced068b84d3238cdde /OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
parent1895e6acbd71455d6c287c258231c2a9ce2ffd1b (diff)
downloadopen-keychain-100ae50e02ef3dfd0330a6e1e7084726ddea69a0.tar.gz
open-keychain-100ae50e02ef3dfd0330a6e1e7084726ddea69a0.tar.bz2
open-keychain-100ae50e02ef3dfd0330a6e1e7084726ddea69a0.zip
cleanup layouts, prepare layouts for new key view
Diffstat (limited to 'OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java')
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java396
1 files changed, 396 insertions, 0 deletions
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
new file mode 100644
index 000000000..5bc30ccc5
--- /dev/null
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2013 Bahtiar 'kalkin' Gadimov
+ *
+ * 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 java.util.ArrayList;
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.spongycastle.openpgp.PGPPublicKey;
+import org.spongycastle.openpgp.PGPPublicKeyRing;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.Id;
+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.ProviderHelper;
+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.annotation.SuppressLint;
+import android.content.Intent;
+import android.net.Uri;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.CreateNdefMessageCallback;
+import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
+import android.nfc.NfcEvent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.format.DateFormat;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuItem;
+import com.beardedhen.androidbootstrap.BootstrapButton;
+
+@SuppressLint("NewApi")
+public class ViewKeyActivity extends SherlockFragmentActivity implements CreateNdefMessageCallback,
+ OnNdefPushCompleteCallback {
+
+ ExportHelper mExportHelper;
+
+ private Uri mDataUri;
+
+ private PGPPublicKey mPublicKey;
+
+ private TextView mAlgorithm;
+ private TextView mFingerint;
+ private TextView mExpiry;
+ private TextView mCreation;
+ private BootstrapButton mActionEncrypt;
+
+ private ListView mUserIds;
+ private ListView mKeys;
+
+ // NFC
+ private NfcAdapter mNfcAdapter;
+ private byte[] mSharedKeyringBytes;
+ private static final int NFC_SENT = 1;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mExportHelper = new ExportHelper(this);
+
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setHomeButtonEnabled(true);
+
+ setContentView(R.layout.view_key_activity);
+
+ mFingerint = (TextView) findViewById(R.id.fingerprint);
+ mExpiry = (TextView) findViewById(R.id.expiry);
+ mCreation = (TextView) findViewById(R.id.creation);
+ mAlgorithm = (TextView) findViewById(R.id.algorithm);
+ mActionEncrypt = (BootstrapButton) findViewById(R.id.action_encrypt);
+ mUserIds = (ListView) findViewById(R.id.user_ids);
+ mKeys = (ListView) findViewById(R.id.keys);
+
+ Intent intent = getIntent();
+ mDataUri = intent.getData();
+ if (mDataUri == null) {
+ Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
+ finish();
+ return;
+ } else {
+ Log.d(Constants.TAG, "uri: " + mDataUri);
+ loadData(mDataUri);
+ initNfc(mDataUri);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getSupportMenuInflater().inflate(R.menu.key_view, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ 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;
+ case R.id.menu_key_view_export_file:
+ mExportHelper.showExportKeysDialog(mDataUri, Id.type.public_key, Constants.path.APP_DIR
+ + "/pubexport.asc");
+ return true;
+ case R.id.menu_key_view_share_default:
+ shareKey(mDataUri);
+ return true;
+ case R.id.menu_key_view_share_qr_code:
+ shareKeyQrCode(mDataUri);
+ return true;
+ case R.id.menu_key_view_share_nfc:
+ shareNfc();
+ return true;
+ case R.id.menu_key_view_share_clipboard:
+ 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);
+ return true;
+ }
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void loadData(Uri dataUri) {
+ PGPPublicKeyRing ring = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, dataUri);
+ mPublicKey = ring.getPublicKey();
+
+ mFingerint.setText(PgpKeyHelper.shortifyFingerprint(PgpKeyHelper
+ .convertFingerprintToHex(mPublicKey.getFingerprint())));
+ String[] mainUserId = splitUserId("");
+
+ Date expiryDate = PgpKeyHelper.getExpiryDate(mPublicKey);
+ if (expiryDate == null) {
+ mExpiry.setText("");
+ } else {
+ mExpiry.setText(DateFormat.getDateFormat(getApplicationContext()).format(expiryDate));
+ }
+
+ mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(
+ PgpKeyHelper.getCreationDate(mPublicKey)));
+ mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(mPublicKey));
+
+ mActionEncrypt.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ long[] encryptionKeyIds = new long[] { mPublicKey.getKeyID() };
+ 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);
+ }
+ });
+ }
+
+ /**
+ * TODO: does this duplicate functionality from elsewhere? put in helper!
+ */
+ private String[] splitUserId(String userId) {
+ String[] result = new String[] { "", "", "" };
+ Log.v("UserID", userId);
+
+ Pattern withComment = Pattern.compile("^(.*) [(](.*)[)] <(.*)>$");
+ Matcher matcher = withComment.matcher(userId);
+ if (matcher.matches()) {
+ result[0] = matcher.group(1);
+ result[1] = matcher.group(2);
+ result[2] = matcher.group(3);
+ return result;
+ }
+
+ Pattern withoutComment = Pattern.compile("^(.*) <(.*)>$");
+ matcher = withoutComment.matcher(userId);
+ if (matcher.matches()) {
+ result[0] = matcher.group(1);
+ result[1] = matcher.group(2);
+ return result;
+ }
+ return result;
+ }
+
+ private void uploadToKeyserver(Uri dataUri) {
+ long keyRingRowId = Long.valueOf(dataUri.getLastPathSegment());
+
+ Intent uploadIntent = new Intent(this, KeyServerUploadActivity.class);
+ uploadIntent.setAction(KeyServerUploadActivity.ACTION_EXPORT_KEY_TO_SERVER);
+ uploadIntent.putExtra(KeyServerUploadActivity.EXTRA_KEYRING_ROW_ID, (int) keyRingRowId);
+ startActivityForResult(uploadIntent, Id.request.export_to_server);
+ }
+
+ private void updateFromKeyserver(Uri dataUri) {
+ long updateKeyId = 0;
+ PGPPublicKeyRing updateRing = (PGPPublicKeyRing) ProviderHelper
+ .getPGPKeyRing(this, dataUri);
+
+ if (updateRing != null) {
+ updateKeyId = PgpKeyHelper.getMasterKey(updateRing).getKeyID();
+ }
+ if (updateKeyId == 0) {
+ Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!");
+ return;
+ }
+
+ Intent signIntent = new Intent(this, SignKeyActivity.class);
+ signIntent.putExtra(SignKeyActivity.EXTRA_KEY_ID, updateKeyId);
+ startActivity(signIntent);
+
+ Intent queryIntent = new Intent(this, KeyServerQueryActivity.class);
+ queryIntent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID_AND_RETURN);
+ queryIntent.putExtra(KeyServerQueryActivity.EXTRA_KEY_ID, updateKeyId);
+
+ // TODO: lookup??
+ startActivityForResult(queryIntent, Id.request.look_up_key_id);
+ }
+
+ private void signKey(Uri dataUri) {
+ long keyId = 0;
+ PGPPublicKeyRing signKey = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, dataUri);
+
+ if (signKey != null) {
+ keyId = PgpKeyHelper.getMasterKey(signKey).getKeyID();
+ }
+ if (keyId == 0) {
+ Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!");
+ return;
+ }
+
+ Intent signIntent = new Intent(this, SignKeyActivity.class);
+ signIntent.putExtra(SignKeyActivity.EXTRA_KEY_ID, keyId);
+ startActivity(signIntent);
+ }
+
+ private void shareKey(Uri dataUri) {
+ // get public keyring as ascii armored string
+ long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
+ ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri,
+ new long[] { masterKeyId });
+
+ // let user choose application
+ Intent sendIntent = new Intent(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_TEXT, keyringArmored.get(0));
+ sendIntent.setType("text/plain");
+ startActivity(Intent.createChooser(sendIntent,
+ getResources().getText(R.string.action_share_key_with)));
+ }
+
+ private void shareKeyQrCode(Uri dataUri) {
+ // get public keyring as ascii armored string
+ long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
+ ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri,
+ new long[] { masterKeyId });
+
+ ShareQrCodeDialogFragment dialog = ShareQrCodeDialogFragment.newInstance(keyringArmored
+ .get(0));
+ dialog.show(getSupportFragmentManager(), "shareQrCodeDialog");
+ }
+
+ private void copyToClipboard(Uri dataUri) {
+ // get public keyring as ascii armored string
+ long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
+ ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri,
+ new long[] { masterKeyId });
+
+ ClipboardReflection.copyToClipboard(this, keyringArmored.get(0));
+ }
+
+ private void shareNfc() {
+ ShareNfcDialogFragment dialog = ShareNfcDialogFragment.newInstance();
+ dialog.show(getSupportFragmentManager(), "shareNfcDialog");
+ }
+
+ /**
+ * NFC: Initialize NFC sharing if OS and device supports it
+ */
+ private void initNfc(Uri dataUri) {
+ // check if NFC Beam is supported (>= Android 4.1)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ // Check for available NFC Adapter
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
+ if (mNfcAdapter != null) {
+ // init nfc
+
+ // get public keyring as byte array
+ long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
+ mSharedKeyringBytes = ProviderHelper.getKeyRingsAsByteArray(this, dataUri,
+ new long[] { masterKeyId });
+
+ // Register callback to set NDEF message
+ mNfcAdapter.setNdefPushMessageCallback(this, this);
+ // Register callback to listen for message-sent success
+ mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
+ }
+ }
+ }
+
+ /**
+ * NFC: Implementation for the CreateNdefMessageCallback interface
+ */
+ @Override
+ public NdefMessage createNdefMessage(NfcEvent event) {
+ /**
+ * When a device receives a push with an AAR in it, the application specified in the AAR is
+ * guaranteed to run. The AAR overrides the tag dispatch system. You can add it back in to
+ * guarantee that this activity starts when receiving a beamed message. For now, this code
+ * uses the tag dispatch system.
+ */
+ NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
+ mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
+ return msg;
+ }
+
+ /**
+ * NFC: Implementation for the OnNdefPushCompleteCallback interface
+ */
+ @Override
+ public void onNdefPushComplete(NfcEvent arg0) {
+ // A handler is needed to send messages to the activity when this
+ // callback occurs, because it happens from a binder thread
+ mNfcHandler.obtainMessage(NFC_SENT).sendToTarget();
+ }
+
+ /**
+ * NFC: This handler receives a message from onNdefPushComplete
+ */
+ private final Handler mNfcHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case NFC_SENT:
+ Toast.makeText(getApplicationContext(), R.string.nfc_successfull, Toast.LENGTH_LONG)
+ .show();
+ break;
+ }
+ }
+ };
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (!mExportHelper.handleActivityResult(requestCode, resultCode, data)) {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+}