Merge "Use notifications for login failures"
This commit is contained in:
commit
4a66884b74
@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!-- TODO: Use a theme style color for the text view -->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="3dp"
|
||||
>
|
||||
<ImageView android:id="@+id/image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_marginRight="10dp"
|
||||
/>
|
||||
<TextView android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:textColor="#000"
|
||||
/>
|
||||
</LinearLayout>
|
@ -378,11 +378,15 @@ save attachment.</string>
|
||||
messages moved to <xliff:g id="mailbox_name" example="Inbox" >%2$s</xliff:g></item>
|
||||
</plurals>
|
||||
<!-- Notification ticker when a forwarded attachment couldn't be sent [CHAR LIMIT=none] -->
|
||||
<string name="forward_download_failed_ticker">"An attachment couldn't be forwarded"</string>
|
||||
<string name="forward_download_failed_ticker">Could not forward one or more attachments</string>
|
||||
<!-- Notification text when a forwarded attachment couldn't be sent -->
|
||||
<string name="forward_download_failed_notification">"The attachment "<xliff:g id="filename">%s
|
||||
</xliff:g>" couldn't be sent with your outgoing mail because it couldn't be downloaded."
|
||||
</string>
|
||||
<string name="forward_download_failed_notification">Could not forward <xliff:g id="filename">
|
||||
%s</xliff:g></string>
|
||||
<!-- Notification ticker when email account authentication fails [CHAR LIMIT=20] -->
|
||||
<string name="login_failed_ticker"><xliff:g id="account_name">%s
|
||||
</xliff:g> sign-in failed</string>
|
||||
<!-- Notification text when email account authentication fails [CHAR LIMIT=75]-->
|
||||
<string name="login_failed_notification">Touch to change account settings</string>
|
||||
|
||||
<!-- Size unit for bytes for attachments [CHAR LIMIT=10] -->
|
||||
<plurals name="message_view_attachment_bytes">
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.email;
|
||||
|
||||
import com.android.email.mail.AuthenticationFailedException;
|
||||
import com.android.email.mail.FetchProfile;
|
||||
import com.android.email.mail.Flag;
|
||||
import com.android.email.mail.Folder;
|
||||
@ -376,6 +377,7 @@ public class MessagingController implements Runnable {
|
||||
private void synchronizeMailboxSynchronous(final EmailContent.Account account,
|
||||
final EmailContent.Mailbox folder) {
|
||||
mListeners.synchronizeMailboxStarted(account.mId, folder.mId);
|
||||
NotificationController nc = NotificationController.getInstance(mContext);
|
||||
try {
|
||||
processPendingActionsSynchronous(account);
|
||||
|
||||
@ -393,10 +395,16 @@ public class MessagingController implements Runnable {
|
||||
mListeners.synchronizeMailboxFinished(account.mId, folder.mId,
|
||||
results.mTotalMessages,
|
||||
results.mNewMessages);
|
||||
// Clear authentication notification for this account
|
||||
nc.cancelLoginFailedNotification(account.mId);
|
||||
} catch (MessagingException e) {
|
||||
if (Email.LOGD) {
|
||||
Log.v(Email.LOG_TAG, "synchronizeMailbox", e);
|
||||
}
|
||||
if (e instanceof AuthenticationFailedException) {
|
||||
// Generate authentication notification
|
||||
nc.showLoginFailedNotification(account.mId);
|
||||
}
|
||||
mListeners.synchronizeMailboxFailed(account.mId, folder.mId, e);
|
||||
}
|
||||
}
|
||||
@ -1974,6 +1982,7 @@ public class MessagingController implements Runnable {
|
||||
*/
|
||||
public void sendPendingMessagesSynchronous(final EmailContent.Account account,
|
||||
long sentFolderId) {
|
||||
NotificationController nc = NotificationController.getInstance(mContext);
|
||||
// 1. Loop through all messages in the account's outbox
|
||||
long outboxId = Mailbox.findMailboxOfType(mContext, account.mId, Mailbox.TYPE_OUTBOX);
|
||||
if (outboxId == Mailbox.NO_MAILBOX) {
|
||||
@ -2018,6 +2027,9 @@ public class MessagingController implements Runnable {
|
||||
sender.sendMessage(messageId);
|
||||
} catch (MessagingException me) {
|
||||
// report error for this message, but keep trying others
|
||||
if (me instanceof AuthenticationFailedException) {
|
||||
nc.showLoginFailedNotification(account.mId);
|
||||
}
|
||||
mListeners.sendPendingMessagesFailed(account.mId, messageId, me);
|
||||
continue;
|
||||
}
|
||||
@ -2045,8 +2057,11 @@ public class MessagingController implements Runnable {
|
||||
}
|
||||
// 6. report completion/success
|
||||
mListeners.sendPendingMessagesCompleted(account.mId);
|
||||
|
||||
nc.cancelLoginFailedNotification(account.mId);
|
||||
} catch (MessagingException me) {
|
||||
if (me instanceof AuthenticationFailedException) {
|
||||
nc.showLoginFailedNotification(account.mId);
|
||||
}
|
||||
mListeners.sendPendingMessagesFailed(account.mId, -1, me);
|
||||
} finally {
|
||||
c.close();
|
||||
|
@ -18,15 +18,18 @@ package com.android.email;
|
||||
|
||||
import com.android.email.activity.ContactStatusLoader;
|
||||
import com.android.email.activity.Welcome;
|
||||
import com.android.email.activity.setup.AccountSettingsXL;
|
||||
import com.android.email.mail.Address;
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Account;
|
||||
import com.android.email.provider.EmailContent.Attachment;
|
||||
import com.android.email.provider.EmailContent.Message;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.media.AudioManager;
|
||||
@ -41,8 +44,10 @@ import android.text.TextUtils;
|
||||
public class NotificationController {
|
||||
public static final int NOTIFICATION_ID_SECURITY_NEEDED = 1;
|
||||
public static final int NOTIFICATION_ID_EXCHANGE_CALENDAR_ADDED = 2;
|
||||
public static final int NOTIFICATION_ID_WARNING = 3;
|
||||
private static final int NOTIFICATION_ID_NEW_MESSAGES_BASE = 10;
|
||||
public static final int NOTIFICATION_ID_ATTACHMENT_WARNING = 3;
|
||||
|
||||
private static final int NOTIFICATION_ID_BASE_NEW_MESSAGES = 0x10000000;
|
||||
private static final int NOTIFICATION_ID_BASE_LOGIN_WARNING = 0x20000000;
|
||||
|
||||
private static NotificationController sInstance;
|
||||
private final Context mContext;
|
||||
@ -70,7 +75,7 @@ public class NotificationController {
|
||||
* accountID won't be too huge. Any other smarter/cleaner way?
|
||||
*/
|
||||
private int getNewMessageNotificationId(long accountId) {
|
||||
return (int) (NOTIFICATION_ID_NEW_MESSAGES_BASE + accountId);
|
||||
return (int) (NOTIFICATION_ID_BASE_NEW_MESSAGES + accountId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,4 +229,51 @@ public class NotificationController {
|
||||
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||
notification.defaults |= Notification.DEFAULT_LIGHTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic warning notification
|
||||
*/
|
||||
public void showWarningNotification(int id, String tickerText, String notificationText,
|
||||
Intent intent) {
|
||||
PendingIntent pendingIntent =
|
||||
PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
Notification n = new Notification(android.R.drawable.stat_notify_error, tickerText,
|
||||
System.currentTimeMillis());
|
||||
n.setLatestEventInfo(mContext, tickerText, notificationText, pendingIntent);
|
||||
n.flags = Notification.FLAG_AUTO_CANCEL;
|
||||
mNotificationManager.notify(id, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert the user that an attachment couldn't be forwarded. This is a very unusual case, and
|
||||
* perhaps we shouldn't even send a notification. For now, it's helpful for debugging.
|
||||
*/
|
||||
public void showDownloadForwardFailedNotification(Attachment att) {
|
||||
showWarningNotification(NOTIFICATION_ID_ATTACHMENT_WARNING,
|
||||
mContext.getString(R.string.forward_download_failed_ticker),
|
||||
mContext.getString(R.string.forward_download_failed_notification,
|
||||
att.mFileName),
|
||||
Welcome.createOpenCombinedOutboxIntent(mContext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert the user that login failed for the specified account
|
||||
*/
|
||||
private int getLoginFailedNotificationId(long accountId) {
|
||||
return NOTIFICATION_ID_BASE_LOGIN_WARNING + (int)accountId;
|
||||
}
|
||||
|
||||
// NOTE: DO NOT CALL THIS METHOD FROM THE UI THREAD (DATABASE ACCESS)
|
||||
public void showLoginFailedNotification(long accountId) {
|
||||
final Account account = Account.restoreAccountWithId(mContext, accountId);
|
||||
if (account == null) return;
|
||||
showWarningNotification(getLoginFailedNotificationId(accountId),
|
||||
mContext.getString(R.string.login_failed_ticker, account.mDisplayName),
|
||||
mContext.getString(R.string.login_failed_notification),
|
||||
AccountSettingsXL.createAccountSettingsIntent(mContext, accountId));
|
||||
}
|
||||
|
||||
public void cancelLoginFailedNotification(long accountId) {
|
||||
mNotificationManager.cancel(getLoginFailedNotificationId(accountId));
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class Welcome extends Activity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Intent to open "Combined Inbox".
|
||||
* Create an Intent to open "Combined Outbox".
|
||||
*/
|
||||
public static Intent createOpenCombinedInboxIntent(Context context) {
|
||||
Intent i = new Intent(context, Welcome.class);
|
||||
@ -118,6 +118,15 @@ public class Welcome extends Activity {
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Intent to open "Combined Inbox".
|
||||
*/
|
||||
public static Intent createOpenCombinedOutboxIntent(Context context) {
|
||||
Intent i = new Intent(context, Welcome.class);
|
||||
i.putExtra(EXTRA_MAILBOX_ID, Mailbox.QUERY_ALL_OUTBOX);
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open account's inbox.
|
||||
*/
|
||||
|
@ -121,6 +121,16 @@ public class AccountSettingsXL extends PreferenceActivity implements OnClickList
|
||||
fromActivity.startActivity(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return an intent to display (and edit) settings for a specific account, or -1
|
||||
* for any/all accounts
|
||||
*/
|
||||
public static Intent createAccountSettingsIntent(Context context, long accountId) {
|
||||
Intent i = new Intent(context, AccountSettingsXL.class);
|
||||
i.putExtra(EXTRA_ACCOUNT_ID, accountId);
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch generic settings and pre-enable the debug preferences
|
||||
*/
|
||||
|
@ -418,11 +418,19 @@ public class ImapStore extends Store {
|
||||
} catch (IOException ioe) {
|
||||
connection.close();
|
||||
throw new MessagingException("Unable to get folder list.", ioe);
|
||||
} catch (AuthenticationFailedException afe) {
|
||||
// We do NOT want this connection pooled, or we will continue to send NOOP and SELECT
|
||||
// commands to the server
|
||||
connection.destroyResponses();
|
||||
connection = null;
|
||||
throw afe;
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.destroyResponses();
|
||||
poolConnection(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle checkSettings() throws MessagingException {
|
||||
@ -601,6 +609,11 @@ public class ImapStore extends Store {
|
||||
} finally {
|
||||
destroyResponses();
|
||||
}
|
||||
} catch (AuthenticationFailedException e) {
|
||||
// Don't cache this connection, so we're forced to try connecting/login again
|
||||
mConnection = null;
|
||||
close(false);
|
||||
throw e;
|
||||
} catch (MessagingException e) {
|
||||
mExists = false;
|
||||
close(false);
|
||||
@ -1633,6 +1646,8 @@ public class ImapStore extends Store {
|
||||
}
|
||||
|
||||
static class ImapException extends MessagingException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
String mAlertText;
|
||||
|
||||
public ImapException(String message, String alertText, Throwable throwable) {
|
||||
|
@ -18,11 +18,9 @@ package com.android.email.service;
|
||||
|
||||
import com.android.email.Email;
|
||||
import com.android.email.NotificationController;
|
||||
import com.android.email.R;
|
||||
import com.android.email.Utility;
|
||||
import com.android.email.Controller.ControllerService;
|
||||
import com.android.email.ExchangeUtils.NullEmailService;
|
||||
import com.android.email.activity.Welcome;
|
||||
import com.android.email.provider.AttachmentProvider;
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Account;
|
||||
@ -30,9 +28,6 @@ import com.android.email.provider.EmailContent.Attachment;
|
||||
import com.android.email.provider.EmailContent.Message;
|
||||
import com.android.exchange.ExchangeService;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
@ -42,7 +37,6 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
@ -349,7 +343,8 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||
// message never get sent
|
||||
EmailContent.delete(mContext, Attachment.CONTENT_URI, attachment.mId);
|
||||
// TODO: Talk to UX about whether this is even worth doing
|
||||
showDownloadForwardFailedNotification(attachment);
|
||||
NotificationController nc = NotificationController.getInstance(mContext);
|
||||
nc.showDownloadForwardFailedNotification(attachment);
|
||||
deleted = true;
|
||||
}
|
||||
// If we're an attachment on forwarded mail, and if we're not still blocked,
|
||||
@ -457,31 +452,6 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert the user that an attachment couldn't be forwarded. This is a very unusual case, and
|
||||
* perhaps we shouldn't even send a notification. For now, it's helpful for debugging.
|
||||
* Note the STOPSHIP below...
|
||||
*/
|
||||
void showDownloadForwardFailedNotification(Attachment att) {
|
||||
// STOPSHIP: Tentative UI; if we use a notification, replace this text with a resource
|
||||
RemoteViews contentView = new RemoteViews(getPackageName(),
|
||||
R.layout.attachment_forward_failed_notification);
|
||||
contentView.setImageViewResource(R.id.image, R.drawable.ic_email_attachment);
|
||||
contentView.setTextViewText(R.id.text,
|
||||
getString(R.string.forward_download_failed_notification, att.mFileName));
|
||||
Notification n = new Notification(R.drawable.stat_notify_email_generic,
|
||||
getString(R.string.forward_download_failed_ticker), System.currentTimeMillis());
|
||||
n.contentView = contentView;
|
||||
Intent i = new Intent(mContext, Welcome.class);
|
||||
PendingIntent pending = PendingIntent.getActivity(mContext, 0, i,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
n.contentIntent = pending;
|
||||
n.flags = Notification.FLAG_AUTO_CANCEL;
|
||||
NotificationManager nm =
|
||||
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(NotificationController.NOTIFICATION_ID_WARNING, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class of the service used by the account type of the provided account id. We
|
||||
* cache the results to avoid repeated database access
|
||||
|
@ -701,6 +701,8 @@ public class MailService extends Service {
|
||||
@Override
|
||||
public void updateMailboxCallback(MessagingException result, long accountId,
|
||||
long mailboxId, int progress, int numNewMessages) {
|
||||
// First, look for authentication failures and notify
|
||||
//checkAuthenticationStatus(result, accountId);
|
||||
if (result != null || progress == 100) {
|
||||
// We only track the inbox here in the service - ignore other mailboxes
|
||||
long inboxId = Mailbox.findMailboxOfType(MailService.this,
|
||||
|
@ -19,6 +19,7 @@ package com.android.exchange;
|
||||
|
||||
import com.android.email.AccountBackupRestore;
|
||||
import com.android.email.Email;
|
||||
import com.android.email.NotificationController;
|
||||
import com.android.email.Utility;
|
||||
import com.android.email.mail.transport.SSLUtils;
|
||||
import com.android.email.provider.EmailContent;
|
||||
@ -975,14 +976,17 @@ public class ExchangeService extends Service implements Runnable {
|
||||
* is null, mailboxes from all accounts with the specified hold will be released
|
||||
* @param reason the reason for the SyncError (AbstractSyncService.EXIT_XXX)
|
||||
* @param account an Account whose mailboxes should be released (or all if null)
|
||||
* @return whether or not any mailboxes were released
|
||||
*/
|
||||
/*package*/ void releaseSyncHolds(Context context, int reason, Account account) {
|
||||
releaseSyncHoldsImpl(context, reason, account);
|
||||
/*package*/ boolean releaseSyncHolds(Context context, int reason, Account account) {
|
||||
boolean holdWasReleased = releaseSyncHoldsImpl(context, reason, account);
|
||||
kick("security release");
|
||||
return holdWasReleased;
|
||||
}
|
||||
|
||||
private void releaseSyncHoldsImpl(Context context, int reason, Account account) {
|
||||
private boolean releaseSyncHoldsImpl(Context context, int reason, Account account) {
|
||||
synchronized(sSyncLock) {
|
||||
boolean holdWasReleased = false;
|
||||
ArrayList<Long> releaseList = new ArrayList<Long>();
|
||||
for (long mailboxId: mSyncErrorMap.keySet()) {
|
||||
if (account != null) {
|
||||
@ -1000,7 +1004,9 @@ public class ExchangeService extends Service implements Runnable {
|
||||
}
|
||||
for (long mailboxId: releaseList) {
|
||||
mSyncErrorMap.remove(mailboxId);
|
||||
holdWasReleased = true;
|
||||
}
|
||||
return holdWasReleased;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2376,6 +2382,20 @@ public class ExchangeService extends Service implements Runnable {
|
||||
SyncError syncError = errorMap.get(mailboxId);
|
||||
exchangeService.releaseMailbox(mailboxId);
|
||||
int exitStatus = svc.mExitStatus;
|
||||
Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
|
||||
if (m == null) return;
|
||||
|
||||
if (exitStatus != AbstractSyncService.EXIT_LOGIN_FAILURE) {
|
||||
long accountId = m.mAccountKey;
|
||||
Account account = Account.restoreAccountWithId(exchangeService, accountId);
|
||||
if (account == null) return;
|
||||
if (exchangeService.releaseSyncHolds(exchangeService,
|
||||
AbstractSyncService.EXIT_LOGIN_FAILURE, account)) {
|
||||
NotificationController.getInstance(exchangeService)
|
||||
.cancelLoginFailedNotification(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
switch (exitStatus) {
|
||||
case AbstractSyncService.EXIT_DONE:
|
||||
if (svc.hasPendingRequests()) {
|
||||
@ -2389,8 +2409,6 @@ public class ExchangeService extends Service implements Runnable {
|
||||
break;
|
||||
// I/O errors get retried at increasing intervals
|
||||
case AbstractSyncService.EXIT_IO_ERROR:
|
||||
Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId);
|
||||
if (m == null) return;
|
||||
if (syncError != null) {
|
||||
syncError.escalate();
|
||||
log(m.mDisplayName + " held for " + syncError.holdDelay + "ms");
|
||||
@ -2400,8 +2418,11 @@ public class ExchangeService extends Service implements Runnable {
|
||||
}
|
||||
break;
|
||||
// These errors are not retried automatically
|
||||
case AbstractSyncService.EXIT_SECURITY_FAILURE:
|
||||
case AbstractSyncService.EXIT_LOGIN_FAILURE:
|
||||
NotificationController.getInstance(exchangeService)
|
||||
.showLoginFailedNotification(m.mAccountKey);
|
||||
// Fall through
|
||||
case AbstractSyncService.EXIT_SECURITY_FAILURE:
|
||||
case AbstractSyncService.EXIT_EXCEPTION:
|
||||
errorMap.put(mailboxId, exchangeService.new SyncError(exitStatus, true));
|
||||
break;
|
||||
|
@ -73,7 +73,8 @@ public class ExchangeServiceAccountTests extends AccountTestCase {
|
||||
// We should have 4
|
||||
assertEquals(4, errorMap.keySet().size());
|
||||
// Release the holds on acct2 (there are two of them)
|
||||
exchangeService.releaseSyncHolds(context, AbstractSyncService.EXIT_SECURITY_FAILURE, acct2);
|
||||
assertTrue(exchangeService.releaseSyncHolds(context,
|
||||
AbstractSyncService.EXIT_SECURITY_FAILURE, acct2));
|
||||
// There should be two left
|
||||
assertEquals(2, errorMap.keySet().size());
|
||||
// And these are the two...
|
||||
@ -86,19 +87,22 @@ public class ExchangeServiceAccountTests extends AccountTestCase {
|
||||
// We should have 4 again
|
||||
assertEquals(4, errorMap.keySet().size());
|
||||
// Release all of the security holds
|
||||
exchangeService.releaseSyncHolds(context, AbstractSyncService.EXIT_SECURITY_FAILURE, null);
|
||||
assertTrue(exchangeService.releaseSyncHolds(context,
|
||||
AbstractSyncService.EXIT_SECURITY_FAILURE, null));
|
||||
// There should be one left
|
||||
assertEquals(1, errorMap.keySet().size());
|
||||
// And this is the one
|
||||
assertNotNull(errorMap.get(box2.mId));
|
||||
|
||||
// Release the i/o holds on account 2 (there aren't any)
|
||||
exchangeService.releaseSyncHolds(context, AbstractSyncService.EXIT_IO_ERROR, acct2);
|
||||
assertFalse(exchangeService.releaseSyncHolds(context,
|
||||
AbstractSyncService.EXIT_IO_ERROR, acct2));
|
||||
// There should still be one left
|
||||
assertEquals(1, errorMap.keySet().size());
|
||||
|
||||
// Release the i/o holds on account 1 (there's one)
|
||||
exchangeService.releaseSyncHolds(context, AbstractSyncService.EXIT_IO_ERROR, acct1);
|
||||
assertTrue(exchangeService.releaseSyncHolds(context,
|
||||
AbstractSyncService.EXIT_IO_ERROR, acct1));
|
||||
// There should still be one left
|
||||
assertEquals(0, errorMap.keySet().size());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user