mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 17:22:16 -05:00
rewrite data flow in EncryptFileFragment preserve state correctly
This commit is contained in:
parent
b9563ff2ef
commit
313b4ac7d3
@ -57,6 +57,10 @@ public class SignEncryptParcel extends PgpSignEncryptInputParcel {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isIncomplete() {
|
||||||
|
return mInputUris.size() > mOutputUris.size();
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
return mBytes;
|
return mBytes;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
|||||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.SpacesItemDecoration;
|
import org.sufficientlysecure.keychain.ui.adapter.SpacesItemDecoration;
|
||||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
|
import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
||||||
@ -70,7 +70,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class EncryptFilesFragment extends CryptoOperationFragment {
|
public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEncryptParcel> {
|
||||||
|
|
||||||
public static final String ARG_DELETE_AFTER_ENCRYPT = "delete_after_encrypt";
|
public static final String ARG_DELETE_AFTER_ENCRYPT = "delete_after_encrypt";
|
||||||
public static final String ARG_ENCRYPT_FILENAMES = "encrypt_filenames";
|
public static final String ARG_ENCRYPT_FILENAMES = "encrypt_filenames";
|
||||||
@ -89,7 +89,7 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
|
|
||||||
private boolean mShareAfterEncrypt;
|
private boolean mShareAfterEncrypt;
|
||||||
|
|
||||||
private ArrayList<Uri> mOutputUris = new ArrayList<>();
|
private ArrayList<Uri> mOutputUris;
|
||||||
|
|
||||||
private RecyclerView mSelectedFiles;
|
private RecyclerView mSelectedFiles;
|
||||||
|
|
||||||
@ -221,33 +221,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encryptClicked(boolean share) {
|
|
||||||
if (mFilesModels.isEmpty()) {
|
|
||||||
Notify.create(getActivity(), R.string.error_no_file_selected,
|
|
||||||
Notify.Style.ERROR).show(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (share) {
|
|
||||||
mOutputUris.clear();
|
|
||||||
int filenameCounter = 1;
|
|
||||||
for (FilesAdapter.ViewModel model : mFilesModels) {
|
|
||||||
String targetName =
|
|
||||||
(mEncryptFilenames ? String.valueOf(filenameCounter) : FileHelper.getFilename(getActivity(), model.inputUri))
|
|
||||||
+ (mUseArmor ? Constants.FILE_EXTENSION_ASC : Constants.FILE_EXTENSION_PGP_MAIN);
|
|
||||||
mOutputUris.add(TemporaryStorageProvider.createFile(getActivity(), targetName));
|
|
||||||
filenameCounter++;
|
|
||||||
}
|
|
||||||
startEncrypt(true);
|
|
||||||
} else {
|
|
||||||
if (mFilesModels.size() > 1) {
|
|
||||||
Notify.create(getActivity(), R.string.error_multi_not_supported,
|
|
||||||
Notify.Style.ERROR).show(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showOutputFileDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addFile(Intent data) {
|
public void addFile(Intent data) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||||
addInputUri(data.getData());
|
addInputUri(data.getData());
|
||||||
@ -281,11 +254,11 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.encrypt_save: {
|
case R.id.encrypt_save: {
|
||||||
encryptClicked(false);
|
cryptoOperation(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.encrypt_share: {
|
case R.id.encrypt_share: {
|
||||||
encryptClicked(true);
|
cryptoOperation(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.check_use_armor: {
|
case R.id.check_use_armor: {
|
||||||
@ -351,27 +324,49 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SignEncryptParcel createEncryptBundle() {
|
// prepares mOutputUris, either directly and returns false, or indirectly
|
||||||
|
// which returns true and will call cryptoOperation after mOutputUris has
|
||||||
|
// been set at a later point.
|
||||||
|
private boolean prepareOutputStreams(boolean share) {
|
||||||
|
|
||||||
if (mFilesModels.isEmpty()) {
|
if (mFilesModels.isEmpty()) {
|
||||||
Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR)
|
Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR)
|
||||||
.show(this);
|
.show(this);
|
||||||
return null;
|
return true;
|
||||||
} else if (mFilesModels.size() > 1 && !mShareAfterEncrypt) {
|
} else if (mFilesModels.size() > 1 && !mShareAfterEncrypt) {
|
||||||
Log.e(Constants.TAG, "Aborting: mInputUris.size() > 1 && !mShareAfterEncrypt");
|
Log.e(Constants.TAG, "Aborting: mInputUris.size() > 1 && !mShareAfterEncrypt");
|
||||||
// This should be impossible...
|
// This should be impossible...
|
||||||
return null;
|
return true;
|
||||||
} else if (mFilesModels.size() != mOutputUris.size()) {
|
|
||||||
Log.e(Constants.TAG, "Aborting: mInputUris.size() != mOutputUris.size()");
|
|
||||||
// This as well
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (share) {
|
||||||
|
mOutputUris = new ArrayList<>();
|
||||||
|
int filenameCounter = 1;
|
||||||
|
for (FilesAdapter.ViewModel model : mFilesModels) {
|
||||||
|
String targetName =
|
||||||
|
(mEncryptFilenames ? String.valueOf(filenameCounter) : FileHelper.getFilename(getActivity(), model.inputUri))
|
||||||
|
+ (mUseArmor ? Constants.FILE_EXTENSION_ASC : Constants.FILE_EXTENSION_PGP_MAIN);
|
||||||
|
mOutputUris.add(TemporaryStorageProvider.createFile(getActivity(), targetName));
|
||||||
|
filenameCounter++;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (mFilesModels.size() > 1) {
|
||||||
|
Notify.create(getActivity(), R.string.error_multi_not_supported,
|
||||||
|
Notify.Style.ERROR).show(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
showOutputFileDialog();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SignEncryptParcel createIncompleteEncryptBundle() {
|
||||||
|
|
||||||
// fill values for this action
|
// fill values for this action
|
||||||
SignEncryptParcel data = new SignEncryptParcel();
|
SignEncryptParcel data = new SignEncryptParcel();
|
||||||
|
|
||||||
data.addInputUris(mFilesAdapter.getAsArrayList());
|
data.addInputUris(mFilesAdapter.getAsArrayList());
|
||||||
data.addOutputUris(mOutputUris);
|
|
||||||
|
|
||||||
if (mUseCompression) {
|
if (mUseCompression) {
|
||||||
data.setCompressionId(PgpConstants.sPreferredCompressionAlgorithms.get(0));
|
data.setCompressionId(PgpConstants.sPreferredCompressionAlgorithms.get(0));
|
||||||
@ -471,27 +466,50 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
return sendIntent;
|
return sendIntent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startEncrypt(boolean share) {
|
public void cryptoOperation(boolean share) {
|
||||||
mShareAfterEncrypt = share;
|
mShareAfterEncrypt = share;
|
||||||
cryptoOperation();
|
cryptoOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
protected void cryptoOperation(CryptoInputParcel cryptoInput, SignEncryptParcel actionsParcel) {
|
||||||
|
|
||||||
final SignEncryptParcel input = createEncryptBundle();
|
// we have three cases here: nothing cached, cached except output, fully cached
|
||||||
|
if (actionsParcel == null) {
|
||||||
|
|
||||||
|
// clear output uris for now, they will be created by prepareOutputStreams later
|
||||||
|
mOutputUris = null;
|
||||||
|
|
||||||
|
actionsParcel = createIncompleteEncryptBundle();
|
||||||
// this is null if invalid, just return in that case
|
// this is null if invalid, just return in that case
|
||||||
if (input == null) {
|
if (actionsParcel == null) {
|
||||||
// Notify was created by inputIsValid.
|
// Notify was created by createEncryptBundle.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheActionsParcel(actionsParcel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's incomplete, prepare output streams
|
||||||
|
if (actionsParcel.isIncomplete()) {
|
||||||
|
// if this is still null, prepare output streams again
|
||||||
|
if (mOutputUris == null) {
|
||||||
|
// this may interrupt the flow, and call us again from onActivityResult
|
||||||
|
if (prepareOutputStreams(mShareAfterEncrypt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actionsParcel.addOutputUris(mOutputUris);
|
||||||
|
cacheActionsParcel(actionsParcel);
|
||||||
|
}
|
||||||
|
|
||||||
// Send all information needed to service to edit key in other thread
|
// Send all information needed to service to edit key in other thread
|
||||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||||
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||||
|
|
||||||
Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, actionsParcel);
|
||||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||||
|
|
||||||
@ -545,9 +563,9 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
case REQUEST_CODE_OUTPUT: {
|
case REQUEST_CODE_OUTPUT: {
|
||||||
// This happens after output file was selected, so start our operation
|
// This happens after output file was selected, so start our operation
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||||
mOutputUris.clear();
|
mOutputUris = new ArrayList<>(1);
|
||||||
mOutputUris.add(data.getData());
|
mOutputUris.add(data.getData());
|
||||||
startEncrypt(false);
|
cryptoOperation(false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -85,11 +85,9 @@ public class EncryptModeAsymmetricFragment extends EncryptModeFragment {
|
|||||||
mProviderHelper = new ProviderHelper(getActivity());
|
mProviderHelper = new ProviderHelper(getActivity());
|
||||||
|
|
||||||
// preselect keys given, from state or arguments
|
// preselect keys given, from state or arguments
|
||||||
long signatureKeyId, encryptionKeyIds[];
|
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
signatureKeyId = getArguments().getLong(ARG_SINGATURE_KEY_ID);
|
Long signatureKeyId = getArguments().getLong(ARG_SINGATURE_KEY_ID);
|
||||||
encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS);
|
long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS);
|
||||||
preselectKeys(signatureKeyId, encryptionKeyIds);
|
preselectKeys(signatureKeyId, encryptionKeyIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,8 +96,8 @@ public class EncryptModeAsymmetricFragment extends EncryptModeFragment {
|
|||||||
/**
|
/**
|
||||||
* If an Intent gives a signatureMasterKeyId and/or encryptionMasterKeyIds, preselect those!
|
* If an Intent gives a signatureMasterKeyId and/or encryptionMasterKeyIds, preselect those!
|
||||||
*/
|
*/
|
||||||
private void preselectKeys(long signatureKeyId, long[] encryptionKeyIds) {
|
private void preselectKeys(Long signatureKeyId, long[] encryptionKeyIds) {
|
||||||
if (signatureKeyId != Constants.key.none) {
|
if (signatureKeyId != null) {
|
||||||
try {
|
try {
|
||||||
CachedPublicKeyRing keyring = mProviderHelper.getCachedPublicKeyRing(
|
CachedPublicKeyRing keyring = mProviderHelper.getCachedPublicKeyRing(
|
||||||
KeyRings.buildUnifiedKeyRingUri(signatureKeyId));
|
KeyRings.buildUnifiedKeyRingUri(signatureKeyId));
|
||||||
|
@ -44,7 +44,7 @@ import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
|||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
|
import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||||
@ -53,7 +53,7 @@ import org.sufficientlysecure.keychain.util.ShareHelper;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class EncryptTextFragment extends CryptoOperationFragment {
|
public class EncryptTextFragment extends CachingCryptoOperationFragment<SignEncryptParcel> {
|
||||||
|
|
||||||
public static final String ARG_TEXT = "text";
|
public static final String ARG_TEXT = "text";
|
||||||
public static final String ARG_USE_COMPRESSION = "use_compression";
|
public static final String ARG_USE_COMPRESSION = "use_compression";
|
||||||
@ -308,21 +308,26 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
protected void cryptoOperation(CryptoInputParcel cryptoInput, SignEncryptParcel actionsParcel) {
|
||||||
|
|
||||||
final SignEncryptParcel input = createEncryptBundle();
|
if (actionsParcel == null) {
|
||||||
|
|
||||||
|
actionsParcel = createEncryptBundle();
|
||||||
// this is null if invalid, just return in that case
|
// this is null if invalid, just return in that case
|
||||||
if (input == null) {
|
if (actionsParcel == null) {
|
||||||
// Notify was created by inputIsValid.
|
// Notify was created by inputIsValid.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheActionsParcel(actionsParcel);
|
||||||
|
}
|
||||||
|
|
||||||
// Send all information needed to service to edit key in other thread
|
// Send all information needed to service to edit key in other thread
|
||||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||||
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||||
|
|
||||||
final Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, actionsParcel);
|
||||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user