ImportKeys: Refactoring

This commit is contained in:
Andrea Torlaschi
2016-06-18 12:14:57 +02:00
parent 9f7320b857
commit 5e93b68b6e
15 changed files with 211 additions and 176 deletions

View File

@@ -1,4 +0,0 @@
package org.sufficientlysecure.keychain.keyimport.loader;
public interface LoaderState {
}

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.sufficientlysecure.keychain.keyimport.loader; package org.sufficientlysecure.keychain.keyimport.processing;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;

View File

@@ -1,4 +1,4 @@
package org.sufficientlysecure.keychain.keyimport.loader; package org.sufficientlysecure.keychain.keyimport.processing;
import android.net.Uri; import android.net.Uri;

View File

@@ -1,4 +1,4 @@
package org.sufficientlysecure.keychain.keyimport.loader; package org.sufficientlysecure.keychain.keyimport.processing;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.sufficientlysecure.keychain.keyimport.loader; package org.sufficientlysecure.keychain.keyimport.processing;
import android.content.Context; import android.content.Context;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.sufficientlysecure.keychain.keyimport.loader; package org.sufficientlysecure.keychain.keyimport.processing;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;

View File

@@ -0,0 +1,11 @@
package org.sufficientlysecure.keychain.keyimport.processing;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
public interface ImportKeysListener {
void loadKeys(LoaderState loaderState);
void importKeys();
void handleResult(ImportKeyResult result);
}

View File

@@ -0,0 +1,52 @@
package org.sufficientlysecure.keychain.keyimport.processing;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import java.util.ArrayList;
public class ImportKeysOperationCallback implements
CryptoOperationHelper.Callback<ImportKeyringParcel, ImportKeyResult> {
private ImportKeysListener mResultListener;
private String mKeyserver;
private ArrayList<ParcelableKeyRing> mKeyList;
public ImportKeysOperationCallback(
ImportKeysListener resultListener,
String keyserver,
ArrayList<ParcelableKeyRing> keyList
) {
this.mResultListener = resultListener;
this.mKeyserver = keyserver;
this.mKeyList = keyList;
}
@Override
public ImportKeyringParcel createOperationInput() {
return new ImportKeyringParcel(mKeyList, mKeyserver);
}
@Override
public void onCryptoOperationSuccess(ImportKeyResult result) {
mResultListener.handleResult(result);
}
@Override
public void onCryptoOperationCancelled() {
// do nothing
}
@Override
public void onCryptoOperationError(ImportKeyResult result) {
mResultListener.handleResult(result);
}
@Override
public boolean onCryptoSetProgress(String msg, int progress, int max) {
return false;
}
}

View File

@@ -0,0 +1,4 @@
package org.sufficientlysecure.keychain.keyimport.processing;
public interface LoaderState {
}

View File

@@ -21,9 +21,7 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.remote.CryptoInputParcelCacheService;
import org.sufficientlysecure.keychain.ui.ImportKeysActivity; import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
import org.sufficientlysecure.keychain.ui.SecurityTokenOperationActivity;
public class RemoteImportKeysActivity extends ImportKeysActivity { public class RemoteImportKeysActivity extends ImportKeysActivity {
@@ -39,7 +37,7 @@ public class RemoteImportKeysActivity extends ImportKeysActivity {
} }
@Override @Override
protected void handleResult(ImportKeyResult result) { public void handleResult(ImportKeyResult result) {
setResult(RESULT_OK, mPendingIntentData); setResult(RESULT_OK, mPendingIntentData);
finish(); finish();
} }

View File

@@ -18,10 +18,6 @@
package org.sufficientlysecure.keychain.ui; package org.sufficientlysecure.keychain.ui;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@@ -36,6 +32,7 @@ import android.widget.TextView;
import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
@@ -44,10 +41,13 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.SecurityTokenListenerFragment; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.SecurityTokenListenerFragment;
import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment;
import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
public class CreateSecurityTokenImportResetFragment public class CreateSecurityTokenImportResetFragment
extends QueueingCryptoOperationFragment<ImportKeyringParcel, ImportKeyResult> extends QueueingCryptoOperationFragment<ImportKeyringParcel, ImportKeyResult>
@@ -211,7 +211,7 @@ public class CreateSecurityTokenImportResetFragment
} }
public void refreshSearch() { public void refreshSearch() {
mListFragment.loadNew(new CloudLoaderState("0x" + mTokenFingerprint, mListFragment.loadState(new CloudLoaderState("0x" + mTokenFingerprint,
Preferences.getPreferences(getActivity()).getCloudSearchPrefs())); Preferences.getPreferences(getActivity()).getCloudSearchPrefs()));
} }

View File

@@ -33,26 +33,26 @@ import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
import org.sufficientlysecure.keychain.keyimport.FacebookKeyserver; import org.sufficientlysecure.keychain.keyimport.FacebookKeyserver;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState;
import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState;
import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener;
import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysOperationCallback;
import org.sufficientlysecure.keychain.keyimport.processing.LoaderState;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.BaseActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState;
import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState;
import org.sufficientlysecure.keychain.keyimport.loader.LoaderState;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache; import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ImportKeysActivity extends BaseActivity public class ImportKeysActivity extends BaseActivity implements ImportKeysListener {
implements CryptoOperationHelper.Callback<ImportKeyringParcel, ImportKeyResult> {
public static final String ACTION_IMPORT_KEY = OpenKeychainIntents.IMPORT_KEY; public static final String ACTION_IMPORT_KEY = OpenKeychainIntents.IMPORT_KEY;
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = OpenKeychainIntents.IMPORT_KEY_FROM_KEYSERVER; public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = OpenKeychainIntents.IMPORT_KEY_FROM_KEYSERVER;
@@ -81,14 +81,10 @@ public class ImportKeysActivity extends BaseActivity
public static final String TAG_FRAG_LIST = "frag_list"; public static final String TAG_FRAG_LIST = "frag_list";
public static final String TAG_FRAG_TOP = "frag_top"; public static final String TAG_FRAG_TOP = "frag_top";
// for CryptoOperationHelper.Callback private boolean mFreshIntent;
private String mKeyserver;
private ArrayList<ParcelableKeyRing> mKeyList;
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mOperationHelper; private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mOperationHelper;
private boolean mFreshIntent;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -322,72 +318,6 @@ public class ImportKeysActivity extends BaseActivity
} }
} }
public void loadCallback(LoaderState loaderState) {
FragmentManager fragMan = getSupportFragmentManager();
ImportKeysListFragment keyListFragment = (ImportKeysListFragment) fragMan.findFragmentByTag(TAG_FRAG_LIST);
keyListFragment.loadNew(loaderState);
}
public void importAllKeys() {
FragmentManager fragMan = getSupportFragmentManager();
ImportKeysListFragment keyListFragment = (ImportKeysListFragment) fragMan.findFragmentByTag(TAG_FRAG_LIST);
if (keyListFragment.getEntries().size() == 0) {
Notify.create(this, R.string.error_nothing_import_selected, Notify.Style.ERROR)
.show((ViewGroup) findViewById(R.id.import_snackbar));
return;
}
mOperationHelper = new CryptoOperationHelper<>(
1, this, this, R.string.progress_importing
);
LoaderState ls = keyListFragment.getLoaderState();
if (ls instanceof BytesLoaderState) {
Log.d(Constants.TAG, "importKeys started");
// get DATA from selected key entries
IteratorWithSize<ParcelableKeyRing> entries = keyListFragment.getData();
// 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<>(this, "key_import.pcl");
cache.writeCache(entries);
} catch (IOException e) {
Log.e(Constants.TAG, "Problem writing cache file", e);
Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR)
.show((ViewGroup) findViewById(R.id.import_snackbar));
return;
}
mKeyList = null;
mKeyserver = null;
} else if (ls instanceof CloudLoaderState) {
CloudLoaderState sls = (CloudLoaderState) ls;
// get selected key entries
ArrayList<ParcelableKeyRing> keys = new ArrayList<>();
{
// change the format into ParcelableKeyRing
List<ImportKeysListEntry> entries = keyListFragment.getEntries();
for (ImportKeysListEntry entry : entries) {
keys.add(new ParcelableKeyRing(entry.getFingerprintHex(),
entry.getKeyIdHex(), entry.getKeybaseName(), entry.getFbUsername()));
}
}
mKeyList = keys;
mKeyserver = sls.mCloudPrefs.keyserver;
}
mOperationHelper.cryptoOperation();
}
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mOperationHelper != null && if (mOperationHelper != null &&
@@ -397,18 +327,81 @@ public class ImportKeysActivity extends BaseActivity
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }
/** @Override
* Defines how the result of this activity is returned. public void loadKeys(LoaderState loaderState) {
* Is overwritten in RemoteImportKeysActivity FragmentManager fM = getSupportFragmentManager();
*/ ImportKeysListFragment listFragment = (ImportKeysListFragment) fM.findFragmentByTag(TAG_FRAG_LIST);
protected void handleResult(ImportKeyResult result) {
listFragment.loadState(loaderState);
}
@Override
public void importKeys() {
FragmentManager fM = getSupportFragmentManager();
ImportKeysListFragment listFragment = (ImportKeysListFragment) fM.findFragmentByTag(TAG_FRAG_LIST);
if (listFragment.getEntries().size() == 0) {
Notify.create(this, R.string.error_nothing_import_selected, Notify.Style.ERROR).show();
return;
}
String keyserver = null;
ArrayList<ParcelableKeyRing> keyList = null;
LoaderState loaderState = listFragment.getState();
Log.d(Constants.TAG, "importKeys started");
if (loaderState instanceof BytesLoaderState) {
// get DATA from selected key entries
ParcelableFileCache.IteratorWithSize<ParcelableKeyRing> entries = listFragment.getData();
// 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<>(this, "key_import.pcl");
cache.writeCache(entries);
} catch (IOException e) {
Log.e(Constants.TAG, "Problem writing cache file", e);
Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR).show();
return;
}
keyList = null;
keyserver = null;
} else if (loaderState instanceof CloudLoaderState) {
CloudLoaderState sls = (CloudLoaderState) loaderState;
// get selected key entries
ArrayList<ParcelableKeyRing> keys = new ArrayList<>();
// change the format into ParcelableKeyRing
List<ImportKeysListEntry> entries = listFragment.getEntries();
for (ImportKeysListEntry entry : entries) {
keys.add(new ParcelableKeyRing(entry.getFingerprintHex(),
entry.getKeyIdHex(), entry.getKeybaseName(), entry.getFbUsername()));
}
keyList = keys;
keyserver = sls.mCloudPrefs.keyserver;
}
ImportKeysOperationCallback callback = new ImportKeysOperationCallback(this, keyserver, keyList);
mOperationHelper = new CryptoOperationHelper(1, this, callback, R.string.progress_importing);
mOperationHelper.cryptoOperation();
}
@Override
public void handleResult(ImportKeyResult result) {
String intentAction = getIntent().getAction(); String intentAction = getIntent().getAction();
if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(intentAction) if (ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(intentAction)
|| ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(intentAction)) { || ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(intentAction)) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); intent.putExtra(ImportKeyResult.EXTRA_RESULT, result);
setResult(RESULT_OK, intent); setResult(Activity.RESULT_OK, intent);
finish(); finish();
} else if (result.isOkNew() || result.isOkUpdated()) { } else if (result.isOkNew() || result.isOkUpdated()) {
// User has successfully imported a key, hide first time dialog // User has successfully imported a key, hide first time dialog
@@ -419,35 +412,8 @@ public class ImportKeysActivity extends BaseActivity
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent); startActivity(intent);
} else { } else {
result.createNotify(ImportKeysActivity.this) result.createNotify(this).show();
.show((ViewGroup) findViewById(R.id.import_snackbar));
} }
} }
// methods from CryptoOperationHelper.Callback
@Override
public ImportKeyringParcel createOperationInput() {
return new ImportKeyringParcel(mKeyList, mKeyserver);
}
@Override
public void onCryptoOperationSuccess(ImportKeyResult result) {
handleResult(result);
}
@Override
public void onCryptoOperationCancelled() {
// do nothing
}
@Override
public void onCryptoOperationError(ImportKeyResult result) {
handleResult(result);
}
@Override
public boolean onCryptoSetProgress(String msg, int progress, int max) {
return false;
}
} }

View File

@@ -39,7 +39,8 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener;
import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState;
import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
@@ -50,11 +51,13 @@ import java.util.List;
* Consists of the search bar, search button, and search settings button * Consists of the search bar, search button, and search settings button
*/ */
public class ImportKeysCloudFragment extends Fragment { public class ImportKeysCloudFragment extends Fragment {
public static final String ARG_QUERY = "query"; public static final String ARG_QUERY = "query";
public static final String ARG_DISABLE_QUERY_EDIT = "disable_query_edit"; public static final String ARG_DISABLE_QUERY_EDIT = "disable_query_edit";
public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs"; public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs";
private ImportKeysActivity mImportActivity; private Activity mActivity;
private ImportKeysListener mCallback;
private AutoCompleteTextView mQueryEditText; private AutoCompleteTextView mQueryEditText;
@@ -154,7 +157,14 @@ public class ImportKeysCloudFragment extends Fragment {
public void onAttach(Activity activity) { public void onAttach(Activity activity) {
super.onAttach(activity); super.onAttach(activity);
mImportActivity = (ImportKeysActivity) activity; mActivity = activity;
try {
mCallback = (ImportKeysListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement ImportKeysListener");
}
} }
@Override @Override
@@ -167,7 +177,7 @@ public class ImportKeysCloudFragment extends Fragment {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.import_cloud_settings: case R.id.import_cloud_settings:
Intent intent = new Intent(mImportActivity, SettingsActivity.class); Intent intent = new Intent(mActivity, SettingsActivity.class);
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.CloudSearchPrefsFragment.class.getName()); intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.CloudSearchPrefsFragment.class.getName());
startActivity(intent); startActivity(intent);
return true; return true;
@@ -185,7 +195,7 @@ public class ImportKeysCloudFragment extends Fragment {
cloudSearchPrefs = Preferences.getPreferences(getActivity()).getCloudSearchPrefs(); cloudSearchPrefs = Preferences.getPreferences(getActivity()).getCloudSearchPrefs();
} }
mImportActivity.loadCallback(new CloudLoaderState(query, cloudSearchPrefs)); mCallback.loadKeys(new CloudLoaderState(query, cloudSearchPrefs));
toggleKeyboard(false); toggleKeyboard(false);
} }

View File

@@ -39,8 +39,9 @@ import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener;
import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState;
import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState;
import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.FileHelper;
@@ -49,7 +50,10 @@ import org.sufficientlysecure.keychain.util.Log;
import java.io.IOException; import java.io.IOException;
public class ImportKeysFileFragment extends Fragment { public class ImportKeysFileFragment extends Fragment {
private ImportKeysActivity mImportActivity;
private Activity mActivity;
private ImportKeysListener mCallback;
private View mBrowse; private View mBrowse;
private View mClipboardButton; private View mClipboardButton;
@@ -78,7 +82,6 @@ public class ImportKeysFileFragment extends Fragment {
View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false); View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false);
mBrowse = view.findViewById(R.id.import_keys_file_browse); mBrowse = view.findViewById(R.id.import_keys_file_browse);
mBrowse.setOnClickListener(new View.OnClickListener() { mBrowse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
// open .asc or .gpg files // open .asc or .gpg files
@@ -100,10 +103,10 @@ public class ImportKeysFileFragment extends Fragment {
sendText = clipboardText.toString(); sendText = clipboardText.toString();
sendText = PgpHelper.getPgpKeyContent(sendText); sendText = PgpHelper.getPgpKeyContent(sendText);
if (sendText == null) { if (sendText == null) {
Notify.create(mImportActivity, R.string.error_bad_data, Style.ERROR).show(); Notify.create(mActivity, R.string.error_bad_data, Style.ERROR).show();
return; return;
} }
mImportActivity.loadCallback(new BytesLoaderState(sendText.getBytes(), null)); mCallback.loadKeys(new BytesLoaderState(sendText.getBytes(), null));
} }
} }
}); });
@@ -117,7 +120,14 @@ public class ImportKeysFileFragment extends Fragment {
public void onAttach(Activity activity) { public void onAttach(Activity activity) {
super.onAttach(activity); super.onAttach(activity);
mImportActivity = (ImportKeysActivity) activity; mActivity = activity;
try {
mCallback = (ImportKeysListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement ImportKeysListener");
}
} }
@Override @Override
@@ -130,7 +140,7 @@ public class ImportKeysFileFragment extends Fragment {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.import_all_keys: case R.id.import_all_keys:
mImportActivity.importAllKeys(); mCallback.importKeys();
return true; return true;
} }
@@ -161,30 +171,30 @@ public class ImportKeysFileFragment extends Fragment {
private void startImportingKeys() { private void startImportingKeys() {
boolean isEncrypted; boolean isEncrypted;
try { try {
isEncrypted = FileHelper.isEncryptedFile(mImportActivity, mCurrentUri); isEncrypted = FileHelper.isEncryptedFile(mActivity, mCurrentUri);
} catch (IOException e) { } catch (IOException e) {
Log.e(Constants.TAG, "Error opening file", e); Log.e(Constants.TAG, "Error opening file", e);
Notify.create(mImportActivity, R.string.error_bad_data, Style.ERROR).show(); Notify.create(mActivity, R.string.error_bad_data, Style.ERROR).show();
return; return;
} }
if (isEncrypted) { if (isEncrypted) {
Intent intent = new Intent(mImportActivity, DecryptActivity.class); Intent intent = new Intent(mActivity, DecryptActivity.class);
intent.setAction(Intent.ACTION_VIEW); intent.setAction(Intent.ACTION_VIEW);
intent.setData(mCurrentUri); intent.setData(mCurrentUri);
startActivity(intent); startActivity(intent);
} else { } else {
mImportActivity.loadCallback(new BytesLoaderState(null, mCurrentUri)); mCallback.loadKeys(new BytesLoaderState(null, mCurrentUri));
} }
} }
/** /**
* Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris. * Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris.
* <p/> * <p>
* This method returns true on Android < 6, or if permission is already granted. It * This method returns true on Android < 6, or if permission is already granted. It
* requests the permission and returns false otherwise. * requests the permission and returns false otherwise.
* <p/> * <p>
* see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html * see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html
*/ */
private boolean checkAndRequestReadPermission(final Uri uri) { private boolean checkAndRequestReadPermission(final Uri uri) {
@@ -225,9 +235,9 @@ public class ImportKeysFileFragment extends Fragment {
if (permissionWasGranted) { if (permissionWasGranted) {
startImportingKeys(); startImportingKeys();
} else { } else {
Toast.makeText(getActivity(), R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); Toast.makeText(mActivity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show();
getActivity().setResult(Activity.RESULT_CANCELED); mActivity.setResult(Activity.RESULT_CANCELED);
getActivity().finish(); mActivity.finish();
} }
} }

View File

@@ -46,15 +46,15 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.databinding.ImportKeysListFragmentBinding; import org.sufficientlysecure.keychain.databinding.ImportKeysListFragmentBinding;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.keyimport.processing.AsyncTaskResultWrapper;
import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState;
import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState;
import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListCloudLoader;
import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListLoader;
import org.sufficientlysecure.keychain.keyimport.processing.LoaderState;
import org.sufficientlysecure.keychain.operations.results.GetKeyResult; import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter;
import org.sufficientlysecure.keychain.keyimport.loader.AsyncTaskResultWrapper;
import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState;
import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState;
import org.sufficientlysecure.keychain.keyimport.loader.ImportKeysListCloudLoader;
import org.sufficientlysecure.keychain.keyimport.loader.ImportKeysListLoader;
import org.sufficientlysecure.keychain.keyimport.loader.LoaderState;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.ParcelableProxy;
@@ -77,6 +77,7 @@ public class ImportKeysListFragment extends Fragment implements
private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12;
private FragmentActivity mActivity; private FragmentActivity mActivity;
private ImportKeysListFragmentBinding binding; private ImportKeysListFragmentBinding binding;
private ParcelableProxy mParcelableProxy; private ParcelableProxy mParcelableProxy;
@@ -92,16 +93,10 @@ public class ImportKeysListFragment extends Fragment implements
private static final int LOADER_ID_BYTES = 0; private static final int LOADER_ID_BYTES = 0;
private static final int LOADER_ID_CLOUD = 1; private static final int LOADER_ID_CLOUD = 1;
private LongSparseArray<ParcelableKeyRing> mCachedKeyData; private LongSparseArray<ParcelableKeyRing> mCachedKeyData;
private boolean mShowingOrbotDialog; private boolean mShowingOrbotDialog;
public LoaderState getLoaderState() {
return mLoaderState;
}
/** /**
* Returns an Iterator (with size) of the selected data items. * Returns an Iterator (with size) of the selected data items.
* This iterator is sort of a tradeoff, it's slightly more complex than an * This iterator is sort of a tradeoff, it's slightly more complex than an
@@ -287,7 +282,11 @@ public class ImportKeysListFragment extends Fragment implements
} }
} }
public void loadNew(LoaderState loaderState) { public LoaderState getState() {
return mLoaderState;
}
public void loadState(LoaderState loaderState) {
mLoaderState = loaderState; mLoaderState = loaderState;
if (mLoaderState instanceof BytesLoaderState) { if (mLoaderState instanceof BytesLoaderState) {
@@ -301,17 +300,6 @@ public class ImportKeysListFragment extends Fragment implements
restartLoaders(); restartLoaders();
} }
public void destroyLoader() {
LoaderManager loaderManager = getLoaderManager();
if (loaderManager.getLoader(LOADER_ID_BYTES) != null) {
loaderManager.destroyLoader(LOADER_ID_BYTES);
}
if (loaderManager.getLoader(LOADER_ID_CLOUD) != null) {
loaderManager.destroyLoader(LOADER_ID_CLOUD);
}
}
private void restartLoaders() { private void restartLoaders() {
LoaderManager loaderManager = getLoaderManager(); LoaderManager loaderManager = getLoaderManager();