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[] mPubMasterKeyIds;
|
||||||
|
|
||||||
private long mSignMasterKeyId = Constants.key.none;
|
|
||||||
|
|
||||||
public static final String[] USER_IDS_PROJECTION = new String[]{
|
public static final String[] USER_IDS_PROJECTION = new String[]{
|
||||||
UserPackets._ID,
|
UserPackets._ID,
|
||||||
UserPackets.MASTER_KEY_ID,
|
UserPackets.MASTER_KEY_ID,
|
||||||
@ -149,19 +147,13 @@ public class CertifyKeyFragment extends CryptoOperationFragment
|
|||||||
vActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
|
vActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light),
|
||||||
PorterDuff.Mode.SRC_IN);
|
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);
|
View vCertifyButton = view.findViewById(R.id.certify_key_certify_button);
|
||||||
vCertifyButton.setOnClickListener(new OnClickListener() {
|
vCertifyButton.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
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.create(getActivity(), getString(R.string.select_key_to_certify),
|
||||||
Notify.Style.ERROR).show();
|
Notify.Style.ERROR).show();
|
||||||
} else {
|
} else {
|
||||||
@ -307,8 +299,10 @@ public class CertifyKeyFragment extends CryptoOperationFragment
|
|||||||
|
|
||||||
Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
{
|
{
|
||||||
|
long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId();
|
||||||
|
|
||||||
// fill values for this action
|
// fill values for this action
|
||||||
CertifyActionsParcel parcel = new CertifyActionsParcel(mSignMasterKeyId);
|
CertifyActionsParcel parcel = new CertifyActionsParcel(selectedKeyId);
|
||||||
parcel.mCertifyActions.addAll(certifyActions);
|
parcel.mCertifyActions.addAll(certifyActions);
|
||||||
|
|
||||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
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;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
||||||
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
|
||||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class EncryptFilesActivity extends BaseActivity implements
|
public class EncryptFilesActivity extends EncryptActivity {
|
||||||
EncryptModeAsymmetricFragment.IAsymmetric, EncryptModeSymmetricFragment.ISymmetric,
|
|
||||||
EncryptFilesFragment.IMode {
|
|
||||||
|
|
||||||
/* Intents */
|
// Intents
|
||||||
public static final String ACTION_ENCRYPT_DATA = OpenKeychainIntents.ENCRYPT_DATA;
|
public static final String ACTION_ENCRYPT_DATA = OpenKeychainIntents.ENCRYPT_DATA;
|
||||||
|
|
||||||
// enables ASCII Armor for file encryption when uri is given
|
// enables ASCII Armor for file encryption when uri is given
|
||||||
public static final String EXTRA_ASCII_ARMOR = OpenKeychainIntents.ENCRYPT_EXTRA_ASCII_ARMOR;
|
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
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -62,19 +48,7 @@ public class EncryptFilesActivity extends BaseActivity implements
|
|||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
// Handle intent actions
|
Intent intent = getIntent();
|
||||||
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) {
|
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
String type = intent.getType();
|
String type = intent.getType();
|
||||||
@ -88,10 +62,6 @@ public class EncryptFilesActivity extends BaseActivity implements
|
|||||||
uris.add(intent.getData());
|
uris.add(intent.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Android's Action
|
|
||||||
*/
|
|
||||||
|
|
||||||
// When sending to OpenKeychain Encrypt via share menu
|
// When sending to OpenKeychain Encrypt via share menu
|
||||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||||
// Files via content provider, override uri and action
|
// Files via content provider, override uri and action
|
||||||
@ -103,56 +73,21 @@ public class EncryptFilesActivity extends BaseActivity implements
|
|||||||
uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
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);
|
boolean useArmor = extras.getBoolean(EXTRA_ASCII_ARMOR, false);
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||||
|
|
||||||
mModeFragment = EncryptModeAsymmetricFragment.newInstance(mSigningKeyId, mEncryptionKeyIds);
|
EncryptFilesFragment encryptFragment = EncryptFilesFragment.newInstance(uris, useArmor);
|
||||||
transaction.replace(R.id.encrypt_mode_container, mModeFragment, "mode");
|
transaction.replace(R.id.encrypt_file_container, encryptFragment);
|
||||||
|
|
||||||
mEncryptFragment = EncryptFilesFragment.newInstance(uris, useArmor);
|
|
||||||
transaction.replace(R.id.encrypt_file_container, mEncryptFragment, "files");
|
|
||||||
|
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
getSupportFragmentManager().executePendingTransactions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onModeChanged(boolean symmetric) {
|
protected void initLayout() {
|
||||||
// switch fragments
|
setContentView(R.layout.encrypt_files_activity);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -72,19 +72,12 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class EncryptFilesFragment extends CryptoOperationFragment {
|
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_USE_ASCII_ARMOR = "use_ascii_armor";
|
||||||
public static final String ARG_URIS = "uris";
|
public static final String ARG_URIS = "uris";
|
||||||
|
|
||||||
private static final int REQUEST_CODE_INPUT = 0x00007003;
|
private static final int REQUEST_CODE_INPUT = 0x00007003;
|
||||||
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
||||||
|
|
||||||
private IMode mModeInterface;
|
|
||||||
|
|
||||||
private boolean mSymmetricMode = false;
|
|
||||||
private boolean mUseArmor = false;
|
private boolean mUseArmor = false;
|
||||||
private boolean mUseCompression = true;
|
private boolean mUseCompression = true;
|
||||||
private boolean mDeleteAfterEncrypt = false;
|
private boolean mDeleteAfterEncrypt = false;
|
||||||
@ -92,11 +85,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
private boolean mEncryptFilenames = true;
|
private boolean mEncryptFilenames = true;
|
||||||
private boolean mHiddenRecipients = false;
|
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 ArrayList<Uri> mOutputUris = new ArrayList<>();
|
||||||
|
|
||||||
private RecyclerView mSelectedFiles;
|
private RecyclerView mSelectedFiles;
|
||||||
@ -118,29 +106,11 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
return frag;
|
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
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
try {
|
if ( ! (activity instanceof EncryptActivity) ) {
|
||||||
mModeInterface = (IMode) activity;
|
throw new AssertionError(activity + " must inherit from EncryptionActivity");
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new ClassCastException(activity + " must be IMode");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,8 +263,8 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.check_use_symmetric: {
|
case R.id.check_use_symmetric: {
|
||||||
mSymmetricMode = item.isChecked();
|
EncryptActivity encryptActivity = (EncryptActivity) getActivity();
|
||||||
mModeInterface.onModeChanged(mSymmetricMode);
|
encryptActivity.toggleModeFragment();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.check_use_armor: {
|
case R.id.check_use_armor: {
|
||||||
@ -325,53 +295,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
return true;
|
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) {
|
public void onEncryptSuccess(final SignEncryptResult result) {
|
||||||
if (mDeleteAfterEncrypt) {
|
if (mDeleteAfterEncrypt) {
|
||||||
DeleteFileDialogFragment deleteFileDialog =
|
DeleteFileDialogFragment deleteFileDialog =
|
||||||
@ -403,6 +326,21 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected SignEncryptParcel createEncryptBundle() {
|
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
|
// fill values for this action
|
||||||
SignEncryptParcel data = new SignEncryptParcel();
|
SignEncryptParcel data = new SignEncryptParcel();
|
||||||
|
|
||||||
@ -419,17 +357,39 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||||
data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||||
|
|
||||||
if (mSymmetricMode) {
|
EncryptActivity encryptActivity = (EncryptActivity) getActivity();
|
||||||
Log.d(Constants.TAG, "Symmetric encryption enabled!");
|
EncryptModeFragment modeFragment = encryptActivity.getModeFragment();
|
||||||
Passphrase passphrase = mPassphrase;
|
|
||||||
|
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()) {
|
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);
|
data.setSymmetricPassphrase(passphrase);
|
||||||
} else {
|
|
||||||
data.setEncryptionMasterKeyIds(mEncryptionKeyIds);
|
|
||||||
data.setSignatureMasterKeyId(mSigningKeyId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,16 +421,27 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
}
|
}
|
||||||
sendIntent.setType(Constants.ENCRYPTED_FILES_MIME);
|
sendIntent.setType(Constants.ENCRYPTED_FILES_MIME);
|
||||||
|
|
||||||
if (!mSymmetricMode && mEncryptionUserIds != null) {
|
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||||
Set<String> users = new HashSet<>();
|
EncryptModeFragment modeFragment = modeInterface.getModeFragment();
|
||||||
for (String user : mEncryptionUserIds) {
|
if (!modeFragment.isAsymmetric()) {
|
||||||
KeyRing.UserId userId = KeyRing.splitUserId(user);
|
return sendIntent;
|
||||||
if (userId.email != null) {
|
|
||||||
users.add(userId.email);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] encryptionUserIds = modeFragment.getAsymmetricEncryptionUserIds();
|
||||||
|
if (encryptionUserIds == null) {
|
||||||
|
return sendIntent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> users = new HashSet<>();
|
||||||
|
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;
|
return sendIntent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,19 +453,17 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
@Override
|
@Override
|
||||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
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.
|
// Notify was created by inputIsValid.
|
||||||
Log.d(Constants.TAG, "Input not valid!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log.d(Constants.TAG, "Input valid!");
|
|
||||||
|
|
||||||
// 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 SignEncryptParcel input = createEncryptBundle();
|
|
||||||
|
|
||||||
Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
||||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||||
@ -727,7 +696,7 @@ public class EncryptFilesFragment extends CryptoOperationFragment {
|
|||||||
for (Uri inputUri : inputUris) {
|
for (Uri inputUri : inputUris) {
|
||||||
ViewModel newModel = new ViewModel(mActivity, inputUri);
|
ViewModel newModel = new ViewModel(mActivity, inputUri);
|
||||||
if (mDataset.contains(newModel)) {
|
if (mDataset.contains(newModel)) {
|
||||||
Log.e(Constants.TAG, "Skipped duplicate " + inputUri.toString());
|
Log.e(Constants.TAG, "Skipped duplicate " + inputUri);
|
||||||
} else {
|
} else {
|
||||||
mDataset.add(newModel);
|
mDataset.add(newModel);
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,13 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.tokenautocomplete.TokenCompleteTextView;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
|
|
||||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
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.EncryptKeyCompletionView;
|
||||||
import org.sufficientlysecure.keychain.ui.widget.KeySpinner;
|
import org.sufficientlysecure.keychain.ui.widget.KeySpinner;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class EncryptModeAsymmetricFragment extends Fragment {
|
public class EncryptModeAsymmetricFragment extends EncryptModeFragment {
|
||||||
|
|
||||||
public interface IAsymmetric {
|
|
||||||
|
|
||||||
public void onSignatureKeyIdChanged(long signatureKeyId);
|
|
||||||
|
|
||||||
public void onEncryptionKeyIdsChanged(long[] encryptionKeyIds);
|
|
||||||
|
|
||||||
public void onEncryptionUserIdsChanged(String[] encryptionUserIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProviderHelper mProviderHelper;
|
ProviderHelper mProviderHelper;
|
||||||
|
|
||||||
// view
|
private KeySpinner mSignKeySpinner;
|
||||||
private KeySpinner mSign;
|
|
||||||
private EncryptKeyCompletionView mEncryptKeyView;
|
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_SINGATURE_KEY_ID = "signature_key_id";
|
||||||
public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids";
|
public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids";
|
||||||
|
|
||||||
@ -89,16 +65,6 @@ public class EncryptModeAsymmetricFragment extends Fragment {
|
|||||||
return frag;
|
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
|
* Inflate the layout for this fragment
|
||||||
*/
|
*/
|
||||||
@ -106,13 +72,7 @@ public class EncryptModeAsymmetricFragment extends Fragment {
|
|||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false);
|
View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false);
|
||||||
|
|
||||||
mSign = (KeySpinner) view.findViewById(R.id.sign);
|
mSignKeySpinner = (KeySpinner) view.findViewById(R.id.sign);
|
||||||
mSign.setOnKeyChangedListener(new KeySpinner.OnKeyChangedListener() {
|
|
||||||
@Override
|
|
||||||
public void onKeyChanged(long masterKeyId) {
|
|
||||||
mEncryptInterface.onSignatureKeyIdChanged(masterKeyId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mEncryptKeyView = (EncryptKeyCompletionView) view.findViewById(R.id.recipient_list);
|
mEncryptKeyView = (EncryptKeyCompletionView) view.findViewById(R.id.recipient_list);
|
||||||
mEncryptKeyView.setThreshold(1); // Start working from first character
|
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 signatureKeyId = getArguments().getLong(ARG_SINGATURE_KEY_ID);
|
||||||
long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS);
|
long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS);
|
||||||
preselectKeys(signatureKeyId, encryptionKeyIds);
|
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(
|
CachedPublicKeyRing keyring = mProviderHelper.getCachedPublicKeyRing(
|
||||||
KeyRings.buildUnifiedKeyRingUri(signatureKeyId));
|
KeyRings.buildUnifiedKeyRingUri(signatureKeyId));
|
||||||
if (keyring.hasAnySecret()) {
|
if (keyring.hasAnySecret()) {
|
||||||
mEncryptInterface.onSignatureKeyIdChanged(keyring.getMasterKeyId());
|
mSignKeySpinner.setSelectedKeyId(signatureKeyId);
|
||||||
mSign.setSelectedKeyId(signatureKeyId);
|
|
||||||
}
|
}
|
||||||
} catch (PgpKeyNotFoundException e) {
|
} catch (PgpKeyNotFoundException e) {
|
||||||
Log.e(Constants.TAG, "key not found!", 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
|
// This is to work-around a rendering bug in TokenCompleteTextView
|
||||||
mEncryptKeyView.requestFocus();
|
mEncryptKeyView.requestFocus();
|
||||||
updateEncryptionKeys();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateEncryptionKeys() {
|
@Override
|
||||||
List<Object> objects = mEncryptKeyView.getObjects();
|
public boolean isAsymmetric() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getAsymmetricSigningKeyId() {
|
||||||
|
return mSignKeySpinner.getSelectedItemId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long[] getAsymmetricEncryptionKeyIds() {
|
||||||
List<Long> keyIds = new ArrayList<>();
|
List<Long> keyIds = new ArrayList<>();
|
||||||
List<String> userIds = new ArrayList<>();
|
for (Object object : mEncryptKeyView.getObjects()) {
|
||||||
for (Object object : objects) {
|
|
||||||
if (object instanceof KeyItem) {
|
if (object instanceof KeyItem) {
|
||||||
keyIds.add(((KeyItem) object).mKeyId);
|
keyIds.add(((KeyItem) object).mKeyId);
|
||||||
userIds.add(((KeyItem) object).mUserIdFull);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long[] keyIdsArr = new long[keyIds.size()];
|
long[] keyIdsArr = new long[keyIds.size()];
|
||||||
Iterator<Long> iterator = keyIds.iterator();
|
Iterator<Long> iterator = keyIds.iterator();
|
||||||
for (int i = 0; i < keyIds.size(); i++) {
|
for (int i = 0; i < keyIds.size(); i++) {
|
||||||
keyIdsArr[i] = iterator.next();
|
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;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.os.Bundle;
|
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.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -30,14 +26,7 @@ import android.widget.EditText;
|
|||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||||
|
|
||||||
public class EncryptModeSymmetricFragment extends Fragment {
|
public class EncryptModeSymmetricFragment extends EncryptModeFragment {
|
||||||
|
|
||||||
public interface ISymmetric {
|
|
||||||
|
|
||||||
public void onPassphraseChanged(Passphrase passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ISymmetric mEncryptInterface;
|
|
||||||
|
|
||||||
private EditText mPassphrase;
|
private EditText mPassphrase;
|
||||||
private EditText mPassphraseAgain;
|
private EditText mPassphraseAgain;
|
||||||
@ -54,53 +43,54 @@ public class EncryptModeSymmetricFragment extends Fragment {
|
|||||||
return frag;
|
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
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.encrypt_symmetric_fragment, container, false);
|
View view = inflater.inflate(R.layout.encrypt_symmetric_fragment, container, false);
|
||||||
|
|
||||||
mPassphrase = (EditText) view.findViewById(R.id.passphrase);
|
mPassphrase = (EditText) view.findViewById(R.id.passphrase);
|
||||||
mPassphraseAgain = (EditText) view.findViewById(R.id.passphraseAgain);
|
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;
|
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.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
|
||||||
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
|
||||||
|
|
||||||
public class EncryptTextActivity extends BaseActivity implements
|
public class EncryptTextActivity extends EncryptActivity {
|
||||||
EncryptModeAsymmetricFragment.IAsymmetric, EncryptModeSymmetricFragment.ISymmetric,
|
|
||||||
EncryptTextFragment.IMode {
|
|
||||||
|
|
||||||
/* Intents */
|
/* Intents */
|
||||||
public static final String ACTION_ENCRYPT_TEXT = OpenKeychainIntents.ENCRYPT_TEXT;
|
public static final String ACTION_ENCRYPT_TEXT = OpenKeychainIntents.ENCRYPT_TEXT;
|
||||||
@ -41,13 +35,6 @@ public class EncryptTextActivity extends BaseActivity implements
|
|||||||
/* EXTRA keys for input */
|
/* EXTRA keys for input */
|
||||||
public static final String EXTRA_TEXT = OpenKeychainIntents.ENCRYPT_EXTRA_TEXT;
|
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
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -89,23 +76,14 @@ public class EncryptTextActivity extends BaseActivity implements
|
|||||||
textData = "";
|
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) {
|
if (savedInstanceState == null) {
|
||||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||||
|
|
||||||
mModeFragment = EncryptModeAsymmetricFragment.newInstance(mSigningKeyId, mEncryptionKeyIds);
|
EncryptTextFragment encryptFragment = EncryptTextFragment.newInstance(textData);
|
||||||
transaction.replace(R.id.encrypt_mode_container, mModeFragment, "mode");
|
transaction.replace(R.id.encrypt_text_container, encryptFragment);
|
||||||
|
|
||||||
mEncryptFragment = EncryptTextFragment.newInstance(textData);
|
|
||||||
transaction.replace(R.id.encrypt_text_container, mEncryptFragment, "text");
|
|
||||||
|
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
getSupportFragmentManager().executePendingTransactions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -113,44 +91,4 @@ public class EncryptTextActivity extends BaseActivity implements
|
|||||||
setContentView(R.layout.encrypt_text_activity);
|
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.base.CryptoOperationFragment;
|
||||||
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.Log;
|
|
||||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||||
import org.sufficientlysecure.keychain.util.ShareHelper;
|
import org.sufficientlysecure.keychain.util.ShareHelper;
|
||||||
|
|
||||||
@ -56,44 +55,14 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class EncryptTextFragment extends CryptoOperationFragment {
|
public class EncryptTextFragment extends CryptoOperationFragment {
|
||||||
|
|
||||||
public interface IMode {
|
|
||||||
public void onModeChanged(boolean symmetric);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String ARG_TEXT = "text";
|
public static final String ARG_TEXT = "text";
|
||||||
|
|
||||||
private IMode mModeInterface;
|
|
||||||
|
|
||||||
private boolean mSymmetricMode = false;
|
|
||||||
private boolean mShareAfterEncrypt = false;
|
private boolean mShareAfterEncrypt = false;
|
||||||
private boolean mUseCompression = true;
|
private boolean mUseCompression = true;
|
||||||
private boolean mHiddenRecipients = false;
|
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 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
|
* Creates new instance of this fragment
|
||||||
*/
|
*/
|
||||||
@ -110,10 +79,8 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
try {
|
if ( ! (activity instanceof EncryptActivity) ) {
|
||||||
mModeInterface = (IMode) activity;
|
throw new AssertionError(activity + " must inherit from EncryptionActivity");
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new ClassCastException(activity.toString() + " must implement IMode");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,8 +91,8 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.encrypt_text_fragment, container, false);
|
View view = inflater.inflate(R.layout.encrypt_text_fragment, container, false);
|
||||||
|
|
||||||
mText = (TextView) view.findViewById(R.id.encrypt_text_text);
|
TextView textView = (TextView) view.findViewById(R.id.encrypt_text_text);
|
||||||
mText.addTextChangedListener(new TextWatcher() {
|
textView.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
@ -144,7 +111,7 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
|
|
||||||
// set initial text
|
// set initial text
|
||||||
if (mMessage != null) {
|
if (mMessage != null) {
|
||||||
mText.setText(mMessage);
|
textView.setText(mMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
@ -171,8 +138,8 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
}
|
}
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.check_use_symmetric: {
|
case R.id.check_use_symmetric: {
|
||||||
mSymmetricMode = item.isChecked();
|
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||||
mModeInterface.onModeChanged(mSymmetricMode);
|
modeInterface.toggleModeFragment();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.check_enable_compression: {
|
case R.id.check_enable_compression: {
|
||||||
@ -185,11 +152,11 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
case R.id.encrypt_copy: {
|
case R.id.encrypt_copy: {
|
||||||
startEncrypt(false);
|
cryptoOperation(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.encrypt_share: {
|
case R.id.encrypt_share: {
|
||||||
startEncrypt(true);
|
cryptoOperation(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -199,7 +166,6 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void onEncryptSuccess(SignEncryptResult result) {
|
protected void onEncryptSuccess(SignEncryptResult result) {
|
||||||
if (mShareAfterEncrypt) {
|
if (mShareAfterEncrypt) {
|
||||||
// Share encrypted message/file
|
// Share encrypted message/file
|
||||||
@ -215,6 +181,13 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected SignEncryptParcel createEncryptBundle() {
|
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
|
// fill values for this action
|
||||||
SignEncryptParcel data = new SignEncryptParcel();
|
SignEncryptParcel data = new SignEncryptParcel();
|
||||||
|
|
||||||
@ -227,22 +200,45 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED);
|
data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED);
|
||||||
}
|
}
|
||||||
data.setHiddenRecipients(mHiddenRecipients);
|
data.setHiddenRecipients(mHiddenRecipients);
|
||||||
data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
data.setSymmetricEncryptionAlgorithm(
|
||||||
data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||||
|
data.setSignatureHashAlgorithm(
|
||||||
|
PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED);
|
||||||
|
|
||||||
// Always use armor for messages
|
// Always use armor for messages
|
||||||
data.setEnableAsciiArmorOutput(true);
|
data.setEnableAsciiArmorOutput(true);
|
||||||
|
|
||||||
if (mSymmetricMode) {
|
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||||
Log.d(Constants.TAG, "Symmetric encryption enabled!");
|
EncryptModeFragment modeFragment = modeInterface.getModeFragment();
|
||||||
Passphrase passphrase = mSymmetricPassphrase;
|
|
||||||
|
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()) {
|
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);
|
data.setSymmetricPassphrase(passphrase);
|
||||||
} else {
|
|
||||||
data.setEncryptionMasterKeyIds(mEncryptionKeyIds);
|
|
||||||
data.setSignatureMasterKeyId(mSigningKeyId);
|
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -273,65 +269,41 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
sendIntent.setType(Constants.ENCRYPTED_TEXT_MIME);
|
sendIntent.setType(Constants.ENCRYPTED_TEXT_MIME);
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, new String(resultBytes));
|
sendIntent.putExtra(Intent.EXTRA_TEXT, new String(resultBytes));
|
||||||
|
|
||||||
if (!mSymmetricMode && mEncryptionUserIds != null) {
|
EncryptActivity modeInterface = (EncryptActivity) getActivity();
|
||||||
Set<String> users = new HashSet<>();
|
EncryptModeFragment modeFragment = modeInterface.getModeFragment();
|
||||||
for (String user : mEncryptionUserIds) {
|
if (!modeFragment.isAsymmetric()) {
|
||||||
KeyRing.UserId userId = KeyRing.splitUserId(user);
|
return sendIntent;
|
||||||
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()]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] encryptionUserIds = modeFragment.getAsymmetricEncryptionUserIds();
|
||||||
|
if (encryptionUserIds == null) {
|
||||||
|
return sendIntent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> users = new HashSet<>();
|
||||||
|
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;
|
return sendIntent;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean inputIsValid() {
|
public void cryptoOperation(boolean share) {
|
||||||
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) {
|
|
||||||
mShareAfterEncrypt = share;
|
mShareAfterEncrypt = share;
|
||||||
cryptoOperation();
|
cryptoOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
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.
|
// Notify was created by inputIsValid.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -340,7 +312,6 @@ public class EncryptTextFragment extends CryptoOperationFragment {
|
|||||||
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 SignEncryptParcel input = createEncryptBundle();
|
|
||||||
final Bundle data = new Bundle();
|
final Bundle data = new Bundle();
|
||||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input);
|
||||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||||
|
@ -20,12 +20,14 @@ package org.sufficientlysecure.keychain.ui.widget;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Color;
|
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.FragmentActivity;
|
||||||
import android.support.v4.app.LoaderManager;
|
import android.support.v4.app.LoaderManager;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.support.v4.widget.CursorAdapter;
|
import android.support.v4.widget.CursorAdapter;
|
||||||
import android.support.v7.widget.AppCompatSpinner;
|
import android.support.v7.widget.AppCompatSpinner;
|
||||||
import android.text.format.DateFormat;
|
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -42,17 +44,18 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
|
|||||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
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.
|
* Use AppCompatSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon.
|
||||||
* Related: http://stackoverflow.com/a/27713090
|
* 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 interface OnKeyChangedListener {
|
||||||
public void onKeyChanged(long masterKeyId);
|
void onKeyChanged(long masterKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long mSelectedKeyId = Constants.key.none;
|
protected long mSelectedKeyId = Constants.key.none;
|
||||||
@ -82,15 +85,17 @@ public abstract class KeySpinner extends AppCompatSpinner implements LoaderManag
|
|||||||
super.setOnItemSelectedListener(new OnItemSelectedListener() {
|
super.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
mSelectedKeyId = id;
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListener.onKeyChanged(id);
|
mListener.onKeyChanged(mSelectedKeyId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNothingSelected(AdapterView<?> parent) {
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
mSelectedKeyId = Constants.key.none;
|
||||||
if (mListener != null) {
|
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) {
|
public void setSelectedKeyId(long selectedKeyId) {
|
||||||
this.mSelectedKeyId = selectedKeyId;
|
mSelectedKeyId = selectedKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class SelectKeyAdapter extends BaseAdapter implements SpinnerAdapter {
|
protected class SelectKeyAdapter extends BaseAdapter implements SpinnerAdapter {
|
||||||
|
Loading…
Reference in New Issue
Block a user