Merge branch 'development' of https://github.com/open-keychain/open-keychain into development
This commit is contained in:
@@ -123,7 +123,6 @@ public class CreateKeyEmailFragment extends Fragment {
|
||||
if (mAdditionalEmailModels == null) {
|
||||
mAdditionalEmailModels = new ArrayList<>();
|
||||
}
|
||||
|
||||
if (mEmailAdapter == null) {
|
||||
mEmailAdapter = new EmailAdapter(mAdditionalEmailModels, new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -136,6 +135,9 @@ public class CreateKeyEmailFragment extends Fragment {
|
||||
mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails);
|
||||
}
|
||||
}
|
||||
if (mAdditionalEmailModels.isEmpty() && mCreateKeyActivity.mAdditionalEmails != null) {
|
||||
mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails);
|
||||
}
|
||||
|
||||
mEmailsRecyclerView.setAdapter(mEmailAdapter);
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.Editable;
|
||||
import android.text.method.HideReturnsTransformationMethod;
|
||||
import android.text.method.PasswordTransformationMethod;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -37,9 +36,6 @@ import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
|
||||
import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CreateKeyPassphraseFragment extends Fragment {
|
||||
|
||||
// view
|
||||
@@ -111,8 +107,8 @@ public class CreateKeyPassphraseFragment extends Fragment {
|
||||
// initial values
|
||||
// TODO: using String here is unsafe...
|
||||
if (mCreateKeyActivity.mPassphrase != null) {
|
||||
mPassphraseEdit.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray()));
|
||||
mPassphraseEditAgain.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray()));
|
||||
mPassphraseEdit.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray()));
|
||||
mPassphraseEditAgain.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray()));
|
||||
}
|
||||
|
||||
mPassphraseEdit.requestFocus();
|
||||
|
||||
@@ -240,7 +240,7 @@ public class DecryptFilesFragment extends DecryptFragment {
|
||||
}
|
||||
case KeychainIntentService.ACTION_DECRYPT_VERIFY: {
|
||||
// display signature result in activity
|
||||
onResult(pgpResult);
|
||||
loadVerifyResult(pgpResult);
|
||||
|
||||
if (mDeleteAfter.isChecked()) {
|
||||
// Create and show dialog to delete original file
|
||||
@@ -308,4 +308,8 @@ public class DecryptFilesFragment extends DecryptFragment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onVerifyLoaded(boolean verified) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,26 +17,49 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
public abstract class DecryptFragment extends CryptoOperationFragment {
|
||||
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
|
||||
|
||||
protected long mSignatureKeyId = 0;
|
||||
public abstract class DecryptFragment extends CryptoOperationFragment implements
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
public static final int LOADER_ID_UNIFIED = 0;
|
||||
|
||||
protected LinearLayout mResultLayout;
|
||||
|
||||
@@ -46,155 +69,119 @@ public abstract class DecryptFragment extends CryptoOperationFragment {
|
||||
protected TextView mSignatureText;
|
||||
|
||||
protected View mSignatureLayout;
|
||||
protected View mSignatureDivider1;
|
||||
protected View mSignatureDivider2;
|
||||
protected TextView mSignatureName;
|
||||
protected TextView mSignatureEmail;
|
||||
protected TextView mSignatureAction;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
private OpenPgpSignatureResult mSignatureResult;
|
||||
|
||||
mResultLayout = (LinearLayout) getView().findViewById(R.id.result_main_layout);
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// NOTE: These views are inside the activity!
|
||||
mResultLayout = (LinearLayout) getActivity().findViewById(R.id.result_main_layout);
|
||||
mResultLayout.setVisibility(View.GONE);
|
||||
|
||||
mEncryptionIcon = (ImageView) getView().findViewById(R.id.result_encryption_icon);
|
||||
mEncryptionText = (TextView) getView().findViewById(R.id.result_encryption_text);
|
||||
mSignatureIcon = (ImageView) getView().findViewById(R.id.result_signature_icon);
|
||||
mSignatureText = (TextView) getView().findViewById(R.id.result_signature_text);
|
||||
mSignatureLayout = getView().findViewById(R.id.result_signature_layout);
|
||||
mSignatureDivider1 = getView().findViewById(R.id.result_signature_divider1);
|
||||
mSignatureDivider2 = getView().findViewById(R.id.result_signature_divider2);
|
||||
mSignatureName = (TextView) getView().findViewById(R.id.result_signature_name);
|
||||
mSignatureEmail = (TextView) getView().findViewById(R.id.result_signature_email);
|
||||
mSignatureAction = (TextView) getView().findViewById(R.id.result_signature_action);
|
||||
mEncryptionIcon = (ImageView) getActivity().findViewById(R.id.result_encryption_icon);
|
||||
mEncryptionText = (TextView) getActivity().findViewById(R.id.result_encryption_text);
|
||||
mSignatureIcon = (ImageView) getActivity().findViewById(R.id.result_signature_icon);
|
||||
mSignatureText = (TextView) getActivity().findViewById(R.id.result_signature_text);
|
||||
mSignatureLayout = getActivity().findViewById(R.id.result_signature_layout);
|
||||
mSignatureName = (TextView) getActivity().findViewById(R.id.result_signature_name);
|
||||
mSignatureEmail = (TextView) getActivity().findViewById(R.id.result_signature_email);
|
||||
mSignatureAction = (TextView) getActivity().findViewById(R.id.result_signature_action);
|
||||
|
||||
}
|
||||
|
||||
private void lookupUnknownKey(long unknownKeyId) {
|
||||
Intent intent = new Intent(getActivity(), ImportKeysActivity.class);
|
||||
intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER);
|
||||
intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId);
|
||||
startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY);
|
||||
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(getActivity()) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
if (message.arg1 == MessageStatus.OKAY.ordinal()) {
|
||||
// get returned data bundle
|
||||
Bundle returnData = message.getData();
|
||||
|
||||
if (returnData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ImportKeyResult result =
|
||||
returnData.getParcelable(OperationResult.EXTRA_RESULT);
|
||||
|
||||
// if (!result.success()) {
|
||||
result.createNotify(getActivity()).show();
|
||||
// }
|
||||
|
||||
getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, DecryptFragment.this);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
// search config
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
}
|
||||
|
||||
{
|
||||
ParcelableKeyRing keyEntry = new ParcelableKeyRing(null,
|
||||
KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null);
|
||||
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
|
||||
selectedEntries.add(keyEntry);
|
||||
|
||||
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries);
|
||||
}
|
||||
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
getActivity().startService(intent);
|
||||
|
||||
}
|
||||
|
||||
private void showKey(long keyId) {
|
||||
Intent viewKeyIntent = new Intent(getActivity(), ViewKeyActivity.class);
|
||||
viewKeyIntent.setData(KeychainContract.KeyRings
|
||||
.buildGenericKeyRingUri(keyId));
|
||||
startActivity(viewKeyIntent);
|
||||
try {
|
||||
|
||||
Intent viewKeyIntent = new Intent(getActivity(), ViewKeyActivity.class);
|
||||
long masterKeyId = new ProviderHelper(getActivity()).getCachedPublicKeyRing(
|
||||
KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(keyId)
|
||||
).getMasterKeyId();
|
||||
viewKeyIntent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId));
|
||||
startActivity(viewKeyIntent);
|
||||
|
||||
} catch (PgpKeyNotFoundException e) {
|
||||
Notify.create(getActivity(), R.string.error_key_not_found, Style.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return returns false if signature is invalid, key is revoked or expired.
|
||||
*/
|
||||
protected boolean onResult(DecryptVerifyResult decryptVerifyResult) {
|
||||
final OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
|
||||
protected void loadVerifyResult(DecryptVerifyResult decryptVerifyResult) {
|
||||
|
||||
boolean valid = false;
|
||||
|
||||
mSignatureKeyId = 0;
|
||||
mSignatureResult = decryptVerifyResult.getSignatureResult();
|
||||
mResultLayout.setVisibility(View.VISIBLE);
|
||||
if (signatureResult != null) {
|
||||
mSignatureKeyId = signatureResult.getKeyId();
|
||||
|
||||
String userId = signatureResult.getPrimaryUserId();
|
||||
KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId);
|
||||
if (userIdSplit.name != null) {
|
||||
mSignatureName.setText(userIdSplit.name);
|
||||
} else {
|
||||
mSignatureName.setText(R.string.user_id_no_name);
|
||||
}
|
||||
if (userIdSplit.email != null) {
|
||||
mSignatureEmail.setText(userIdSplit.email);
|
||||
} else {
|
||||
mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), mSignatureKeyId));
|
||||
}
|
||||
// unsigned data
|
||||
if (mSignatureResult == null) {
|
||||
|
||||
if (signatureResult.isSignatureOnly()) {
|
||||
mEncryptionText.setText(R.string.decrypt_result_not_encrypted);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED);
|
||||
} else {
|
||||
mEncryptionText.setText(R.string.decrypt_result_encrypted);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
|
||||
}
|
||||
|
||||
switch (signatureResult.getStatus()) {
|
||||
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_certified);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(mSignatureKeyId);
|
||||
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_uncertified);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(mSignatureKeyId);
|
||||
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_missing_key);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
mSignatureAction.setText(R.string.decrypt_result_action_Lookup);
|
||||
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0);
|
||||
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
lookupUnknownKey(mSignatureKeyId);
|
||||
}
|
||||
});
|
||||
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_expired_key);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(mSignatureKeyId);
|
||||
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(mSignatureKeyId);
|
||||
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenPgpSignatureResult.SIGNATURE_ERROR: {
|
||||
mSignatureText.setText(R.string.decrypt_result_invalid_signature);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID);
|
||||
|
||||
setSignatureLayoutVisibility(View.GONE);
|
||||
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setSignatureLayoutVisibility(View.GONE);
|
||||
|
||||
mSignatureText.setText(R.string.decrypt_result_no_signature);
|
||||
@@ -202,16 +189,27 @@ public abstract class DecryptFragment extends CryptoOperationFragment {
|
||||
mEncryptionText.setText(R.string.decrypt_result_encrypted);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
|
||||
|
||||
valid = true;
|
||||
getLoaderManager().destroyLoader(LOADER_ID_UNIFIED);
|
||||
|
||||
onVerifyLoaded(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return valid;
|
||||
if (mSignatureResult.isSignatureOnly()) {
|
||||
mEncryptionText.setText(R.string.decrypt_result_not_encrypted);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED);
|
||||
} else {
|
||||
mEncryptionText.setText(R.string.decrypt_result_encrypted);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED);
|
||||
}
|
||||
|
||||
getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, this);
|
||||
|
||||
}
|
||||
|
||||
private void setSignatureLayoutVisibility(int visibility) {
|
||||
mSignatureLayout.setVisibility(visibility);
|
||||
mSignatureDivider1.setVisibility(visibility);
|
||||
mSignatureDivider2.setVisibility(visibility);
|
||||
}
|
||||
|
||||
private void setShowAction(final long signatureKeyId) {
|
||||
@@ -225,4 +223,177 @@ public abstract class DecryptFragment extends CryptoOperationFragment {
|
||||
});
|
||||
}
|
||||
|
||||
// These are the rows that we will retrieve.
|
||||
static final String[] UNIFIED_PROJECTION = new String[]{
|
||||
KeychainContract.KeyRings._ID,
|
||||
KeychainContract.KeyRings.MASTER_KEY_ID,
|
||||
KeychainContract.KeyRings.USER_ID,
|
||||
KeychainContract.KeyRings.IS_REVOKED,
|
||||
KeychainContract.KeyRings.IS_EXPIRED,
|
||||
KeychainContract.KeyRings.VERIFIED,
|
||||
};
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static final int INDEX_MASTER_KEY_ID = 1;
|
||||
static final int INDEX_USER_ID = 2;
|
||||
static final int INDEX_IS_REVOKED = 3;
|
||||
static final int INDEX_IS_EXPIRED = 4;
|
||||
static final int INDEX_VERIFIED = 5;
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
if (id != LOADER_ID_UNIFIED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(
|
||||
mSignatureResult.getKeyId());
|
||||
return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||
|
||||
if (loader.getId() != LOADER_ID_UNIFIED) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the key is unknown, show it as such
|
||||
if (data.getCount() == 0 || !data.moveToFirst()) {
|
||||
showUnknownKeyStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
long signatureKeyId = mSignatureResult.getKeyId();
|
||||
|
||||
String userId = data.getString(INDEX_USER_ID);
|
||||
KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId);
|
||||
if (userIdSplit.name != null) {
|
||||
mSignatureName.setText(userIdSplit.name);
|
||||
} else {
|
||||
mSignatureName.setText(R.string.user_id_no_name);
|
||||
}
|
||||
if (userIdSplit.email != null) {
|
||||
mSignatureEmail.setText(userIdSplit.email);
|
||||
} else {
|
||||
mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(
|
||||
getActivity(), mSignatureResult.getKeyId()));
|
||||
}
|
||||
|
||||
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) != 0;
|
||||
boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
|
||||
boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
|
||||
|
||||
if (isRevoked) {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(signatureKeyId);
|
||||
|
||||
onVerifyLoaded(false);
|
||||
|
||||
} else if (isExpired) {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_expired_key);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(signatureKeyId);
|
||||
|
||||
onVerifyLoaded(true);
|
||||
|
||||
} else if (isVerified) {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_certified);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(signatureKeyId);
|
||||
|
||||
onVerifyLoaded(true);
|
||||
|
||||
} else {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_uncertified);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
setShowAction(signatureKeyId);
|
||||
|
||||
onVerifyLoaded(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
|
||||
if (loader.getId() != LOADER_ID_UNIFIED) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSignatureLayoutVisibility(View.GONE);
|
||||
|
||||
}
|
||||
|
||||
private void showUnknownKeyStatus() {
|
||||
|
||||
final long signatureKeyId = mSignatureResult.getKeyId();
|
||||
|
||||
int result = mSignatureResult.getStatus();
|
||||
if (result != OpenPgpSignatureResult.SIGNATURE_KEY_MISSING
|
||||
&& result != OpenPgpSignatureResult.SIGNATURE_ERROR) {
|
||||
Log.e(Constants.TAG, "got missing status for non-missing key, shouldn't happen!");
|
||||
}
|
||||
|
||||
String userId = mSignatureResult.getPrimaryUserId();
|
||||
KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId);
|
||||
if (userIdSplit.name != null) {
|
||||
mSignatureName.setText(userIdSplit.name);
|
||||
} else {
|
||||
mSignatureName.setText(R.string.user_id_no_name);
|
||||
}
|
||||
if (userIdSplit.email != null) {
|
||||
mSignatureEmail.setText(userIdSplit.email);
|
||||
} else {
|
||||
mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(
|
||||
getActivity(), mSignatureResult.getKeyId()));
|
||||
}
|
||||
|
||||
switch (mSignatureResult.getStatus()) {
|
||||
|
||||
case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_missing_key);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY);
|
||||
|
||||
setSignatureLayoutVisibility(View.VISIBLE);
|
||||
mSignatureAction.setText(R.string.decrypt_result_action_Lookup);
|
||||
mSignatureAction
|
||||
.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0);
|
||||
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
lookupUnknownKey(signatureKeyId);
|
||||
}
|
||||
});
|
||||
|
||||
onVerifyLoaded(true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenPgpSignatureResult.SIGNATURE_ERROR: {
|
||||
mSignatureText.setText(R.string.decrypt_result_invalid_signature);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID);
|
||||
|
||||
setSignatureLayoutVisibility(View.GONE);
|
||||
|
||||
onVerifyLoaded(false);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected abstract void onVerifyLoaded(boolean verified);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
@@ -39,7 +42,6 @@ import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ShareHelper;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@@ -54,6 +56,7 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
|
||||
// model
|
||||
private String mCiphertext;
|
||||
private boolean mShowMenuOptions = false;
|
||||
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
@@ -79,22 +82,6 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
mInvalidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_invalid);
|
||||
mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
|
||||
|
||||
View vShareButton = view.findViewById(R.id.action_decrypt_share_plaintext);
|
||||
vShareButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString()));
|
||||
}
|
||||
});
|
||||
|
||||
View vCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext);
|
||||
vCopyButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
copyToClipboard(mText.getText().toString());
|
||||
}
|
||||
});
|
||||
|
||||
Button vInvalidButton = (Button) view.findViewById(R.id.decrypt_text_invalid_button);
|
||||
vInvalidButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -110,9 +97,9 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
/**
|
||||
* Create Intent Chooser but exclude decrypt activites
|
||||
*/
|
||||
private Intent sendWithChooserExcludingEncrypt(String text) {
|
||||
private Intent sendWithChooserExcludingDecrypt(String text) {
|
||||
Intent prototype = createSendIntent(text);
|
||||
String title = getString(R.string.title_share_file);
|
||||
String title = getString(R.string.title_share_message);
|
||||
|
||||
// we don't want to decrypt the decrypted, no inception ;)
|
||||
String[] blacklist = new String[]{
|
||||
@@ -139,6 +126,8 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
String ciphertext = getArguments().getString(ARG_CIPHERTEXT);
|
||||
if (ciphertext != null) {
|
||||
mCiphertext = ciphertext;
|
||||
@@ -146,6 +135,33 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
if (mShowMenuOptions) {
|
||||
inflater.inflate(R.menu.decrypt_menu, menu);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.decrypt_share: {
|
||||
startActivity(sendWithChooserExcludingDecrypt(mText.getText().toString()));
|
||||
break;
|
||||
}
|
||||
case R.id.decrypt_copy: {
|
||||
copyToClipboard(mText.getText().toString());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
||||
// Send all information needed to service to decrypt in other thread
|
||||
@@ -206,15 +222,8 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
pgpResult.createNotify(getActivity()).show();
|
||||
|
||||
// display signature result in activity
|
||||
boolean valid = onResult(pgpResult);
|
||||
loadVerifyResult(pgpResult);
|
||||
|
||||
if (valid) {
|
||||
mInvalidLayout.setVisibility(View.GONE);
|
||||
mValidLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mInvalidLayout.setVisibility(View.VISIBLE);
|
||||
mValidLayout.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
pgpResult.createNotify(getActivity()).show();
|
||||
// TODO: show also invalid layout with different text?
|
||||
@@ -234,4 +243,19 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
getActivity().startService(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onVerifyLoaded(boolean verified) {
|
||||
|
||||
mShowMenuOptions = verified;
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
|
||||
if (verified) {
|
||||
mInvalidLayout.setVisibility(View.GONE);
|
||||
mValidLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mInvalidLayout.setVisibility(View.VISIBLE);
|
||||
mValidLayout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,23 +98,20 @@ public class EncryptTextActivity extends BaseActivity implements
|
||||
// handle like normal text encryption, override action and extras to later
|
||||
// executeServiceMethod ACTION_ENCRYPT_TEXT in main actions
|
||||
extras.putString(EXTRA_TEXT, sharedText);
|
||||
action = ACTION_ENCRYPT_TEXT;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
String textData = extras.getString(EXTRA_TEXT);
|
||||
if (ACTION_ENCRYPT_TEXT.equals(action) && textData == null) {
|
||||
Log.e(Constants.TAG, "Include the extra 'text' in your Intent!");
|
||||
return;
|
||||
if (textData == null) {
|
||||
textData = "";
|
||||
}
|
||||
|
||||
// preselect keys given by intent
|
||||
long mSigningKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID);
|
||||
long[] mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS);
|
||||
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com>
|
||||
* Copyright (C) 2015 Kai Jiang <jiangkai@gmail.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
|
||||
@@ -20,36 +21,98 @@ package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.mikepenz.community_material_typeface_library.CommunityMaterial;
|
||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
|
||||
import com.mikepenz.iconics.typeface.FontAwesome;
|
||||
import com.mikepenz.materialdrawer.Drawer;
|
||||
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.remote.ui.AppsListFragment;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import org.sufficientlysecure.keychain.util.FabContainer;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer;
|
||||
public class MainActivity extends AppCompatActivity implements FabContainer {
|
||||
|
||||
public class MainActivity extends MaterialNavigationDrawer implements FabContainer {
|
||||
public Drawer.Result result;
|
||||
|
||||
private KeyListFragment mKeyListFragment ;
|
||||
private AppsListFragment mAppsListFragment;
|
||||
private EncryptDecryptOverviewFragment mEncryptDecryptOverviewFragment;
|
||||
private Fragment mLastUsedFragment;
|
||||
private Toolbar mToolbar;
|
||||
|
||||
@Override
|
||||
public void init(Bundle savedInstanceState) {
|
||||
// don't open drawer on first run
|
||||
disableLearningPattern();
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_activity);
|
||||
|
||||
// addMultiPaneSupport();
|
||||
//initialize FragmentLayout with KeyListFragment at first
|
||||
Fragment mainFragment = new KeyListFragment();
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
FragmentTransaction transaction = fm.beginTransaction();
|
||||
transaction.replace(R.id.main_fragment_container, mainFragment);
|
||||
transaction.commit();
|
||||
|
||||
// set the header image
|
||||
// create and set the header
|
||||
setDrawerHeaderImage(R.drawable.drawer_header);
|
||||
mToolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
mToolbar.setTitle(R.string.app_name);
|
||||
setSupportActionBar(mToolbar);
|
||||
|
||||
// create sections
|
||||
addSection(newSection(getString(R.string.nav_keys), R.drawable.ic_vpn_key_black_24dp, new KeyListFragment()));
|
||||
addSection(newSection(getString(R.string.nav_encrypt_decrypt), R.drawable.ic_lock_black_24dp, new EncryptDecryptOverviewFragment()));
|
||||
addSection(newSection(getString(R.string.title_api_registered_apps), R.drawable.ic_apps_black_24dp, new AppsListFragment()));
|
||||
|
||||
// create bottom section
|
||||
addBottomSection(newSection(getString(R.string.menu_preferences), R.drawable.ic_settings_black_24dp, new Intent(this, SettingsActivity.class)));
|
||||
addBottomSection(newSection(getString(R.string.menu_help), R.drawable.ic_help_black_24dp, new Intent(this, HelpActivity.class)));
|
||||
result = new Drawer()
|
||||
.withActivity(this)
|
||||
.withHeader(R.layout.main_drawer_header)
|
||||
.withToolbar(mToolbar)
|
||||
.addDrawerItems(
|
||||
new PrimaryDrawerItem().withName(R.string.nav_keys).withIcon(CommunityMaterial.Icon.cmd_key).withIdentifier(1).withCheckable(false),
|
||||
new PrimaryDrawerItem().withName(R.string.nav_encrypt_decrypt).withIcon(FontAwesome.Icon.faw_lock).withIdentifier(2).withCheckable(false),
|
||||
new PrimaryDrawerItem().withName(R.string.title_api_registered_apps).withIcon(CommunityMaterial.Icon.cmd_apps).withIdentifier(3).withCheckable(false)
|
||||
)
|
||||
.addStickyDrawerItems(
|
||||
// display and stick on bottom of drawer
|
||||
new PrimaryDrawerItem().withName(R.string.menu_preferences).withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(4).withCheckable(false),
|
||||
new PrimaryDrawerItem().withName(R.string.menu_help).withIcon(CommunityMaterial.Icon.cmd_help_circle).withIdentifier(5).withCheckable(false)
|
||||
)
|
||||
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id, IDrawerItem drawerItem) {
|
||||
if (drawerItem != null) {
|
||||
Intent intent = null;
|
||||
switch(drawerItem.getIdentifier()) {
|
||||
case 1:
|
||||
onKeysSelected();
|
||||
break;
|
||||
case 2:
|
||||
onEnDecryptSelected();
|
||||
break;
|
||||
case 3:
|
||||
onAppsSelected();
|
||||
break;
|
||||
case 4:
|
||||
intent = new Intent(MainActivity.this, SettingsActivity.class);
|
||||
break;
|
||||
case 5:
|
||||
intent = new Intent(MainActivity.this, HelpActivity.class);
|
||||
break;
|
||||
}
|
||||
if (intent != null) {
|
||||
MainActivity.this.startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.withSelectedItem(-1)
|
||||
.withSavedInstance(savedInstanceState)
|
||||
.build();
|
||||
|
||||
// if this is the first time show first time activity
|
||||
Preferences prefs = Preferences.getPreferences(this);
|
||||
@@ -69,9 +132,83 @@ public class MainActivity extends MaterialNavigationDrawer implements FabContain
|
||||
}
|
||||
}
|
||||
|
||||
private void clearFragments() {
|
||||
mKeyListFragment = null;
|
||||
mAppsListFragment = null;
|
||||
mEncryptDecryptOverviewFragment = null;
|
||||
|
||||
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
|
||||
private void setFragment(Fragment fragment) {
|
||||
setFragment(fragment, true);
|
||||
}
|
||||
|
||||
private void setFragment(Fragment fragment, boolean addToBackStack) {
|
||||
this.mLastUsedFragment = fragment;
|
||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
ft.replace(R.id.main_fragment_container, fragment);
|
||||
if (addToBackStack) {
|
||||
ft.addToBackStack(null);
|
||||
}
|
||||
ft.commit();
|
||||
}
|
||||
|
||||
private boolean onKeysSelected() {
|
||||
mToolbar.setTitle(R.string.app_name);
|
||||
clearFragments();
|
||||
|
||||
if (mKeyListFragment == null) {
|
||||
mKeyListFragment = new KeyListFragment();
|
||||
}
|
||||
|
||||
setFragment(mKeyListFragment, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean onEnDecryptSelected() {
|
||||
mToolbar.setTitle(R.string.nav_encrypt_decrypt);
|
||||
clearFragments();
|
||||
if (mEncryptDecryptOverviewFragment == null) {
|
||||
mEncryptDecryptOverviewFragment = new EncryptDecryptOverviewFragment();
|
||||
}
|
||||
|
||||
setFragment(mEncryptDecryptOverviewFragment);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean onAppsSelected() {
|
||||
mToolbar.setTitle(R.string.nav_apps);
|
||||
clearFragments();
|
||||
if (mAppsListFragment == null) {
|
||||
mAppsListFragment = new AppsListFragment();
|
||||
}
|
||||
|
||||
setFragment(mAppsListFragment);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
//add the values which need to be saved from the drawer to the bundle
|
||||
outState = result.saveInstanceState(outState);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed(){
|
||||
//handle the back press :D close the drawer first and if the drawer is closed close the activity
|
||||
if (result != null && result.isDrawerOpen()) {
|
||||
result.closeDrawer();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fabMoveUp(int height) {
|
||||
Object fragment = getCurrentSection().getTargetFragment();
|
||||
Object fragment = getSupportFragmentManager()
|
||||
.findFragmentById(R.id.main_fragment_container);
|
||||
if (fragment instanceof FabContainer) {
|
||||
((FabContainer) fragment).fabMoveUp(height);
|
||||
}
|
||||
@@ -79,7 +216,8 @@ public class MainActivity extends MaterialNavigationDrawer implements FabContain
|
||||
|
||||
@Override
|
||||
public void fabRestorePosition() {
|
||||
Object fragment = getCurrentSection().getTargetFragment();
|
||||
Object fragment = getSupportFragmentManager()
|
||||
.findFragmentById(R.id.main_fragment_container);
|
||||
if (fragment instanceof FabContainer) {
|
||||
((FabContainer) fragment).fabRestorePosition();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class PagerTabStripAdapter extends FragmentPagerAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public PagerTabStripAdapter(ActionBarActivity activity) {
|
||||
public PagerTabStripAdapter(AppCompatActivity activity) {
|
||||
super(activity.getSupportFragmentManager());
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.
|
||||
}
|
||||
}
|
||||
|
||||
public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
|
||||
public TabsAdapter(AppCompatActivity activity, ViewPager pager) {
|
||||
super(activity.getSupportFragmentManager());
|
||||
mContext = activity;
|
||||
mActionBar = activity.getSupportActionBar();
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.ui.base;
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -33,7 +33,7 @@ import org.sufficientlysecure.keychain.R;
|
||||
/**
|
||||
* Setups Toolbar
|
||||
*/
|
||||
public abstract class BaseActivity extends ActionBarActivity {
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
protected Toolbar mToolbar;
|
||||
protected View mStatusBar;
|
||||
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.v7.widget.AppCompatAutoCompleteTextView;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
@@ -27,14 +26,13 @@ import android.util.AttributeSet;
|
||||
import android.util.Patterns;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.util.ContactHelper;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class EmailEditText extends AutoCompleteTextView {
|
||||
public class EmailEditText extends AppCompatAutoCompleteTextView {
|
||||
|
||||
public EmailEditText(Context context) {
|
||||
super(context);
|
||||
@@ -51,12 +49,6 @@ public class EmailEditText extends AutoCompleteTextView {
|
||||
init();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public EmailEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||
reenableKeyboardSuggestions();
|
||||
|
||||
@@ -108,9 +108,8 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
mLoaderManager = ((FragmentActivity) getContext()).getSupportLoaderManager();
|
||||
|
||||
if (getContext() instanceof FragmentActivity) {
|
||||
mLoaderManager = ((FragmentActivity) getContext()).getSupportLoaderManager();
|
||||
mLoaderManager.initLoader(hashCode(), null, this);
|
||||
} else {
|
||||
Log.e(Constants.TAG, "EncryptKeyCompletionView must be attached to a FragmentActivity, this is " + getContext().getClass());
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.support.v7.internal.widget.TintSpinner;
|
||||
import android.support.v7.widget.AppCompatSpinner;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
@@ -46,10 +46,10 @@ import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Use TintSpinner 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
|
||||
*/
|
||||
public abstract class KeySpinner extends TintSpinner implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
public abstract class KeySpinner extends AppCompatSpinner implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
public interface OnKeyChangedListener {
|
||||
public void onKeyChanged(long masterKeyId);
|
||||
}
|
||||
|
||||
@@ -17,17 +17,15 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.v7.widget.AppCompatAutoCompleteTextView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
|
||||
import org.sufficientlysecure.keychain.util.ContactHelper;
|
||||
|
||||
public class NameEditText extends AutoCompleteTextView {
|
||||
public class NameEditText extends AppCompatAutoCompleteTextView {
|
||||
public NameEditText(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
@@ -43,12 +41,6 @@ public class NameEditText extends AutoCompleteTextView {
|
||||
init();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public NameEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
reenableKeyboardSuggestions();
|
||||
initAdapter();
|
||||
|
||||
@@ -19,15 +19,13 @@ package org.sufficientlysecure.keychain.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.support.v7.widget.AppCompatEditText;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.EditText;
|
||||
|
||||
import org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator.PasswordStrengthBarView;
|
||||
|
||||
public class PassphraseEditText extends EditText {
|
||||
public class PassphraseEditText extends AppCompatEditText {
|
||||
|
||||
PasswordStrengthBarView mPasswordStrengthBarView;
|
||||
int mPasswordBarWidth;
|
||||
|
||||
@@ -22,13 +22,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator;
|
||||
package org.sufficientlysecure.keychain.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
/**
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator;
|
||||
package org.sufficientlysecure.keychain.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -56,7 +56,6 @@ import org.sufficientlysecure.keychain.R;
|
||||
*/
|
||||
public class PasswordStrengthView extends View {
|
||||
|
||||
|
||||
protected int mMinWidth;
|
||||
protected int mMinHeight;
|
||||
|
||||
Reference in New Issue
Block a user