diff --git a/OpenPGP-Keychain/AndroidManifest.xml b/OpenPGP-Keychain/AndroidManifest.xml index 8a340708d..fd7edff2a 100644 --- a/OpenPGP-Keychain/AndroidManifest.xml +++ b/OpenPGP-Keychain/AndroidManifest.xml @@ -118,7 +118,6 @@ android:name=".ui.EditKeyActivity" android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:label="@string/title_edit_key" - android:uiOptions="splitActionBarWhenNarrow" android:windowSoftInputMode="stateHidden" /> + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/res/values/strings.xml b/OpenPGP-Keychain/res/values/strings.xml index e837e01dc..0e4f42c59 100644 --- a/OpenPGP-Keychain/res/values/strings.xml +++ b/OpenPGP-Keychain/res/values/strings.xml @@ -100,7 +100,8 @@ Copy to clipboard Sign key Beam settings - + Cancel + Sign Message diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java index b07ac53f8..1683c7c0e 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -493,7 +493,7 @@ public class ProviderHelper { */ public static long getPublicMasterKeyId(Context context, long keyRingRowId) { Uri queryUri = KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowId)); - return getMasterKeyId(context, queryUri, keyRingRowId); + return getMasterKeyId(context, queryUri); } /** @@ -551,7 +551,7 @@ public class ProviderHelper { */ public static long getSecretMasterKeyId(Context context, long keyRingRowId) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId)); - return getMasterKeyId(context, queryUri, keyRingRowId); + return getMasterKeyId(context, queryUri); } /** @@ -562,7 +562,7 @@ public class ProviderHelper { * @param keyRingRowId * @return */ - private static long getMasterKeyId(Context context, Uri queryUri, long keyRingRowId) { + public static long getMasterKeyId(Context context, Uri queryUri) { String[] projection = new String[] { KeyRings.MASTER_KEY_ID }; ContentResolver cr = context.getContentResolver(); @@ -592,7 +592,7 @@ public class ProviderHelper { return getKeyRingsAsArmoredString(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds); } - private static ArrayList getKeyRingsAsArmoredString(Context context, Uri uri, + public static ArrayList getKeyRingsAsArmoredString(Context context, Uri uri, long[] masterKeyIds) { ArrayList output = new ArrayList(); @@ -661,7 +661,7 @@ public class ProviderHelper { return getKeyRingsAsByteArray(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds); } - private static byte[] getKeyRingsAsByteArray(Context context, Uri uri, long[] masterKeyIds) { + public static byte[] getKeyRingsAsByteArray(Context context, Uri uri, long[] masterKeyIds) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); if (masterKeyIds != null && masterKeyIds.length > 0) { diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 4dcaa6d73..c0c81b969 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -34,6 +34,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.widget.KeyEditor; @@ -45,6 +46,7 @@ import org.sufficientlysecure.keychain.util.Log; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -60,9 +62,10 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.LinearLayout; import android.widget.Toast; -import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; -public class EditKeyActivity extends SherlockFragmentActivity { +public class EditKeyActivity extends KeyActivity { // Actions for internal use only: public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY"; @@ -72,13 +75,14 @@ public class EditKeyActivity extends SherlockFragmentActivity { public static final String EXTRA_USER_IDS = "user_ids"; public static final String EXTRA_NO_PASSPHRASE = "no_passphrase"; public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generate_default_keys"; - public static final String EXTRA_MASTER_KEY_ID = "master_key_id"; - public static final String EXTRA_MASTER_CAN_SIGN = "master_can_sign"; // results when saving key public static final String RESULT_EXTRA_MASTER_KEY_ID = "master_key_id"; public static final String RESULT_EXTRA_USER_ID = "user_id"; + // EDIT + private Uri mDataUri; + private PGPSecretKeyRing mKeyRing = null; private SectionView mUserIdsView; @@ -96,29 +100,10 @@ public class EditKeyActivity extends SherlockFragmentActivity { Vector mKeysUsages; boolean masterCanSign = true; - // will be set to false to build layout later in handler - private boolean mBuildLayout = true; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Inflate a "Done"/"Cancel" custom action bar - ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_save, - new View.OnClickListener() { - @Override - public void onClick(View v) { - // save - saveClicked(); - } - }, R.string.btn_do_not_save, new View.OnClickListener() { - @Override - public void onClick(View v) { - // cancel - cancelClicked(); - } - }); - mUserIds = new Vector(); mKeys = new Vector(); mKeysUsages = new Vector(); @@ -131,10 +116,6 @@ public class EditKeyActivity extends SherlockFragmentActivity { } else if (ACTION_EDIT_KEY.equals(action)) { handleActionEditKey(intent); } - - if (mBuildLayout) { - buildLayout(); - } } /** @@ -143,6 +124,20 @@ public class EditKeyActivity extends SherlockFragmentActivity { * @param intent */ private void handleActionCreateKey(Intent intent) { + // Inflate a "Done"/"Cancel" custom action bar + ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_save, + new View.OnClickListener() { + @Override + public void onClick(View v) { + saveClicked(); + } + }, R.string.btn_do_not_save, new View.OnClickListener() { + @Override + public void onClick(View v) { + cancelClicked(); + } + }); + Bundle extras = intent.getExtras(); mCurrentPassPhrase = ""; @@ -169,9 +164,6 @@ public class EditKeyActivity extends SherlockFragmentActivity { boolean generateDefaultKeys = extras.getBoolean(EXTRA_GENERATE_DEFAULT_KEYS); if (generateDefaultKeys) { - // build layout in handler after generating keys not directly in onCreate - mBuildLayout = false; - // Send all information needed to service generate keys in other thread Intent serviceIntent = new Intent(this, KeychainIntentService.class); serviceIntent.setAction(KeychainIntentService.ACTION_GENERATE_DEFAULT_RSA_KEYS); @@ -228,12 +220,55 @@ public class EditKeyActivity extends SherlockFragmentActivity { startService(serviceIntent); } } + } else { + buildLayout(); + } + } + + /** + * Handle intent action to edit existing key + * + * @param intent + */ + private void handleActionEditKey(Intent intent) { + // Inflate a "Done"/"Cancel" custom action bar + ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_save, + new View.OnClickListener() { + @Override + public void onClick(View v) { + saveClicked(); + } + }); + + 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); + + long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); + + // get master key id using row id + long masterKeyId = ProviderHelper.getSecretMasterKeyId(this, keyRingRowId); + + boolean masterCanSign = ProviderHelper.getSecretMasterKeyCanSign(this, keyRingRowId); + + String passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); + if (passphrase == null) { + showPassphraseDialog(masterKeyId, masterCanSign); + } else { + // PgpMain.setEditPassPhrase(passPhrase); + mCurrentPassPhrase = passphrase; + + finallyEdit(masterKeyId, masterCanSign); + } } } private void showPassphraseDialog(final long masterKeyId, final boolean masterCanSign) { // Message is received after passphrase is cached - final boolean mCanSign = masterCanSign; Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { @@ -263,37 +298,41 @@ public class EditKeyActivity extends SherlockFragmentActivity { } } - /** - * Handle intent action to edit existing key - * - * @param intent - */ - private void handleActionEditKey(Intent intent) { - Bundle extras = intent.getExtras(); - - if (extras != null) { - if (extras.containsKey(EXTRA_MASTER_CAN_SIGN)) { - masterCanSign = extras.getBoolean(EXTRA_MASTER_CAN_SIGN); - } - if (extras.containsKey(EXTRA_MASTER_KEY_ID)) { - long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID); - - // build layout in edit() - mBuildLayout = false; - - String passPhrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); - if (passPhrase == null) { - showPassphraseDialog(masterKeyId, masterCanSign); - } else { - // PgpMain.setEditPassPhrase(passPhrase); - mCurrentPassPhrase = passPhrase; - - finallyEdit(masterKeyId, masterCanSign); - } - } + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + // show menu only on edit + if (mDataUri != null) { + return super.onPrepareOptionsMenu(menu); + } else { + return false; } } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + getSupportMenuInflater().inflate(R.menu.key_edit, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_key_edit_cancel: + cancelClicked(); + return true; + case R.id.menu_key_edit_export_file: + showExportKeysDialog(mDataUri, Id.type.secret_key, Constants.path.APP_DIR + + "/secexport.asc"); + return true; + case R.id.menu_key_edit_delete: + deleteKey(mDataUri, Id.type.secret_key); + return true; + } + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("unchecked") private void finallyEdit(final long masterKeyId, final boolean masterCanSign) { if (masterKeyId != 0) { PGPSecretKey masterKey = null; @@ -316,13 +355,13 @@ public class EditKeyActivity extends SherlockFragmentActivity { } } - buildLayout(); - // TODO: ??? if (mCurrentPassPhrase == null) { mCurrentPassPhrase = ""; } + buildLayout(); + if (mCurrentPassPhrase.equals("")) { // check "no passphrase" checkbox and remove button mNoPassphrase.setChecked(true); diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyActivity.java new file mode 100644 index 000000000..0415087dc --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyActivity.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2013 Dominik Schürmann + * + * 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 . + */ + +package org.sufficientlysecure.keychain.ui; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; +import org.sufficientlysecure.keychain.util.Log; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.widget.Toast; + +import com.actionbarsherlock.app.SherlockFragmentActivity; + +/** + * TODO: get key type by looking at dataUri! + * + */ +public class KeyActivity extends SherlockFragmentActivity { + + protected FileDialogFragment mFileDialog; + protected String mExportFilename; + + protected void deleteKey(Uri dataUri, final int keyType) { + long keyRingRowId = Long.valueOf(dataUri.getLastPathSegment()); + + // 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(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, + new long[] { keyRingRowId }, keyType); + + deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog"); + } + + /** + * Show dialog where to export keys + * + * @param keyRingMasterKeyId + * if -1 export all keys + */ + public void showExportKeysDialog(Uri dataUri, final int keyType, final String exportFilename) { + long keyRingRowId = Long.valueOf(dataUri.getLastPathSegment()); + + // TODO? + final long keyRingMasterKeyId = ProviderHelper.getSecretMasterKeyId(this, keyRingRowId); + mExportFilename = exportFilename; + + // Message is received after file is selected + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); + + exportKeys(keyRingMasterKeyId, keyType); + } + } + }; + + // Create a new Messenger for the communication back + final Messenger messenger = new Messenger(returnHandler); + + DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { + public void run() { + String title = null; + if (keyRingMasterKeyId != -1) { + // single key export + title = getString(R.string.title_export_key); + } else { + title = getString(R.string.title_export_keys); + } + + String message = null; + if (keyType == Id.type.public_key) { + message = getString(R.string.specify_file_to_export_to); + } else { + message = getString(R.string.specify_file_to_export_secret_keys_to); + } + + mFileDialog = FileDialogFragment.newInstance(messenger, title, message, + exportFilename, null, Id.request.filename); + + mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + } + }); + } + + /** + * Export keys + * + * @param keyRingMasterKeyId + * if -1 export all keys + */ + public void exportKeys(long keyRingMasterKeyId, int keyType) { + Log.d(Constants.TAG, "exportKeys started"); + + // Send all information needed to service to export key in other thread + Intent intent = new Intent(this, KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_EXPORT_KEYRING); + + // fill values for this action + Bundle data = new Bundle(); + + data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename); + data.putInt(KeychainIntentService.EXPORT_KEY_TYPE, keyType); + + if (keyRingMasterKeyId == -1) { + data.putBoolean(KeychainIntentService.EXPORT_ALL, true); + } else { + data.putLong(KeychainIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, keyRingMasterKeyId); + } + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after exporting is done in ApgService + KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(this, + R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + int exported = returnData.getInt(KeychainIntentService.RESULT_EXPORT); + String toastMessage; + if (exported == 1) { + toastMessage = getString(R.string.key_exported); + } else if (exported > 0) { + toastMessage = getString(R.string.keys_exported, exported); + } else { + toastMessage = getString(R.string.no_keys_exported); + } + Toast.makeText(KeyActivity.this, toastMessage, Toast.LENGTH_SHORT).show(); + + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(exportHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + exportHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + + @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 = data.getData().getPath(); + Log.d(Constants.TAG, "path=" + path); + + // set filename used in export/import dialogs + mFileDialog.setFilename(path); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "Nullpointer while retrieving path!", e); + } + } + return; + } + + default: { + break; + } + } + super.onActivityResult(requestCode, resultCode, data); + } +} diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java index f0a009482..fde90bb32 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java @@ -35,9 +35,6 @@ 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; @@ -122,7 +119,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte Set positions = mAdapter.getCurrentCheckedPosition(); switch (item.getItemId()) { case R.id.delete_entry: - + // get IDs for checked positions as long array long[] ids = new long[positions.size()]; int i = 0; @@ -233,25 +230,10 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte /** * Show dialog to delete key * - * TODO: no messenger needed etc! - * * @param keyRingRowIds */ public void showDeleteKeyDialog(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) { - // no further actions needed - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, + DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(null, keyRingRowIds, Id.type.public_key); deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog"); diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java index d98b5ab37..c19cdeea5 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java @@ -45,8 +45,8 @@ public class KeyListSecretActivity extends KeyListActivity { super.onCreateOptionsMenu(menu); menu.add(1, Id.menu.option.create, 1, R.string.menu_create_key).setShowAsAction( MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - menu.add(1, Id.menu.option.createExpert, 2, R.string.menu_create_key_expert).setShowAsAction( - MenuItem.SHOW_AS_ACTION_NEVER); + menu.add(1, Id.menu.option.createExpert, 2, R.string.menu_create_key_expert) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); return true; } @@ -84,12 +84,4 @@ public class KeyListSecretActivity extends KeyListActivity { startActivityForResult(intent, 0); } - void editKey(long masterKeyId, boolean masterCanSign) { - Intent intent = new Intent(this, EditKeyActivity.class); - intent.setAction(EditKeyActivity.ACTION_EDIT_KEY); - intent.putExtra(EditKeyActivity.EXTRA_MASTER_KEY_ID, masterKeyId); - intent.putExtra(EditKeyActivity.EXTRA_MASTER_CAN_SIGN, masterCanSign); - startActivityForResult(intent, 0); - } - } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java index e8a306063..40579a3c2 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListSecretFragment.java @@ -19,11 +19,12 @@ package org.sufficientlysecure.keychain.ui; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.KeyListSecretAdapter; +import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -37,7 +38,7 @@ import android.widget.AdapterView.OnItemClickListener; import com.actionbarsherlock.app.SherlockListFragment; public class KeyListSecretFragment extends SherlockListFragment implements - LoaderManager.LoaderCallbacks { + LoaderManager.LoaderCallbacks, OnItemClickListener { private KeyListSecretActivity mKeyListSecretActivity; @@ -52,20 +53,7 @@ public class KeyListSecretFragment extends SherlockListFragment implements mKeyListSecretActivity = (KeyListSecretActivity) getActivity(); - getListView().setOnItemClickListener(new OnItemClickListener() { - @Override - public void onItemClick(AdapterView adapterView, View view, int position, long id) { - // TODO: currently this is EDIT directly, later first show VIEW - - // get master key id using row id - long masterKeyId = ProviderHelper.getSecretMasterKeyId(mKeyListSecretActivity, id); - - boolean masterCanSign = ProviderHelper.getSecretMasterKeyCanSign( - mKeyListSecretActivity, id); - - mKeyListSecretActivity.editKey(masterKeyId, masterCanSign); - } - }); + getListView().setOnItemClickListener(this); // Give some text to display if there is no data. In a real // application this would come from a resource. @@ -124,4 +112,15 @@ public class KeyListSecretFragment extends SherlockListFragment implements // longer using it. mAdapter.swapCursor(null); } + + /** + * On click on item, start key view activity + */ + @Override + public void onItemClick(AdapterView adapterView, View view, int position, long id) { + Intent editIntent = new Intent(mKeyListSecretActivity, EditKeyActivity.class); + editIntent.setData(KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(id))); + editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); + startActivityForResult(editIntent, 0); + } } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java index 13926d172..c32a797be 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java @@ -52,12 +52,11 @@ import android.text.format.DateFormat; import android.widget.TextView; import android.widget.Toast; -import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; @SuppressLint("NewApi") -public class KeyViewActivity extends SherlockFragmentActivity implements CreateNdefMessageCallback, +public class KeyViewActivity extends KeyActivity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback { private Uri mDataUri; @@ -96,7 +95,7 @@ public class KeyViewActivity extends SherlockFragmentActivity implements CreateN } else { Log.d(Constants.TAG, "uri: " + mDataUri); loadData(mDataUri); - initNfc(); + initNfc(mDataUri); } } @@ -111,31 +110,32 @@ public class KeyViewActivity extends SherlockFragmentActivity implements CreateN public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_key_view_update: - updateFromKeyserver(); + updateFromKeyserver(mDataUri); return true; case R.id.menu_key_view_sign: - signKey(); + signKey(mDataUri); return true; case R.id.menu_key_view_export_keyserver: - uploadToKeyserver(); + uploadToKeyserver(mDataUri); return true; case R.id.menu_key_view_export_file: - exportToFile(); + showExportKeysDialog(mDataUri, Id.type.public_key, Constants.path.APP_DIR + + "/pubexport.asc"); return true; case R.id.menu_key_view_share_default: - shareKey(); + shareKey(mDataUri); return true; case R.id.menu_key_view_share_qr_code: - shareKeyQrCode(); + shareKeyQrCode(mDataUri); return true; case R.id.menu_key_view_share_nfc: shareNfc(); return true; case R.id.menu_key_view_share_clipboard: - copyToClipboard(); + copyToClipboard(mDataUri); return true; case R.id.menu_key_view_delete: - deleteKey(); + deleteKey(mDataUri, Id.type.public_key); return true; } @@ -188,24 +188,8 @@ public class KeyViewActivity extends SherlockFragmentActivity implements CreateN return result; } - private void exportToFile() { - // long masterKeyId = ProviderHelper.getPublicMasterKeyId(mKeyListActivity, - // keyRingRowId); - // if (masterKeyId == -1) { - // masterKeyId = ProviderHelper.getSecretMasterKeyId(mKeyListActivity, keyRingRowId); - // } - // - // mKeyListActivity.showExportKeysDialog(masterKeyId); - } - - private void deleteKey() { - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); - - // mKeyListActivity.showDeleteKeyDialog(keyRingRowId); - } - - private void uploadToKeyserver() { - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); + 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); @@ -213,20 +197,22 @@ public class KeyViewActivity extends SherlockFragmentActivity implements CreateN startActivityForResult(uploadIntent, Id.request.export_to_server); } - private void updateFromKeyserver() { - // TODO: use data uri! - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); - + private void updateFromKeyserver(Uri dataUri) { long updateKeyId = 0; - PGPPublicKeyRing updateKeyRing = ProviderHelper.getPGPPublicKeyRingByRowId(this, - keyRingRowId); - if (updateKeyRing != null) { - updateKeyId = PgpKeyHelper.getMasterKey(updateKeyRing).getKeyID(); + PGPPublicKeyRing updateRing = (PGPPublicKeyRing) ProviderHelper + .getPGPKeyRing(this, dataUri); + + if (updateRing != null) { + updateKeyId = PgpKeyHelper.getMasterKey(updateRing).getKeyID(); } - // if (updateKeyId == 0) { - // // this shouldn't happen - // return true; - // } + 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); @@ -234,35 +220,29 @@ public class KeyViewActivity extends SherlockFragmentActivity implements CreateN // TODO: lookup?? startActivityForResult(queryIntent, Id.request.look_up_key_id); - } - private void signKey() { - // TODO: use data uri! - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); - + private void signKey(Uri dataUri) { long keyId = 0; - PGPPublicKeyRing signKeyRing = ProviderHelper - .getPGPPublicKeyRingByRowId(this, keyRingRowId); - if (signKeyRing != null) { - keyId = PgpKeyHelper.getMasterKey(signKeyRing).getKeyID(); + 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; } - // if (keyId == 0) { - // // this shouldn't happen - // return true; - // } Intent signIntent = new Intent(this, SignKeyActivity.class); signIntent.putExtra(SignKeyActivity.EXTRA_KEY_ID, keyId); startActivity(signIntent); } - private void shareKey() { - // TODO: use data uri! - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); - long masterKeyId = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); + private void shareKey(Uri dataUri) { // get public keyring as ascii armored string - ArrayList keyringArmored = ProviderHelper.getPublicKeyRingsAsArmoredString(this, + long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); + ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri, new long[] { masterKeyId }); // let user choose application @@ -273,12 +253,10 @@ public class KeyViewActivity extends SherlockFragmentActivity implements CreateN getResources().getText(R.string.action_share_key_with))); } - private void shareKeyQrCode() { - // TODO: use data uri! - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); - long masterKeyId = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); + private void shareKeyQrCode(Uri dataUri) { // get public keyring as ascii armored string - ArrayList keyringArmored = ProviderHelper.getPublicKeyRingsAsArmoredString(this, + long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); + ArrayList keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri, new long[] { masterKeyId }); ShareQrCodeDialogFragment dialog = ShareQrCodeDialogFragment.newInstance(keyringArmored @@ -286,38 +264,34 @@ public class KeyViewActivity extends SherlockFragmentActivity implements CreateN dialog.show(getSupportFragmentManager(), "shareQrCodeDialog"); } - private void shareNfc() { - ShareNfcDialogFragment dialog = ShareNfcDialogFragment.newInstance(); - dialog.show(getSupportFragmentManager(), "shareNfcDialog"); - } - - private void copyToClipboard() { - // TODO: use data uri! - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); - long masterKeyId = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); + private void copyToClipboard(Uri dataUri) { // get public keyring as ascii armored string - ArrayList keyringArmored = ProviderHelper.getPublicKeyRingsAsArmoredString(this, + long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); + ArrayList 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() { + 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 - // TODO: use data uri! - long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); - long masterKeyId = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); // get public keyring as byte array - mSharedKeyringBytes = ProviderHelper.getPublicKeyRingsAsByteArray(this, + long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); + mSharedKeyringBytes = ProviderHelper.getKeyRingsAsByteArray(this, dataUri, new long[] { masterKeyId }); // Register callback to set NDEF message diff --git a/README.md b/README.md index 59a6c1660..78bb79ebd 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ On error see: http://code.google.com/p/zxing/issues/detail?id=1207 ## ZXing -XZing classes were extracted from the ZXing library (http://code.google.com/p/zxing/). +ZXing classes were extracted from the ZXing library (http://code.google.com/p/zxing/). Only classes related to QR Code generation are utilized. ## Bouncy Castle