diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 10f112f23..4fabf7432 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -50,6 +50,7 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sufficientlysecure.keychain.helper; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.content.Context; +import android.util.Patterns; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class ContactHelper { + + public static final List getMailAccounts(Context context) { + final Account[] accounts = AccountManager.get(context).getAccounts(); + final Set emailSet = new HashSet(); + for (Account account : accounts) { + if (Patterns.EMAIL_ADDRESS.matcher(account.name).matches()) { + emailSet.add(account.name); + } + } + return new ArrayList(emailSet); + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java index 6aa28fec8..19dfccbde 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/ExportHelper.java @@ -20,7 +20,6 @@ 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; @@ -63,7 +62,7 @@ public class ExportHelper { /** * Show dialog where to export keys */ - public void showExportKeysDialog(final Uri dataUri, final int keyType, + public void showExportKeysDialog(final long[] rowIds, final int keyType, final String exportFilename) { mExportFilename = exportFilename; @@ -75,7 +74,7 @@ public class ExportHelper { Bundle data = message.getData(); mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - exportKeys(dataUri, keyType); + exportKeys(rowIds, keyType); } } }; @@ -86,7 +85,7 @@ public class ExportHelper { DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { public void run() { String title = null; - if (dataUri == null) { + if (rowIds == null) { // export all keys title = activity.getString(R.string.title_export_keys); } else { @@ -112,7 +111,7 @@ public class ExportHelper { /** * Export keys */ - public void exportKeys(Uri dataUri, int keyType) { + public void exportKeys(long[] rowIds, int keyType) { Log.d(Constants.TAG, "exportKeys started"); // Send all information needed to service to export key in other thread @@ -126,13 +125,10 @@ public class ExportHelper { data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFilename); data.putInt(KeychainIntentService.EXPORT_KEY_TYPE, keyType); - if (dataUri == null) { + if (rowIds == null) { data.putBoolean(KeychainIntentService.EXPORT_ALL, true); } else { - // TODO: put data uri into service??? - long keyRingMasterKeyId = ProviderHelper.getMasterKeyId(activity, dataUri); - - data.putLong(KeychainIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, keyRingMasterKeyId); + data.putLongArray(KeychainIntentService.EXPORT_KEY_RING_ROW_ID, rowIds); } intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 493f25707..f18a290b3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -144,8 +144,8 @@ public class Preferences { Constants.defaults.KEY_SERVERS); Vector servers = new Vector(); String chunks[] = rawData.split(","); - for (int i = 0; i < chunks.length; ++i) { - String tmp = chunks[i].trim(); + for (String c : chunks) { + String tmp = c.trim(); if (tmp.length() > 0) { servers.add(tmp); } @@ -156,8 +156,8 @@ public class Preferences { public void setKeyServers(String[] value) { SharedPreferences.Editor editor = mSharedPreferences.edit(); String rawData = ""; - for (int i = 0; i < value.length; ++i) { - String tmp = value[i].trim(); + for (String v : value) { + String tmp = v.trim(); if (tmp.length() == 0) { continue; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index 7ac904d89..1db4f98b1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -193,11 +193,10 @@ public class PgpHelper { * @param context * @param progress * @param file - * @throws FileNotFoundException * @throws IOException */ public static void deleteFileSecurely(Context context, ProgressDialogUpdater progress, File file) - throws FileNotFoundException, IOException { + throws IOException { long length = file.length(); SecureRandom random = new SecureRandom(); RandomAccessFile raf = new RandomAccessFile(file, "rws"); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index 7c635a00b..138e54f71 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -79,8 +79,9 @@ public class PgpImportExport { public boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ArmoredOutputStream aos = new ArmoredOutputStream(bos); + ArmoredOutputStream aos = null; try { + aos = new ArmoredOutputStream(bos); aos.write(keyring.getEncoded()); aos.close(); @@ -95,7 +96,8 @@ public class PgpImportExport { return false; } finally { try { - bos.close(); + if (aos != null) aos.close(); + if (bos != null) bos.close(); } catch (IOException e) { } } @@ -155,59 +157,53 @@ public class PgpImportExport { return returnData; } - public Bundle exportKeyRings(ArrayList keyRingMasterKeyIds, int keyType, - OutputStream outStream) throws PgpGeneralException, FileNotFoundException, + public Bundle exportKeyRings(ArrayList keyRingRowIds, int keyType, + OutputStream outStream) throws PgpGeneralException, PGPException, IOException { Bundle returnData = new Bundle(); + int rowIdsSize = keyRingRowIds.size(); + updateProgress( mContext.getResources().getQuantityString(R.plurals.progress_exporting_key, - keyRingMasterKeyIds.size()), 0, 100); + rowIdsSize), 0, 100); if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { throw new PgpGeneralException( mContext.getString(R.string.error_external_storage_not_ready)); } + // For each row id + for (int i = 0; i < rowIdsSize; ++i) { + // Create an output stream + ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream); + arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext)); - if (keyType == Id.type.secret_key) { - ArmoredOutputStream outSec = new ArmoredOutputStream(outStream); - outSec.setHeader("Version", PgpHelper.getFullVersion(mContext)); - - for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) { - updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100); - - PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId( - mContext, keyRingMasterKeyIds.get(i)); + // If the keyType is secret get the PGPSecretKeyRing + // based on the row id and encode it to the output + if (keyType == Id.type.secret_key) { + updateProgress(i * 100 / rowIdsSize / 2, 100); + PGPSecretKeyRing secretKeyRing = + ProviderHelper.getPGPSecretKeyRingByRowId(mContext, keyRingRowIds.get(i)); if (secretKeyRing != null) { - secretKeyRing.encode(outSec); + secretKeyRing.encode(arOutStream); } - } - outSec.close(); - } else { - // export public keyrings... - ArmoredOutputStream outPub = new ArmoredOutputStream(outStream); - outPub.setHeader("Version", PgpHelper.getFullVersion(mContext)); - - for (int i = 0; i < keyRingMasterKeyIds.size(); ++i) { - // double the needed time if exporting both public and secret parts - if (keyType == Id.type.secret_key) { - updateProgress(i * 100 / keyRingMasterKeyIds.size() / 2, 100); - } else { - updateProgress(i * 100 / keyRingMasterKeyIds.size(), 100); - } - - PGPPublicKeyRing publicKeyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId( - mContext, keyRingMasterKeyIds.get(i)); + // Else if it's a public key get the PGPPublicKeyRing + // and encode that to the output + } else { + updateProgress(i * 100 / rowIdsSize, 100); + PGPPublicKeyRing publicKeyRing = + ProviderHelper.getPGPPublicKeyRingByRowId(mContext, keyRingRowIds.get(i)); if (publicKeyRing != null) { - publicKeyRing.encode(outPub); + publicKeyRing.encode(arOutStream); } } - outPub.close(); + + arOutStream.close(); } - returnData.putInt(KeychainIntentService.RESULT_EXPORT, keyRingMasterKeyIds.size()); + returnData.putInt(KeychainIntentService.RESULT_EXPORT, rowIdsSize); updateProgress(R.string.progress_done, 100, 100); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index e1ca88fb0..5ebb53f20 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -190,7 +190,7 @@ public class PgpKeyOperation { } public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, - String newPassPhrase) throws IOException, PGPException, PGPException, + String newPassPhrase) throws IOException, PGPException, NoSuchProviderException { updateProgress(R.string.progress_building_key, 0, 100); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index ac0692213..dd538fbf4 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -404,6 +404,30 @@ public class ProviderHelper { return masterKeyIds; } + /** + * Private helper method + */ + private static ArrayList getKeyRingsRowIds(Context context, Uri queryUri) { + Cursor cursor = context.getContentResolver().query(queryUri, + new String[]{KeyRings._ID}, null, null, null); + + ArrayList rowIds = new ArrayList(); + if (cursor != null) { + int IdCol = cursor.getColumnIndex(KeyRings._ID); + if (cursor.moveToFirst()) { + do { + rowIds.add(cursor.getLong(IdCol)); + } while (cursor.moveToNext()); + } + } + + if (cursor != null) { + cursor.close(); + } + + return rowIds; + } + /** * Retrieves ids of all SecretKeyRings */ @@ -420,6 +444,22 @@ public class ProviderHelper { return getKeyRingsMasterKeyIds(context, queryUri); } + /** + * Retrieves ids of all SecretKeyRings + */ + public static ArrayList getSecretKeyRingsRowIds(Context context) { + Uri queryUri = KeyRings.buildSecretKeyRingsUri(); + return getKeyRingsRowIds(context, queryUri); + } + + /** + * Retrieves ids of all PublicKeyRings + */ + public static ArrayList getPublicKeyRingsRowIds(Context context) { + Uri queryUri = KeyRings.buildPublicKeyRingsUri(); + return getKeyRingsRowIds(context, queryUri); + } + public static void deletePublicKeyRing(Context context, long rowId) { ContentResolver cr = context.getContentResolver(); cr.delete(KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)), null, null); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 902c66fe9..93238349d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -50,6 +50,7 @@ import org.sufficientlysecure.keychain.pgp.PgpImportExport; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; @@ -153,6 +154,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String EXPORT_KEY_TYPE = "export_key_type"; public static final String EXPORT_ALL = "export_all"; public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id"; + public static final String EXPORT_KEY_RING_ROW_ID = "export_key_rind_row_id"; // upload key public static final String UPLOAD_KEY_SERVER = "upload_key_server"; @@ -675,10 +677,12 @@ public class KeychainIntentService extends IntentService implements ProgressDial String outputFile = data.getString(EXPORT_FILENAME); + long[] rowIds = new long[0]; + + // If not exporting all keys get the rowIds of the keys to export from the intent boolean exportAll = data.getBoolean(EXPORT_ALL); - long keyRingMasterKeyId = -1; if (!exportAll) { - keyRingMasterKeyId = data.getLong(EXPORT_KEY_RING_MASTER_KEY_ID); + rowIds = data.getLongArray(EXPORT_KEY_RING_ROW_ID); } /* Operation */ @@ -691,24 +695,26 @@ public class KeychainIntentService extends IntentService implements ProgressDial // OutputStream FileOutputStream outStream = new FileOutputStream(outputFile); - ArrayList keyRingMasterKeyIds = new ArrayList(); + ArrayList keyRingRowIds = new ArrayList(); if (exportAll) { - // get all key ring row ids based on export type + // get all key ring row ids based on export type if (keyType == Id.type.public_key) { - keyRingMasterKeyIds = ProviderHelper.getPublicKeyRingsMasterKeyIds(this); + keyRingRowIds = ProviderHelper.getPublicKeyRingsRowIds(this); } else { - keyRingMasterKeyIds = ProviderHelper.getSecretKeyRingsMasterKeyIds(this); + keyRingRowIds = ProviderHelper.getSecretKeyRingsRowIds(this); } } else { - keyRingMasterKeyIds.add(keyRingMasterKeyId); + for(long rowId : rowIds) { + keyRingRowIds.add(rowId); + } } - Bundle resultData = new Bundle(); + Bundle resultData; PgpImportExport pgpImportExport = new PgpImportExport(this, this); resultData = pgpImportExport - .exportKeyRings(keyRingMasterKeyIds, keyType, outStream); + .exportKeyRings(keyRingRowIds, keyType, outStream); sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData); } catch (Exception e) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index abd2320e3..ce34d451d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -21,6 +21,7 @@ import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import android.util.LongSparseArray; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPSecretKey; @@ -77,7 +78,7 @@ public class PassphraseCacheService extends Service { private BroadcastReceiver mIntentReceiver; - private HashMap mPassphraseCache = new HashMap(); + private LongSparseArray mPassphraseCache = new LongSparseArray(); Context mContext; @@ -347,7 +348,7 @@ public class PassphraseCacheService extends Service { Log.d(TAG, "Timeout of keyId " + keyId + ", removed from memory!"); // stop whole service if no cached passphrases remaining - if (mPassphraseCache.isEmpty()) { + if (mPassphraseCache.size() == 0) { Log.d(TAG, "No passphrases remaining in memory, stopping service!"); stopSelf(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java index a7afc9698..178b2fc67 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsActivity.java @@ -41,7 +41,7 @@ public class AppSettingsActivity extends ActionBarActivity { super.onCreate(savedInstanceState); // Inflate a "Done" custom action bar - ActionBarHelper.setDoneView(getSupportActionBar(), R.string.api_settings_save, + ActionBarHelper.setOneButtonView(getSupportActionBar(), R.string.api_settings_save, R.drawable.ic_action_done, new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index 11b3ee217..8fb562884 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -88,7 +88,7 @@ public class RemoteServiceActivity extends ActionBarActivity { final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); // Inflate a "Done"/"Cancel" custom action bar view - ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.api_register_allow, + ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.api_register_allow, R.drawable.ic_action_done, new View.OnClickListener() { @Override public void onClick(View v) { @@ -108,7 +108,7 @@ public class RemoteServiceActivity extends ActionBarActivity { RemoteServiceActivity.this.finish(); } } - }, R.string.api_register_disallow, new View.OnClickListener() { + }, R.string.api_register_disallow, R.drawable.ic_action_cancel, new View.OnClickListener() { @Override public void onClick(View v) { // Disallow @@ -161,7 +161,7 @@ public class RemoteServiceActivity extends ActionBarActivity { } // Inflate a "Done"/"Cancel" custom action bar view - ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay, + ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done, new View.OnClickListener() { @Override public void onClick(View v) { @@ -173,7 +173,7 @@ public class RemoteServiceActivity extends ActionBarActivity { RemoteServiceActivity.this.setResult(RESULT_OK, resultData); RemoteServiceActivity.this.finish(); } - }, R.string.btn_do_not_save, new View.OnClickListener() { + }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() { @Override public void onClick(View v) { // cancel @@ -214,7 +214,7 @@ public class RemoteServiceActivity extends ActionBarActivity { String text = "" + errorMessage + ""; // Inflate a "Done" custom action bar view - ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_okay, + ActionBarHelper.setOneButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done, new View.OnClickListener() { @Override 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 76acf15b0..38d763ce4 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 @@ -530,6 +530,10 @@ public class DecryptActivity extends DrawerActivity { Log.e(Constants.TAG, "File not found!", e); AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()), AppMsg.STYLE_ALERT).show(); + } finally { + try { + if (inStream != null) inStream.close(); + } catch (Exception e){ } } } else { inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes()); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java index 628f642d8..72dc97ccd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java @@ -134,14 +134,14 @@ public class EditKeyActivity extends ActionBarActivity { * @param intent */ private void handleActionCreateKey(Intent intent) { - // Inflate a "Done"/"Cancel" custom action bar - ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_save, + // Inflate a "Save"/"Cancel" custom action bar + ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_save, R.drawable.ic_action_save, new View.OnClickListener() { @Override public void onClick(View v) { saveClicked(); } - }, R.string.btn_do_not_save, new View.OnClickListener() { + }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() { @Override public void onClick(View v) { cancelClicked(); @@ -249,8 +249,8 @@ public class EditKeyActivity extends ActionBarActivity { * @param intent */ private void handleActionEditKey(Intent intent) { - // Inflate a "Done"/"Cancel" custom action bar - ActionBarHelper.setSaveView(getSupportActionBar(), R.string.btn_save, + // Inflate a "Save"/"Cancel" custom action bar + ActionBarHelper.setOneButtonView(getSupportActionBar(), R.string.btn_save, R.drawable.ic_action_save, new View.OnClickListener() { @Override public void onClick(View v) { @@ -329,8 +329,8 @@ public class EditKeyActivity extends ActionBarActivity { cancelClicked(); return true; case R.id.menu_key_edit_export_file: - mExportHelper.showExportKeysDialog(mDataUri, Id.type.secret_key, Constants.path.APP_DIR - + "/secexport.asc"); + long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())}; + mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.path.APP_DIR_FILE_SEC); return true; case R.id.menu_key_edit_delete: { // Message is received after key is deleted diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java index 4521786f7..9bd9ee225 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java @@ -59,8 +59,7 @@ public class KeyListPublicActivity extends DrawerActivity { return true; case R.id.menu_key_list_public_export: - mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.path.APP_DIR - + "/pubexport.asc"); + mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB); return true; default: 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 514b0e00e..de965daa5 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 @@ -18,10 +18,11 @@ package org.sufficientlysecure.keychain.ui; import java.util.ArrayList; -import java.util.Set; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; @@ -47,6 +48,7 @@ import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.MenuItemCompat; +import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.text.TextUtils; import android.view.ActionMode; @@ -179,6 +181,11 @@ public class KeyListPublicFragment extends Fragment implements SearchView.OnQuer encrypt(mode, ids); break; } + case R.id.menu_key_list_public_multi_export: { + ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); + mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB); + break; + } case R.id.menu_key_list_public_multi_delete: { showDeleteKeyDialog(mode, ids); break; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java index e58ebe819..cd3c8b4fd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListSecretActivity.java @@ -62,8 +62,7 @@ public class KeyListSecretActivity extends DrawerActivity { return true; case R.id.menu_key_list_secret_export: - mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.path.APP_DIR - + "/secexport.asc"); + mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.path.APP_DIR_FILE_SEC); return true; case R.id.menu_key_list_secret_import: 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 76212afc3..e84b2f4c8 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,10 +17,10 @@ package org.sufficientlysecure.keychain.ui; -import java.util.Set; - +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; @@ -41,6 +41,7 @@ import android.support.v4.app.ListFragment; 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.view.ActionMode; import android.view.Menu; import android.view.MenuItem; @@ -106,6 +107,12 @@ public class KeyListSecretFragment extends ListFragment implements } break; } + case R.id.menu_key_list_public_multi_export: { + ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); + mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.path.APP_DIR_FILE_SEC); + break; + } + } return true; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java index b5ac739ae..50fec1ffc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java @@ -50,14 +50,14 @@ public class PreferencesKeyServerActivity extends ActionBarActivity implements O super.onCreate(savedInstanceState); // Inflate a "Done"/"Cancel" custom action bar view - ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay, + ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done, new View.OnClickListener() { @Override public void onClick(View v) { // ok okClicked(); } - }, R.string.btn_do_not_save, new View.OnClickListener() { + }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() { @Override public void onClick(View v) { // cancel @@ -81,11 +81,11 @@ public class PreferencesKeyServerActivity extends ActionBarActivity implements O Intent intent = getIntent(); String servers[] = intent.getStringArrayExtra(EXTRA_KEY_SERVERS); if (servers != null) { - for (int i = 0; i < servers.length; ++i) { + for (String serv : servers) { KeyServerEditor view = (KeyServerEditor) mInflater.inflate( R.layout.key_server_editor, mEditors, false); view.setEditorListener(this); - view.setValue(servers[i]); + view.setValue(serv); mEditors.addView(view); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java index 86ae0073f..3c63628f7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java @@ -46,14 +46,14 @@ public class SelectPublicKeyActivity extends ActionBarActivity { super.onCreate(savedInstanceState); // Inflate a "Done"/"Cancel" custom action bar view - ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay, + ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done, new View.OnClickListener() { @Override public void onClick(View v) { // ok okClicked(); } - }, R.string.btn_do_not_save, new View.OnClickListener() { + }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() { @Override public void onClick(View v) { // cancel diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java index c1c9aa705..d320af451 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java @@ -199,8 +199,8 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T if (masterKeyIds != null) { for (int i = 0; i < getListView().getCount(); ++i) { long keyId = mAdapter.getMasterKeyId(i); - for (int j = 0; j < masterKeyIds.length; ++j) { - if (keyId == masterKeyIds[j]) { + for (long masterKeyId : masterKeyIds) { + if (keyId == masterKeyId) { getListView().setItemChecked(i, true); break; } 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 390de9ab9..4cc5e1b62 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 @@ -118,8 +118,8 @@ public class ViewKeyActivity extends ActionBarActivity { 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"); + long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())}; + mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB); return true; case R.id.menu_key_view_share_default_fingerprint: shareKey(mDataUri, true); 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 index 65fe08484..adb06a068 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -280,13 +280,14 @@ public class ViewKeyMainFragment extends Fragment implements // for each 4 characters of the fingerprint + 1 space for (int i = 0; i < fingerprint.length(); i += 5) { - String fourChars = fingerprint.substring(i, Math.min(i + 4, fingerprint.length())); + int minFingLength = Math.min(i + 4, fingerprint.length()); + String fourChars = fingerprint.substring(i, minFingLength); // Create a foreground color by converting the 4 fingerprint chars to an int hashcode // and then converting that int to hex to use as a color fcs = new ForegroundColorSpan( Color.parseColor(String.format("#%06X", (0xFFFFFF & fourChars.hashCode())))); - sb.setSpan(fcs, i, Math.min(i+4, fingerprint.length()), Spannable.SPAN_INCLUSIVE_INCLUSIVE); + sb.setSpan(fcs, i, minFingLength, Spannable.SPAN_INCLUSIVE_INCLUSIVE); } return sb; 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 b8f60633e..d7bb62d01 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 @@ -18,8 +18,6 @@ package org.sufficientlysecure.keychain.ui.adapter; import java.util.HashMap; -import java.util.Set; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; 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 ca3a26066..0bffcaa19 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 @@ -18,7 +18,6 @@ package org.sufficientlysecure.keychain.ui.adapter; import java.util.HashMap; -import java.util.Set; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java index 98b677511..a47601c9b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java @@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.util.Choice; +import java.util.ArrayList; import java.util.Vector; public class CreateKeyDialogFragment extends DialogFragment { @@ -78,7 +79,7 @@ public class CreateKeyDialogFragment extends DialogFragment { boolean wouldBeMasterKey = (childCount == 0); final Spinner algorithm = (Spinner) view.findViewById(R.id.create_key_algorithm); - Vector choices = new Vector(); + ArrayList choices = new ArrayList(); choices.add(new Choice(Id.choice.algorithm.dsa, getResources().getString( R.string.dsa))); if (!wouldBeMasterKey) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java index 5428b626e..71cd89ae8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget; import java.util.regex.Matcher; import java.util.regex.Pattern; +import android.widget.*; import org.sufficientlysecure.keychain.R; import android.content.Context; @@ -26,11 +27,9 @@ import android.util.AttributeSet; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.RadioButton; import com.beardedhen.androidbootstrap.BootstrapButton; +import org.sufficientlysecure.keychain.helper.ContactHelper; public class UserIdEditor extends LinearLayout implements Editor, OnClickListener { private EditorListener mEditorListener = null; @@ -38,7 +37,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene private BootstrapButton mDeleteButton; private RadioButton mIsMainUserId; private EditText mName; - private EditText mEmail; + private AutoCompleteTextView mEmail; private EditText mComment; // see http://www.regular-expressions.info/email.html @@ -102,9 +101,17 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene mIsMainUserId.setOnClickListener(this); mName = (EditText) findViewById(R.id.name); - mEmail = (EditText) findViewById(R.id.email); + mEmail = (AutoCompleteTextView) findViewById(R.id.email); mComment = (EditText) findViewById(R.id.comment); + + mEmail.setThreshold(1); // Start working from first character + mEmail.setAdapter( + new ArrayAdapter + (this.getContext(), android.R.layout.simple_dropdown_item_1line, + ContactHelper.getMailAccounts(getContext()) + )); + super.onFinishInflate(); } diff --git a/OpenPGP-Keychain/src/main/res/layout/actionbar_custom_view_save.xml b/OpenPGP-Keychain/src/main/res/layout/actionbar_custom_view_save.xml deleted file mode 100644 index f0dcf177c..000000000 --- a/OpenPGP-Keychain/src/main/res/layout/actionbar_custom_view_save.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/actionbar_custom_view_save_cancel.xml b/OpenPGP-Keychain/src/main/res/layout/actionbar_custom_view_save_cancel.xml deleted file mode 100644 index ba08a7714..000000000 --- a/OpenPGP-Keychain/src/main/res/layout/actionbar_custom_view_save_cancel.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/actionbar_include_save_button.xml b/OpenPGP-Keychain/src/main/res/layout/actionbar_include_save_button.xml deleted file mode 100644 index 86c59dcc5..000000000 --- a/OpenPGP-Keychain/src/main/res/layout/actionbar_include_save_button.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml index 5927dbf43..48aa89d4f 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_error_message.xml @@ -1,6 +1,5 @@ diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml index 877b4e74e..a10592607 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_select_pub_keys_activity.xml @@ -1,6 +1,5 @@ diff --git a/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml b/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml index 663949d8e..3030d6bae 100644 --- a/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/edit_key_user_id_item.xml @@ -49,7 +49,7 @@ android:paddingRight="5dip" android:text="@string/label_email" /> - diff --git a/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml b/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml index d30ee5e8f..9df17615e 100644 --- a/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml +++ b/OpenPGP-Keychain/src/main/res/menu/key_list_public_multi.xml @@ -5,6 +5,10 @@ android:id="@+id/menu_key_list_public_multi_select_all" android:icon="@drawable/ic_action_select_all" android:title="@string/menu_select_all" /> + + Code Style > Java, select OpenPgpChecker, + as well as Code Style > XML and select OpenPgpChecker again. +* Start code inspection and see the results by selecting Analyze > Inspect Code from Android-Studio + or you can directly run checkstyle via cli with .tools/checkstyle. Make sure it's executable first. + ## Licenses OpenPGP Kechain is licensed under GPLv3+. Some parts (older parts and some libraries are Apache License v2, MIT X11 License) diff --git a/tools/checkstyle b/tools/checkstyle new file mode 100755 index 000000000..27aabced2 --- /dev/null +++ b/tools/checkstyle @@ -0,0 +1 @@ +checkstyle -c tools/checkstyle.xml -r OpenPGP-Keychain/src/main/java 2>&1 | egrep -v 'log4j' diff --git a/tools/checkstyle.xml b/tools/checkstyle.xml new file mode 100644 index 000000000..95ef07a90 --- /dev/null +++ b/tools/checkstyle.xml @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +