mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
rewrite EncryptActivity data flow
This commit is contained in:
parent
08e0357471
commit
6c17734e73
@ -77,8 +77,6 @@ public class CertifyKeyFragment extends CryptoOperationFragment
|
||||
|
||||
private long[] mPubMasterKeyIds;
|
||||
|
||||
private long mSignMasterKeyId = Constants.key.none;
|
||||
|
||||
public static final String[] USER_IDS_PROJECTION = new String[]{
|
||||
UserPackets._ID,
|
||||
UserPackets.MASTER_KEY_ID,
|
||||
@ -149,19 +147,13 @@ public class CertifyKeyFragment extends CryptoOperationFragment
|
||||
vActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
|
||||
PorterDuff.Mode.SRC_IN);
|
||||
|
||||
mCertifyKeySpinner.setOnKeyChangedListener(new KeySpinner.OnKeyChangedListener() {
|
||||
@Override
|
||||
public void onKeyChanged(long masterKeyId) {
|
||||
mSignMasterKeyId = masterKeyId;
|
||||
}
|
||||
});
|
||||
|
||||
View vCertifyButton = view.findViewById(R.id.certify_key_certify_button);
|
||||
vCertifyButton.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mSignMasterKeyId == Constants.key.none) {
|
||||
long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId();
|
||||
if (selectedKeyId == Constants.key.none) {
|
||||
Notify.create(getActivity(), getString(R.string.select_key_to_certify),
|
||||
Notify.Style.ERROR).show();
|
||||
} else {
|
||||
@ -307,8 +299,10 @@ public class CertifyKeyFragment extends CryptoOperationFragment
|
||||
|
||||
Bundle data = new Bundle();
|
||||
{
|
||||
long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId();
|
||||
|
||||
// fill values for this action
|
||||
CertifyActionsParcel parcel = new CertifyActionsParcel(mSignMasterKeyId);
|
||||
CertifyActionsParcel parcel = new CertifyActionsParcel(selectedKeyId);
|
||||
parcel.mCertifyActions.addAll(certifyActions);
|
||||
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
||||
|
||||
public class EncryptActivity extends BaseActivity {
|
||||
|
||||
// preselect ids, for internal use
|
||||
public static final String EXTRA_SIGNATURE_KEY_ID = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_ID";
|
||||
public static final String EXTRA_ENCRYPTION_KEY_IDS = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_IDS";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Intent intent = getIntent();
|
||||
Bundle extras = intent.getExtras();
|
||||
|
||||
if (extras == null) {
|
||||
extras = new Bundle();
|
||||
}
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
// preselect keys given by intent
|
||||
long signingKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID);
|
||||
long[] encryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS);
|
||||
|
||||
Fragment modeFragment = EncryptModeAsymmetricFragment.newInstance(signingKeyId, encryptionKeyIds);
|
||||
transaction.replace(R.id.encrypt_mode_container, modeFragment);
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleModeFragment() {
|
||||
boolean symmetric = getModeFragment() instanceof EncryptModeAsymmetricFragment;
|
||||
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
transaction.replace(R.id.encrypt_mode_container,
|
||||
symmetric
|
||||
? EncryptModeSymmetricFragment.newInstance()
|
||||
: EncryptModeAsymmetricFragment.newInstance(0, null)
|
||||
);
|
||||
|
||||
// doesn't matter if the user doesn't look at the activity
|
||||
transaction.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
public EncryptModeFragment getModeFragment() {
|
||||
return (EncryptModeFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.encrypt_mode_container);
|
||||
}
|
||||
}
|
@ -18,39 +18,25 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.View;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
||||
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class EncryptFilesActivity extends BaseActivity implements
|
||||
EncryptModeAsymmetricFragment.IAsymmetric, EncryptModeSymmetricFragment.ISymmetric,
|
||||
EncryptFilesFragment.IMode {
|
||||
public class EncryptFilesActivity extends EncryptActivity {
|
||||
|
||||
/* Intents */
|
||||
// Intents
|
||||
public static final String ACTION_ENCRYPT_DATA = OpenKeychainIntents.ENCRYPT_DATA;
|
||||
|
||||
// enables ASCII Armor for file encryption when uri is given
|
||||
public static final String EXTRA_ASCII_ARMOR = OpenKeychainIntents.ENCRYPT_EXTRA_ASCII_ARMOR;
|
||||
|
||||
// preselect ids, for internal use
|
||||
public static final String EXTRA_SIGNATURE_KEY_ID = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_ID";
|
||||
public static final String EXTRA_ENCRYPTION_KEY_IDS = Constants.EXTRA_PREFIX + "EXTRA_ENCRYPTION_IDS";
|
||||
|
||||
Fragment mModeFragment;
|
||||
EncryptFilesFragment mEncryptFragment;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -62,19 +48,7 @@ public class EncryptFilesActivity extends BaseActivity implements
|
||||
}
|
||||
}, false);
|
||||
|
||||
// Handle intent actions
|
||||
handleActions(getIntent(), savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initLayout() {
|
||||
setContentView(R.layout.encrypt_files_activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles all actions with this intent
|
||||
*/
|
||||
private void handleActions(Intent intent, Bundle savedInstanceState) {
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
Bundle extras = intent.getExtras();
|
||||
String type = intent.getType();
|
||||
@ -88,10 +62,6 @@ public class EncryptFilesActivity extends BaseActivity implements
|
||||
uris.add(intent.getData());
|
||||
}
|
||||
|
||||
/*
|
||||
* Android's Action
|
||||
*/
|
||||
|
||||
// When sending to OpenKeychain Encrypt via share menu
|
||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||
// Files via content provider, override uri and action
|
||||
@ -103,56 +73,21 @@ public class EncryptFilesActivity extends BaseActivity implements
|
||||
uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
}
|
||||
|
||||
long mSigningKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID);
|
||||
long[] mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS);
|
||||
boolean useArmor = extras.getBoolean(EXTRA_ASCII_ARMOR, false);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
mModeFragment = EncryptModeAsymmetricFragment.newInstance(mSigningKeyId, mEncryptionKeyIds);
|
||||
transaction.replace(R.id.encrypt_mode_container, mModeFragment, "mode");
|
||||
|
||||
mEncryptFragment = EncryptFilesFragment.newInstance(uris, useArmor);
|
||||
transaction.replace(R.id.encrypt_file_container, mEncryptFragment, "files");
|
||||
|
||||
EncryptFilesFragment encryptFragment = EncryptFilesFragment.newInstance(uris, useArmor);
|
||||
transaction.replace(R.id.encrypt_file_container, encryptFragment);
|
||||
transaction.commit();
|
||||
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModeChanged(boolean symmetric) {
|
||||
// switch fragments
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.encrypt_mode_container,
|
||||
symmetric
|
||||
? EncryptModeSymmetricFragment.newInstance()
|
||||
: EncryptModeAsymmetricFragment.newInstance(0, null)
|
||||
)
|
||||
.commitAllowingStateLoss();
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignatureKeyIdChanged(long signatureKeyId) {
|
||||
mEncryptFragment.setSigningKeyId(signatureKeyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEncryptionKeyIdsChanged(long[] encryptionKeyIds) {
|
||||
mEncryptFragment.setEncryptionKeyIds(encryptionKeyIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEncryptionUserIdsChanged(String[] encryptionUserIds) {
|
||||
mEncryptFragment.setEncryptionUserIds(encryptionUserIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPassphraseChanged(Passphrase passphrase) {
|
||||
mEncryptFragment.setPassphrase(passphrase);
|
||||
protected void initLayout() {
|
||||
setContentView(R.layout.encrypt_files_activity);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -72,19 +72,12 @@ import java.util.Set;
|
||||
|
||||
public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
|
||||
public interface IMode {
|
||||
public void onModeChanged(boolean symmetric);
|
||||
}
|
||||
|
||||
public static final String ARG_USE_ASCII_ARMOR = "use_ascii_armor";
|
||||
public static final String ARG_URIS = "uris";
|
||||
|
||||
private static final int REQUEST_CODE_INPUT = 0x00007003;
|
||||
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
||||
|
||||
private IMode mModeInterface;
|
||||
|
||||
private boolean mSymmetricMode = false;
|
||||
private boolean mUseArmor = false;
|
||||
private boolean mUseCompression = true;
|
||||
private boolean mDeleteAfterEncrypt = false;
|
||||
@ -92,11 +85,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
private boolean mEncryptFilenames = true;
|
||||
private boolean mHiddenRecipients = false;
|
||||
|
||||
private long mEncryptionKeyIds[] = null;
|
||||
private String mEncryptionUserIds[] = null;
|
||||
private long mSigningKeyId = Constants.key.none;
|
||||
private Passphrase mPassphrase = new Passphrase();
|
||||
|
||||
private ArrayList<Uri> mOutputUris = new ArrayList<>();
|
||||
|
||||
private RecyclerView mSelectedFiles;
|
||||
@ -118,29 +106,11 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
return frag;
|
||||
}
|
||||
|
||||
public void setEncryptionKeyIds(long[] encryptionKeyIds) {
|
||||
mEncryptionKeyIds = encryptionKeyIds;
|
||||
}
|
||||
|
||||
public void setEncryptionUserIds(String[] encryptionUserIds) {
|
||||
mEncryptionUserIds = encryptionUserIds;
|
||||
}
|
||||
|
||||
public void setSigningKeyId(long signingKeyId) {
|
||||
mSigningKeyId = signingKeyId;
|
||||
}
|
||||
|
||||
public void setPassphrase(Passphrase passphrase) {
|
||||
mPassphrase = passphrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mModeInterface = (IMode) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity + " must be IMode");
|
||||
if ( ! (activity instanceof EncryptActivity) ) {
|
||||
throw new AssertionError(activity + " must inherit from EncryptionActivity");
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,8 +263,8 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
break;
|
||||
}
|
||||
case R.id.check_use_symmetric: {
|
||||
mSymmetricMode = item.isChecked();
|
||||
mModeInterface.onModeChanged(mSymmetricMode);
|
||||
EncryptActivity encryptActivity = (EncryptActivity) getActivity();
|
||||
encryptActivity.toggleModeFragment();
|
||||
break;
|
||||
}
|
||||
case R.id.check_use_armor: {
|
||||
@ -325,53 +295,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean inputIsValid() {
|
||||
// file checks
|
||||
|
||||
if (mFilesModels.isEmpty()) {
|
||||
Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
} else if (mFilesModels.size() > 1 && !mShareAfterEncrypt) {
|
||||
Log.e(Constants.TAG, "Aborting: mInputUris.size() > 1 && !mShareAfterEncrypt");
|
||||
// This should be impossible...
|
||||
return false;
|
||||
} else if (mFilesModels.size() != mOutputUris.size()) {
|
||||
Log.e(Constants.TAG, "Aborting: mInputUris.size() != mOutputUris.size()");
|
||||
// This as well
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSymmetricMode) {
|
||||
// symmetric encryption checks
|
||||
|
||||
if (mPassphrase == null) {
|
||||
Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
}
|
||||
if (mPassphrase.isEmpty()) {
|
||||
Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// asymmetric encryption checks
|
||||
|
||||
boolean gotEncryptionKeys = (mEncryptionKeyIds != null
|
||||
&& mEncryptionKeyIds.length > 0);
|
||||
|
||||
// Files must be encrypted, only text can be signed-only right now
|
||||
if (!gotEncryptionKeys) {
|
||||
Notify.create(getActivity(), R.string.select_encryption_key, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onEncryptSuccess(final SignEncryptResult result) {
|
||||
if (mDeleteAfterEncrypt) {
|
||||
DeleteFileDialogFragment deleteFileDialog =
|
||||
@ -403,6 +326,21 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
}
|
||||
|
||||
protected SignEncryptParcel createEncryptBundle() {
|
||||
|
||||
if (mFilesModels.isEmpty()) {
|
||||
Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
} else if (mFilesModels.size() > 1 && !mShareAfterEncrypt) {
|
||||
Log.e(Constants.TAG, "Aborting: mInputUris.size() > 1 && !mShareAfterEncrypt");
|
||||
// This should be impossible...
|
||||
return null;
|
||||
} else if (mFilesModels.size() != mOutputUris.size()) {
|
||||
Log.e(Constants.TAG, "Aborting: mInputUris.size() != mOutputUris.size()");
|
||||
// This as well
|
||||
return null;
|
||||
}
|
||||
|
||||
// fill values for this action
|
||||
SignEncryptParcel data = new SignEncryptParcel();
|
||||
|
||||
@ -419,17 +357,39 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||
data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||
|
||||
if (mSymmetricMode) {
|
||||
Log.d(Constants.TAG, "Symmetric encryption enabled!");
|
||||
Passphrase passphrase = mPassphrase;
|
||||
EncryptActivity encryptActivity = (EncryptActivity) getActivity();
|
||||
EncryptModeFragment modeFragment = encryptActivity.getModeFragment();
|
||||
|
||||
if (modeFragment.isAsymmetric()) {
|
||||
long[] encryptionKeyIds = modeFragment.getAsymmetricEncryptionKeyIds();
|
||||
long signingKeyId = modeFragment.getAsymmetricSigningKeyId();
|
||||
|
||||
boolean gotEncryptionKeys = (encryptionKeyIds != null
|
||||
&& encryptionKeyIds.length > 0);
|
||||
|
||||
if (!gotEncryptionKeys && signingKeyId == 0) {
|
||||
Notify.create(getActivity(), R.string.select_encryption_or_signature_key, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
data.setEncryptionMasterKeyIds(encryptionKeyIds);
|
||||
data.setSignatureMasterKeyId(signingKeyId);
|
||||
} else {
|
||||
Passphrase passphrase = modeFragment.getSymmetricPassphrase();
|
||||
if (passphrase == null) {
|
||||
Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
}
|
||||
if (passphrase.isEmpty()) {
|
||||
passphrase = null;
|
||||
Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
}
|
||||
data.setSymmetricPassphrase(passphrase);
|
||||
} else {
|
||||
data.setEncryptionMasterKeyIds(mEncryptionKeyIds);
|
||||
data.setSignatureMasterKeyId(mSigningKeyId);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -461,16 +421,27 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
}
|
||||
sendIntent.setType(Constants.ENCRYPTED_FILES_MIME);
|
||||
|
||||
if (!mSymmetricMode && mEncryptionUserIds != null) {
|
||||
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||
EncryptModeFragment modeFragment = modeInterface.getModeFragment();
|
||||
if (!modeFragment.isAsymmetric()) {
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
String[] encryptionUserIds = modeFragment.getAsymmetricEncryptionUserIds();
|
||||
if (encryptionUserIds == null) {
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
Set<String> users = new HashSet<>();
|
||||
for (String user : mEncryptionUserIds) {
|
||||
for (String user : encryptionUserIds) {
|
||||
KeyRing.UserId userId = KeyRing.splitUserId(user);
|
||||
if (userId.email != null) {
|
||||
users.add(userId.email);
|
||||
}
|
||||
}
|
||||
// pass trough email addresses as extra for email applications
|
||||
sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()]));
|
||||
}
|
||||
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
@ -482,19 +453,17 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
@Override
|
||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
||||
|
||||
if (!inputIsValid()) {
|
||||
final SignEncryptParcel input = createEncryptBundle();
|
||||
// this is null if invalid, just return in that case
|
||||
if (input == null) {
|
||||
// Notify was created by inputIsValid.
|
||||
Log.d(Constants.TAG, "Input not valid!");
|
||||
return;
|
||||
}
|
||||
Log.d(Constants.TAG, "Input valid!");
|
||||
|
||||
// Send all information needed to service to edit key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||
|
||||
final SignEncryptParcel input = createEncryptBundle();
|
||||
|
||||
Bundle data = new Bundle();
|
||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
@ -727,7 +696,7 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
||||
for (Uri inputUri : inputUris) {
|
||||
ViewModel newModel = new ViewModel(mActivity, inputUri);
|
||||
if (mDataset.contains(newModel)) {
|
||||
Log.e(Constants.TAG, "Skipped duplicate " + inputUri.toString());
|
||||
Log.e(Constants.TAG, "Skipped duplicate " + inputUri);
|
||||
} else {
|
||||
mDataset.add(newModel);
|
||||
}
|
||||
|
@ -17,18 +17,13 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.tokenautocomplete.TokenCompleteTextView;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||
@ -39,38 +34,19 @@ import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter.KeyItem;
|
||||
import org.sufficientlysecure.keychain.ui.widget.EncryptKeyCompletionView;
|
||||
import org.sufficientlysecure.keychain.ui.widget.KeySpinner;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class EncryptModeAsymmetricFragment extends Fragment {
|
||||
|
||||
public interface IAsymmetric {
|
||||
|
||||
public void onSignatureKeyIdChanged(long signatureKeyId);
|
||||
|
||||
public void onEncryptionKeyIdsChanged(long[] encryptionKeyIds);
|
||||
|
||||
public void onEncryptionUserIdsChanged(String[] encryptionUserIds);
|
||||
}
|
||||
public class EncryptModeAsymmetricFragment extends EncryptModeFragment {
|
||||
|
||||
ProviderHelper mProviderHelper;
|
||||
|
||||
// view
|
||||
private KeySpinner mSign;
|
||||
private KeySpinner mSignKeySpinner;
|
||||
private EncryptKeyCompletionView mEncryptKeyView;
|
||||
|
||||
// model
|
||||
private IAsymmetric mEncryptInterface;
|
||||
|
||||
// @Override
|
||||
// public void updateUi() {
|
||||
// if (mSign != null) {
|
||||
// mSign.setSelectedKeyId(mEncryptInterface.getSignatureKey());
|
||||
// }
|
||||
// }
|
||||
|
||||
public static final String ARG_SINGATURE_KEY_ID = "signature_key_id";
|
||||
public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids";
|
||||
|
||||
@ -89,16 +65,6 @@ public class EncryptModeAsymmetricFragment extends Fragment {
|
||||
return frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mEncryptInterface = (IAsymmetric) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity + " must implement IAsymmetric");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate the layout for this fragment
|
||||
*/
|
||||
@ -106,13 +72,7 @@ public class EncryptModeAsymmetricFragment extends Fragment {
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false);
|
||||
|
||||
mSign = (KeySpinner) view.findViewById(R.id.sign);
|
||||
mSign.setOnKeyChangedListener(new KeySpinner.OnKeyChangedListener() {
|
||||
@Override
|
||||
public void onKeyChanged(long masterKeyId) {
|
||||
mEncryptInterface.onSignatureKeyIdChanged(masterKeyId);
|
||||
}
|
||||
});
|
||||
mSignKeySpinner = (KeySpinner) view.findViewById(R.id.sign);
|
||||
mEncryptKeyView = (EncryptKeyCompletionView) view.findViewById(R.id.recipient_list);
|
||||
mEncryptKeyView.setThreshold(1); // Start working from first character
|
||||
|
||||
@ -128,22 +88,6 @@ public class EncryptModeAsymmetricFragment extends Fragment {
|
||||
long signatureKeyId = getArguments().getLong(ARG_SINGATURE_KEY_ID);
|
||||
long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS);
|
||||
preselectKeys(signatureKeyId, encryptionKeyIds);
|
||||
|
||||
mEncryptKeyView.setTokenListener(new TokenCompleteTextView.TokenListener() {
|
||||
@Override
|
||||
public void onTokenAdded(Object token) {
|
||||
if (token instanceof KeyItem) {
|
||||
updateEncryptionKeys();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTokenRemoved(Object token) {
|
||||
if (token instanceof KeyItem) {
|
||||
updateEncryptionKeys();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,8 +99,7 @@ public class EncryptModeAsymmetricFragment extends Fragment {
|
||||
CachedPublicKeyRing keyring = mProviderHelper.getCachedPublicKeyRing(
|
||||
KeyRings.buildUnifiedKeyRingUri(signatureKeyId));
|
||||
if (keyring.hasAnySecret()) {
|
||||
mEncryptInterface.onSignatureKeyIdChanged(keyring.getMasterKeyId());
|
||||
mSign.setSelectedKeyId(signatureKeyId);
|
||||
mSignKeySpinner.setSelectedKeyId(signatureKeyId);
|
||||
}
|
||||
} catch (PgpKeyNotFoundException e) {
|
||||
Log.e(Constants.TAG, "key not found!", e);
|
||||
@ -175,27 +118,55 @@ public class EncryptModeAsymmetricFragment extends Fragment {
|
||||
}
|
||||
// This is to work-around a rendering bug in TokenCompleteTextView
|
||||
mEncryptKeyView.requestFocus();
|
||||
updateEncryptionKeys();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateEncryptionKeys() {
|
||||
List<Object> objects = mEncryptKeyView.getObjects();
|
||||
@Override
|
||||
public boolean isAsymmetric() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAsymmetricSigningKeyId() {
|
||||
return mSignKeySpinner.getSelectedItemId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getAsymmetricEncryptionKeyIds() {
|
||||
List<Long> keyIds = new ArrayList<>();
|
||||
List<String> userIds = new ArrayList<>();
|
||||
for (Object object : objects) {
|
||||
for (Object object : mEncryptKeyView.getObjects()) {
|
||||
if (object instanceof KeyItem) {
|
||||
keyIds.add(((KeyItem) object).mKeyId);
|
||||
userIds.add(((KeyItem) object).mUserIdFull);
|
||||
}
|
||||
}
|
||||
|
||||
long[] keyIdsArr = new long[keyIds.size()];
|
||||
Iterator<Long> iterator = keyIds.iterator();
|
||||
for (int i = 0; i < keyIds.size(); i++) {
|
||||
keyIdsArr[i] = iterator.next();
|
||||
}
|
||||
mEncryptInterface.onEncryptionKeyIdsChanged(keyIdsArr);
|
||||
mEncryptInterface.onEncryptionUserIdsChanged(userIds.toArray(new String[userIds.size()]));
|
||||
|
||||
return keyIdsArr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAsymmetricEncryptionUserIds() {
|
||||
|
||||
List<String> userIds = new ArrayList<>();
|
||||
for (Object object : mEncryptKeyView.getObjects()) {
|
||||
if (object instanceof KeyItem) {
|
||||
userIds.add(((KeyItem) object).mUserIdFull);
|
||||
}
|
||||
}
|
||||
|
||||
return userIds.toArray(new String[userIds.size()]);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Passphrase getSymmetricPassphrase() {
|
||||
throw new UnsupportedOperationException("should never happen, this is a programming error!");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
|
||||
public abstract class EncryptModeFragment extends Fragment {
|
||||
|
||||
public abstract boolean isAsymmetric();
|
||||
|
||||
public abstract long getAsymmetricSigningKeyId();
|
||||
public abstract long[] getAsymmetricEncryptionKeyIds();
|
||||
public abstract String[] getAsymmetricEncryptionUserIds();
|
||||
|
||||
public abstract Passphrase getSymmetricPassphrase();
|
||||
|
||||
}
|
@ -17,11 +17,7 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -30,14 +26,7 @@ import android.widget.EditText;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
public class EncryptModeSymmetricFragment extends Fragment {
|
||||
|
||||
public interface ISymmetric {
|
||||
|
||||
public void onPassphraseChanged(Passphrase passphrase);
|
||||
}
|
||||
|
||||
private ISymmetric mEncryptInterface;
|
||||
public class EncryptModeSymmetricFragment extends EncryptModeFragment {
|
||||
|
||||
private EditText mPassphrase;
|
||||
private EditText mPassphraseAgain;
|
||||
@ -54,53 +43,54 @@ public class EncryptModeSymmetricFragment extends Fragment {
|
||||
return frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mEncryptInterface = (ISymmetric) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement ISymmetric");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate the layout for this fragment
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.encrypt_symmetric_fragment, container, false);
|
||||
|
||||
mPassphrase = (EditText) view.findViewById(R.id.passphrase);
|
||||
mPassphraseAgain = (EditText) view.findViewById(R.id.passphraseAgain);
|
||||
TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
// update passphrase in EncryptActivity
|
||||
Passphrase p1 = new Passphrase(mPassphrase.getText());
|
||||
Passphrase p2 = new Passphrase(mPassphraseAgain.getText());
|
||||
boolean passesEquals = (p1.equals(p2));
|
||||
p1.removeFromMemory();
|
||||
p2.removeFromMemory();
|
||||
if (passesEquals) {
|
||||
mEncryptInterface.onPassphraseChanged(new Passphrase(mPassphrase.getText()));
|
||||
} else {
|
||||
mEncryptInterface.onPassphraseChanged(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
mPassphrase.addTextChangedListener(textWatcher);
|
||||
mPassphraseAgain.addTextChangedListener(textWatcher);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsymmetric() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAsymmetricSigningKeyId() {
|
||||
throw new UnsupportedOperationException("should never happen, this is a programming error!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getAsymmetricEncryptionKeyIds() {
|
||||
throw new UnsupportedOperationException("should never happen, this is a programming error!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAsymmetricEncryptionUserIds() {
|
||||
throw new UnsupportedOperationException("should never happen, this is a programming error!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Passphrase getSymmetricPassphrase() {
|
||||
Passphrase p1 = null, p2 = null;
|
||||
try {
|
||||
p1 = new Passphrase(mPassphrase.getText());
|
||||
p2 = new Passphrase(mPassphraseAgain.getText());
|
||||
if (!p1.equals(p2)) {
|
||||
return null;
|
||||
}
|
||||
return new Passphrase(mPassphrase.getText());
|
||||
} finally {
|
||||
if (p1 != null) {
|
||||
p1.removeFromMemory();
|
||||
}
|
||||
if (p2 != null) {
|
||||
p2.removeFromMemory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,20 +20,14 @@ package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.View;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
||||
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
public class EncryptTextActivity extends BaseActivity implements
|
||||
EncryptModeAsymmetricFragment.IAsymmetric, EncryptModeSymmetricFragment.ISymmetric,
|
||||
EncryptTextFragment.IMode {
|
||||
public class EncryptTextActivity extends EncryptActivity {
|
||||
|
||||
/* Intents */
|
||||
public static final String ACTION_ENCRYPT_TEXT = OpenKeychainIntents.ENCRYPT_TEXT;
|
||||
@ -41,13 +35,6 @@ public class EncryptTextActivity extends BaseActivity implements
|
||||
/* EXTRA keys for input */
|
||||
public static final String EXTRA_TEXT = OpenKeychainIntents.ENCRYPT_EXTRA_TEXT;
|
||||
|
||||
// preselect ids, for internal use
|
||||
public static final String EXTRA_SIGNATURE_KEY_ID = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_ID";
|
||||
public static final String EXTRA_ENCRYPTION_KEY_IDS = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_IDS";
|
||||
|
||||
Fragment mModeFragment;
|
||||
EncryptTextFragment mEncryptFragment;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -89,23 +76,14 @@ public class EncryptTextActivity extends BaseActivity implements
|
||||
textData = "";
|
||||
}
|
||||
|
||||
// preselect keys given by intent
|
||||
long mSigningKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID);
|
||||
long[] mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
mModeFragment = EncryptModeAsymmetricFragment.newInstance(mSigningKeyId, mEncryptionKeyIds);
|
||||
transaction.replace(R.id.encrypt_mode_container, mModeFragment, "mode");
|
||||
|
||||
mEncryptFragment = EncryptTextFragment.newInstance(textData);
|
||||
transaction.replace(R.id.encrypt_text_container, mEncryptFragment, "text");
|
||||
|
||||
EncryptTextFragment encryptFragment = EncryptTextFragment.newInstance(textData);
|
||||
transaction.replace(R.id.encrypt_text_container, encryptFragment);
|
||||
transaction.commit();
|
||||
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -113,44 +91,4 @@ public class EncryptTextActivity extends BaseActivity implements
|
||||
setContentView(R.layout.encrypt_text_activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModeChanged(boolean symmetric) {
|
||||
// switch fragments
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.encrypt_mode_container,
|
||||
symmetric
|
||||
? EncryptModeSymmetricFragment.newInstance()
|
||||
: EncryptModeAsymmetricFragment.newInstance(0, null)
|
||||
)
|
||||
.commitAllowingStateLoss();
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignatureKeyIdChanged(long signatureKeyId) {
|
||||
if (mEncryptFragment != null) {
|
||||
mEncryptFragment.setSigningKeyId(signatureKeyId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEncryptionKeyIdsChanged(long[] encryptionKeyIds) {
|
||||
if (mEncryptFragment != null) {
|
||||
mEncryptFragment.setEncryptionKeyIds(encryptionKeyIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEncryptionUserIdsChanged(String[] encryptionUserIds) {
|
||||
if (mEncryptFragment != null) {
|
||||
mEncryptFragment.setEncryptionUserIds(encryptionUserIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPassphraseChanged(Passphrase passphrase) {
|
||||
if (mEncryptFragment != null) {
|
||||
mEncryptFragment.setSymmetricPassphrase(passphrase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
import org.sufficientlysecure.keychain.util.ShareHelper;
|
||||
|
||||
@ -56,44 +55,14 @@ import java.util.Set;
|
||||
|
||||
public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
|
||||
public interface IMode {
|
||||
public void onModeChanged(boolean symmetric);
|
||||
}
|
||||
|
||||
public static final String ARG_TEXT = "text";
|
||||
|
||||
private IMode mModeInterface;
|
||||
|
||||
private boolean mSymmetricMode = false;
|
||||
private boolean mShareAfterEncrypt = false;
|
||||
private boolean mUseCompression = true;
|
||||
private boolean mHiddenRecipients = false;
|
||||
|
||||
private long mEncryptionKeyIds[] = null;
|
||||
private String mEncryptionUserIds[] = null;
|
||||
// TODO Constants.key.none? What's wrong with a null value?
|
||||
private long mSigningKeyId = Constants.key.none;
|
||||
private Passphrase mSymmetricPassphrase = new Passphrase();
|
||||
private String mMessage = "";
|
||||
|
||||
private TextView mText;
|
||||
|
||||
public void setEncryptionKeyIds(long[] encryptionKeyIds) {
|
||||
mEncryptionKeyIds = encryptionKeyIds;
|
||||
}
|
||||
|
||||
public void setEncryptionUserIds(String[] encryptionUserIds) {
|
||||
mEncryptionUserIds = encryptionUserIds;
|
||||
}
|
||||
|
||||
public void setSigningKeyId(long signingKeyId) {
|
||||
mSigningKeyId = signingKeyId;
|
||||
}
|
||||
|
||||
public void setSymmetricPassphrase(Passphrase passphrase) {
|
||||
mSymmetricPassphrase = passphrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
*/
|
||||
@ -110,10 +79,8 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mModeInterface = (IMode) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement IMode");
|
||||
if ( ! (activity instanceof EncryptActivity) ) {
|
||||
throw new AssertionError(activity + " must inherit from EncryptionActivity");
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,8 +91,8 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.encrypt_text_fragment, container, false);
|
||||
|
||||
mText = (TextView) view.findViewById(R.id.encrypt_text_text);
|
||||
mText.addTextChangedListener(new TextWatcher() {
|
||||
TextView textView = (TextView) view.findViewById(R.id.encrypt_text_text);
|
||||
textView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
@ -144,7 +111,7 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
|
||||
// set initial text
|
||||
if (mMessage != null) {
|
||||
mText.setText(mMessage);
|
||||
textView.setText(mMessage);
|
||||
}
|
||||
|
||||
return view;
|
||||
@ -171,8 +138,8 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
}
|
||||
switch (item.getItemId()) {
|
||||
case R.id.check_use_symmetric: {
|
||||
mSymmetricMode = item.isChecked();
|
||||
mModeInterface.onModeChanged(mSymmetricMode);
|
||||
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||
modeInterface.toggleModeFragment();
|
||||
break;
|
||||
}
|
||||
case R.id.check_enable_compression: {
|
||||
@ -185,11 +152,11 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
// break;
|
||||
// }
|
||||
case R.id.encrypt_copy: {
|
||||
startEncrypt(false);
|
||||
cryptoOperation(false);
|
||||
break;
|
||||
}
|
||||
case R.id.encrypt_share: {
|
||||
startEncrypt(true);
|
||||
cryptoOperation(true);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -199,7 +166,6 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected void onEncryptSuccess(SignEncryptResult result) {
|
||||
if (mShareAfterEncrypt) {
|
||||
// Share encrypted message/file
|
||||
@ -215,6 +181,13 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
}
|
||||
|
||||
protected SignEncryptParcel createEncryptBundle() {
|
||||
|
||||
if (mMessage == null || mMessage.isEmpty()) {
|
||||
Notify.create(getActivity(), R.string.error_empty_text, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
// fill values for this action
|
||||
SignEncryptParcel data = new SignEncryptParcel();
|
||||
|
||||
@ -227,22 +200,45 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED);
|
||||
}
|
||||
data.setHiddenRecipients(mHiddenRecipients);
|
||||
data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||
data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||
data.setSymmetricEncryptionAlgorithm(
|
||||
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||
data.setSignatureHashAlgorithm(
|
||||
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||
|
||||
// Always use armor for messages
|
||||
data.setEnableAsciiArmorOutput(true);
|
||||
|
||||
if (mSymmetricMode) {
|
||||
Log.d(Constants.TAG, "Symmetric encryption enabled!");
|
||||
Passphrase passphrase = mSymmetricPassphrase;
|
||||
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||
EncryptModeFragment modeFragment = modeInterface.getModeFragment();
|
||||
|
||||
if (modeFragment.isAsymmetric()) {
|
||||
long[] encryptionKeyIds = modeFragment.getAsymmetricEncryptionKeyIds();
|
||||
long signingKeyId = modeFragment.getAsymmetricSigningKeyId();
|
||||
|
||||
boolean gotEncryptionKeys = (encryptionKeyIds != null
|
||||
&& encryptionKeyIds.length > 0);
|
||||
|
||||
if (!gotEncryptionKeys && signingKeyId == 0L) {
|
||||
Notify.create(getActivity(), R.string.select_encryption_or_signature_key, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
data.setEncryptionMasterKeyIds(encryptionKeyIds);
|
||||
data.setSignatureMasterKeyId(signingKeyId);
|
||||
} else {
|
||||
Passphrase passphrase = modeFragment.getSymmetricPassphrase();
|
||||
if (passphrase == null) {
|
||||
Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
}
|
||||
if (passphrase.isEmpty()) {
|
||||
passphrase = null;
|
||||
Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return null;
|
||||
}
|
||||
data.setSymmetricPassphrase(passphrase);
|
||||
} else {
|
||||
data.setEncryptionMasterKeyIds(mEncryptionKeyIds);
|
||||
data.setSignatureMasterKeyId(mSigningKeyId);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@ -273,9 +269,19 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
sendIntent.setType(Constants.ENCRYPTED_TEXT_MIME);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, new String(resultBytes));
|
||||
|
||||
if (!mSymmetricMode && mEncryptionUserIds != null) {
|
||||
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||
EncryptModeFragment modeFragment = modeInterface.getModeFragment();
|
||||
if (!modeFragment.isAsymmetric()) {
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
String[] encryptionUserIds = modeFragment.getAsymmetricEncryptionUserIds();
|
||||
if (encryptionUserIds == null) {
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
Set<String> users = new HashSet<>();
|
||||
for (String user : mEncryptionUserIds) {
|
||||
for (String user : encryptionUserIds) {
|
||||
KeyRing.UserId userId = KeyRing.splitUserId(user);
|
||||
if (userId.email != null) {
|
||||
users.add(userId.email);
|
||||
@ -283,55 +289,21 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
}
|
||||
// pass trough email addresses as extra for email applications
|
||||
sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()]));
|
||||
}
|
||||
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
protected boolean inputIsValid() {
|
||||
if (mMessage == null || mMessage.isEmpty()) {
|
||||
Notify.create(getActivity(), R.string.error_empty_text, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSymmetricMode) {
|
||||
// symmetric encryption checks
|
||||
|
||||
if (mSymmetricPassphrase == null) {
|
||||
Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
}
|
||||
if (mSymmetricPassphrase.isEmpty()) {
|
||||
Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// asymmetric encryption checks
|
||||
|
||||
boolean gotEncryptionKeys = (mEncryptionKeyIds != null
|
||||
&& mEncryptionKeyIds.length > 0);
|
||||
|
||||
if (!gotEncryptionKeys && mSigningKeyId == 0) {
|
||||
Notify.create(getActivity(), R.string.select_encryption_or_signature_key, Notify.Style.ERROR)
|
||||
.show(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void startEncrypt(boolean share) {
|
||||
public void cryptoOperation(boolean share) {
|
||||
mShareAfterEncrypt = share;
|
||||
cryptoOperation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
||||
if (!inputIsValid()) {
|
||||
|
||||
final SignEncryptParcel input = createEncryptBundle();
|
||||
// this is null if invalid, just return in that case
|
||||
if (input == null) {
|
||||
// Notify was created by inputIsValid.
|
||||
return;
|
||||
}
|
||||
@ -340,7 +312,6 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||
|
||||
final SignEncryptParcel input = createEncryptBundle();
|
||||
final Bundle data = new Bundle();
|
||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
|
@ -20,12 +20,14 @@ package org.sufficientlysecure.keychain.ui.widget;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.support.v7.widget.AppCompatSpinner;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
@ -42,17 +44,18 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Use AppCompatSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon.
|
||||
* Related: http://stackoverflow.com/a/27713090
|
||||
*/
|
||||
public abstract class KeySpinner extends AppCompatSpinner implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
public abstract class KeySpinner extends AppCompatSpinner implements
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
public static final String ARG_SUPER_STATE = "super_state";
|
||||
public static final String ARG_SELECTED_KEY_ID = "select_key_id";
|
||||
|
||||
public interface OnKeyChangedListener {
|
||||
public void onKeyChanged(long masterKeyId);
|
||||
void onKeyChanged(long masterKeyId);
|
||||
}
|
||||
|
||||
protected long mSelectedKeyId = Constants.key.none;
|
||||
@ -82,15 +85,17 @@ public abstract class KeySpinner extends AppCompatSpinner implements LoaderManag
|
||||
super.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
mSelectedKeyId = id;
|
||||
if (mListener != null) {
|
||||
mListener.onKeyChanged(id);
|
||||
mListener.onKeyChanged(mSelectedKeyId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
mSelectedKeyId = Constants.key.none;
|
||||
if (mListener != null) {
|
||||
mListener.onKeyChanged(Constants.key.none);
|
||||
mListener.onKeyChanged(mSelectedKeyId);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -138,7 +143,7 @@ public abstract class KeySpinner extends AppCompatSpinner implements LoaderManag
|
||||
}
|
||||
|
||||
public void setSelectedKeyId(long selectedKeyId) {
|
||||
this.mSelectedKeyId = selectedKeyId;
|
||||
mSelectedKeyId = selectedKeyId;
|
||||
}
|
||||
|
||||
protected class SelectKeyAdapter extends BaseAdapter implements SpinnerAdapter {
|
||||
|
Loading…
Reference in New Issue
Block a user