1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-01-10 05:08:18 -05:00

Merge branch 'master' into ms-eas. Format cleanup with astyle.

This commit is contained in:
wongk 2011-11-30 12:06:30 -05:00
commit 4d032a861e
59 changed files with 3116 additions and 1726 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="14013"
android:versionName="3.913" package="com.fsck.k9"
android:versionCode="15002"
android:versionName="4.102" package="com.fsck.k9"
>
<uses-sdk
android:minSdkVersion="7"

1111
res/values-da/strings.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -491,6 +491,7 @@
<item></item>
<item>ca</item>
<item>cs</item>
<item>da</item>
<item>de</item>
<item>en</item>
<item>es</item>

View File

@ -61,6 +61,7 @@
<string name="forward_action">Forward</string>
<string name="move_action">Move</string>
<string name="continue_action">Continue</string>
<string name="back_action">Back</string>
<string name="done_action">Done</string> <!-- Used to complete a multi-step process -->
<string name="remove_action">Remove</string>
<string name="discard_action">Discard</string>
@ -597,6 +598,8 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
<string name="account_settings_crypto_app_not_available">not available</string>
<string name="account_settings_crypto_auto_signature">Auto-sign</string>
<string name="account_settings_crypto_auto_signature_summary">Use the account\'s email address to guess the signature key.</string>
<string name="account_settings_crypto_auto_encrypt">Auto-encrypt</string>
<string name="account_settings_crypto_auto_encrypt_summary">Automatically set encrypt if a public key matches a recipient.</string>
<string name="account_settings_mail_check_frequency_label">Folder poll frequency</string>
<string name="account_settings_second_class_check_frequency_label">2nd class check frequency</string>
@ -1023,6 +1026,12 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
<string name="save_or_discard_draft_message_dlg_title">Save draft message?</string>
<string name="save_or_discard_draft_message_instructions_fmt">Save or Discard this message?</string>
<string name="refuse_to_save_draft_marked_encrypted_dlg_title">Refuse to save draft message.</string>
<string name="refuse_to_save_draft_marked_encrypted_instructions_fmt">Refuse to save draft message marked encrypted.</string>
<string name="continue_without_public_key_dlg_title">Continue without public key?</string>
<string name="continue_without_public_key_instructions_fmt">One or more recipients do not have a saved public key. Continue?</string>
<string name="charset_not_found">This message can\'t be displayed because the charset \"<xliff:g id="charset">%s</xliff:g>\" wasn\'t found.</string>
<string name="select_text_now">Select text to copy.</string>

View File

@ -474,6 +474,13 @@
android:summary="@string/account_settings_crypto_auto_signature_summary"
android:dependency="crypto_app"/>
<CheckBoxPreference
android:persistent="false"
android:key="crypto_auto_encrypt"
android:title="@string/account_settings_crypto_auto_encrypt"
android:summary="@string/account_settings_crypto_auto_encrypt_summary"
android:dependency="crypto_app"/>
</PreferenceScreen>
</PreferenceScreen>

View File

@ -152,6 +152,7 @@ public class Account implements BaseAccount {
// The following 2 settings are currently only used by the EasStore.
private String mSyncKey;
private String mSecurityKey;
private boolean mCryptoAutoEncrypt;
private CryptoProvider mCryptoProvider = null;
@ -243,6 +244,7 @@ public class Account implements BaseAccount {
mSyncRemoteDeletions = true;
mCryptoApp = Apg.NAME;
mCryptoAutoSignature = false;
mCryptoAutoEncrypt = false;
mEnabled = true;
searchableFolders = Searchable.ALL;
@ -411,6 +413,7 @@ public class Account implements BaseAccount {
mCryptoApp = prefs.getString(mUuid + ".cryptoApp", Apg.NAME);
mCryptoAutoSignature = prefs.getBoolean(mUuid + ".cryptoAutoSignature", false);
mCryptoAutoEncrypt = prefs.getBoolean(mUuid + ".cryptoAutoEncrypt", false);
mEnabled = prefs.getBoolean(mUuid + ".enabled", true);
mSyncKey = prefs.getString(mUuid + ".syncKey", "");
mSecurityKey = prefs.getString(mUuid + ".securityKey", "");
@ -487,6 +490,7 @@ public class Account implements BaseAccount {
editor.remove(mUuid + ".stripSignature");
editor.remove(mUuid + ".cryptoApp");
editor.remove(mUuid + ".cryptoAutoSignature");
editor.remove(mUuid + ".cryptoAutoEncrypt");
editor.remove(mUuid + ".enabled");
editor.remove(mUuid + ".syncKey");
editor.remove(mUuid + ".securityKey");
@ -535,19 +539,16 @@ public class Account implements BaseAccount {
if (i > 0 && uuids[i].equals(mUuid)) {
newUuids[i] = newUuids[i - 1];
newUuids[i - 1] = mUuid;
}
else {
} else {
newUuids[i] = uuids[i];
}
}
}
else {
} else {
for (int i = uuids.length - 1; i >= 0; i--) {
if (i < uuids.length - 1 && uuids[i].equals(mUuid)) {
newUuids[i] = newUuids[i + 1];
newUuids[i + 1] = mUuid;
}
else {
} else {
newUuids[i] = uuids[i];
}
}
@ -653,6 +654,7 @@ public class Account implements BaseAccount {
editor.putBoolean(mUuid + ".stripSignature", mStripSignature);
editor.putString(mUuid + ".cryptoApp", mCryptoApp);
editor.putBoolean(mUuid + ".cryptoAutoSignature", mCryptoAutoSignature);
editor.putBoolean(mUuid + ".cryptoAutoEncrypt", mCryptoAutoEncrypt);
editor.putBoolean(mUuid + ".enabled", mEnabled);
editor.putString(mUuid + ".syncKey", mSyncKey);
editor.putString(mUuid + ".securityKey", mSecurityKey);
@ -1494,6 +1496,14 @@ public class Account implements BaseAccount {
mSecurityKey = key;
}
public boolean isCryptoAutoEncrypt() {
return mCryptoAutoEncrypt;
}
public void setCryptoAutoEncrypt(boolean cryptoAutoEncrypt) {
mCryptoAutoEncrypt = cryptoAutoEncrypt;
}
public String getInboxFolderName() {
return mInboxFolderName;
}

View File

@ -1218,19 +1218,16 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
item.setVisible(false);
}
}
}
else {
} else {
EnumSet<ACCOUNT_LOCATION> accountLocation = accountLocation(account);
if (accountLocation.contains(ACCOUNT_LOCATION.TOP)) {
menu.findItem(R.id.move_up).setEnabled(false);
}
else {
} else {
menu.findItem(R.id.move_up).setEnabled(true);
}
if (accountLocation.contains(ACCOUNT_LOCATION.BOTTOM)) {
menu.findItem(R.id.move_down).setEnabled(false);
}
else {
} else {
menu.findItem(R.id.move_down).setEnabled(true);
}
}
@ -1476,7 +1473,9 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
}
@Override
public void onNothingSelected(AdapterView<?> arg0) { /* Do nothing */ }
public void onNothingSelected(AdapterView<?> arg0) {
/* Do nothing */
}
});
if (selection != null) {
@ -1853,7 +1852,9 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
} finally {
try {
is.close();
} catch (IOException e) { /* Ignore */ }
} catch (IOException e) {
/* Ignore */
}
}
} catch (SettingsImportExportException e) {
Log.w(K9.LOG_TAG, "Exception during import", e);
@ -1924,13 +1925,14 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
} finally {
try {
is.close();
} catch (IOException e) { /* Ignore */ }
} catch (IOException e) {
/* Ignore */
}
}
} catch (SettingsImportExportException e) {
Log.w(K9.LOG_TAG, "Exception during export", e);
return false;
}
catch (FileNotFoundException e) {
} catch (FileNotFoundException e) {
Log.w(K9.LOG_TAG, "Couldn't read content from URI " + mUri);
return false;
}

View File

@ -367,8 +367,7 @@ public class FolderList extends K9ListActivity {
public boolean onKeyDown(int keyCode, KeyEvent event) {
//Shortcuts that work no matter what is selected
switch (keyCode) {
case KeyEvent.KEYCODE_Q:
{
case KeyEvent.KEYCODE_Q: {
onAccounts();
return true;
}

View File

@ -79,6 +79,8 @@ import com.fsck.k9.mail.store.LocalStore.LocalAttachmentBody;
public class MessageCompose extends K9Activity implements OnClickListener, OnFocusChangeListener {
private static final int DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE = 1;
private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2;
private static final int DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY = 3;
private static final String ACTION_COMPOSE = "com.fsck.k9.intent.action.COMPOSE";
private static final String ACTION_REPLY = "com.fsck.k9.intent.action.REPLY";
@ -112,6 +114,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private static final String STATE_REFERENCES = "com.fsck.k9.activity.MessageCompose.references";
private static final String STATE_KEY_MESSAGE_FORMAT = "com.fsck.k9.activity.MessageCompose.messageFormat";
private static final String STATE_KEY_READ_RECEIPT = "com.fsck.k9.activity.MessageCompose.messageReadReceipt";
private static final String STATE_KEY_DRAFT_NEEDS_SAVING = "com.fsck.k9.activity.MessageCompose.mDraftNeedsSaving";
private static final int MSG_PROGRESS_ON = 1;
private static final int MSG_PROGRESS_OFF = 2;
@ -207,6 +210,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private ImageButton mAddBccFromContacts;
private PgpData mPgpData = null;
private boolean mAutoEncrypt = false;
private boolean mContinueWithoutPublicKey = false;
private String mReferences;
private String mInReplyTo;
@ -218,6 +223,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private boolean mDraftNeedsSaving = false;
private boolean mPreventDraftSaving = false;
private boolean mIgnoreOnStop = false;
/**
* The draft uid of this message. This is used when saving drafts so that the same draft is
* overwritten instead of being created anew. This property is null until the first save.
@ -441,6 +448,30 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
public void afterTextChanged(android.text.Editable s) { }
};
// For watching changes to the To:, Cc:, and Bcc: fields for auto-encryption on a matching
// address.
TextWatcher recipientWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int before, int after) { }
public void onTextChanged(CharSequence s, int start, int before, int count) {
mDraftNeedsSaving = true;
}
public void afterTextChanged(android.text.Editable s) {
final CryptoProvider crypto = mAccount.getCryptoProvider();
if (mAutoEncrypt && crypto.isAvailable(getApplicationContext())) {
for (Address address : getRecipientAddresses()) {
if (crypto.hasPublicKeyForEmail(getApplicationContext(),
address.getAddress())) {
mEncryptCheckbox.setChecked(true);
mContinueWithoutPublicKey = false;
break;
}
}
}
}
};
TextWatcher sigwatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start,
int before, int after) { }
@ -454,9 +485,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
public void afterTextChanged(android.text.Editable s) { }
};
mToView.addTextChangedListener(watcher);
mCcView.addTextChangedListener(watcher);
mBccView.addTextChangedListener(watcher);
mToView.addTextChangedListener(recipientWatcher);
mCcView.addTextChangedListener(recipientWatcher);
mBccView.addTextChangedListener(recipientWatcher);
mSubjectView.addTextChangedListener(watcher);
mMessageContentView.addTextChangedListener(watcher);
@ -615,6 +646,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mCryptoSignatureUserId = (TextView)findViewById(R.id.userId);
mCryptoSignatureUserIdRest = (TextView)findViewById(R.id.userIdRest);
mEncryptCheckbox = (CheckBox)findViewById(R.id.cb_encrypt);
if (mSourceMessageBody != null) {
// mSourceMessageBody is set to something when replying to and forwarding decrypted
// messages, so the sender probably wants the message to be encrypted.
mEncryptCheckbox.setChecked(true);
}
initializeCrypto();
final CryptoProvider crypto = mAccount.getCryptoProvider();
@ -648,6 +684,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
}
updateEncryptLayout();
mAutoEncrypt = mAccount.isCryptoAutoEncrypt();
} else {
mEncryptLayout.setVisibility(View.GONE);
}
@ -681,8 +718,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
* Dear developer, if your application is using those EXTRAs you're doing
* it wrong! So go fix your program or get AOSP to change the documentation.
*/
}
else if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action)) {
} else if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action)) {
/*
* Note: Here we allow a slight deviation from the documentated behavior.
* EXTRA_TEXT is used as message body (if available) regardless of the MIME
@ -773,6 +809,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mCryptoSignatureUserId.setVisibility(View.INVISIBLE);
mCryptoSignatureUserIdRest.setVisibility(View.INVISIBLE);
} else {
mMessageFormat = MessageFormat.TEXT;
// if a signature key is selected, then the checkbox itself has no text
mCryptoSignatureCheckbox.setText("");
mCryptoSignatureCheckbox.setChecked(true);
@ -800,14 +837,23 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
@Override
public void onResume() {
super.onResume();
mIgnoreOnStop = false;
MessagingController.getInstance(getApplication()).addListener(mListener);
}
@Override
public void onPause() {
super.onPause();
saveIfNeeded();
MessagingController.getInstance(getApplication()).removeListener(mListener);
// Save email as draft when activity is changed (go to home screen, call received) or screen locked
// don't do this if only changing orientations
if ((getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) {
// don't do this if selecting signature or if "Encrypt" is checked or if adding an attachment
if (!mPreventDraftSaving && !mEncryptCheckbox.isChecked() && !mIgnoreOnStop) {
saveIfNeeded();
finish();
}
}
}
/**
@ -821,7 +867,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveIfNeeded();
ArrayList<Uri> attachments = new ArrayList<Uri>();
for (int i = 0, count = mAttachments.getChildCount(); i < count; i++) {
View view = mAttachments.getChildAt(i);
@ -842,6 +887,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
outState.putSerializable(STATE_KEY_HTML_QUOTE, mQuotedHtmlContent);
outState.putSerializable(STATE_KEY_MESSAGE_FORMAT, mMessageFormat);
outState.putBoolean(STATE_KEY_READ_RECEIPT, mReadReceipt);
outState.putBoolean(STATE_KEY_DRAFT_NEEDS_SAVING, mDraftNeedsSaving);
}
@Override
@ -875,13 +921,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
mPgpData = (PgpData) savedInstanceState.getSerializable(STATE_PGP_DATA);
mInReplyTo = savedInstanceState.getString(STATE_IN_REPLY_TO);
mReferences = savedInstanceState.getString(STATE_REFERENCES);
mDraftNeedsSaving = savedInstanceState.getBoolean(STATE_KEY_DRAFT_NEEDS_SAVING);
initializeCrypto();
updateFrom();
updateSignature();
updateEncryptLayout();
mDraftNeedsSaving = false;
}
private void updateTitle() {
@ -916,6 +962,16 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
return Address.parseUnencoded(view.getText().toString().trim());
}
/*
* Returns an Address array of recipients this email will be sent to.
* @return Address array of recipients this email will be sent to.
*/
private Address[] getRecipientAddresses() {
String addresses = mToView.getText().toString() + mCcView.getText().toString()
+ mBccView.getText().toString();
return Address.parseUnencoded(addresses.trim());
}
/*
* Build the Body that will contain the text of the message. We'll decide where to
* include it later. Draft messages are treated somewhat differently in that signatures are not
@ -957,7 +1013,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
// Place the signature immediately after the reply.
if (!isDraft) {
if (mQuoteStyle == QuoteStyle.HEADER || replyAfterQuote || mAccount.isSignatureBeforeQuotedText()) {
Log.d("ASH", "appending signature after new content");
text = appendSignature(text);
}
}
@ -1427,7 +1482,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
private void saveIfNeeded() {
if (!mDraftNeedsSaving || mPreventDraftSaving || mPgpData.hasEncryptionKeys()) {
if (!mDraftNeedsSaving || mPreventDraftSaving || mPgpData.hasEncryptionKeys() ||
mEncryptCheckbox.isChecked()) {
return;
}
@ -1457,19 +1513,20 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
Toast.makeText(this, getString(R.string.message_compose_error_no_recipients), Toast.LENGTH_LONG).show();
return;
}
final CryptoProvider crypto = mAccount.getCryptoProvider();
if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) {
mMessageFormat = MessageFormat.TEXT;
// key selection before encryption
StringBuilder emails = new StringBuilder();
Address[][] addresses = new Address[][] { getAddresses(mToView),
getAddresses(mCcView),
getAddresses(mBccView)
};
for (Address[] addressArray : addresses) {
for (Address address : addressArray) {
for (Address address : getRecipientAddresses()) {
if (emails.length() != 0) {
emails.append(',');
}
emails.append(address.getAddress());
if (!mContinueWithoutPublicKey &&
!crypto.hasPublicKeyForEmail(this, address.getAddress())) {
showDialog(DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY);
return;
}
}
if (emails.length() != 0) {
@ -1478,7 +1535,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
emails.append(mIdentity.getEmail());
mPreventDraftSaving = true;
if (!mAccount.getCryptoProvider().selectEncryptionKeys(MessageCompose.this, emails.toString(), mPgpData)) {
if (!crypto.selectEncryptionKeys(MessageCompose.this, emails.toString(), mPgpData)) {
mPreventDraftSaving = false;
}
return;
@ -1487,7 +1544,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
if (mPgpData.getEncryptedData() == null) {
String text = buildText(false).getText();
mPreventDraftSaving = true;
if (!mAccount.getCryptoProvider().encrypt(this, text, mPgpData)) {
if (!crypto.encrypt(this, text, mPgpData)) {
mPreventDraftSaving = false;
}
return;
@ -1520,7 +1577,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
private void onSave() {
mDraftNeedsSaving = true;
saveIfNeeded();
finish();
}
@ -1547,6 +1603,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
* Kick off a picker for whatever kind of MIME types we'll accept and let Android take over.
*/
private void onAddAttachment() {
mIgnoreOnStop = true;
if (K9.isGalleryBuggy()) {
if (K9.useGalleryBugWorkaround()) {
Toast.makeText(MessageCompose.this,
@ -1853,7 +1910,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
onSend();
break;
case R.id.save:
if (mEncryptCheckbox.isChecked()) {
showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED);
} else {
onSave();
}
break;
case R.id.discard:
onDiscard();
@ -1927,7 +1988,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
@Override
public void onBackPressed() {
if (mDraftNeedsSaving) {
if (mEncryptCheckbox.isChecked()) {
showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED);
} else if (mDraftNeedsSaving) {
showDialog(DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE);
} else {
super.onBackPressed();
@ -1954,6 +2017,34 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
}
})
.create();
case DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED:
return new AlertDialog.Builder(this)
.setTitle(R.string.refuse_to_save_draft_marked_encrypted_dlg_title)
.setMessage(R.string.refuse_to_save_draft_marked_encrypted_instructions_fmt)
.setNeutralButton(R.string.okay_action, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dismissDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED);
}
})
.create();
case DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY:
return new AlertDialog.Builder(this)
.setTitle(R.string.continue_without_public_key_dlg_title)
.setMessage(R.string.continue_without_public_key_instructions_fmt)
.setPositiveButton(R.string.continue_action, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dismissDialog(DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY);
mContinueWithoutPublicKey = true;
onSend();
}
})
.setNegativeButton(R.string.back_action, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dismissDialog(DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY);
mContinueWithoutPublicKey = false;
}
})
.create();
}
return super.onCreateDialog(id);
}
@ -2824,7 +2915,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
private class SaveMessageTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
/*
* Create the message from all the data the user has entered.
*/
@ -2855,10 +2945,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
Message draftMessage = messagingController.saveDraft(mAccount, message);
mDraftUid = draftMessage.getUid();
// Don't display the toast if the user is just changing the orientation
if ((getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) {
mHandler.sendEmptyMessage(MSG_SAVED_DRAFT);
}
return null;
}
}

View File

@ -92,7 +92,9 @@ public class MessageView extends K9Activity implements OnClickListener {
}
@Override
public void onMount(String providerId) { /* no-op */ }
public void onMount(String providerId) {
/* no-op */
}
}
@ -117,7 +119,7 @@ public class MessageView extends K9Activity implements OnClickListener {
public boolean dispatchKeyEvent(KeyEvent event) {
boolean ret = false;
if (KeyEvent.ACTION_DOWN == event.getAction()) {
ret = onKeyDown(event.getKeyCode(), event);
ret = onCustomKeyDown(event.getKeyCode(), event);
}
if (!ret) {
ret = super.dispatchKeyEvent(event);
@ -125,29 +127,36 @@ public class MessageView extends K9Activity implements OnClickListener {
return ret;
}
@Override
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
if (
// XXX TODO - when we go to android 2.0, uncomment this
// android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR &&
keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
// Take care of calling this method on earlier versions of
// the platform where it doesn't exist.
onBackPressed();
return true;
}
/**
* Handle hotkeys
*
* <p>
* This method is called by {@link #dispatchKeyEvent(KeyEvent)} before any view had the chance
* to consume this key event.
* </p>
*
* @param keyCode
* The value in {@code event.getKeyCode()}.
* @param event
* Description of the key event.
*
* @return {@code true} if this event was consumed.
*/
public boolean onCustomKeyDown(final int keyCode, final KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP: {
if (K9.useVolumeKeysForNavigationEnabled()) {
onNext();
return true;
}
break;
}
case KeyEvent.KEYCODE_VOLUME_DOWN: {
if (K9.useVolumeKeysForNavigationEnabled()) {
onPrevious();
return true;
}
break;
}
case KeyEvent.KEYCODE_SHIFT_LEFT:
case KeyEvent.KEYCODE_SHIFT_RIGHT: {
@ -222,7 +231,7 @@ public class MessageView extends K9Activity implements OnClickListener {
return true;
}
}
return super.onKeyDown(keyCode, event);
return false;
}
@Override

View File

@ -96,6 +96,7 @@ public class AccountSettings extends K9PreferenceActivity {
private static final String PREFERENCE_SYNC_REMOTE_DELETIONS = "account_sync_remote_deletetions";
private static final String PREFERENCE_CRYPTO_APP = "crypto_app";
private static final String PREFERENCE_CRYPTO_AUTO_SIGNATURE = "crypto_auto_signature";
private static final String PREFERENCE_CRYPTO_AUTO_ENCRYPT = "crypto_auto_encrypt";
private static final String PREFERENCE_LOCAL_STORAGE_PROVIDER = "local_storage_provider";
@ -160,6 +161,7 @@ public class AccountSettings extends K9PreferenceActivity {
private ListPreference mMaxPushFolders;
private ListPreference mCryptoApp;
private CheckBoxPreference mCryptoAutoSignature;
private CheckBoxPreference mCryptoAutoEncrypt;
private ListPreference mLocalStorageProvider;
@ -680,14 +682,19 @@ public class AccountSettings extends K9PreferenceActivity {
mCryptoAutoSignature = (CheckBoxPreference) findPreference(PREFERENCE_CRYPTO_AUTO_SIGNATURE);
mCryptoAutoSignature.setChecked(mAccount.getCryptoAutoSignature());
mCryptoAutoEncrypt = (CheckBoxPreference) findPreference(PREFERENCE_CRYPTO_AUTO_ENCRYPT);
mCryptoAutoEncrypt.setChecked(mAccount.isCryptoAutoEncrypt());
handleCryptoAppDependencies();
}
private void handleCryptoAppDependencies() {
if ("".equals(mCryptoApp.getValue())) {
mCryptoAutoSignature.setEnabled(false);
mCryptoAutoEncrypt.setEnabled(false);
} else {
mCryptoAutoSignature.setEnabled(true);
mCryptoAutoEncrypt.setEnabled(true);
}
}
@ -733,6 +740,7 @@ public class AccountSettings extends K9PreferenceActivity {
mAccount.setStripSignature(mStripSignature.isChecked());
mAccount.setCryptoApp(mCryptoApp.getValue());
mAccount.setCryptoAutoSignature(mCryptoAutoSignature.isChecked());
mAccount.setCryptoAutoEncrypt(mCryptoAutoEncrypt.isChecked());
mAccount.setLocalStorageProviderId(mLocalStorageProvider.getValue());
// In webdav account we use the exact folder name also for inbox,

View File

@ -232,6 +232,95 @@ public class Apg extends CryptoProvider {
return ids;
}
/**
* Get public key ids based on a given email.
*
* @param context
* @param email The email in question.
* @return key ids
*/
@Override
public long[] getPublicKeyIdsFromEmail(Context context, String email) {
long ids[] = null;
try {
Uri contentUri = Uri.withAppendedPath(Apg.CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS, email);
Cursor c = context.getContentResolver().query(contentUri,
new String[] { "master_key_id" }, null, null, null);
if (c != null && c.getCount() > 0) {
ids = new long[c.getCount()];
while (c.moveToNext()) {
ids[c.getPosition()] = c.getLong(0);
}
}
if (c != null) {
c.close();
}
} catch (SecurityException e) {
Toast.makeText(context,
context.getResources().getString(R.string.insufficient_apg_permissions),
Toast.LENGTH_LONG).show();
}
return ids;
}
/**
* Find out if a given email has a secret key.
*
* @param context
* @param email The email in question.
* @return true if there is a secret key for this email.
*/
@Override
public boolean hasSecretKeyForEmail(Context context, String email) {
try {
Uri contentUri = Uri.withAppendedPath(Apg.CONTENT_URI_SECRET_KEY_RING_BY_EMAILS, email);
Cursor c = context.getContentResolver().query(contentUri,
new String[] { "master_key_id" }, null, null, null);
if (c != null && c.getCount() > 0) {
c.close();
return true;
}
if (c != null) {
c.close();
}
} catch (SecurityException e) {
Toast.makeText(context,
context.getResources().getString(R.string.insufficient_apg_permissions),
Toast.LENGTH_LONG).show();
}
return false;
}
/**
* Find out if a given email has a public key.
*
* @param context
* @param email The email in question.
* @return true if there is a public key for this email.
*/
@Override
public boolean hasPublicKeyForEmail(Context context, String email) {
try {
Uri contentUri = Uri.withAppendedPath(Apg.CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS, email);
Cursor c = context.getContentResolver().query(contentUri,
new String[] { "master_key_id" }, null, null, null);
if (c != null && c.getCount() > 0) {
c.close();
return true;
}
if (c != null) {
c.close();
}
} catch (SecurityException e) {
Toast.makeText(context,
context.getResources().getString(R.string.insufficient_apg_permissions),
Toast.LENGTH_LONG).show();
}
return false;
}
/**
* Get the user id based on the key id.
*

View File

@ -24,6 +24,9 @@ abstract public class CryptoProvider {
abstract public boolean encrypt(Activity activity, String data, PgpData pgpData);
abstract public boolean decrypt(Activity activity, String data, PgpData pgpData);
abstract public long[] getSecretKeyIdsFromEmail(Context context, String email);
abstract public long[] getPublicKeyIdsFromEmail(Context context, String email);
abstract public boolean hasSecretKeyForEmail(Context context, String email);
abstract public boolean hasPublicKeyForEmail(Context context, String email);
abstract public String getUserId(Context context, long keyId);
abstract public String getName();
abstract public boolean test(Context context);

View File

@ -37,6 +37,21 @@ public class None extends CryptoProvider {
return null;
}
@Override
public long[] getPublicKeyIdsFromEmail(Context context, String email) {
return null;
}
@Override
public boolean hasSecretKeyForEmail(Context context, String email) {
return false;
}
@Override
public boolean hasPublicKeyForEmail(Context context, String email) {
return false;
}
@Override
public String getUserId(Context context, long keyId) {
return null;

View File

@ -10,9 +10,9 @@ import java.io.InputStream;
* past where the protocol handler intended the client to read.
*/
public class FixedLengthInputStream extends InputStream {
private InputStream mIn;
private int mLength;
private int mCount;
private final InputStream mIn;
private final int mLength;
private int mCount = 0;
public FixedLengthInputStream(InputStream in, int length) {
this.mIn = in;
@ -26,34 +26,44 @@ public class FixedLengthInputStream extends InputStream {
@Override
public int read() throws IOException {
if (mCount < mLength) {
mCount++;
return mIn.read();
} else {
if (mCount >= mLength) {
return -1;
}
int d = mIn.read();
if (d != -1) {
mCount++;
}
return d;
}
@Override
public int read(byte[] b, int offset, int length) throws IOException {
if (mCount < mLength) {
if (mCount >= mLength) {
return -1;
}
int d = mIn.read(b, offset, Math.min(mLength - mCount, length));
if (d == -1) {
return -1;
} else {
if (d != -1) {
mCount += d;
}
return d;
}
} else {
return -1;
}
}
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
@Override
public long skip(long n) throws IOException {
long d = mIn.skip(Math.min(n, available()));
if (d > 0) {
mCount += d;
}
return d;
}
@Override
public String toString() {
return String.format("FixedLengthInputStream(in=%s, length=%d)", mIn.toString(), mLength);

View File

@ -109,7 +109,10 @@ public class MimeHeader {
v = EncoderUtil.encodeEncodedWord(field.value, charset);
}
writer.write(field.name + ": " + v + "\r\n");
writer.write(field.name);
writer.write(": ");
writer.write(v);
writer.write("\r\n");
}
}
writer.flush();

View File

@ -70,22 +70,29 @@ public class MimeMultipart extends Multipart {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
if (mPreamble != null) {
writer.write(mPreamble + "\r\n");
writer.write(mPreamble);
writer.write("\r\n");
}
if (mParts.isEmpty()) {
writer.write("--" + mBoundary + "\r\n");
writer.write("--");
writer.write(mBoundary);
writer.write("\r\n");
}
for (int i = 0, count = mParts.size(); i < count; i++) {
BodyPart bodyPart = mParts.get(i);
writer.write("--" + mBoundary + "\r\n");
writer.write("--");
writer.write(mBoundary);
writer.write("\r\n");
writer.flush();
bodyPart.writeTo(out);
writer.write("\r\n");
}
writer.write("--" + mBoundary + "--\r\n");
writer.write("--");
writer.write(mBoundary);
writer.write("--\r\n");
writer.flush();
}

View File

@ -888,7 +888,8 @@ public class MimeUtility {
*/
private static final String[][] MIME_TYPE_REPLACEMENT_MAP = new String[][] {
{"image/jpg", "image/jpeg"},
{"image/pjpeg", "image/jpeg"} // see issue 1712
{"image/pjpeg", "image/jpeg"}, // see issue 1712
{"application/x-zip-compressed", "application/zip"} // see issue 3791
};
public static String unfold(String s) {

View File

@ -767,8 +767,7 @@ public class EasStore extends Store {
if (getStoreSyncKey().equals(INITIAL_SYNC_KEY)) {
try {
getInitialFolderList();
}
catch (MessagingException e) {
} catch (MessagingException e) {
e.printStackTrace();
}
}

View File

@ -244,8 +244,7 @@ public class ImapStore extends Store {
userEnc = URLEncoder.encode(server.username, "UTF-8");
passwordEnc = (server.password != null) ?
URLEncoder.encode(server.password, "UTF-8") : "";
}
catch (UnsupportedEncodingException e) {
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Could not encode username or password", e);
}
@ -280,9 +279,9 @@ public class ImapStore extends Store {
String userInfo = authType.toString() + ":" + userEnc + ":" + passwordEnc;
try {
Map<String, String> extra = server.getExtra();
String prefix = (extra != null) ? extra.get(ImapStoreSettings.PATH_PREFIX_KEY) : null;
String path = (extra != null) ? "/" + extra.get(ImapStoreSettings.PATH_PREFIX_KEY) : null;
return new URI(scheme, userInfo, server.host, server.port,
prefix,
path,
null, null).toString();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Can't create ImapStore URI", e);

View File

@ -301,8 +301,7 @@ public class LocalStore extends Store implements Serializable {
Log.e(K9.LOG_TAG, " error trying to ugpgrade a folder class", e);
}
}
}
catch (SQLiteException e) {
} catch (SQLiteException e) {
Log.e(K9.LOG_TAG, "Exception while upgrading database to v41. folder classes may have vanished", e);
} finally {
@ -373,8 +372,7 @@ public class LocalStore extends Store implements Serializable {
}
}
}
}
catch (SQLiteException e) {
} catch (SQLiteException e) {
Log.e(K9.LOG_TAG, "Exception while upgrading database. Resetting the DB to v0");
db.setVersion(0);
throw new Error("Database upgrade failed! Resetting your DB version to 0 to force a full schema recreation.");
@ -2399,7 +2397,9 @@ public class LocalStore extends Store implements Serializable {
if (s != null) {
try {
size = Integer.parseInt(s);
} catch (NumberFormatException e) { /* Ignore */ }
} catch (NumberFormatException e) {
/* Ignore */
}
}
}
}
@ -2829,7 +2829,7 @@ public class LocalStore extends Store implements Serializable {
mLastUid = lastUid;
}
public long getOldestMessageDate() throws MessagingException {
public Long getOldestMessageDate() throws MessagingException {
return database.execute(false, new DbCallback<Long>() {
@Override
public Long doDbWork(final SQLiteDatabase db) {

View File

@ -156,8 +156,7 @@ public class Pop3Store extends Store {
userEnc = URLEncoder.encode(server.username, "UTF-8");
passwordEnc = (server.password != null) ?
URLEncoder.encode(server.password, "UTF-8") : "";
}
catch (UnsupportedEncodingException e) {
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Could not encode username or password", e);
}

View File

@ -206,8 +206,7 @@ public class WebDavStore extends Store {
userEnc = URLEncoder.encode(server.username, "UTF-8");
passwordEnc = (server.password != null) ?
URLEncoder.encode(server.password, "UTF-8") : "";
}
catch (UnsupportedEncodingException e) {
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Could not encode username or password", e);
}
@ -242,9 +241,9 @@ public class WebDavStore extends Store {
authPath = (authPath != null) ? authPath : "";
String mailboxPath = extra.get(WebDavStoreSettings.MAILBOX_PATH_KEY);
mailboxPath = (mailboxPath != null) ? mailboxPath : "";
uriPath = path + "|" + authPath + "|" + mailboxPath;
uriPath = "/" + path + "|" + authPath + "|" + mailboxPath;
} else {
uriPath = "||";
uriPath = "/||";
}
try {

View File

@ -368,11 +368,16 @@ public class ProvisionParser extends Parser {
// bit 25: remote wipe capability required
private static final int REQUIRE_REMOTE_WIPE = 1 << 25;
/*package*/ final int mMinPasswordLength;
/*package*/ final int mPasswordMode;
/*package*/ final int mMaxPasswordFails;
/*package*/ final int mMaxScreenLockTime;
/*package*/ final boolean mRequireRemoteWipe;
/*package*/
final int mMinPasswordLength;
/*package*/
final int mPasswordMode;
/*package*/
final int mMaxPasswordFails;
/*package*/
final int mMaxScreenLockTime;
/*package*/
final boolean mRequireRemoteWipe;
public int getMinPasswordLengthForTest() {
return mMinPasswordLength;

View File

@ -479,7 +479,8 @@ public class Tags {
public static final int BASE_CONTENT_TYPE = BASE_PAGE + 0x17;
static public String[][] pages = {
{ // 0x00 AirSync
{
// 0x00 AirSync
"Sync", "Responses", "Add", "Change", "Delete", "Fetch", "SyncKey", "ClientId",
"ServerId", "Status", "Collection", "Class", "Version", "CollectionId", "GetChanges",
"MoreAvailable", "WindowSize", "Commands", "Options", "FilterType", "Truncation",

View File

@ -139,8 +139,7 @@ public class SmtpTransport extends Transport {
URLEncoder.encode(server.username, "UTF-8") : "";
passwordEnc = (server.password != null) ?
URLEncoder.encode(server.password, "UTF-8") : "";
}
catch (UnsupportedEncodingException e) {
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("Could not encode username or password", e);
}

View File

@ -27,6 +27,7 @@ public class AccountSettings {
s.put("chipColor", new ColorSetting(0xFF0000FF));
s.put("cryptoApp", new StringSetting(Apg.NAME));
s.put("cryptoAutoSignature", new BooleanSetting(false));
s.put("cryptoAutoEncrypt", new BooleanSetting(false)); // added to version 3
s.put("defaultQuotedTextShown", new BooleanSetting(Account.DEFAULT_QUOTED_TEXT_SHOWN));
s.put("deletePolicy", new DeletePolicySetting(Account.DELETE_POLICY_NEVER));
s.put("displayCount", new IntegerResourceSetting(K9.DEFAULT_VISIBLE_LIMIT,
@ -248,7 +249,9 @@ public class AccountSettings {
if (mMapping.containsKey(deletePolicy)) {
return deletePolicy;
}
} catch (NumberFormatException e) { /* do nothing */ }
} catch (NumberFormatException e) {
/* do nothing */
}
throw new InvalidSettingValueException();
}

View File

@ -186,7 +186,9 @@ public class GlobalSettings {
if (mMapping.containsKey(theme)) {
return theme;
}
} catch (NumberFormatException e) { /* do nothing */ }
} catch (NumberFormatException e) {
/* do nothing */
}
throw new InvalidSettingValueException();
}
@ -249,7 +251,9 @@ public class GlobalSettings {
if (new File(value).isDirectory()) {
return value;
}
} catch (Exception e) { /* do nothing */ }
} catch (Exception e) {
/* do nothing */
}
throw new InvalidSettingValueException();
}

View File

@ -32,7 +32,7 @@ public class Settings {
*
* @see SettingsExporter
*/
public static final int VERSION = 2;
public static final int VERSION = 3;
public static Map<String, String> validate(Map<String, SettingsDescription> settings,
Map<String, String> importedSettings, boolean useDefaultValues) {
@ -245,7 +245,9 @@ public class Settings {
if (value.length() == 7) {
return Integer.parseInt(value.substring(1), 16) | 0xFF000000;
}
} catch (NumberFormatException e) { /* do nothing */ }
} catch (NumberFormatException e) {
/* do nothing */
}
throw new InvalidSettingValueException();
}
@ -339,7 +341,9 @@ public class Settings {
if (mMapping.containsKey(fontSize)) {
return fontSize;
}
} catch (NumberFormatException e) { /* do nothing */ }
} catch (NumberFormatException e) {
/* do nothing */
}
throw new InvalidSettingValueException();
}
@ -375,7 +379,9 @@ public class Settings {
if (mMapping.containsKey(fontSize)) {
return fontSize;
}
} catch (NumberFormatException e) { /* do nothing */ }
} catch (NumberFormatException e) {
/* do nothing */
}
throw new InvalidSettingValueException();
}
@ -401,7 +407,9 @@ public class Settings {
if (mStart <= intValue && intValue <= mEnd) {
return intValue;
}
} catch (NumberFormatException e) { /* do nothing */ }
} catch (NumberFormatException e) {
/* do nothing */
}
throw new InvalidSettingValueException();
}

View File

@ -81,8 +81,7 @@ public class SettingsExporter {
OutputStream os = null;
String filename = null;
try
{
try {
File dir = new File(Environment.getExternalStorageDirectory() + File.separator
+ context.getPackageName());
dir.mkdirs();
@ -114,7 +113,7 @@ public class SettingsExporter {
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(os, "UTF-8");
serializer.startDocument(null, Boolean.valueOf(true));
serializer.startDocument(null, Boolean.TRUE);
// Output with indentation
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@ -293,7 +292,9 @@ public class SettingsExporter {
// This is an identity key. Save identity index for later...
try {
identities.add(Integer.parseInt(thirdPart));
} catch (NumberFormatException e) { /* ignore */ }
} catch (NumberFormatException e) {
/* ignore */
}
// ... but don't write it now.
continue;
}

View File

@ -176,8 +176,7 @@ public class SettingsImporter {
boolean globalSettings, List<String> accountUuids, boolean overwrite)
throws SettingsImportExportException {
try
{
try {
boolean globalSettingsImported = false;
List<AccountDescriptionPair> importedAccounts = new ArrayList<AccountDescriptionPair>();
List<AccountDescription> errorneousAccounts = new ArrayList<AccountDescription>();

View File

@ -258,7 +258,9 @@ public abstract class CoreService extends Service {
try {
// Release the wake lock acquired at the start of this method
wakeLock.release();
} catch (Exception e) { /* ignore */ }
} catch (Exception e) {
/* ignore */
}
try {
// If there is no outstanding work to be done in a background thread we can stop
@ -267,7 +269,9 @@ public abstract class CoreService extends Service {
stopSelf(startId);
startFlag = START_NOT_STICKY;
}
} catch (Exception e) { /* ignore */ }
} catch (Exception e) {
/* ignore */
}
}
return startFlag;

View File

@ -120,8 +120,7 @@ public class SleepService extends CoreService {
endSleep(id);
}
return START_NOT_STICKY;
}
finally {
} finally {
stopSelf(startId);
}
}