am 067c874c: DO NOT MERGE: Backport fix for IMAP delete bug

* commit '067c874c316f36b80551dbda2280e1a4f964eafe':
  DO NOT MERGE: Backport fix for IMAP delete bug
This commit is contained in:
Andy Stadler 2011-02-28 16:04:50 -08:00 committed by Android Git Automerger
commit f912a7e827
3 changed files with 191 additions and 5 deletions

View File

@ -20,6 +20,7 @@ import com.android.email.AccountBackupRestore;
import com.android.email.Email;
import com.android.email.R;
import com.android.email.Utility;
import com.android.email.mail.Store;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
@ -334,17 +335,21 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment {
mPasswordView.setText(password);
}
if (uri.getScheme().startsWith("pop3")) {
mLoadedDeletePolicy = account.getDeletePolicy();
SpinnerOption.setSpinnerOptionValue(mDeletePolicyView, mLoadedDeletePolicy);
} else if (uri.getScheme().startsWith("imap")) {
if (uri.getScheme().startsWith(Store.STORE_SCHEME_IMAP)) {
if (uri.getPath() != null && uri.getPath().length() > 0) {
mImapPathPrefixView.setText(uri.getPath().substring(1));
}
} else {
} else if (!uri.getScheme().startsWith(Store.STORE_SCHEME_POP3)) {
// Account must either be IMAP or POP3
throw new Error("Unknown account type: " + account.getStoreUri(mContext));
}
// The delete policy is set for all accounts. For POP3 accounts, the user sets
// the policy explicitly. For IMAP accounts, the policy is set when the Account object
// is created. @see AccountSetupBasics#populateSetupData
mLoadedDeletePolicy = account.getDeletePolicy();
SpinnerOption.setSpinnerOptionValue(mDeletePolicyView, mLoadedDeletePolicy);
for (int i = 0; i < mAccountSchemes.length; i++) {
if (mAccountSchemes[i].equals(uri.getScheme())) {
SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, i);

View File

@ -22,14 +22,23 @@ import com.android.email.Preferences;
import com.android.email.SecurityPolicy;
import com.android.email.VendorPolicyLoader;
import com.android.email.activity.setup.AccountSettingsXL;
import com.android.email.mail.Store;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.AccountColumns;
import com.android.email.provider.EmailContent.HostAuth;
import com.android.email.provider.WidgetProvider;
import android.accounts.AccountManager;
import android.app.IntentService;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
/**
@ -155,6 +164,12 @@ public class EmailBroadcastProcessorService extends IntentService {
ExchangeUtils.enableEasCalendarSync(this);
}
if (progress < 2) {
Log.i(Email.LOG_TAG, "Onetime initialization: 2");
progress = 2;
setImapDeletePolicy(this);
}
// Add your initialization steps here.
// Use "progress" to skip the initializations that's already done before.
// Using this preference also makes it safe when a user skips an upgrade. (i.e. upgrading
@ -166,6 +181,34 @@ public class EmailBroadcastProcessorService extends IntentService {
}
}
/**
* Sets the delete policy to the correct value for all IMAP accounts. This will have no
* effect on either EAS or POP3 accounts.
*/
/*package*/ static void setImapDeletePolicy(Context context) {
ContentResolver resolver = context.getContentResolver();
Cursor c = resolver.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION,
null, null, null);
try {
while (c.moveToNext()) {
long recvAuthKey = c.getLong(Account.CONTENT_HOST_AUTH_KEY_RECV_COLUMN);
HostAuth recvAuth = HostAuth.restoreHostAuthWithId(context, recvAuthKey);
if (Store.STORE_SCHEME_IMAP.equals(recvAuth.mProtocol)) {
int flags = c.getInt(Account.CONTENT_FLAGS_COLUMN);
flags &= ~Account.FLAGS_DELETE_POLICY_MASK;
flags |= Account.DELETE_POLICY_ON_DELETE << Account.FLAGS_DELETE_POLICY_SHIFT;
ContentValues cv = new ContentValues();
cv.put(AccountColumns.FLAGS, flags);
long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, accountId);
resolver.update(uri, cv, null, null);
}
}
} finally {
c.close();
}
}
private void setComponentEnabled(Class<?> clazz, boolean enabled) {
final ComponentName c = new ComponentName(this, clazz.getName());
getPackageManager().setComponentEnabledSetting(c,

View File

@ -0,0 +1,138 @@
/*
* Copyright (C) 2011 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.
*/
package com.android.email.service;
import com.android.email.AccountTestCase;
import com.android.email.Utility;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.AccountColumns;
import com.android.email.provider.EmailContent.HostAuth;
import com.android.email.provider.ProviderTestUtils;
import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;
import java.util.NoSuchElementException;
/**
* Tests of the Email provider.
*
* You can run this entire test case with:
* runtest -c com.android.email.service.EmailBroadcastProcessorServiceTests email
*/
public class EmailBroadcastProcessorServiceTests extends AccountTestCase {
Context mMockContext;
public EmailBroadcastProcessorServiceTests() {
super();
}
@Override
public void setUp() throws Exception {
super.setUp();
mMockContext = getMockContext();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
}
/**
* Create a simple HostAuth with protocol
*/
private HostAuth setupSimpleHostAuth(String protocol) {
HostAuth hostAuth = ProviderTestUtils.setupHostAuth(protocol, "name", 1L, false, mContext);
hostAuth.mProtocol = protocol;
return hostAuth;
}
/**
* Returns the flags for the specified account. Throws an exception if the account cannot
* be found.
*/
private int getAccountFlags(long accountId) throws NoSuchElementException {
Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, accountId);
Integer flags = Utility.getFirstRowInt(mMockContext, uri,
new String[] { AccountColumns.FLAGS }, null, null, null, 0);
if (flags == null) {
throw new NoSuchElementException("No cursor");
}
return flags;
}
/**
* Initial testing on setupSyncReportsLocked, making sure that EAS accounts aren't scheduled
*/
public void testSetImapDeletePolicy() {
// Setup accounts of each type, all with manual sync at different intervals
Account account1 = ProviderTestUtils.setupAccount("eas-account1", false, mMockContext);
account1.mHostAuthRecv = setupSimpleHostAuth("eas");
account1.mHostAuthSend = account1.mHostAuthRecv;
account1.save(mMockContext);
long accountId1 = account1.mId;
Account account2 = ProviderTestUtils.setupAccount("pop-account1", false, mMockContext);
account2.mHostAuthRecv = setupSimpleHostAuth("pop3");
account2.mHostAuthSend = setupSimpleHostAuth("smtp");
account2.mFlags = 0x08; // set delete policy
account2.save(mMockContext);
long accountId2 = account2.mId;
Account account3 = ProviderTestUtils.setupAccount("pop-account2", false, mMockContext);
account3.mHostAuthRecv = setupSimpleHostAuth("pop3");
account3.mHostAuthSend = setupSimpleHostAuth("smtp");
account3.save(mMockContext);
long accountId3 = account3.mId;
Account account4 = ProviderTestUtils.setupAccount("imap-account1", false, mMockContext);
account4.mHostAuthRecv = setupSimpleHostAuth("imap");
account4.mHostAuthSend = setupSimpleHostAuth("smtp");
account4.mFlags = 0xa5a5a5a5; // Alternating bits; includes bad delete policy
account4.save(mMockContext);
long accountId4 = account4.mId;
Account account5 = ProviderTestUtils.setupAccount("imap-account2", false, mMockContext);
account5.mHostAuthRecv = setupSimpleHostAuth("imap");
account5.mHostAuthSend = setupSimpleHostAuth("smtp");
account5.mFlags = 0x0c; // All delete policy bits set
account5.save(mMockContext);
long accountId5 = account5.mId;
Account account6 = ProviderTestUtils.setupAccount("imap-account3", false, mMockContext);
account6.mHostAuthRecv = setupSimpleHostAuth("imap");
account6.mHostAuthSend = setupSimpleHostAuth("smtp");
account6.mFlags = 0; // No delete policy bits set
account6.save(mMockContext);
long accountId6 = account6.mId;
// Run the account migration
EmailBroadcastProcessorService.setImapDeletePolicy(mMockContext);
// Test the results
int accountFlags1 = getAccountFlags(accountId1);
assertEquals(4, accountFlags1); // not IMAP; no changes
int accountFlags2 = getAccountFlags(accountId2);
assertEquals(8, accountFlags2); // not IMAP; no changes
int accountFlags3 = getAccountFlags(accountId3);
assertEquals(4, accountFlags3); // not IMAP; no changes
int accountFlags4 = getAccountFlags(accountId4);
assertEquals(0xa5a5a5a9, accountFlags4); // Only update delete policy bits
int accountFlags5 = getAccountFlags(accountId5);
assertEquals(0x00000008, accountFlags5);
int accountFlags6 = getAccountFlags(accountId6);
assertEquals(0x00000008, accountFlags6);
}
}