diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure')
10 files changed, 114 insertions, 97 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index f8f0d2ac3..a32c14ca0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -80,8 +80,6 @@ public final class Constants { public static final String FIRST_TIME = "firstTime"; public static final String SHOW_ADVANCED_TABS = "showAdvancedTabs"; public static final String CACHED_CONSOLIDATE = "cachedConsolidate"; - public static final String CACHED_CONSOLIDATE_SECRETS = "cachedConsolidateSecrets"; - public static final String CACHED_CONSOLIDATE_PUBLICS = "cachedConsolidatePublics"; public static final String SEARCH_KEYSERVER = "search_keyserver_pref"; public static final String SEARCH_KEYBASE = "search_keybase_pref"; public static final String USE_DEFAULT_YUBIKEY_PIN = "useDefaultYubikeyPin"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index 26c705347..dd0549adc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -47,7 +47,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; public class PgpImportExport { @@ -116,11 +115,6 @@ public class PgpImportExport { } } - /** Imports keys from given data. If keyIds is given only those are imported */ - public ImportKeyResult importKeyRings(List<ParcelableKeyRing> entries) { - return importKeyRings(entries.iterator(), entries.size()); - } - public ImportKeyResult importKeyRings(Iterator<ParcelableKeyRing> entries, int num) { updateProgress(R.string.progress_importing, 0, 100); @@ -134,7 +128,11 @@ public class PgpImportExport { int position = 0; double progSteps = 100.0 / num; - for (ParcelableKeyRing entry : new IterableIterator<ParcelableKeyRing>(entries)) { + + // iterate over all entries + while (entries.hasNext()) { + ParcelableKeyRing entry = entries.next(); + // Has this action been cancelled? If so, don't proceed any further if (mCancelled != null && mCancelled.get()) { break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index f8600d9d4..0ca9c60c6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -925,11 +925,9 @@ public class ProviderHelper { return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } - Preferences.getPreferences(mContext).setCachedConsolidateNumSecrets(cursor.getCount()); - ParcelableFileCache<ParcelableKeyRing> cache = new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl"); - cache.writeCache(new Iterator<ParcelableKeyRing>() { + cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() { ParcelableKeyRing ring; @Override @@ -987,11 +985,9 @@ public class ProviderHelper { return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, mLog); } - Preferences.getPreferences(mContext).setCachedConsolidateNumPublics(cursor.getCount()); - ParcelableFileCache<ParcelableKeyRing> cache = new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl"); - cache.writeCache(new Iterator<ParcelableKeyRing>() { + cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() { ParcelableKeyRing ring; @Override @@ -1057,16 +1053,8 @@ public class ProviderHelper { try { Preferences prefs = Preferences.getPreferences(mContext); - // Set flag that we have a cached consolidation here - int numSecrets = prefs.getCachedConsolidateNumSecrets(); - int numPublics = prefs.getCachedConsolidateNumPublics(); - if (recovery) { - if (numSecrets >= 0 && numPublics >= 0) { - log(LogType.MSG_CON_RECOVER, numSecrets, numPublics); - } else { - log(LogType.MSG_CON_RECOVER_UNKNOWN); - } + log(LogType.MSG_CON_RECOVER); mIndent += 1; } @@ -1084,14 +1072,24 @@ public class ProviderHelper { ParcelableFileCache<ParcelableKeyRing> cachePublic = new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl"); - // 3. Re-Import secret keyrings from cache - if (numSecrets > 0) try { + // Set flag that we have a cached consolidation here + try { + Iterator<ParcelableKeyRing> itSecrets = cacheSecret.readCache(false); + int numSecrets = cacheSecret.getNumEntries(); + log(LogType.MSG_CON_REIMPORT_SECRET, numSecrets); mIndent += 1; - new PgpImportExport(mContext, this, - new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) - .importKeyRings(cacheSecret.readCache(false), numSecrets); + // 3. Re-Import secret keyrings from cache + if (numSecrets > 0) { + + new PgpImportExport(mContext, this, + new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport)) + .importKeyRings(itSecrets, numSecrets); + } else { + log(LogType.MSG_CON_REIMPORT_SECRET_SKIP); + } + } catch (IOException e) { Log.e(Constants.TAG, "error importing secret", e); log(LogType.MSG_CON_ERROR_SECRET); @@ -1099,18 +1097,25 @@ public class ProviderHelper { } finally { mIndent -= 1; } - else { - log(LogType.MSG_CON_REIMPORT_SECRET_SKIP); - } - // 4. Re-Import public keyrings from cache - if (numPublics > 0) try { + try { + + Iterator<ParcelableKeyRing> itPublics = cachePublic.readCache(); + int numPublics = cachePublic.getNumEntries(); + log(LogType.MSG_CON_REIMPORT_PUBLIC, numPublics); mIndent += 1; - new PgpImportExport(mContext, this, - new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) - .importKeyRings(cachePublic.readCache(false), numPublics); + // 4. Re-Import public keyrings from cache + if (numPublics > 0) { + + new PgpImportExport(mContext, this, + new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport)) + .importKeyRings(itPublics, numPublics); + } else { + log(LogType.MSG_CON_REIMPORT_PUBLIC_SKIP); + } + } catch (IOException e) { Log.e(Constants.TAG, "error importing public", e); log(LogType.MSG_CON_ERROR_PUBLIC); @@ -1118,9 +1123,6 @@ public class ProviderHelper { } finally { mIndent -= 1; } - else { - log(LogType.MSG_CON_REIMPORT_PUBLIC_SKIP); - } log(LogType.MSG_CON_CRITICAL_OUT); Preferences.getPreferences(mContext).setCachedConsolidate(false); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 0ee3c7093..2101705bc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -31,6 +31,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; import org.sufficientlysecure.keychain.util.FileHelper; +import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; @@ -78,6 +79,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -511,21 +513,26 @@ public class KeychainIntentService extends IntentService implements Progressable } else if (ACTION_IMPORT_KEYRING.equals(action)) { try { - List<ParcelableKeyRing> entries; + Iterator<ParcelableKeyRing> entries; + int numEntries; if (data.containsKey(IMPORT_KEY_LIST)) { // get entries from intent - entries = data.getParcelableArrayList(IMPORT_KEY_LIST); + ArrayList<ParcelableKeyRing> list = data.getParcelableArrayList(IMPORT_KEY_LIST); + entries = list.iterator(); + numEntries = list.size(); } else { // get entries from cached file ParcelableFileCache<ParcelableKeyRing> cache = new ParcelableFileCache<ParcelableKeyRing>(this, "key_import.pcl"); - entries = cache.readCacheIntoList(); + IteratorWithSize<ParcelableKeyRing> it = cache.readCache(); + entries = it; + numEntries = it.getSize(); } ProviderHelper providerHelper = new ProviderHelper(this); PgpImportExport pgpImportExport = new PgpImportExport( this, providerHelper, this, mActionCanceled); - ImportKeyResult result = pgpImportExport.importKeyRings(entries); + ImportKeyResult result = pgpImportExport.importKeyRings(entries, numEntries); // we do this even on failure or cancellation! if (result.mSecret > 0) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java index 0a4d9649f..b9b4cfddb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java @@ -439,7 +439,6 @@ public abstract class OperationResult implements Parcelable { MSG_CON_ERROR_PUBLIC (LogLevel.ERROR, R.string.msg_con_error_public), MSG_CON_ERROR_SECRET (LogLevel.ERROR, R.string.msg_con_error_secret), MSG_CON_RECOVER (LogLevel.DEBUG, R.plurals.msg_con_recover), - MSG_CON_RECOVER_UNKNOWN (LogLevel.DEBUG, R.string.msg_con_recover_unknown), MSG_CON_REIMPORT_PUBLIC (LogLevel.DEBUG, R.plurals.msg_con_reimport_public), MSG_CON_REIMPORT_PUBLIC_SKIP (LogLevel.DEBUG, R.string.msg_con_reimport_public_skip), MSG_CON_REIMPORT_SECRET (LogLevel.DEBUG, R.plurals.msg_con_reimport_secret), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 6298f96c0..efad2e45d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -41,6 +41,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.api.OpenKeychainIntents; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; @@ -481,12 +482,14 @@ public class ImportKeysActivity extends ActionBarActivity { Bundle data = new Bundle(); // get DATA from selected key entries - ArrayList<ParcelableKeyRing> selectedEntries = mListFragment.getSelectedData(); + IteratorWithSize<ParcelableKeyRing> selectedEntries = mListFragment.getSelectedData(); - // instead of given the entries by Intent extra, cache them into a file - // to prevent Java Binder problems on heavy imports + // instead of giving the entries by Intent extra, cache them into a + // file to prevent Java Binder problems on heavy imports // read FileImportCache for more info. try { + // We parcel this iteratively into a file - anything we can + // display here, we should be able to import. ParcelableFileCache<ParcelableKeyRing> cache = new ParcelableFileCache<ParcelableKeyRing>(this, "key_import.pcl"); cache.writeCache(selectedEntries); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index e30af6b29..608c0f032 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -31,6 +31,7 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.Keyserver; @@ -48,6 +49,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class ImportKeysListFragment extends ListFragment implements @@ -74,12 +76,37 @@ public class ImportKeysListFragment extends ListFragment implements return mAdapter.getData(); } - public ArrayList<ParcelableKeyRing> getSelectedData() { - ArrayList<ParcelableKeyRing> result = new ArrayList<ParcelableKeyRing>(); - for (ImportKeysListEntry entry : getSelectedEntries()) { - result.add(mCachedKeyData.get(entry.hashCode())); - } - return result; + /** Returns an Iterator (with size) of the selected data items. + * This iterator is sort of a tradeoff, it's slightly more complex than an + * ArrayList would have been, but we save some memory by just returning + * relevant elements on demand. + */ + public IteratorWithSize<ParcelableKeyRing> getSelectedData() { + final ArrayList<ImportKeysListEntry> entries = getSelectedEntries(); + final Iterator<ImportKeysListEntry> it = entries.iterator(); + return new IteratorWithSize<ParcelableKeyRing>() { + + @Override + public int getSize() { + return entries.size(); + } + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public ParcelableKeyRing next() { + // throws NoSuchElementException if it doesn't exist, but that's not our problem + return mCachedKeyData.get(it.next().hashCode()); + } + + @Override + public void remove() { + it.remove(); + } + }; } public ArrayList<ImportKeysListEntry> getSelectedEntries() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 7b378ae79..b9eb4c8d4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -41,7 +41,6 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -91,17 +90,13 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> { } public ArrayList<ImportKeysListEntry> getSelectedEntries() { - ArrayList<ImportKeysListEntry> selectedData = new ArrayList<ImportKeysListEntry>(); - // Nothing to select, nvm. - if (mData == null) { - return selectedData; - } + ArrayList<ImportKeysListEntry> result = new ArrayList<ImportKeysListEntry>(); for (ImportKeysListEntry entry : mData) { if (entry.isSelected()) { - selectedData.add(entry); + result.add(entry); } } - return selectedData; + return result; } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java index 111bf0124..3081021cf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java @@ -54,11 +54,11 @@ public class ParcelableFileCache<E extends Parcelable> { mFilename = filename; } - public void writeCache(ArrayList<E> selectedEntries) throws IOException { - writeCache(selectedEntries.iterator()); + public void writeCache(IteratorWithSize<E> it) throws IOException { + writeCache(it.getSize(), it); } - public void writeCache(Iterator<E> it) throws IOException { + public void writeCache(int numEntries, Iterator<E> it) throws IOException { File cacheDir = mContext.getCacheDir(); if (cacheDir == null) { @@ -70,6 +70,8 @@ public class ParcelableFileCache<E extends Parcelable> { DataOutputStream oos = new DataOutputStream(new FileOutputStream(tempFile)); + oos.writeInt(numEntries); + while (it.hasNext()) { Parcel p = Parcel.obtain(); // creating empty parcel object p.writeParcelable(it.next(), 0); // saving bundle as parcel @@ -83,20 +85,11 @@ public class ParcelableFileCache<E extends Parcelable> { } - public List<E> readCacheIntoList() throws IOException { - ArrayList<E> result = new ArrayList<E>(); - Iterator<E> it = readCache(); - while (it.hasNext()) { - result.add(it.next()); - } - return result; - } - - public Iterator<E> readCache() throws IOException { + public IteratorWithSize<E> readCache() throws IOException { return readCache(true); } - public Iterator<E> readCache(final boolean deleteAfterRead) throws IOException { + public IteratorWithSize<E> readCache(final boolean deleteAfterRead) throws IOException { File cacheDir = mContext.getCacheDir(); if (cacheDir == null) { @@ -113,12 +106,19 @@ public class ParcelableFileCache<E extends Parcelable> { throw new IOException(e); } - return new Iterator<E>() { + // yes this is sloppy data flow. WE WOULDN'T NEED THIS WITH TUPLE RETURN TYPES + final int numEntries = ois.readInt(); + + return new IteratorWithSize<E>() { E mRing = null; boolean closed = false; byte[] buf = new byte[512]; + public int getSize() { + return numEntries; + } + private void readNext() { if (mRing != null || closed) { return; @@ -204,4 +204,12 @@ public class ParcelableFileCache<E extends Parcelable> { return tempFile.delete(); } + /** As the name implies, this is an extended iterator interface, which + * knows the total number of its entries beforehand. + */ + public static interface IteratorWithSize<E> extends Iterator<E> { + /** Returns the number of total entries in this iterator. */ + int getSize(); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java index d4cd9b385..bdb7c65fc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java @@ -177,26 +177,6 @@ public class Preferences { editor.commit(); } - public int getCachedConsolidateNumPublics() { - return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_PUBLICS, -1); - } - - public void setCachedConsolidateNumPublics(int value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Pref.CACHED_CONSOLIDATE_PUBLICS, value); - editor.commit(); - } - - public int getCachedConsolidateNumSecrets() { - return mSharedPreferences.getInt(Pref.CACHED_CONSOLIDATE_SECRETS, -1); - } - - public void setCachedConsolidateNumSecrets(int value) { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putInt(Pref.CACHED_CONSOLIDATE_SECRETS, value); - editor.commit(); - } - public boolean isFirstTime() { return mSharedPreferences.getBoolean(Constants.Pref.FIRST_TIME, true); } |