mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-24 01:32:16 -05:00
Load of rework on EncryptActivity, still some TODOs
This commit is contained in:
parent
bc9922263c
commit
2913a78b18
@ -236,14 +236,19 @@ public class ContactHelper {
|
||||
}
|
||||
|
||||
public static Bitmap photoFromFingerprint(ContentResolver contentResolver, String fingerprint) {
|
||||
int rawContactId = findRawContactId(contentResolver, fingerprint);
|
||||
if (rawContactId == -1) return null;
|
||||
Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
|
||||
Uri contactUri = ContactsContract.RawContacts.getContactLookupUri(contentResolver, rawContactUri);
|
||||
InputStream photoInputStream =
|
||||
ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, contactUri);
|
||||
if (photoInputStream == null) return null;
|
||||
return BitmapFactory.decodeStream(photoInputStream);
|
||||
if (fingerprint == null) return null;
|
||||
try {
|
||||
int rawContactId = findRawContactId(contentResolver, fingerprint);
|
||||
if (rawContactId == -1) return null;
|
||||
Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
|
||||
Uri contactUri = ContactsContract.RawContacts.getContactLookupUri(contentResolver, rawContactUri);
|
||||
InputStream photoInputStream =
|
||||
ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, contactUri);
|
||||
if (photoInputStream == null) return null;
|
||||
return BitmapFactory.decodeStream(photoInputStream);
|
||||
} catch (Throwable ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,28 +18,38 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.PagerTabStrip;
|
||||
import android.support.v4.view.ViewPager;
|
||||
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.ViewGroup;
|
||||
import com.devspark.appmsg.AppMsg;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||
import org.sufficientlysecure.keychain.util.Choice;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class EncryptActivity extends DrawerActivity implements
|
||||
EncryptSymmetricFragment.OnSymmetricKeySelection,
|
||||
EncryptAsymmetricFragment.OnAsymmetricKeySelection,
|
||||
EncryptActivityInterface {
|
||||
public class EncryptActivity extends DrawerActivity implements EncryptActivityInterface {
|
||||
|
||||
/* Intents */
|
||||
public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT";
|
||||
@ -79,40 +89,25 @@ public class EncryptActivity extends DrawerActivity implements
|
||||
private long mEncryptionKeyIds[] = null;
|
||||
private String mEncryptionUserIds[] = null;
|
||||
private long mSigningKeyId = Constants.key.none;
|
||||
private String mPassphrase;
|
||||
private String mPassphraseAgain;
|
||||
private int mCurrentMode = PAGER_MODE_ASYMMETRIC;
|
||||
private String mPassphrase = "";
|
||||
private boolean mUseArmor;
|
||||
private boolean mDeleteAfterEncrypt = false;
|
||||
private boolean mShareAfterEncrypt = false;
|
||||
private ArrayList<Uri> mInputUris;
|
||||
private ArrayList<Uri> mOutputUris;
|
||||
private String mMessage;
|
||||
|
||||
@Override
|
||||
public void onSigningKeySelected(long signingKeyId) {
|
||||
mSigningKeyId = signingKeyId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEncryptionKeysSelected(long[] encryptionKeyIds) {
|
||||
mEncryptionKeyIds = encryptionKeyIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEncryptionUserSelected(String[] encryptionUserIds) {
|
||||
mEncryptionUserIds = encryptionUserIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPassphraseUpdate(String passphrase) {
|
||||
mPassphrase = passphrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPassphraseAgainUpdate(String passphrase) {
|
||||
mPassphraseAgain = passphrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModeSymmetric() {
|
||||
return PAGER_MODE_SYMMETRIC == mCurrentMode;
|
||||
return PAGER_MODE_SYMMETRIC == mViewPagerMode.getCurrentItem();
|
||||
}
|
||||
|
||||
public boolean isContentMessage() {
|
||||
return PAGER_CONTENT_MESSAGE == mViewPagerContent.getCurrentItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseArmor() {
|
||||
return mUseArmor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -131,23 +126,263 @@ public class EncryptActivity extends DrawerActivity implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassphrase() {
|
||||
return mPassphrase;
|
||||
public void setSignatureKey(long signatureKey) {
|
||||
mSigningKeyId = signatureKey;
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassphraseAgain() {
|
||||
return mPassphraseAgain;
|
||||
public void setEncryptionKeys(long[] encryptionKeys) {
|
||||
mEncryptionKeyIds = encryptionKeys;
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseArmor() {
|
||||
return mUseArmor;
|
||||
public void setEncryptionUsers(String[] encryptionUsers) {
|
||||
mEncryptionUserIds = encryptionUsers;
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleteAfterEncrypt() {
|
||||
return mDeleteAfterEncrypt;
|
||||
public void setPassphrase(String passphrase) {
|
||||
mPassphrase = passphrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<Uri> getInputUris() {
|
||||
if (mInputUris == null) mInputUris = new ArrayList<Uri>();
|
||||
return mInputUris;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<Uri> getOutputUris() {
|
||||
if (mOutputUris == null) mOutputUris = new ArrayList<Uri>();
|
||||
return mOutputUris;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputUris(ArrayList<Uri> uris) {
|
||||
mInputUris = uris;
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOutputUris(ArrayList<Uri> uris) {
|
||||
mOutputUris = uris;
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return mMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessage(String message) {
|
||||
mMessage = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyUpdate() {
|
||||
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
|
||||
if (fragment instanceof EncryptActivityInterface.UpdateListener) {
|
||||
((UpdateListener) fragment).onNotifyUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startEncrypt(boolean share) {
|
||||
mShareAfterEncrypt = share;
|
||||
startEncrypt();
|
||||
}
|
||||
|
||||
public void startEncrypt() {
|
||||
if (!inputIsValid()) {
|
||||
// AppMsg was created by inputIsValid.
|
||||
return;
|
||||
}
|
||||
|
||||
// Send all information needed to service to edit key in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, createEncryptBundle());
|
||||
|
||||
// Message is received after encrypting is done in KeychainIntentService
|
||||
KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler(this,
|
||||
getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
||||
AppMsg.makeText(EncryptActivity.this, R.string.encrypt_sign_successful, AppMsg.STYLE_INFO).show();
|
||||
|
||||
if (!isContentMessage() && mDeleteAfterEncrypt) {
|
||||
// TODO: Create and show dialog to delete original file
|
||||
//DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment.newInstance(mInputUri);
|
||||
//deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog");
|
||||
//setInputUri(null);
|
||||
}
|
||||
|
||||
if (mShareAfterEncrypt) {
|
||||
// Share encrypted file
|
||||
startActivity(Intent.createChooser(createSendIntent(message), getString(R.string.title_share_file)));
|
||||
} else if (isContentMessage()) {
|
||||
// Copy to clipboard
|
||||
copyToClipboard(message);
|
||||
AppMsg.makeText(EncryptActivity.this,
|
||||
R.string.encrypt_sign_clipboard_successful, AppMsg.STYLE_INFO).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(this);
|
||||
|
||||
// start service with intent
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
private Bundle createEncryptBundle() {
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
if (isContentMessage()) {
|
||||
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
|
||||
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, mMessage.getBytes());
|
||||
} else {
|
||||
data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URIS);
|
||||
data.putParcelableArrayList(KeychainIntentService.ENCRYPT_INPUT_URIS, mInputUris);
|
||||
|
||||
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URIS);
|
||||
data.putParcelableArrayList(KeychainIntentService.ENCRYPT_OUTPUT_URIS, mOutputUris);
|
||||
}
|
||||
|
||||
// Always use armor for messages
|
||||
data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, mUseArmor || isContentMessage());
|
||||
|
||||
// TODO: Only default compression right now...
|
||||
int compressionId = Preferences.getPreferences(this).getDefaultMessageCompression();
|
||||
data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
|
||||
|
||||
if (isModeSymmetric()) {
|
||||
Log.d(Constants.TAG, "Symmetric encryption enabled!");
|
||||
String passphrase = mPassphrase;
|
||||
if (passphrase.length() == 0) {
|
||||
passphrase = null;
|
||||
}
|
||||
data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
|
||||
} else {
|
||||
data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID, mSigningKeyId);
|
||||
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS, mEncryptionKeyIds);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private void copyToClipboard(Message message) {
|
||||
ClipboardReflection.copyToClipboard(this, new String(message.getData().getByteArray(KeychainIntentService.RESULT_BYTES)));
|
||||
}
|
||||
|
||||
private Intent createSendIntent(Message message) {
|
||||
Intent sendIntent;
|
||||
if (isContentMessage()) {
|
||||
sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
sendIntent.setType("text/plain");
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, new String(message.getData().getByteArray(KeychainIntentService.RESULT_BYTES)));
|
||||
} else {
|
||||
// file
|
||||
if (mOutputUris.size() == 1) {
|
||||
sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
sendIntent.setType("*/*");
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, mOutputUris.get(0));
|
||||
} else {
|
||||
sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
|
||||
sendIntent.setType("*/*");
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, mOutputUris);
|
||||
}
|
||||
}
|
||||
if (!isModeSymmetric() && mEncryptionUserIds != null) {
|
||||
Set<String> users = new HashSet<String>();
|
||||
for (String user : mEncryptionUserIds) {
|
||||
String[] userId = KeyRing.splitUserId(user);
|
||||
if (userId[1] != null) {
|
||||
users.add(userId[1]);
|
||||
}
|
||||
}
|
||||
sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()]));
|
||||
}
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
private boolean inputIsValid() {
|
||||
if (!isContentMessage()) {
|
||||
// file checks
|
||||
|
||||
if (mInputUris.isEmpty()) {
|
||||
AppMsg.makeText(this, R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
|
||||
return false;
|
||||
} else if (mInputUris.size() > 1 && !mShareAfterEncrypt) {
|
||||
AppMsg.makeText(this, "TODO", AppMsg.STYLE_ALERT).show(); // TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mInputUris.size() != mOutputUris.size()) {
|
||||
throw new IllegalStateException("Something went terribly wrong if this happens!");
|
||||
}
|
||||
}
|
||||
|
||||
if (isModeSymmetric()) {
|
||||
// symmetric encryption checks
|
||||
|
||||
|
||||
if (mPassphrase == null) {
|
||||
AppMsg.makeText(this, R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
|
||||
return false;
|
||||
}
|
||||
if (mPassphrase.isEmpty()) {
|
||||
AppMsg.makeText(this, R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT).show();
|
||||
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 && !isContentMessage()) {
|
||||
AppMsg.makeText(this, R.string.select_encryption_key, AppMsg.STYLE_ALERT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gotEncryptionKeys && mSigningKeyId == 0) {
|
||||
AppMsg.makeText(this, R.string.select_encryption_or_signature_key,
|
||||
AppMsg.STYLE_ALERT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mSigningKeyId != 0 && PassphraseCacheService.getCachedPassphrase(this, mSigningKeyId) == null) {
|
||||
PassphraseDialogFragment.show(this, mSigningKeyId,
|
||||
new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||
// restart
|
||||
startEncrypt();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
@ -211,12 +446,15 @@ public class EncryptActivity extends DrawerActivity implements
|
||||
case R.id.check_use_symmetric:
|
||||
mSwitchToMode = item.isChecked() ? PAGER_MODE_SYMMETRIC : PAGER_MODE_ASYMMETRIC;
|
||||
mViewPagerMode.setCurrentItem(mSwitchToMode);
|
||||
notifyUpdate();
|
||||
break;
|
||||
case R.id.check_use_armor:
|
||||
mUseArmor = item.isChecked();
|
||||
notifyUpdate();
|
||||
break;
|
||||
case R.id.check_delete_after_encrypt:
|
||||
mDeleteAfterEncrypt = item.isChecked();
|
||||
notifyUpdate();
|
||||
break;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
@ -17,17 +17,41 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface EncryptActivityInterface {
|
||||
|
||||
public boolean isModeSymmetric();
|
||||
public interface UpdateListener {
|
||||
void onNotifyUpdate();
|
||||
}
|
||||
|
||||
public boolean isUseArmor();
|
||||
|
||||
public long getSignatureKey();
|
||||
public long[] getEncryptionKeys();
|
||||
public String[] getEncryptionUsers();
|
||||
public void setSignatureKey(long signatureKey);
|
||||
public void setEncryptionKeys(long[] encryptionKeys);
|
||||
public void setEncryptionUsers(String[] encryptionUsers);
|
||||
|
||||
public String getPassphrase();
|
||||
public String getPassphraseAgain();
|
||||
public void setPassphrase(String passphrase);
|
||||
|
||||
boolean isUseArmor();
|
||||
boolean isDeleteAfterEncrypt();
|
||||
// ArrayList on purpose as only those are parcelable
|
||||
public ArrayList<Uri> getInputUris();
|
||||
public ArrayList<Uri> getOutputUris();
|
||||
public void setInputUris(ArrayList<Uri> uris);
|
||||
public void setOutputUris(ArrayList<Uri> uris);
|
||||
|
||||
public String getMessage();
|
||||
public void setMessage(String message);
|
||||
|
||||
/**
|
||||
* Call this to notify the UI for changes done on the array lists or arrays,
|
||||
* automatically called if setter is used
|
||||
*/
|
||||
public void notifyUpdate();
|
||||
|
||||
public void startEncrypt(boolean share);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@ -26,14 +26,15 @@ import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.*;
|
||||
|
||||
import com.tokenautocomplete.TokenCompleteTextView;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
@ -42,9 +43,13 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.ui.widget.EncryptKeyCompletionView;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class EncryptAsymmetricFragment extends Fragment implements EncryptActivityInterface.UpdateListener {
|
||||
private static final String SIGN_KEY_SELECTION = KeyRings.CAN_SIGN + " = 1 AND " + KeyRings.IS_REVOKED + " = 0";
|
||||
|
||||
public class EncryptAsymmetricFragment extends Fragment {
|
||||
public static final String ARG_SIGNATURE_KEY_ID = "signature_key_id";
|
||||
public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids";
|
||||
|
||||
@ -53,55 +58,39 @@ public class EncryptAsymmetricFragment extends Fragment {
|
||||
|
||||
ProviderHelper mProviderHelper;
|
||||
|
||||
OnAsymmetricKeySelection mKeySelectionListener;
|
||||
|
||||
// view
|
||||
private CheckBox mSign;
|
||||
private Spinner mSign;
|
||||
private EncryptKeyCompletionView mEncryptKeyView;
|
||||
private SelectSignKeyCursorAdapter mSignAdapter = new SelectSignKeyCursorAdapter();
|
||||
|
||||
// model
|
||||
private long mSecretKeyId = Constants.key.none;
|
||||
private long mEncryptionKeyIds[] = null;
|
||||
private String mEncryptionUserIds[] = null;
|
||||
private EncryptActivityInterface mEncryptInterface;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnAsymmetricKeySelection {
|
||||
public void onSigningKeySelected(long signingKeyId);
|
||||
@Override
|
||||
public void onNotifyUpdate() {
|
||||
|
||||
public void onEncryptionKeysSelected(long[] encryptionKeyIds);
|
||||
|
||||
public void onEncryptionUserSelected(String[] encryptionUserIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mKeySelectionListener = (OnAsymmetricKeySelection) activity;
|
||||
mEncryptInterface = (EncryptActivityInterface) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnAsymmetricKeySelection");
|
||||
throw new ClassCastException(activity.toString() + " must implement EncryptActivityInterface");
|
||||
}
|
||||
}
|
||||
|
||||
private void setSignatureKeyId(long signatureKeyId) {
|
||||
mSecretKeyId = signatureKeyId;
|
||||
// update key selection in EncryptActivity
|
||||
mKeySelectionListener.onSigningKeySelected(signatureKeyId);
|
||||
updateView();
|
||||
mEncryptInterface.setSignatureKey(signatureKeyId);
|
||||
}
|
||||
|
||||
private void setEncryptionKeyIds(long[] encryptionKeyIds) {
|
||||
mEncryptionKeyIds = encryptionKeyIds;
|
||||
// update key selection in EncryptActivity
|
||||
mKeySelectionListener.onEncryptionKeysSelected(encryptionKeyIds);
|
||||
updateView();
|
||||
mEncryptInterface.setEncryptionKeys(encryptionKeyIds);
|
||||
}
|
||||
|
||||
private void setEncryptionUserIds(String[] encryptionUserIds) {
|
||||
mEncryptionUserIds = encryptionUserIds;
|
||||
// update key selection in EncryptActivity
|
||||
mKeySelectionListener.onEncryptionUserSelected(encryptionUserIds);
|
||||
updateView();
|
||||
mEncryptInterface.setEncryptionUsers(encryptionUserIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,15 +100,17 @@ public class EncryptAsymmetricFragment extends Fragment {
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false);
|
||||
|
||||
mSign = (CheckBox) view.findViewById(R.id.sign);
|
||||
mSign.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
CheckBox checkBox = (CheckBox) v;
|
||||
if (checkBox.isChecked()) {
|
||||
selectSecretKey();
|
||||
} else {
|
||||
setSignatureKeyId(Constants.key.none);
|
||||
}
|
||||
mSign = (Spinner) view.findViewById(R.id.sign);
|
||||
mSign.setAdapter(mSignAdapter);
|
||||
mSign.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
setSignatureKeyId(parent.getAdapter().getItemId(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
setSignatureKeyId(Constants.key.none);
|
||||
}
|
||||
});
|
||||
mEncryptKeyView = (EncryptKeyCompletionView) view.findViewById(R.id.recipient_list);
|
||||
@ -136,6 +127,11 @@ public class EncryptAsymmetricFragment extends Fragment {
|
||||
|
||||
mProviderHelper = new ProviderHelper(getActivity());
|
||||
|
||||
// preselect keys given by arguments (given by Intent to EncryptActivity)
|
||||
preselectKeys(signatureKeyId, encryptionKeyIds, mProviderHelper);
|
||||
|
||||
// TODO: Move this into widget!
|
||||
|
||||
getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
@ -146,12 +142,55 @@ public class EncryptAsymmetricFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||
mEncryptKeyView.fromCursor(data);
|
||||
mEncryptKeyView.swapCursor(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
mEncryptKeyView.fromCursor(null);
|
||||
mEncryptKeyView.swapCursor(null);
|
||||
}
|
||||
});
|
||||
getLoaderManager().initLoader(1, null, new LoaderManager.LoaderCallbacks<Cursor>() {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
// This is called when a new Loader needs to be created. This
|
||||
// sample only has one Loader, so we don't care about the ID.
|
||||
Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
|
||||
|
||||
// These are the rows that we will retrieve.
|
||||
String[] projection = new String[]{
|
||||
KeyRings._ID,
|
||||
KeyRings.MASTER_KEY_ID,
|
||||
KeyRings.KEY_ID,
|
||||
KeyRings.USER_ID,
|
||||
KeyRings.EXPIRY,
|
||||
KeyRings.IS_REVOKED,
|
||||
// can certify info only related to master key
|
||||
KeyRings.CAN_CERTIFY,
|
||||
// has sign may be any subkey
|
||||
KeyRings.HAS_SIGN,
|
||||
KeyRings.HAS_ANY_SECRET,
|
||||
KeyRings.HAS_SECRET
|
||||
};
|
||||
|
||||
String where = KeyRings.HAS_ANY_SECRET + " = 1";
|
||||
|
||||
// Now create and return a CursorLoader that will take care of
|
||||
// creating a Cursor for the data being displayed.
|
||||
return new CursorLoader(getActivity(), baseUri, projection, where, null, null);
|
||||
/*return new CursorLoader(getActivity(), KeyRings.buildUnifiedKeyRingsUri(),
|
||||
new String[]{KeyRings.USER_ID, KeyRings.KEY_ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET}, SIGN_KEY_SELECTION,
|
||||
null, null);*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||
mSignAdapter.swapCursor(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
mSignAdapter.swapCursor(null);
|
||||
}
|
||||
});
|
||||
mEncryptKeyView.setTokenListener(new TokenCompleteTextView.TokenListener() {
|
||||
@ -169,9 +208,6 @@ public class EncryptAsymmetricFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// preselect keys given by arguments (given by Intent to EncryptActivity)
|
||||
preselectKeys(signatureKeyId, encryptionKeyIds, mProviderHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,42 +247,6 @@ public class EncryptAsymmetricFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateView() {
|
||||
/*if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) {
|
||||
mSelectKeysButton.setText(getString(R.string.select_keys_button_default));
|
||||
} else {
|
||||
mSelectKeysButton.setText(getResources().getQuantityString(
|
||||
R.plurals.select_keys_button, mEncryptionKeyIds.length,
|
||||
mEncryptionKeyIds.length));
|
||||
}*/
|
||||
|
||||
/*
|
||||
if (mSecretKeyId == Constants.key.none) {
|
||||
mSign.setChecked(false);
|
||||
} else {
|
||||
// See if we can get a user_id from a unified query
|
||||
String[] userId;
|
||||
try {
|
||||
userId = mProviderHelper.getCachedPublicKeyRing(
|
||||
KeyRings.buildUnifiedKeyRingUri(mSecretKeyId)).getSplitPrimaryUserId();
|
||||
} catch (PgpGeneralException e) {
|
||||
userId = null;
|
||||
}
|
||||
if (userId != null && userId[0] != null) {
|
||||
mMainUserId.setText(userId[0]);
|
||||
} else {
|
||||
mMainUserId.setText(getResources().getString(R.string.user_id_no_name));
|
||||
}
|
||||
if (userId != null && userId[1] != null) {
|
||||
mMainUserIdRest.setText(userId[1]);
|
||||
} else {
|
||||
mMainUserIdRest.setText("");
|
||||
}
|
||||
mSign.setChecked(true);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void updateEncryptionKeys() {
|
||||
List<Object> objects = mEncryptKeyView.getObjects();
|
||||
List<Long> keyIds = new ArrayList<Long>();
|
||||
@ -266,58 +266,81 @@ public class EncryptAsymmetricFragment extends Fragment {
|
||||
setEncryptionUserIds(userIds.toArray(new String[userIds.size()]));
|
||||
}
|
||||
|
||||
private void selectPublicKeys() {
|
||||
Intent intent = new Intent(getActivity(), SelectPublicKeyActivity.class);
|
||||
Vector<Long> keyIds = new Vector<Long>();
|
||||
if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) {
|
||||
for (int i = 0; i < mEncryptionKeyIds.length; ++i) {
|
||||
keyIds.add(mEncryptionKeyIds[i]);
|
||||
}
|
||||
}
|
||||
long[] initialKeyIds = null;
|
||||
if (keyIds.size() > 0) {
|
||||
initialKeyIds = new long[keyIds.size()];
|
||||
for (int i = 0; i < keyIds.size(); ++i) {
|
||||
initialKeyIds[i] = keyIds.get(i);
|
||||
}
|
||||
}
|
||||
intent.putExtra(SelectPublicKeyActivity.EXTRA_SELECTED_MASTER_KEY_IDS, initialKeyIds);
|
||||
startActivityForResult(intent, REQUEST_CODE_PUBLIC_KEYS);
|
||||
}
|
||||
private class SelectSignKeyCursorAdapter extends BaseAdapter implements SpinnerAdapter {
|
||||
private CursorAdapter inner;
|
||||
private int mIndexUserId;
|
||||
private int mIndexKeyId;
|
||||
private int mIndexMasterKeyId;
|
||||
|
||||
private void selectSecretKey() {
|
||||
Intent intent = new Intent(getActivity(), SelectSecretKeyActivity.class);
|
||||
intent.putExtra(SelectSecretKeyActivity.EXTRA_FILTER_SIGN, true);
|
||||
startActivityForResult(intent, REQUEST_CODE_SECRET_KEYS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_PUBLIC_KEYS: {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Bundle bundle = data.getExtras();
|
||||
setEncryptionKeyIds(bundle
|
||||
.getLongArray(SelectPublicKeyActivity.RESULT_EXTRA_MASTER_KEY_IDS));
|
||||
setEncryptionUserIds(bundle.getStringArray(SelectPublicKeyActivity.RESULT_EXTRA_USER_IDS));
|
||||
public SelectSignKeyCursorAdapter() {
|
||||
inner = new CursorAdapter(null, null, 0) {
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
return getActivity().getLayoutInflater().inflate(R.layout.encrypt_asymmetric_signkey, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case REQUEST_CODE_SECRET_KEYS: {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Uri uriMasterKey = data.getData();
|
||||
setSignatureKeyId(Long.valueOf(uriMasterKey.getLastPathSegment()));
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
((TextView) view.findViewById(android.R.id.text1)).setText(cursor.getString(mIndexUserId));
|
||||
view.findViewById(android.R.id.text2).setVisibility(View.VISIBLE);
|
||||
((TextView) view.findViewById(android.R.id.text2)).setText(PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
mCursor.moveToPosition(position);
|
||||
return mCursor.getLong(mIndexMasterKeyId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Cursor swapCursor(Cursor newCursor) {
|
||||
if (newCursor == null) return inner.swapCursor(null);
|
||||
|
||||
mIndexKeyId = newCursor.getColumnIndex(KeyRings.KEY_ID);
|
||||
mIndexUserId = newCursor.getColumnIndex(KeyRings.USER_ID);
|
||||
mIndexMasterKeyId = newCursor.getColumnIndex(KeyRings.MASTER_KEY_ID);
|
||||
if (newCursor.moveToFirst()) {
|
||||
do {
|
||||
if (newCursor.getLong(mIndexMasterKeyId) == mEncryptInterface.getSignatureKey()) {
|
||||
mSign.setSelection(newCursor.getPosition() + 1);
|
||||
}
|
||||
} while (newCursor.moveToNext());
|
||||
}
|
||||
return inner.swapCursor(newCursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return inner.getCount() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
if (position == 0) return null;
|
||||
return inner.getItem(position - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (position == 0) return Constants.key.none;
|
||||
return inner.getItemId(position - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (position == 0) {
|
||||
View v;
|
||||
if (convertView == null) {
|
||||
v = inner.newView(null, null, parent);
|
||||
} else {
|
||||
setSignatureKeyId(Constants.key.none);
|
||||
v = convertView;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
break;
|
||||
((TextView) v.findViewById(android.R.id.text1)).setText("None");
|
||||
v.findViewById(android.R.id.text2).setVisibility(View.GONE);
|
||||
return v;
|
||||
} else {
|
||||
return inner.getView(position - 1, convertView, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,44 +18,28 @@
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Point;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.*;
|
||||
|
||||
import com.devspark.appmsg.AppMsg;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
|
||||
import org.sufficientlysecure.keychain.helper.FileHelper;
|
||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
|
||||
import org.sufficientlysecure.keychain.util.Choice;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class EncryptFileFragment extends Fragment {
|
||||
public class EncryptFileFragment extends Fragment implements EncryptActivityInterface.UpdateListener {
|
||||
public static final String ARG_URIS = "uris";
|
||||
|
||||
private static final int REQUEST_CODE_INPUT = 0x00007003;
|
||||
@ -64,15 +48,11 @@ public class EncryptFileFragment extends Fragment {
|
||||
private EncryptActivityInterface mEncryptInterface;
|
||||
|
||||
// view
|
||||
private Spinner mFileCompression = null;
|
||||
private View mAddView;
|
||||
private View mShareFile;
|
||||
private View mEncryptFile;
|
||||
private SelectedFilesAdapter mAdapter = new SelectedFilesAdapter();
|
||||
|
||||
// model
|
||||
private ArrayList<Uri> mInputUri = new ArrayList<Uri>();
|
||||
private ArrayList<Uri> mOutputUri = new ArrayList<Uri>();
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
@ -105,34 +85,23 @@ public class EncryptFileFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
//mFilename = (TextView) view.findViewById(R.id.filename);
|
||||
//view.findViewById(R.id.btn_browse).setOnClickListener(new View.OnClickListener() {
|
||||
// public void onClick(View v) {
|
||||
// if (Constants.KITKAT) {
|
||||
// FileHelper.openDocument(EncryptFileFragment.this, "*/*", REQUEST_CODE_INPUT);
|
||||
// } else {
|
||||
// FileHelper.openFile(EncryptFileFragment.this,
|
||||
// mInputUri.isEmpty() ? null : mInputUri.get(mInputUri.size() - 1), "*/*", REQUEST_CODE_INPUT);
|
||||
// }
|
||||
// }
|
||||
//});
|
||||
|
||||
View addFile = inflater.inflate(R.layout.file_list_entry_add, null);
|
||||
addFile.setOnClickListener(new View.OnClickListener() {
|
||||
mAddView = inflater.inflate(R.layout.file_list_entry_add, null);
|
||||
mAddView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (Constants.KITKAT) {
|
||||
FileHelper.openDocument(EncryptFileFragment.this, "*/*", REQUEST_CODE_INPUT);
|
||||
} else {
|
||||
FileHelper.openFile(EncryptFileFragment.this,
|
||||
mInputUri.isEmpty() ? null : mInputUri.get(mInputUri.size() - 1), "*/*", REQUEST_CODE_INPUT);
|
||||
mEncryptInterface.getInputUris().isEmpty() ? null : mEncryptInterface.getInputUris().get(mEncryptInterface.getInputUris().size() - 1), "*/*", REQUEST_CODE_INPUT);
|
||||
}
|
||||
}
|
||||
});
|
||||
ListView listView = (ListView) view.findViewById(R.id.selected_files_list);
|
||||
listView.addFooterView(addFile);
|
||||
listView.addFooterView(mAddView);
|
||||
listView.setAdapter(mAdapter);
|
||||
|
||||
/*
|
||||
mFileCompression = (Spinner) view.findViewById(R.id.fileCompression);
|
||||
Choice[] choices = new Choice[]{
|
||||
new Choice(Constants.choice.compression.none, getString(R.string.choice_none) + " ("
|
||||
@ -149,6 +118,7 @@ public class EncryptFileFragment extends Fragment {
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
mFileCompression.setAdapter(adapter);
|
||||
|
||||
|
||||
int defaultFileCompression = Preferences.getPreferences(getActivity()).getDefaultFileCompression();
|
||||
for (int i = 0; i < choices.length; ++i) {
|
||||
if (choices[i].getId() == defaultFileCompression) {
|
||||
@ -156,6 +126,7 @@ public class EncryptFileFragment extends Fragment {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return view;
|
||||
}
|
||||
@ -180,20 +151,39 @@ public class EncryptFileFragment extends Fragment {
|
||||
return;
|
||||
}
|
||||
|
||||
mInputUri.add(inputUri);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
mEncryptInterface.getInputUris().add(inputUri);
|
||||
mEncryptInterface.notifyUpdate();
|
||||
|
||||
/**
|
||||
* We hide the encrypt to file button if multiple files are selected.
|
||||
*
|
||||
* With Android L it will be possible to select a target directory for multiple files, so we might want to
|
||||
* change this later
|
||||
*/
|
||||
|
||||
if (mEncryptInterface.getInputUris().size() > 1) {
|
||||
mEncryptFile.setVisibility(View.GONE);
|
||||
} else {
|
||||
mEncryptFile.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void delInputUri(int position) {
|
||||
mInputUri.remove(position);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
mEncryptInterface.getInputUris().remove(position);
|
||||
mEncryptInterface.notifyUpdate();
|
||||
|
||||
if (mEncryptInterface.getInputUris().size() > 1) {
|
||||
mEncryptFile.setVisibility(View.GONE);
|
||||
} else {
|
||||
mEncryptFile.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void showOutputFileDialog() {
|
||||
if (mInputUri.size() > 1 || mInputUri.isEmpty()) {
|
||||
if (mEncryptInterface.getInputUris().size() > 1 || mEncryptInterface.getInputUris().isEmpty()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
Uri inputUri = mInputUri.get(0);
|
||||
Uri inputUri = mEncryptInterface.getInputUris().get(0);
|
||||
if (!Constants.KITKAT) {
|
||||
File file = new File(inputUri.getPath());
|
||||
File parentDir = file.exists() ? file.getParentFile() : Constants.Path.APP_DIR;
|
||||
@ -209,176 +199,19 @@ public class EncryptFileFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void encryptClicked(boolean share) {
|
||||
if (mInputUri.isEmpty()) {
|
||||
AppMsg.makeText(getActivity(), R.string.no_file_selected, AppMsg.STYLE_ALERT).show();
|
||||
return;
|
||||
} else if (mInputUri.size() > 1 && !share) {
|
||||
AppMsg.makeText(getActivity(), "TODO", AppMsg.STYLE_ALERT).show(); // TODO
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEncryptInterface.isModeSymmetric()) {
|
||||
// symmetric encryption
|
||||
|
||||
boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null
|
||||
&& mEncryptInterface.getPassphrase().length() != 0);
|
||||
if (!gotPassphrase) {
|
||||
AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
|
||||
AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// asymmetric encryption
|
||||
|
||||
boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null
|
||||
&& mEncryptInterface.getEncryptionKeys().length > 0);
|
||||
|
||||
if (!gotEncryptionKeys) {
|
||||
AppMsg.makeText(getActivity(), R.string.select_encryption_key, AppMsg.STYLE_ALERT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
|
||||
AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
|
||||
AppMsg.STYLE_ALERT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEncryptInterface.getSignatureKey() != 0 &&
|
||||
PassphraseCacheService.getCachedPassphrase(getActivity(),
|
||||
mEncryptInterface.getSignatureKey()) == null) {
|
||||
PassphraseDialogFragment.show(getActivity(), mEncryptInterface.getSignatureKey(),
|
||||
new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||
showOutputFileDialog();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (share) {
|
||||
mOutputUri.clear();
|
||||
for (Uri uri : mInputUri) {
|
||||
mEncryptInterface.getOutputUris().clear();
|
||||
for (Uri uri : mEncryptInterface.getInputUris()) {
|
||||
String targetName = FileHelper.getFilename(getActivity(), uri) +
|
||||
(mEncryptInterface.isUseArmor() ? ".asc" : ".gpg");
|
||||
mOutputUri.add(TemporaryStorageProvider.createFile(getActivity(), targetName));
|
||||
mEncryptInterface.getOutputUris().add(TemporaryStorageProvider.createFile(getActivity(), targetName));
|
||||
}
|
||||
encryptStart(true);
|
||||
} else if (mInputUri.size() == 1) {
|
||||
mEncryptInterface.startEncrypt(share);
|
||||
} else if (mEncryptInterface.getInputUris().size() == 1) {
|
||||
showOutputFileDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private void encryptStart(final boolean share) {
|
||||
if (mInputUri == null || mOutputUri == null || mInputUri.size() != mOutputUri.size()) {
|
||||
throw new IllegalStateException("Something went terribly wrong if this happens!");
|
||||
}
|
||||
|
||||
// Send all information needed to service to edit key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
Log.d(Constants.TAG, "mInputUri=" + mInputUri + ", mOutputUri=" + mOutputUri);
|
||||
|
||||
data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URIS);
|
||||
data.putParcelableArrayList(KeychainIntentService.ENCRYPT_INPUT_URIS, mInputUri);
|
||||
|
||||
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URIS);
|
||||
data.putParcelableArrayList(KeychainIntentService.ENCRYPT_OUTPUT_URIS, mOutputUri);
|
||||
|
||||
if (mEncryptInterface.isModeSymmetric()) {
|
||||
Log.d(Constants.TAG, "Symmetric encryption enabled!");
|
||||
String passphrase = mEncryptInterface.getPassphrase();
|
||||
if (passphrase.length() == 0) {
|
||||
passphrase = null;
|
||||
}
|
||||
data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
|
||||
} else {
|
||||
data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID,
|
||||
mEncryptInterface.getSignatureKey());
|
||||
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS,
|
||||
mEncryptInterface.getEncryptionKeys());
|
||||
}
|
||||
|
||||
data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, mEncryptInterface.isUseArmor());
|
||||
|
||||
int compressionId = ((Choice) mFileCompression.getSelectedItem()).getId();
|
||||
data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after encrypting is done in KeychainIntentService
|
||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
|
||||
getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
||||
AppMsg.makeText(getActivity(), R.string.encrypt_sign_successful,
|
||||
AppMsg.STYLE_INFO).show();
|
||||
|
||||
if (mEncryptInterface.isDeleteAfterEncrypt()) {
|
||||
// Create and show dialog to delete original file
|
||||
/*DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment.newInstance(mInputUri);
|
||||
deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog");
|
||||
setInputUri(null);*/
|
||||
}
|
||||
|
||||
if (share) {
|
||||
// Share encrypted file
|
||||
Intent sendFileIntent;
|
||||
if (mOutputUri.size() == 1) {
|
||||
sendFileIntent = new Intent(Intent.ACTION_SEND);
|
||||
sendFileIntent.setType("*/*");
|
||||
sendFileIntent.putExtra(Intent.EXTRA_STREAM, mOutputUri.get(0));
|
||||
} else {
|
||||
sendFileIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
|
||||
sendFileIntent.setType("*/*");
|
||||
sendFileIntent.putExtra(Intent.EXTRA_STREAM, mOutputUri);
|
||||
}
|
||||
if (!mEncryptInterface.isModeSymmetric() && mEncryptInterface.getEncryptionUsers() != null) {
|
||||
Set<String> users = new HashSet<String>();
|
||||
for (String user : mEncryptInterface.getEncryptionUsers()) {
|
||||
String[] userId = KeyRing.splitUserId(user);
|
||||
if (userId[1] != null) {
|
||||
users.add(userId[1]);
|
||||
}
|
||||
}
|
||||
sendFileIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()]));
|
||||
}
|
||||
startActivity(Intent.createChooser(sendFileIntent,
|
||||
getString(R.string.title_share_file)));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
||||
// start service with intent
|
||||
getActivity().startService(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
@ -391,8 +224,8 @@ public class EncryptFileFragment extends Fragment {
|
||||
case REQUEST_CODE_OUTPUT: {
|
||||
// This happens after output file was selected, so start our operation
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
mOutputUri.add(data.getData());
|
||||
encryptStart(false);
|
||||
mEncryptInterface.getOutputUris().add(data.getData());
|
||||
mEncryptInterface.startEncrypt(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -405,15 +238,20 @@ public class EncryptFileFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotifyUpdate() {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private class SelectedFilesAdapter extends BaseAdapter {
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mInputUri.size();
|
||||
return mEncryptInterface.getInputUris().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return mInputUri.get(position);
|
||||
return mEncryptInterface.getInputUris().get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -429,8 +267,8 @@ public class EncryptFileFragment extends Fragment {
|
||||
} else {
|
||||
view = convertView;
|
||||
}
|
||||
((TextView) view.findViewById(R.id.filename)).setText(FileHelper.getFilename(getActivity(), mInputUri.get(position)));
|
||||
long size = FileHelper.getFileSize(getActivity(), mInputUri.get(position));
|
||||
((TextView) view.findViewById(R.id.filename)).setText(FileHelper.getFilename(getActivity(), mEncryptInterface.getInputUris().get(position)));
|
||||
long size = FileHelper.getFileSize(getActivity(), mEncryptInterface.getInputUris().get(position));
|
||||
if (size == -1) {
|
||||
((TextView) view.findViewById(R.id.filesize)).setText("");
|
||||
} else {
|
||||
@ -443,7 +281,7 @@ public class EncryptFileFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
int px = OtherHelper.dpToPx(getActivity(), 48);
|
||||
Bitmap bitmap = FileHelper.getThumbnail(getActivity(), mInputUri.get(position), new Point(px, px));
|
||||
Bitmap bitmap = FileHelper.getThumbnail(getActivity(), mEncryptInterface.getInputUris().get(position), new Point(px, px));
|
||||
if (bitmap != null) {
|
||||
((ImageView) view.findViewById(R.id.thumbnail)).setImageBitmap(bitmap);
|
||||
} else {
|
||||
|
@ -25,6 +25,8 @@ import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
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;
|
||||
@ -75,18 +77,34 @@ public class EncryptMessageFragment extends Fragment {
|
||||
View view = inflater.inflate(R.layout.encrypt_message_fragment, container, false);
|
||||
|
||||
mMessage = (TextView) view.findViewById(R.id.message);
|
||||
mMessage.addTextChangedListener(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) {
|
||||
mEncryptInterface.setMessage(s.toString());
|
||||
}
|
||||
});
|
||||
mEncryptClipboard = view.findViewById(R.id.action_encrypt_clipboard);
|
||||
mEncryptShare = view.findViewById(R.id.action_encrypt_share);
|
||||
mEncryptClipboard.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
encryptClicked(true);
|
||||
mEncryptInterface.startEncrypt(false);
|
||||
}
|
||||
});
|
||||
mEncryptShare.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
encryptClicked(false);
|
||||
mEncryptInterface.startEncrypt(true);
|
||||
}
|
||||
});
|
||||
|
||||
@ -98,7 +116,7 @@ public class EncryptMessageFragment extends Fragment {
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
String text = getArguments().getString(ARG_TEXT);
|
||||
String text = mEncryptInterface.getMessage();
|
||||
if (text != null) {
|
||||
mMessage.setText(text);
|
||||
}
|
||||
@ -123,150 +141,4 @@ public class EncryptMessageFragment extends Fragment {
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private void encryptClicked(final boolean toClipboard) {
|
||||
if (mEncryptInterface.isModeSymmetric()) {
|
||||
// symmetric encryption
|
||||
|
||||
boolean gotPassphrase = (mEncryptInterface.getPassphrase() != null
|
||||
&& mEncryptInterface.getPassphrase().length() != 0);
|
||||
if (!gotPassphrase) {
|
||||
AppMsg.makeText(getActivity(), R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mEncryptInterface.getPassphrase().equals(mEncryptInterface.getPassphraseAgain())) {
|
||||
AppMsg.makeText(getActivity(), R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
// asymmetric encryption
|
||||
|
||||
boolean gotEncryptionKeys = (mEncryptInterface.getEncryptionKeys() != null
|
||||
&& mEncryptInterface.getEncryptionKeys().length > 0);
|
||||
|
||||
if (!gotEncryptionKeys && mEncryptInterface.getSignatureKey() == 0) {
|
||||
AppMsg.makeText(getActivity(), R.string.select_encryption_or_signature_key,
|
||||
AppMsg.STYLE_ALERT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEncryptInterface.getSignatureKey() != 0 &&
|
||||
PassphraseCacheService.getCachedPassphrase(getActivity(),
|
||||
mEncryptInterface.getSignatureKey()) == null) {
|
||||
PassphraseDialogFragment.show(getActivity(), mEncryptInterface.getSignatureKey(),
|
||||
new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||
encryptStart(toClipboard);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
encryptStart(toClipboard);
|
||||
}
|
||||
|
||||
private void encryptStart(final boolean toClipboard) {
|
||||
// Send all information needed to service to edit key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES);
|
||||
|
||||
String message = mMessage.getText().toString();
|
||||
|
||||
if (mEncryptInterface.isModeSymmetric()) {
|
||||
Log.d(Constants.TAG, "Symmetric encryption enabled!");
|
||||
String passphrase = mEncryptInterface.getPassphrase();
|
||||
if (passphrase.length() == 0) {
|
||||
passphrase = null;
|
||||
}
|
||||
data.putString(KeychainIntentService.ENCRYPT_SYMMETRIC_PASSPHRASE, passphrase);
|
||||
} else {
|
||||
data.putLong(KeychainIntentService.ENCRYPT_SIGNATURE_KEY_ID,
|
||||
mEncryptInterface.getSignatureKey());
|
||||
data.putLongArray(KeychainIntentService.ENCRYPT_ENCRYPTION_KEYS_IDS,
|
||||
mEncryptInterface.getEncryptionKeys());
|
||||
|
||||
boolean signOnly = (mEncryptInterface.getEncryptionKeys() == null
|
||||
|| mEncryptInterface.getEncryptionKeys().length == 0);
|
||||
if (signOnly) {
|
||||
message = fixBadCharactersForGmail(message);
|
||||
}
|
||||
}
|
||||
|
||||
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes());
|
||||
|
||||
data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, true);
|
||||
|
||||
int compressionId = Preferences.getPreferences(getActivity()).getDefaultMessageCompression();
|
||||
data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after encrypting is done in KeychainIntentService
|
||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
|
||||
getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
||||
// get returned data bundle
|
||||
Bundle data = message.getData();
|
||||
|
||||
String output = new String(data.getByteArray(KeychainIntentService.RESULT_BYTES));
|
||||
Log.d(Constants.TAG, "output: " + output);
|
||||
|
||||
if (toClipboard) {
|
||||
ClipboardReflection.copyToClipboard(getActivity(), output);
|
||||
AppMsg.makeText(getActivity(),
|
||||
R.string.encrypt_sign_clipboard_successful, AppMsg.STYLE_INFO)
|
||||
.show();
|
||||
} else {
|
||||
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
|
||||
// Type is set to text/plain so that encrypted messages can
|
||||
// be sent with Whatsapp, Hangouts, SMS etc...
|
||||
sendIntent.setType("text/plain");
|
||||
Log.d(Constants.TAG, "encrypt to:" + Arrays.toString(mEncryptInterface.getEncryptionUsers()));
|
||||
if (!mEncryptInterface.isModeSymmetric() && mEncryptInterface.getEncryptionUsers() != null) {
|
||||
Set<String> users = new HashSet<String>();
|
||||
for (String user : mEncryptInterface.getEncryptionUsers()) {
|
||||
String[] userId = KeyRing.splitUserId(user);
|
||||
if (userId[1] != null) {
|
||||
users.add(userId[1]);
|
||||
}
|
||||
}
|
||||
sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()]));
|
||||
}
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, output);
|
||||
startActivity(Intent.createChooser(sendIntent,
|
||||
getString(R.string.title_share_with)));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
||||
// start service with intent
|
||||
getActivity().startService(intent);
|
||||
}
|
||||
}
|
||||
|
@ -29,27 +29,20 @@ import android.widget.EditText;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
|
||||
public class EncryptSymmetricFragment extends Fragment {
|
||||
public class EncryptSymmetricFragment extends Fragment implements EncryptActivityInterface.UpdateListener {
|
||||
|
||||
OnSymmetricKeySelection mPassphraseUpdateListener;
|
||||
EncryptActivityInterface mEncryptInterface;
|
||||
|
||||
private EditText mPassphrase;
|
||||
private EditText mPassphraseAgain;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnSymmetricKeySelection {
|
||||
public void onPassphraseUpdate(String passphrase);
|
||||
|
||||
public void onPassphraseAgainUpdate(String passphrase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mPassphraseUpdateListener = (OnSymmetricKeySelection) activity;
|
||||
mEncryptInterface = (EncryptActivityInterface) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString() + " must implement OnSymmetricKeySelection");
|
||||
throw new ClassCastException(activity.toString() + " must implement EncryptActivityInterface");
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +55,7 @@ public class EncryptSymmetricFragment extends Fragment {
|
||||
|
||||
mPassphrase = (EditText) view.findViewById(R.id.passphrase);
|
||||
mPassphraseAgain = (EditText) view.findViewById(R.id.passphraseAgain);
|
||||
mPassphrase.addTextChangedListener(new TextWatcher() {
|
||||
TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
@ -74,25 +67,21 @@ public class EncryptSymmetricFragment extends Fragment {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
// update passphrase in EncryptActivity
|
||||
mPassphraseUpdateListener.onPassphraseUpdate(s.toString());
|
||||
if (mPassphrase.getText().toString().equals(mPassphraseAgain.getText().toString())) {
|
||||
mEncryptInterface.setPassphrase(s.toString());
|
||||
} else {
|
||||
mEncryptInterface.setPassphrase(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
mPassphraseAgain.addTextChangedListener(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
|
||||
mPassphraseUpdateListener.onPassphraseAgainUpdate(s.toString());
|
||||
}
|
||||
});
|
||||
};
|
||||
mPassphrase.addTextChangedListener(textWatcher);
|
||||
mPassphraseAgain.addTextChangedListener(textWatcher);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotifyUpdate() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
fromCursor(null);
|
||||
swapCursor(null);
|
||||
setPrefix(getContext().getString(R.string.label_to) + ": ");
|
||||
allowDuplicates(false);
|
||||
}
|
||||
@ -81,7 +81,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void fromCursor(Cursor cursor) {
|
||||
public void swapCursor(Cursor cursor) {
|
||||
if (cursor == null) {
|
||||
setAdapter(new EncryptKeyAdapter(Collections.<EncryptionKey>emptyList()));
|
||||
return;
|
||||
|
@ -9,12 +9,31 @@
|
||||
android:paddingRight="16dp"
|
||||
android:paddingLeft="16dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/sign"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/label_sign"/>
|
||||
android:padding="0dp"
|
||||
android:layout_margin="0dp"
|
||||
style="@android:style/Widget.EditText">
|
||||
<TextView
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="From: "/>
|
||||
<Spinner
|
||||
android:id="@+id/sign"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/label_sign"
|
||||
android:padding="0dp"
|
||||
android:layout_margin="0dp"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.sufficientlysecure.keychain.ui.widget.EncryptKeyCompletionView
|
||||
android:id="@+id/recipient_list"
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:padding="8dp"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
<TextView
|
||||
android:id="@android:id/text2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
</LinearLayout>
|
@ -25,14 +25,6 @@
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="?android:attr/listDivider"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<include layout="@layout/encrypt_content_adv_settings" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dip"
|
||||
|
Loading…
Reference in New Issue
Block a user