mirror of
https://github.com/moparisthebest/k-9
synced 2025-01-10 13:18:09 -05:00
Update EasStore for the new URI scheme. Implement the DeviceID for EAS.
This commit is contained in:
parent
cdba29b002
commit
41b292ee9d
@ -5,6 +5,7 @@ import java.io.File;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.Editor;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
@ -21,6 +23,7 @@ import android.net.Uri;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -54,7 +57,7 @@ public class K9 extends Application {
|
|||||||
void initializeComponent(K9 application);
|
void initializeComponent(K9 application);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Application app = null;
|
public static K9 app = null;
|
||||||
public static File tempDirectory;
|
public static File tempDirectory;
|
||||||
public static final String LOG_TAG = "k9";
|
public static final String LOG_TAG = "k9";
|
||||||
|
|
||||||
@ -76,6 +79,7 @@ public class K9 extends Application {
|
|||||||
private static final FontSizes fontSizes = new FontSizes();
|
private static final FontSizes fontSizes = new FontSizes();
|
||||||
|
|
||||||
private static BACKGROUND_OPS backgroundOps = BACKGROUND_OPS.WHEN_CHECKED;
|
private static BACKGROUND_OPS backgroundOps = BACKGROUND_OPS.WHEN_CHECKED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some log messages can be sent to a file, so that the logs
|
* Some log messages can be sent to a file, so that the logs
|
||||||
* can be read using unprivileged access (eg. Terminal Emulator)
|
* can be read using unprivileged access (eg. Terminal Emulator)
|
||||||
@ -91,7 +95,6 @@ public class K9 extends Application {
|
|||||||
**/
|
**/
|
||||||
public static boolean DEVELOPER_MODE = true;
|
public static boolean DEVELOPER_MODE = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is enabled there will be additional logging information sent to
|
* If this is enabled there will be additional logging information sent to
|
||||||
* Log.d, including protocol dumps.
|
* Log.d, including protocol dumps.
|
||||||
@ -103,33 +106,26 @@ public class K9 extends Application {
|
|||||||
* Should K-9 log the conversation it has over the wire with
|
* Should K-9 log the conversation it has over the wire with
|
||||||
* SMTP servers?
|
* SMTP servers?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static boolean DEBUG_PROTOCOL_SMTP = true;
|
public static boolean DEBUG_PROTOCOL_SMTP = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should K-9 log the conversation it has over the wire with
|
* Should K-9 log the conversation it has over the wire with
|
||||||
* IMAP servers?
|
* IMAP servers?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static boolean DEBUG_PROTOCOL_IMAP = true;
|
public static boolean DEBUG_PROTOCOL_IMAP = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should K-9 log the conversation it has over the wire with
|
* Should K-9 log the conversation it has over the wire with
|
||||||
* POP3 servers?
|
* POP3 servers?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static boolean DEBUG_PROTOCOL_POP3 = true;
|
public static boolean DEBUG_PROTOCOL_POP3 = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should K-9 log the conversation it has over the wire with
|
* Should K-9 log the conversation it has over the wire with
|
||||||
* WebDAV servers?
|
* WebDAV servers?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static boolean DEBUG_PROTOCOL_WEBDAV = true;
|
public static boolean DEBUG_PROTOCOL_WEBDAV = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is enabled than logging that normally hides sensitive information
|
* If this is enabled than logging that normally hides sensitive information
|
||||||
* like passwords will show that information.
|
* like passwords will show that information.
|
||||||
@ -144,18 +140,15 @@ public class K9 extends Application {
|
|||||||
public static String ERROR_FOLDER_NAME = "K9mail-errors";
|
public static String ERROR_FOLDER_NAME = "K9mail-errors";
|
||||||
|
|
||||||
private static boolean mAnimations = true;
|
private static boolean mAnimations = true;
|
||||||
|
|
||||||
private static boolean mConfirmDelete = false;
|
private static boolean mConfirmDelete = false;
|
||||||
private static boolean mConfirmDeleteStarred = false;
|
private static boolean mConfirmDeleteStarred = false;
|
||||||
private static boolean mConfirmSpam = false;
|
private static boolean mConfirmSpam = false;
|
||||||
private static boolean mConfirmMarkAllAsRead = true;
|
private static boolean mConfirmMarkAllAsRead = true;
|
||||||
private static boolean mKeyguardPrivacy = false;
|
private static boolean mKeyguardPrivacy = false;
|
||||||
|
|
||||||
private static boolean mMessageListStars = true;
|
private static boolean mMessageListStars = true;
|
||||||
private static boolean mMessageListCheckboxes = false;
|
private static boolean mMessageListCheckboxes = false;
|
||||||
private static boolean mMessageListTouchable = false;
|
private static boolean mMessageListTouchable = false;
|
||||||
private static int mMessageListPreviewLines = 2;
|
private static int mMessageListPreviewLines = 2;
|
||||||
|
|
||||||
private static boolean mShowCorrespondentNames = true;
|
private static boolean mShowCorrespondentNames = true;
|
||||||
private static boolean mShowContactName = false;
|
private static boolean mShowContactName = false;
|
||||||
private static boolean mChangeContactNameColor = false;
|
private static boolean mChangeContactNameColor = false;
|
||||||
@ -163,7 +156,6 @@ public class K9 extends Application {
|
|||||||
private static boolean mMessageViewFixedWidthFont = false;
|
private static boolean mMessageViewFixedWidthFont = false;
|
||||||
private static boolean mMessageViewReturnToList = false;
|
private static boolean mMessageViewReturnToList = false;
|
||||||
private static boolean mMessageViewShowNext = false;
|
private static boolean mMessageViewShowNext = false;
|
||||||
|
|
||||||
private static boolean mGesturesEnabled = true;
|
private static boolean mGesturesEnabled = true;
|
||||||
private static boolean mUseVolumeKeysForNavigation = false;
|
private static boolean mUseVolumeKeysForNavigation = false;
|
||||||
private static boolean mUseVolumeKeysForListNavigation = false;
|
private static boolean mUseVolumeKeysForListNavigation = false;
|
||||||
@ -179,11 +171,9 @@ public class K9 extends Application {
|
|||||||
private static String mQuietTimeEnds = null;
|
private static String mQuietTimeEnds = null;
|
||||||
private static boolean compactLayouts = false;
|
private static boolean compactLayouts = false;
|
||||||
private static String mAttachmentDefaultPath = "";
|
private static String mAttachmentDefaultPath = "";
|
||||||
|
|
||||||
|
|
||||||
private static boolean useGalleryBugWorkaround = false;
|
private static boolean useGalleryBugWorkaround = false;
|
||||||
private static boolean galleryBuggy;
|
private static boolean galleryBuggy;
|
||||||
|
private static String mDeviceId = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MIME type(s) of attachments we're willing to view.
|
* The MIME type(s) of attachments we're willing to view.
|
||||||
@ -238,10 +228,10 @@ public class K9 extends Application {
|
|||||||
public static final int MAX_ATTACHMENT_DOWNLOAD_SIZE = (128 * 1024 * 1024);
|
public static final int MAX_ATTACHMENT_DOWNLOAD_SIZE = (128 * 1024 * 1024);
|
||||||
|
|
||||||
|
|
||||||
/* How many times should K-9 try to deliver a message before giving up
|
/**
|
||||||
|
* How many times should K-9 try to deliver a message before giving up
|
||||||
* until the app is killed and restarted
|
* until the app is killed and restarted
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static int MAX_SEND_ATTEMPTS = 5;
|
public static int MAX_SEND_ATTEMPTS = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,17 +252,11 @@ public class K9 extends Application {
|
|||||||
*/
|
*/
|
||||||
public static final int NOTIFICATION_LED_ON_TIME = 500;
|
public static final int NOTIFICATION_LED_ON_TIME = 500;
|
||||||
public static final int NOTIFICATION_LED_OFF_TIME = 2000;
|
public static final int NOTIFICATION_LED_OFF_TIME = 2000;
|
||||||
|
|
||||||
public static final boolean NOTIFICATION_LED_WHILE_SYNCING = false;
|
public static final boolean NOTIFICATION_LED_WHILE_SYNCING = false;
|
||||||
public static final int NOTIFICATION_LED_FAST_ON_TIME = 100;
|
public static final int NOTIFICATION_LED_FAST_ON_TIME = 100;
|
||||||
public static final int NOTIFICATION_LED_FAST_OFF_TIME = 100;
|
public static final int NOTIFICATION_LED_FAST_OFF_TIME = 100;
|
||||||
|
|
||||||
|
|
||||||
public static final int NOTIFICATION_LED_BLINK_SLOW = 0;
|
public static final int NOTIFICATION_LED_BLINK_SLOW = 0;
|
||||||
public static final int NOTIFICATION_LED_BLINK_FAST = 1;
|
public static final int NOTIFICATION_LED_BLINK_FAST = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final int NOTIFICATION_LED_SENDING_FAILURE_COLOR = 0xffff0000;
|
public static final int NOTIFICATION_LED_SENDING_FAILURE_COLOR = 0xffff0000;
|
||||||
|
|
||||||
// Must not conflict with an account number
|
// Must not conflict with an account number
|
||||||
@ -280,7 +264,6 @@ public class K9 extends Application {
|
|||||||
public static final int SEND_FAILED_NOTIFICATION = -1500;
|
public static final int SEND_FAILED_NOTIFICATION = -1500;
|
||||||
public static final int CONNECTIVITY_ID = -3;
|
public static final int CONNECTIVITY_ID = -3;
|
||||||
|
|
||||||
|
|
||||||
public static class Intents {
|
public static class Intents {
|
||||||
|
|
||||||
public static class EmailReceived {
|
public static class EmailReceived {
|
||||||
@ -317,7 +300,6 @@ public class K9 extends Application {
|
|||||||
int acctLength = Preferences.getPreferences(context).getAvailableAccounts().size();
|
int acctLength = Preferences.getPreferences(context).getAvailableAccounts().size();
|
||||||
|
|
||||||
setServicesEnabled(context, acctLength > 0, null);
|
setServicesEnabled(context, acctLength > 0, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setServicesEnabled(Context context, boolean enabled, Integer wakeLockId) {
|
private static void setServicesEnabled(Context context, boolean enabled, Integer wakeLockId) {
|
||||||
@ -356,7 +338,6 @@ public class K9 extends Application {
|
|||||||
*/
|
*/
|
||||||
MailService.actionReset(context, wakeLockId);
|
MailService.actionReset(context, wakeLockId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -414,7 +395,6 @@ public class K9 extends Application {
|
|||||||
editor.putBoolean("quietTimeEnabled", mQuietTimeEnabled);
|
editor.putBoolean("quietTimeEnabled", mQuietTimeEnabled);
|
||||||
editor.putString("quietTimeStarts", mQuietTimeStarts);
|
editor.putString("quietTimeStarts", mQuietTimeStarts);
|
||||||
editor.putString("quietTimeEnds", mQuietTimeEnds);
|
editor.putString("quietTimeEnds", mQuietTimeEnds);
|
||||||
|
|
||||||
editor.putBoolean("startIntegratedInbox", mStartIntegratedInbox);
|
editor.putBoolean("startIntegratedInbox", mStartIntegratedInbox);
|
||||||
editor.putBoolean("measureAccounts", mMeasureAccounts);
|
editor.putBoolean("measureAccounts", mMeasureAccounts);
|
||||||
editor.putBoolean("countSearchMessages", mCountSearchMessages);
|
editor.putBoolean("countSearchMessages", mCountSearchMessages);
|
||||||
@ -423,7 +403,6 @@ public class K9 extends Application {
|
|||||||
editor.putBoolean("messageListCheckboxes", mMessageListCheckboxes);
|
editor.putBoolean("messageListCheckboxes", mMessageListCheckboxes);
|
||||||
editor.putBoolean("messageListTouchable", mMessageListTouchable);
|
editor.putBoolean("messageListTouchable", mMessageListTouchable);
|
||||||
editor.putInt("messageListPreviewLines", mMessageListPreviewLines);
|
editor.putInt("messageListPreviewLines", mMessageListPreviewLines);
|
||||||
|
|
||||||
editor.putBoolean("showCorrespondentNames", mShowCorrespondentNames);
|
editor.putBoolean("showCorrespondentNames", mShowCorrespondentNames);
|
||||||
editor.putBoolean("showContactName", mShowContactName);
|
editor.putBoolean("showContactName", mShowContactName);
|
||||||
editor.putBoolean("changeRegisteredNameColor", mChangeContactNameColor);
|
editor.putBoolean("changeRegisteredNameColor", mChangeContactNameColor);
|
||||||
@ -431,20 +410,17 @@ public class K9 extends Application {
|
|||||||
editor.putBoolean("messageViewFixedWidthFont", mMessageViewFixedWidthFont);
|
editor.putBoolean("messageViewFixedWidthFont", mMessageViewFixedWidthFont);
|
||||||
editor.putBoolean("messageViewReturnToList", mMessageViewReturnToList);
|
editor.putBoolean("messageViewReturnToList", mMessageViewReturnToList);
|
||||||
editor.putBoolean("messageViewShowNext", mMessageViewShowNext);
|
editor.putBoolean("messageViewShowNext", mMessageViewShowNext);
|
||||||
|
|
||||||
editor.putString("language", language);
|
editor.putString("language", language);
|
||||||
editor.putInt("theme", theme);
|
editor.putInt("theme", theme);
|
||||||
editor.putBoolean("useGalleryBugWorkaround", useGalleryBugWorkaround);
|
editor.putBoolean("useGalleryBugWorkaround", useGalleryBugWorkaround);
|
||||||
|
|
||||||
editor.putBoolean("confirmDelete", mConfirmDelete);
|
editor.putBoolean("confirmDelete", mConfirmDelete);
|
||||||
editor.putBoolean("confirmDeleteStarred", mConfirmDeleteStarred);
|
editor.putBoolean("confirmDeleteStarred", mConfirmDeleteStarred);
|
||||||
editor.putBoolean("confirmSpam", mConfirmSpam);
|
editor.putBoolean("confirmSpam", mConfirmSpam);
|
||||||
editor.putBoolean("confirmMarkAllAsRead", mConfirmMarkAllAsRead);
|
editor.putBoolean("confirmMarkAllAsRead", mConfirmMarkAllAsRead);
|
||||||
|
|
||||||
editor.putBoolean("keyguardPrivacy", mKeyguardPrivacy);
|
editor.putBoolean("keyguardPrivacy", mKeyguardPrivacy);
|
||||||
|
|
||||||
editor.putBoolean("compactLayouts", compactLayouts);
|
editor.putBoolean("compactLayouts", compactLayouts);
|
||||||
editor.putString("attachmentdefaultpath", mAttachmentDefaultPath);
|
editor.putString("attachmentdefaultpath", mAttachmentDefaultPath);
|
||||||
|
editor.putString("deviceId", mDeviceId);
|
||||||
fontSizes.save(editor);
|
fontSizes.save(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +430,6 @@ public class K9 extends Application {
|
|||||||
super.onCreate();
|
super.onCreate();
|
||||||
app = this;
|
app = this;
|
||||||
|
|
||||||
|
|
||||||
galleryBuggy = checkForBuggyGallery();
|
galleryBuggy = checkForBuggyGallery();
|
||||||
|
|
||||||
Preferences prefs = Preferences.getPreferences(this);
|
Preferences prefs = Preferences.getPreferences(this);
|
||||||
@ -469,7 +444,6 @@ public class K9 extends Application {
|
|||||||
/*
|
/*
|
||||||
* Enable background sync of messages
|
* Enable background sync of messages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setServicesEnabled(this);
|
setServicesEnabled(this);
|
||||||
registerReceivers();
|
registerReceivers();
|
||||||
|
|
||||||
@ -547,14 +521,11 @@ public class K9 extends Application {
|
|||||||
mMessageListCheckboxes = sprefs.getBoolean("messageListCheckboxes", false);
|
mMessageListCheckboxes = sprefs.getBoolean("messageListCheckboxes", false);
|
||||||
mMessageListTouchable = sprefs.getBoolean("messageListTouchable", false);
|
mMessageListTouchable = sprefs.getBoolean("messageListTouchable", false);
|
||||||
mMessageListPreviewLines = sprefs.getInt("messageListPreviewLines", 2);
|
mMessageListPreviewLines = sprefs.getInt("messageListPreviewLines", 2);
|
||||||
|
|
||||||
mMobileOptimizedLayout = sprefs.getBoolean("mobileOptimizedLayout", false);
|
mMobileOptimizedLayout = sprefs.getBoolean("mobileOptimizedLayout", false);
|
||||||
mZoomControlsEnabled = sprefs.getBoolean("zoomControlsEnabled", false);
|
mZoomControlsEnabled = sprefs.getBoolean("zoomControlsEnabled", false);
|
||||||
|
|
||||||
mQuietTimeEnabled = sprefs.getBoolean("quietTimeEnabled", false);
|
mQuietTimeEnabled = sprefs.getBoolean("quietTimeEnabled", false);
|
||||||
mQuietTimeStarts = sprefs.getString("quietTimeStarts", "21:00");
|
mQuietTimeStarts = sprefs.getString("quietTimeStarts", "21:00");
|
||||||
mQuietTimeEnds = sprefs.getString("quietTimeEnds", "7:00");
|
mQuietTimeEnds = sprefs.getString("quietTimeEnds", "7:00");
|
||||||
|
|
||||||
mShowCorrespondentNames = sprefs.getBoolean("showCorrespondentNames", true);
|
mShowCorrespondentNames = sprefs.getBoolean("showCorrespondentNames", true);
|
||||||
mShowContactName = sprefs.getBoolean("showContactName", false);
|
mShowContactName = sprefs.getBoolean("showContactName", false);
|
||||||
mChangeContactNameColor = sprefs.getBoolean("changeRegisteredNameColor", false);
|
mChangeContactNameColor = sprefs.getBoolean("changeRegisteredNameColor", false);
|
||||||
@ -562,19 +533,15 @@ public class K9 extends Application {
|
|||||||
mMessageViewFixedWidthFont = sprefs.getBoolean("messageViewFixedWidthFont", false);
|
mMessageViewFixedWidthFont = sprefs.getBoolean("messageViewFixedWidthFont", false);
|
||||||
mMessageViewReturnToList = sprefs.getBoolean("messageViewReturnToList", false);
|
mMessageViewReturnToList = sprefs.getBoolean("messageViewReturnToList", false);
|
||||||
mMessageViewShowNext = sprefs.getBoolean("messageViewShowNext", false);
|
mMessageViewShowNext = sprefs.getBoolean("messageViewShowNext", false);
|
||||||
|
|
||||||
useGalleryBugWorkaround = sprefs.getBoolean("useGalleryBugWorkaround", K9.isGalleryBuggy());
|
useGalleryBugWorkaround = sprefs.getBoolean("useGalleryBugWorkaround", K9.isGalleryBuggy());
|
||||||
|
|
||||||
mConfirmDelete = sprefs.getBoolean("confirmDelete", false);
|
mConfirmDelete = sprefs.getBoolean("confirmDelete", false);
|
||||||
mConfirmDeleteStarred = sprefs.getBoolean("confirmDeleteStarred", false);
|
mConfirmDeleteStarred = sprefs.getBoolean("confirmDeleteStarred", false);
|
||||||
mConfirmSpam = sprefs.getBoolean("confirmSpam", false);
|
mConfirmSpam = sprefs.getBoolean("confirmSpam", false);
|
||||||
mConfirmMarkAllAsRead = sprefs.getBoolean("confirmMarkAllAsRead", true);
|
mConfirmMarkAllAsRead = sprefs.getBoolean("confirmMarkAllAsRead", true);
|
||||||
|
|
||||||
|
|
||||||
mKeyguardPrivacy = sprefs.getBoolean("keyguardPrivacy", false);
|
mKeyguardPrivacy = sprefs.getBoolean("keyguardPrivacy", false);
|
||||||
|
|
||||||
compactLayouts = sprefs.getBoolean("compactLayouts", false);
|
compactLayouts = sprefs.getBoolean("compactLayouts", false);
|
||||||
mAttachmentDefaultPath = sprefs.getString("attachmentdefaultpath", Environment.getExternalStorageDirectory().toString());
|
mAttachmentDefaultPath = sprefs.getString("attachmentdefaultpath", Environment.getExternalStorageDirectory().toString());
|
||||||
|
mDeviceId = sprefs.getString("deviceId", null);
|
||||||
fontSizes.load(sprefs);
|
fontSizes.load(sprefs);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -601,10 +568,8 @@ public class K9 extends Application {
|
|||||||
// Discard , as it means we're not running on a device with strict mode
|
// Discard , as it means we're not running on a device with strict mode
|
||||||
Log.v(K9.LOG_TAG, "Failed to turn on strict mode", e);
|
Log.v(K9.LOG_TAG, "Failed to turn on strict mode", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* since Android invokes Application.onCreate() only after invoking all
|
* since Android invokes Application.onCreate() only after invoking all
|
||||||
* other components' onCreate(), here is a way to notify interested
|
* other components' onCreate(), here is a way to notify interested
|
||||||
@ -738,7 +703,6 @@ public class K9 extends Application {
|
|||||||
mQuietTimeEnds = quietTimeEnds;
|
mQuietTimeEnds = quietTimeEnds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isQuietTime() {
|
public static boolean isQuietTime() {
|
||||||
if (!mQuietTimeEnabled) {
|
if (!mQuietTimeEnabled) {
|
||||||
return false;
|
return false;
|
||||||
@ -760,7 +724,6 @@ public class K9 extends Application {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 21:00 - 05:00 means we want to be quiet if it's after 9 or before 5
|
// 21:00 - 05:00 means we want to be quiet if it's after 9 or before 5
|
||||||
if (quietStarts > quietEnds) {
|
if (quietStarts > quietEnds) {
|
||||||
// if it's 22:00 or 03:00 but not 8:00
|
// if it's 22:00 or 03:00 but not 8:00
|
||||||
@ -781,8 +744,6 @@ public class K9 extends Application {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static boolean startIntegratedInbox() {
|
public static boolean startIntegratedInbox() {
|
||||||
return mStartIntegratedInbox;
|
return mStartIntegratedInbox;
|
||||||
}
|
}
|
||||||
@ -1016,4 +977,26 @@ public class K9 extends Application {
|
|||||||
public static void setAttachmentDefaultPath(String attachmentDefaultPath) {
|
public static void setAttachmentDefaultPath(String attachmentDefaultPath) {
|
||||||
K9.mAttachmentDefaultPath = attachmentDefaultPath;
|
K9.mAttachmentDefaultPath = attachmentDefaultPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a uuid that is to identify this application on this device.
|
||||||
|
* The uuid is only generated once, and then persisted.
|
||||||
|
* @return the device Id
|
||||||
|
*/
|
||||||
|
public String getDeviceId() {
|
||||||
|
if (TextUtils.isEmpty(mDeviceId)) {
|
||||||
|
// Remove the dashes from the UUID, so that we have alphanumeric characters only.
|
||||||
|
// This increases the likelyhood of compatability with external systems that may
|
||||||
|
// use the ID.
|
||||||
|
mDeviceId = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
|
||||||
|
// This particular setting is not editted through the settings view, but instead only
|
||||||
|
// set in this method. We need to commit it now to ensure it is persisted correctly.
|
||||||
|
final Preferences preferences = Preferences.getPreferences(this);
|
||||||
|
Editor editor = preferences.getPreferences().edit();
|
||||||
|
editor.putString("deviceId", mDeviceId);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
return mDeviceId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,7 @@ public abstract class Store {
|
|||||||
* @see ImapStore#decodeUri(String)
|
* @see ImapStore#decodeUri(String)
|
||||||
* @see Pop3Store#decodeUri(String)
|
* @see Pop3Store#decodeUri(String)
|
||||||
* @see WebDavStore#decodeUri(String)
|
* @see WebDavStore#decodeUri(String)
|
||||||
|
* @see EasStore#decodeUri(String)
|
||||||
*/
|
*/
|
||||||
public static ServerSettings decodeStoreUri(String uri) {
|
public static ServerSettings decodeStoreUri(String uri) {
|
||||||
if (uri.startsWith("imap")) {
|
if (uri.startsWith("imap")) {
|
||||||
@ -107,6 +108,8 @@ public abstract class Store {
|
|||||||
return Pop3Store.decodeUri(uri);
|
return Pop3Store.decodeUri(uri);
|
||||||
} else if (uri.startsWith("webdav")) {
|
} else if (uri.startsWith("webdav")) {
|
||||||
return WebDavStore.decodeUri(uri);
|
return WebDavStore.decodeUri(uri);
|
||||||
|
} else if (uri.startsWith("eas")) {
|
||||||
|
return EasStore.decodeUri(uri);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Not a valid store URI");
|
throw new IllegalArgumentException("Not a valid store URI");
|
||||||
}
|
}
|
||||||
@ -123,6 +126,7 @@ public abstract class Store {
|
|||||||
* @see ImapStore#createUri(ServerSettings)
|
* @see ImapStore#createUri(ServerSettings)
|
||||||
* @see Pop3Store#createUri(ServerSettings)
|
* @see Pop3Store#createUri(ServerSettings)
|
||||||
* @see WebDavStore#createUri(ServerSettings)
|
* @see WebDavStore#createUri(ServerSettings)
|
||||||
|
* @see EasStore#createUri(ServerSettings)
|
||||||
*/
|
*/
|
||||||
public static String createStoreUri(ServerSettings server) {
|
public static String createStoreUri(ServerSettings server) {
|
||||||
if (ImapStore.STORE_TYPE.equals(server.type)) {
|
if (ImapStore.STORE_TYPE.equals(server.type)) {
|
||||||
@ -131,6 +135,8 @@ public abstract class Store {
|
|||||||
return Pop3Store.createUri(server);
|
return Pop3Store.createUri(server);
|
||||||
} else if (WebDavStore.STORE_TYPE.equals(server.type)) {
|
} else if (WebDavStore.STORE_TYPE.equals(server.type)) {
|
||||||
return WebDavStore.createUri(server);
|
return WebDavStore.createUri(server);
|
||||||
|
} else if (EasStore.STORE_TYPE.equals(server.type)) {
|
||||||
|
return EasStore.createUri(server);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Not a valid store URI");
|
throw new IllegalArgumentException("Not a valid store URI");
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,6 @@ import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
|
|||||||
import org.apache.http.params.BasicHttpParams;
|
import org.apache.http.params.BasicHttpParams;
|
||||||
import org.apache.http.params.HttpConnectionParams;
|
import org.apache.http.params.HttpConnectionParams;
|
||||||
import org.apache.http.params.HttpParams;
|
import org.apache.http.params.HttpParams;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
@ -51,6 +50,7 @@ import com.fsck.k9.controller.MessageRetrievalListener;
|
|||||||
import com.fsck.k9.helper.power.TracingPowerManager;
|
import com.fsck.k9.helper.power.TracingPowerManager;
|
||||||
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
||||||
import com.fsck.k9.mail.AuthenticationFailedException;
|
import com.fsck.k9.mail.AuthenticationFailedException;
|
||||||
|
import com.fsck.k9.mail.ConnectionSecurity;
|
||||||
import com.fsck.k9.mail.FetchProfile;
|
import com.fsck.k9.mail.FetchProfile;
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
import com.fsck.k9.mail.Folder;
|
import com.fsck.k9.mail.Folder;
|
||||||
@ -58,6 +58,7 @@ import com.fsck.k9.mail.Message;
|
|||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.PushReceiver;
|
import com.fsck.k9.mail.PushReceiver;
|
||||||
import com.fsck.k9.mail.Pusher;
|
import com.fsck.k9.mail.Pusher;
|
||||||
|
import com.fsck.k9.mail.ServerSettings;
|
||||||
import com.fsck.k9.mail.Store;
|
import com.fsck.k9.mail.Store;
|
||||||
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
@ -89,31 +90,32 @@ public class EasStore extends Store {
|
|||||||
// we sync the items any "collection" (emails in a folder).
|
// we sync the items any "collection" (emails in a folder).
|
||||||
private static final String INITIAL_SYNC_KEY = "0";
|
private static final String INITIAL_SYNC_KEY = "0";
|
||||||
|
|
||||||
static private final String PING_COMMAND = "Ping";
|
private static final String PING_COMMAND = "Ping";
|
||||||
static private final String PROVISION_COMMAND = "Provision";
|
private static final String PROVISION_COMMAND = "Provision";
|
||||||
|
|
||||||
// Command timeout is the the time allowed for reading data from an open connection before an
|
// Command timeout is the the time allowed for reading data from an open connection before an
|
||||||
// IOException is thrown. After a small added allowance, our watch dog alarm goes off (allowing
|
// IOException is thrown. After a small added allowance, our watch dog alarm goes off (allowing
|
||||||
// us to detect a silently dropped connection). The allowance is defined below.
|
// us to detect a silently dropped connection). The allowance is defined below.
|
||||||
static private final int COMMAND_TIMEOUT = 30 * 1000;
|
private static final int COMMAND_TIMEOUT = 30 * 1000;
|
||||||
// Connection timeout is the time given to connect to the server before reporting an IOException.
|
// Connection timeout is the time given to connect to the server before reporting an IOException.
|
||||||
static private final int CONNECTION_TIMEOUT = 20 * 1000;
|
private static final int CONNECTION_TIMEOUT = 20 * 1000;
|
||||||
|
|
||||||
// This needs to be long enough to send the longest reasonable message, without being so long
|
// This needs to be long enough to send the longest reasonable message, without being so long
|
||||||
// as to effectively "hang" sending of mail. The standard 30 second timeout isn't long enough
|
// as to effectively "hang" sending of mail. The standard 30 second timeout isn't long enough
|
||||||
// for pictures and the like. For now, we'll use 15 minutes, in the knowledge that any socket
|
// for pictures and the like. For now, we'll use 15 minutes, in the knowledge that any socket
|
||||||
// failure would probably generate an Exception before timing out anyway.
|
// failure would probably generate an Exception before timing out anyway.
|
||||||
public static final int SEND_MAIL_TIMEOUT = 15 * 60 * 1000;
|
private static final int SEND_MAIL_TIMEOUT = 15 * 60 * 1000;
|
||||||
|
|
||||||
// MSFT's custom HTTP result code indicating the need to provision.
|
// MSFT's custom HTTP result code indicating the need to provision.
|
||||||
static private final int HTTP_NEED_PROVISIONING = 449;
|
private static final int HTTP_NEED_PROVISIONING = 449;
|
||||||
|
|
||||||
// The EAS protocol Provision status for "we implement all of the policies".
|
// The EAS protocol Provision status for "we implement all of the policies".
|
||||||
static private final String PROVISION_STATUS_OK = "1";
|
private static final String PROVISION_STATUS_OK = "1";
|
||||||
// The EAS protocol Provision status meaning "we partially implement the policies".
|
// The EAS protocol Provision status meaning "we partially implement the policies".
|
||||||
static private final String PROVISION_STATUS_PARTIAL = "2";
|
private static final String PROVISION_STATUS_PARTIAL = "2";
|
||||||
|
|
||||||
static public final String EAS_12_POLICY_TYPE = "MS-EAS-Provisioning-WBXML";
|
public static final String EAS_12_POLICY_TYPE = "MS-EAS-Provisioning-WBXML";
|
||||||
static public final String EAS_2_POLICY_TYPE = "MS-WAP-Provisioning-XML";
|
public static final String EAS_2_POLICY_TYPE = "MS-WAP-Provisioning-XML";
|
||||||
|
|
||||||
private static final int IDLE_READ_TIMEOUT_INCREMENT = 5 * 60 * 1000;
|
private static final int IDLE_READ_TIMEOUT_INCREMENT = 5 * 60 * 1000;
|
||||||
private static final int IDLE_FAILURE_COUNT_LIMIT = 10;
|
private static final int IDLE_FAILURE_COUNT_LIMIT = 10;
|
||||||
@ -122,77 +124,178 @@ public class EasStore extends Store {
|
|||||||
|
|
||||||
// The number of emails to fetch for each request to the server.
|
// The number of emails to fetch for each request to the server.
|
||||||
private static final int EMAIL_WINDOW_SIZE = 10;
|
private static final int EMAIL_WINDOW_SIZE = 10;
|
||||||
|
// The maximum length of the DeviceID parameter used by EAS is 32 characters.
|
||||||
|
private static final int MAX_DEVICE_ID_SIZE = 32;
|
||||||
|
|
||||||
public String mProtocolVersion;
|
/**
|
||||||
public Double mProtocolVersionDouble;
|
* Decodes a EasStore URI.
|
||||||
protected String mDeviceId = null;
|
*
|
||||||
protected String mDeviceType = "Android";
|
* <p>Possible forms:</p>
|
||||||
private String mCmdString = null;
|
* <pre>
|
||||||
|
* eas://user:password@server:port CONNECTION_SECURITY_NONE
|
||||||
|
* eas+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL
|
||||||
|
* eas+tls+://user:password@server:port CONNECTION_SECURITY_TLS_REQUIRED
|
||||||
|
* eas+ssl+://user:password@server:port CONNECTION_SECURITY_SSL_REQUIRED
|
||||||
|
* eas+ssl://user:password@server:port CONNECTION_SECURITY_SSL_OPTIONAL
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static ServerSettings decodeUri(String uri) {
|
||||||
|
String host;
|
||||||
|
int port;
|
||||||
|
ConnectionSecurity connectionSecurity;
|
||||||
|
String username = null;
|
||||||
|
String password = null;
|
||||||
|
|
||||||
private final URI mUri; /* Stores the Uniform Resource Indicator with all connection info */
|
URI easUri;
|
||||||
private String mHost; /* Stores the host name for the server */
|
try {
|
||||||
private String mUsername; /* Stores the username for authentications */
|
easUri = new URI(uri);
|
||||||
private String mPassword; /* Stores the password for authentications */
|
} catch (URISyntaxException use) {
|
||||||
|
throw new IllegalArgumentException("Invalid EasStore URI", use);
|
||||||
|
}
|
||||||
|
|
||||||
|
String scheme = easUri.getScheme();
|
||||||
|
if (scheme.equals("eas")) {
|
||||||
|
connectionSecurity = ConnectionSecurity.NONE;
|
||||||
|
} else if (scheme.equals("eas+ssl")) {
|
||||||
|
connectionSecurity = ConnectionSecurity.SSL_TLS_OPTIONAL;
|
||||||
|
} else if (scheme.equals("eas+ssl+")) {
|
||||||
|
connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED;
|
||||||
|
} else if (scheme.equals("eas+tls")) {
|
||||||
|
connectionSecurity = ConnectionSecurity.STARTTLS_OPTIONAL;
|
||||||
|
} else if (scheme.equals("eas+tls+")) {
|
||||||
|
connectionSecurity = ConnectionSecurity.STARTTLS_REQUIRED;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported protocol (" + scheme + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
host = easUri.getHost();
|
||||||
|
if (host.startsWith("http")) {
|
||||||
|
String[] hostParts = host.split("://", 2);
|
||||||
|
if (hostParts.length > 1) {
|
||||||
|
host = hostParts[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
port = easUri.getPort();
|
||||||
|
|
||||||
|
if (easUri.getUserInfo() != null) {
|
||||||
|
try {
|
||||||
|
String[] userInfoParts = easUri.getUserInfo().split(":");
|
||||||
|
|
||||||
|
username = URLDecoder.decode(userInfoParts[0], "UTF-8");
|
||||||
|
|
||||||
|
if (userInfoParts.length > 1) {
|
||||||
|
password = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
||||||
|
}
|
||||||
|
} catch (UnsupportedEncodingException enc) {
|
||||||
|
// This shouldn't happen since the encoding is hardcoded to UTF-8
|
||||||
|
throw new IllegalArgumentException("Couldn't urldecode username or password.", enc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ServerSettings(STORE_TYPE, host, port, connectionSecurity, null, username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a EasStore URI with the supplied settings.
|
||||||
|
*
|
||||||
|
* @param server
|
||||||
|
* The {@link ServerSettings} object that holds the server settings.
|
||||||
|
*
|
||||||
|
* @return A EasStore URI that holds the same information as the {@code server} parameter.
|
||||||
|
*
|
||||||
|
* @see Account#getStoreUri()
|
||||||
|
* @see EasStore#decodeUri(String)
|
||||||
|
*/
|
||||||
|
public static String createUri(ServerSettings server) {
|
||||||
|
String userEnc;
|
||||||
|
String passwordEnc;
|
||||||
|
try {
|
||||||
|
userEnc = URLEncoder.encode(server.username, "UTF-8");
|
||||||
|
passwordEnc = (server.password != null) ?
|
||||||
|
URLEncoder.encode(server.password, "UTF-8") : "";
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new IllegalArgumentException("Could not encode username or password", e);
|
||||||
|
}
|
||||||
|
String userInfo = userEnc + ":" + passwordEnc;
|
||||||
|
|
||||||
|
String scheme;
|
||||||
|
switch (server.connectionSecurity) {
|
||||||
|
case SSL_TLS_OPTIONAL:
|
||||||
|
scheme = "eas+ssl";
|
||||||
|
break;
|
||||||
|
case SSL_TLS_REQUIRED:
|
||||||
|
scheme = "eas+ssl+";
|
||||||
|
break;
|
||||||
|
case STARTTLS_OPTIONAL:
|
||||||
|
scheme = "eas+tls";
|
||||||
|
break;
|
||||||
|
case STARTTLS_REQUIRED:
|
||||||
|
scheme = "eas+tls+";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case NONE:
|
||||||
|
scheme = "eas";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new URI(scheme, userInfo, server.host, server.port, null,
|
||||||
|
null, null).toString();
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new IllegalArgumentException("Can't create EasStore URI", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following members are set during the first contact with the Exchange server, before
|
||||||
|
// we provision or send any other requests. They are synchronized by mInitializationLock.
|
||||||
|
private String mProtocolVersion = null;
|
||||||
|
private Double mProtocolVersionDouble = null;
|
||||||
|
private String mDeviceId = null;
|
||||||
|
private Object mInitializationLock = new Object();
|
||||||
|
private final String mDeviceType = "Android";
|
||||||
|
|
||||||
|
private String mHost;
|
||||||
|
private String mUsername;
|
||||||
|
private String mPassword;
|
||||||
private short mConnectionSecurity;
|
private short mConnectionSecurity;
|
||||||
private boolean mSecure;
|
private boolean mSecure;
|
||||||
private HttpClient mHttpClient = null;
|
private HttpClient mHttpClient = null;
|
||||||
private String mAuthString = null;
|
private String mAuthString = null;
|
||||||
|
private String mCmdString = null;
|
||||||
|
|
||||||
private HashMap<String, EasFolder> mFolderList = new HashMap<String, EasFolder>();
|
private HashMap<String, EasFolder> mFolderList = new HashMap<String, EasFolder>();
|
||||||
|
|
||||||
/**
|
|
||||||
* eas://user:password@server:port CONNECTION_SECURITY_NONE
|
|
||||||
* eas+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL
|
|
||||||
* eas+tls+://user:password@server:port CONNECTION_SECURITY_TLS_REQUIRED
|
|
||||||
* eas+ssl://user:password@server:port CONNECTION_SECURITY_SSL_OPTIONAL
|
|
||||||
* eas+ssl+://user:password@server:port CONNECTION_SECURITY_SSL_REQUIRED
|
|
||||||
*/
|
|
||||||
public EasStore(Account account) throws MessagingException {
|
public EasStore(Account account) throws MessagingException {
|
||||||
super(account);
|
super(account);
|
||||||
|
|
||||||
|
ServerSettings settings;
|
||||||
try {
|
try {
|
||||||
mUri = new URI(mAccount.getStoreUri());
|
settings = decodeUri(mAccount.getStoreUri());
|
||||||
} catch (URISyntaxException use) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new MessagingException("Invalid WebDavStore URI", use);
|
throw new MessagingException("Error while decoding store URI", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
String scheme = mUri.getScheme();
|
mHost = settings.host;
|
||||||
if (scheme.equals("eas")) {
|
mUsername = settings.username;
|
||||||
|
mPassword = settings.password;
|
||||||
|
|
||||||
|
switch (settings.connectionSecurity) {
|
||||||
|
case NONE:
|
||||||
mConnectionSecurity = CONNECTION_SECURITY_NONE;
|
mConnectionSecurity = CONNECTION_SECURITY_NONE;
|
||||||
} else if (scheme.equals("eas+ssl")) {
|
break;
|
||||||
mConnectionSecurity = CONNECTION_SECURITY_SSL_OPTIONAL;
|
case STARTTLS_OPTIONAL:
|
||||||
} else if (scheme.equals("eas+ssl+")) {
|
|
||||||
mConnectionSecurity = CONNECTION_SECURITY_SSL_REQUIRED;
|
|
||||||
} else if (scheme.equals("eas+tls")) {
|
|
||||||
mConnectionSecurity = CONNECTION_SECURITY_TLS_OPTIONAL;
|
mConnectionSecurity = CONNECTION_SECURITY_TLS_OPTIONAL;
|
||||||
} else if (scheme.equals("eas+tls+")) {
|
break;
|
||||||
|
case STARTTLS_REQUIRED:
|
||||||
mConnectionSecurity = CONNECTION_SECURITY_TLS_REQUIRED;
|
mConnectionSecurity = CONNECTION_SECURITY_TLS_REQUIRED;
|
||||||
} else {
|
break;
|
||||||
throw new MessagingException("Unsupported protocol");
|
case SSL_TLS_OPTIONAL:
|
||||||
}
|
mConnectionSecurity = CONNECTION_SECURITY_SSL_OPTIONAL;
|
||||||
|
break;
|
||||||
mHost = mUri.getHost();
|
case SSL_TLS_REQUIRED:
|
||||||
if (mHost.startsWith("http")) {
|
mConnectionSecurity = CONNECTION_SECURITY_SSL_REQUIRED;
|
||||||
String[] hostParts = mHost.split("://", 2);
|
break;
|
||||||
if (hostParts.length > 1) {
|
|
||||||
mHost = hostParts[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mUri.getUserInfo() != null) {
|
|
||||||
try {
|
|
||||||
String[] userInfoParts = mUri.getUserInfo().split(":");
|
|
||||||
|
|
||||||
mUsername = URLDecoder.decode(userInfoParts[0], "UTF-8");
|
|
||||||
|
|
||||||
if (userInfoParts.length > 1) {
|
|
||||||
mPassword = URLDecoder.decode(userInfoParts[1], "UTF-8");
|
|
||||||
}
|
|
||||||
} catch (UnsupportedEncodingException enc) {
|
|
||||||
// This shouldn't happen since the encoding is hardcoded to UTF-8
|
|
||||||
Log.e(K9.LOG_TAG, "Couldn't urldecode username or password.", enc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mSecure = mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED;
|
mSecure = mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED;
|
||||||
@ -218,37 +321,18 @@ public class EasStore extends Store {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkSettings() throws MessagingException {
|
public void checkSettings() throws MessagingException {
|
||||||
boolean ssl = true;
|
validateAccount();
|
||||||
|
|
||||||
boolean trustCertificates = true;
|
|
||||||
|
|
||||||
validateAccount(
|
|
||||||
mHost,
|
|
||||||
mUsername,
|
|
||||||
mPassword,
|
|
||||||
mUri.getPort(),
|
|
||||||
ssl,
|
|
||||||
trustCertificates,
|
|
||||||
K9.app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validateAccount(String hostAddress, String userName, String password, int port,
|
public void validateAccount() throws MessagingException {
|
||||||
boolean ssl, boolean trustCertificates, Context context) throws MessagingException {
|
|
||||||
try {
|
try {
|
||||||
Log.i(K9.LOG_TAG, "Testing EAS: " + hostAddress + ", " + userName + ", ssl = " + (ssl ? "1" : "0"));
|
Log.i(K9.LOG_TAG, "Testing EAS: " + mHost + ", " + mUsername + ", ssl = " + (mSecure ? "1" : "0"));
|
||||||
|
|
||||||
// Account account = Preferences.getPreferences(context).newAccount();
|
|
||||||
// account.setName("%TestAccount%");
|
|
||||||
// account.setStoreUri(mUri.toString());
|
|
||||||
EasStore svc = new EasStore(mAccount);
|
EasStore svc = new EasStore(mAccount);
|
||||||
svc.mHost = hostAddress;
|
// We musn't use the "real" device id or we'll screw up current accounts.
|
||||||
svc.mUsername = userName;
|
// Any string will do, but we'll go for "validate".
|
||||||
svc.mPassword = password;
|
|
||||||
// svc.mSsl = ssl;
|
|
||||||
// svc.mTrustSsl = trustCertificates;
|
|
||||||
// We mustn't use the "real" device id or we'll screw up current accounts
|
|
||||||
// Any string will do, but we'll go for "validate"
|
|
||||||
svc.mDeviceId = "validate";
|
svc.mDeviceId = "validate";
|
||||||
|
|
||||||
HttpResponse resp = svc.sendHttpClientOptions();
|
HttpResponse resp = svc.sendHttpClientOptions();
|
||||||
reclaimConnection(resp);
|
reclaimConnection(resp);
|
||||||
int code = resp.getStatusLine().getStatusCode();
|
int code = resp.getStatusLine().getStatusCode();
|
||||||
@ -319,7 +403,7 @@ public class EasStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getPolicyType() {
|
private String getPolicyType() {
|
||||||
return (getProtocolVersion() >=
|
return (getProtocolVersionDouble() >=
|
||||||
Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) ? EAS_12_POLICY_TYPE : EAS_2_POLICY_TYPE;
|
Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) ? EAS_12_POLICY_TYPE : EAS_2_POLICY_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +508,7 @@ public class EasStore extends Store {
|
|||||||
return (code == HTTP_NEED_PROVISIONING) || (code == HttpStatus.SC_FORBIDDEN);
|
return (code == HTTP_NEED_PROVISIONING) || (code == HttpStatus.SC_FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupProtocolVersion(EasStore service, Header versionHeader)
|
private static void setupProtocolVersion(EasStore service, Header versionHeader)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
// The string is a comma separated list of EAS versions in ascending order
|
// The string is a comma separated list of EAS versions in ascending order
|
||||||
// e.g. 1.0,2.0,2.5,12.0,12.1
|
// e.g. 1.0,2.0,2.5,12.0,12.1
|
||||||
@ -445,13 +529,15 @@ public class EasStore extends Store {
|
|||||||
Log.w(K9.LOG_TAG, "No supported EAS versions: " + supportedVersions);
|
Log.w(K9.LOG_TAG, "No supported EAS versions: " + supportedVersions);
|
||||||
throw new MessagingException("MessagingException.PROTOCOL_VERSION_UNSUPPORTED");
|
throw new MessagingException("MessagingException.PROTOCOL_VERSION_UNSUPPORTED");
|
||||||
} else {
|
} else {
|
||||||
|
synchronized (service.mInitializationLock) {
|
||||||
service.mProtocolVersion = ourVersion;
|
service.mProtocolVersion = ourVersion;
|
||||||
service.mProtocolVersionDouble = Double.parseDouble(ourVersion);
|
service.mProtocolVersionDouble = Double.parseDouble(ourVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Double getProtocolVersion() {
|
private Double getProtocolVersionDouble() {
|
||||||
synchronized (mProtocolVersionDouble) {
|
synchronized (mInitializationLock) {
|
||||||
if (mProtocolVersionDouble == null) {
|
if (mProtocolVersionDouble == null) {
|
||||||
try {
|
try {
|
||||||
init();
|
init();
|
||||||
@ -553,7 +639,9 @@ public class EasStore extends Store {
|
|||||||
*/
|
*/
|
||||||
private void setHeaders(HttpRequestBase method, boolean usePolicyKey) {
|
private void setHeaders(HttpRequestBase method, boolean usePolicyKey) {
|
||||||
method.setHeader("Authorization", mAuthString);
|
method.setHeader("Authorization", mAuthString);
|
||||||
|
synchronized (mInitializationLock) {
|
||||||
method.setHeader("MS-ASProtocolVersion", mProtocolVersion);
|
method.setHeader("MS-ASProtocolVersion", mProtocolVersion);
|
||||||
|
}
|
||||||
method.setHeader("Connection", "keep-alive");
|
method.setHeader("Connection", "keep-alive");
|
||||||
method.setHeader("User-Agent", mDeviceType + '/' + Eas.VERSION);
|
method.setHeader("User-Agent", mDeviceType + '/' + Eas.VERSION);
|
||||||
if (usePolicyKey) {
|
if (usePolicyKey) {
|
||||||
@ -598,9 +686,12 @@ public class EasStore extends Store {
|
|||||||
String safeUserName = URLEncoder.encode(mUsername);
|
String safeUserName = URLEncoder.encode(mUsername);
|
||||||
String cs = mUsername + ':' + mPassword;
|
String cs = mUsername + ':' + mPassword;
|
||||||
mAuthString = "Basic " + Base64.encodeToString(cs.getBytes(), Base64.NO_WRAP);
|
mAuthString = "Basic " + Base64.encodeToString(cs.getBytes(), Base64.NO_WRAP);
|
||||||
|
|
||||||
|
synchronized (mInitializationLock) {
|
||||||
mCmdString = "&User=" + safeUserName + "&DeviceId=" + mDeviceId +
|
mCmdString = "&User=" + safeUserName + "&DeviceId=" + mDeviceId +
|
||||||
"&DeviceType=" + mDeviceType;
|
"&DeviceType=" + mDeviceType;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List <? extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
|
public List <? extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
|
||||||
@ -622,6 +713,16 @@ public class EasStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void init() throws IOException, MessagingException {
|
private void init() throws IOException, MessagingException {
|
||||||
|
synchronized (mInitializationLock) {
|
||||||
|
// Get a unique ID to identify the device and application.
|
||||||
|
if (mDeviceId == null) {
|
||||||
|
mDeviceId = K9.app.getDeviceId();
|
||||||
|
if (mDeviceId.length() > MAX_DEVICE_ID_SIZE) {
|
||||||
|
// This should not happen, since getDeviceId returns a UUID string with the dashes
|
||||||
|
// removed, which is always 32 characters. Best to be safe.
|
||||||
|
mDeviceId = mDeviceId.substring(0, MAX_DEVICE_ID_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Determine our protocol version, if we haven't already and save it in the Account
|
// Determine our protocol version, if we haven't already and save it in the Account
|
||||||
// Also re-check protocol version at least once a day (in case of upgrade)
|
// Also re-check protocol version at least once a day (in case of upgrade)
|
||||||
boolean lastSyncTimeDayDue = false;
|
boolean lastSyncTimeDayDue = false;
|
||||||
@ -649,6 +750,7 @@ public class EasStore extends Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List <? extends Folder > getInitialFolderList() throws MessagingException {
|
private List <? extends Folder > getInitialFolderList() throws MessagingException {
|
||||||
LinkedList<Folder> folderList = new LinkedList<Folder>();
|
LinkedList<Folder> folderList = new LinkedList<Folder>();
|
||||||
@ -1086,7 +1188,7 @@ public class EasStore extends Store {
|
|||||||
// Enable MimeSupport
|
// Enable MimeSupport
|
||||||
s.data(Tags.SYNC_MIME_SUPPORT, "2");
|
s.data(Tags.SYNC_MIME_SUPPORT, "2");
|
||||||
// Set the truncation amount for all classes.
|
// Set the truncation amount for all classes.
|
||||||
if (getProtocolVersion() >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
|
if (getProtocolVersionDouble() >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
|
||||||
s.start(Tags.BASE_BODY_PREFERENCE)
|
s.start(Tags.BASE_BODY_PREFERENCE)
|
||||||
// HTML for email; plain text for everything else.
|
// HTML for email; plain text for everything else.
|
||||||
.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_MIME);
|
.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_MIME);
|
||||||
|
Loading…
Reference in New Issue
Block a user