1b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook/*
2b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * Copyright (C) 2010 The Android Open Source Project
3b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *
4b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * Licensed under the Apache License, Version 2.0 (the "License");
5b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * you may not use this file except in compliance with the License.
6b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * You may obtain a copy of the License at
7b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *
8b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *      http://www.apache.org/licenses/LICENSE-2.0
9b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *
10b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * Unless required by applicable law or agreed to in writing, software
11b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS,
12b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * See the License for the specific language governing permissions and
14b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * limitations under the License.
15b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook */
16b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
17b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookpackage com.android.exchange;
18b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
19b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.accounts.Account;
20b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.accounts.AccountManager;
21b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.accounts.AccountManagerFuture;
22b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.accounts.AuthenticatorException;
23b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.accounts.OperationCanceledException;
24b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.app.NotificationManager;
25b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.content.ContentResolver;
26b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.content.Context;
27b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.database.Cursor;
28b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.provider.CalendarContract;
29b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.test.MoreAsserts;
30b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.test.suitebuilder.annotation.MediumTest;
31b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.text.TextUtils;
32b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.util.Log;
33b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
34b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport com.android.emailcommon.AccountManagerTypes;
35b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport com.android.emailcommon.Logging;
36b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport com.android.exchange.utility.ExchangeTestCase;
37b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
38b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport java.io.IOException;
39b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport java.util.ArrayList;
40b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport java.util.Arrays;
41b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport java.util.HashMap;
42b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport java.util.HashSet;
43b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook@MediumTest
44b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookpublic class CalendarSyncEnablerTest extends ExchangeTestCase {
45b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
46b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected static final String TEST_ACCOUNT_PREFIX = "__test";
47b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected static final String TEST_ACCOUNT_SUFFIX = "@android.com";
48b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
49b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    private HashMap<Account, Boolean> origCalendarSyncStates = new HashMap<Account, Boolean>();
50b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
51b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    // To make the rest of the code shorter thus more readable...
52b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    private static final String EAT = AccountManagerTypes.TYPE_EXCHANGE;
53b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
54b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    @Override
55b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void setUp() throws Exception {
56b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        super.setUp();
57b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Delete any test accounts we might have created earlier
58b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        deleteTemporaryAccountManagerAccounts();
59b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
60b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Save the original calendar sync states.
61b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (Account account : AccountManager.get(getContext()).getAccounts()) {
62b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            origCalendarSyncStates.put(account,
63b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                    ContentResolver.getSyncAutomatically(account, CalendarContract.AUTHORITY));
64b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
65b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
66b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
67b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    @Override
68b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void tearDown() throws Exception {
69b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        super.tearDown();
70b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Delete any test accounts we might have created earlier
71b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        deleteTemporaryAccountManagerAccounts();
72b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
73b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Restore the original calendar sync states.
74b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Note we restore only for Exchange accounts.
75b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Other accounts should remain intact throughout the tests.  Plus we don't know if the
76b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Calendar.AUTHORITY is supported by other types of accounts.
77b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (Account account : getExchangeAccounts()) {
78b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            Boolean state = origCalendarSyncStates.get(account);
79b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            if (state == null) continue; // Shouldn't happen, but just in case.
80b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
81b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            ContentResolver.setSyncAutomatically(account, CalendarContract.AUTHORITY, state);
82b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
83b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
84b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
85b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void testEnableEasCalendarSync() {
86b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        final Account[] baseAccounts = getExchangeAccounts();
87b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
88b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        String a1 = getTestAccountEmailAddress("1");
89b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        String a2 = getTestAccountEmailAddress("2");
90b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
91b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // 1. Test with 1 account
92b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
93b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        CalendarSyncEnabler enabler = new CalendarSyncEnabler(getContext());
94b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
95b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Add exchange accounts
96b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        createAccountManagerAccount(a1);
97b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
98b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        String emailAddresses = enabler.enableEasCalendarSyncInternalForTest();
99b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
100b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Verify
101b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        verifyCalendarSyncState();
102b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
103b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // There seems to be no good way to examine the contents of Notification, so let's verify
104b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // we at least (tried to) show the correct email addresses.
105b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        checkNotificationEmailAddresses(emailAddresses, baseAccounts, a1);
106b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
107b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Delete added account.
108b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        deleteTemporaryAccountManagerAccounts();
109b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
110b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // 2. Test with 2 accounts
111b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        enabler = new CalendarSyncEnabler(getContext());
112b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
113b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Add exchange accounts
114b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        createAccountManagerAccount(a1);
115b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        createAccountManagerAccount(a2);
116b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
117b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        emailAddresses = enabler.enableEasCalendarSyncInternalForTest();
118b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
119b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Verify
120b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        verifyCalendarSyncState();
121b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
122b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Check
123b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        checkNotificationEmailAddresses(emailAddresses, baseAccounts, a1, a2);
124b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
125b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
126b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    private static void checkNotificationEmailAddresses(String actual, Account[] baseAccounts,
127b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            String... addedAddresses) {
128b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Build and sort actual string array.
129b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        final String[] actualArray = TextUtils.split(actual, " ");
130b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        Arrays.sort(actualArray);
131b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
132b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Build and sort expected string array.
133b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        ArrayList<String> expected = new ArrayList<String>();
134b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (Account account : baseAccounts) {
135b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            expected.add(account.name);
136b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
137b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (String address : addedAddresses) {
138b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            expected.add(address);
139b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
140b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        final String[] expectedArray = new String[expected.size()];
141b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        expected.toArray(expectedArray);
142b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        Arrays.sort(expectedArray);
143b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
144b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Check!
145b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        MoreAsserts.assertEquals(expectedArray, actualArray);
146b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
147b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
148b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    /**
149b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     * For all {@link Account}, confirm that:
150b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     * <ol>
151b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     *   <li>Calendar sync is enabled if it's an Exchange account.<br>
152b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     *       Unfortunately setSyncAutomatically() doesn't take effect immediately, so we skip this
153b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     *       check for now.
154b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook             TODO Find a stable way to check this.
155b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     *   <li>Otherwise, calendar sync state isn't changed.
156b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     * </ol>
157b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     */
158b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    private void verifyCalendarSyncState() {
159b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // It's very unfortunate that setSyncAutomatically doesn't take effect immediately.
160b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (Account account : AccountManager.get(getContext()).getAccounts()) {
161b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            String message = "account=" + account.name + "(" + account.type + ")";
162b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            boolean enabled = ContentResolver.getSyncAutomatically(account,
163b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                    CalendarContract.AUTHORITY);
164b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            int syncable = ContentResolver.getIsSyncable(account, CalendarContract.AUTHORITY);
165b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
166b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            if (EAT.equals(account.type)) {
167b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                // Should be enabled.
168b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                // assertEquals(message, Boolean.TRUE, (Boolean) enabled);
169b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                // assertEquals(message, 1, syncable);
170b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            } else {
171b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                // Shouldn't change.
172b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                assertEquals(message, origCalendarSyncStates.get(account), (Boolean) enabled);
173b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            }
174b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
175b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
176b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
177b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void testEnableEasCalendarSyncWithNoExchangeAccounts() {
178b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // This test can only meaningfully run when there's no exchange accounts
179b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // set up on the device.  Otherwise there'll be no difference from
180b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // testEnableEasCalendarSync.
181b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        if (AccountManager.get(getContext()).getAccountsByType(EAT).length > 0) {
182b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            Log.w(Logging.LOG_TAG, "testEnableEasCalendarSyncWithNoExchangeAccounts skipped:"
183b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                    + " It only runs when there's no Exchange account on the device.");
184b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            return;
185b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
186b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        CalendarSyncEnabler enabler = new CalendarSyncEnabler(getContext());
187b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        String emailAddresses = enabler.enableEasCalendarSyncInternalForTest();
188b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
189b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Verify (nothing should change)
190b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        verifyCalendarSyncState();
191b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
192b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // No exchange accounts found.
193b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(0, emailAddresses.length());
194b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
195b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
196b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void testShowNotification() {
197b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        CalendarSyncEnabler enabler = new CalendarSyncEnabler(getContext());
198b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
199b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // We can't really check the result, but at least we can make sure it won't crash....
200b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        enabler.showNotificationForTest("a@b.com");
201b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
202b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Remove the notification.  Comment it out when you want to know how it looks like.
203b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // TODO If NotificationController supports this notification, we can just mock it out
204b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // and remove this code.
205b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE))
206b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                .cancel(CalendarSyncEnabler.NOTIFICATION_ID_EXCHANGE_CALENDAR_ADDED);
207b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
208b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
209b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected Account[] getExchangeAccounts() {
210b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return AccountManager.get(getContext()).getAccountsByType(
211b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                AccountManagerTypes.TYPE_EXCHANGE);
212b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
213b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
214b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected Account makeAccountManagerAccount(String username) {
215b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return new Account(username, AccountManagerTypes.TYPE_EXCHANGE);
216b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
217b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
218b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected void createAccountManagerAccount(String username) {
219b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        final Account account = makeAccountManagerAccount(username);
220b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        AccountManager.get(getContext()).addAccountExplicitly(account, "password", null);
221b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
222b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
223b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected com.android.emailcommon.provider.Account
224b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        setupProviderAndAccountManagerAccount(String username) {
225b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Note that setupAccount creates the email address username@android.com, so that's what
226b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // we need to use for the account manager
227b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        createAccountManagerAccount(username + TEST_ACCOUNT_SUFFIX);
228b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return setupTestAccount(username, true);
229b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
230b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
231b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected ArrayList<com.android.emailcommon.provider.Account> makeExchangeServiceAccountList() {
232b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        ArrayList<com.android.emailcommon.provider.Account> accountList =
233b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            new ArrayList<com.android.emailcommon.provider.Account>();
234b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        Cursor c = mProviderContext.getContentResolver().query(
235b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                com.android.emailcommon.provider.Account.CONTENT_URI,
236b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                com.android.emailcommon.provider.Account.CONTENT_PROJECTION, null, null, null);
237b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        try {
238b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            while (c.moveToNext()) {
239b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                com.android.emailcommon.provider.Account account =
240b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                    new com.android.emailcommon.provider.Account();
241b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                account.restore(c);
242b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                accountList.add(account);
243b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            }
244b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        } finally {
245b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            c.close();
246b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
247b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return accountList;
248b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
249b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
250b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected void deleteAccountManagerAccount(Account account) {
251b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        AccountManagerFuture<Boolean> future =
252b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            AccountManager.get(getContext()).removeAccount(account, null, null);
253b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        try {
254b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            future.getResult();
255b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        } catch (OperationCanceledException e) {
256b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        } catch (AuthenticatorException e) {
257b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        } catch (IOException e) {
258b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
259b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
260b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
261b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected void deleteTemporaryAccountManagerAccounts() {
262b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (Account accountManagerAccount: getExchangeAccounts()) {
263b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            if (accountManagerAccount.name.startsWith(TEST_ACCOUNT_PREFIX) &&
264b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                    accountManagerAccount.name.endsWith(TEST_ACCOUNT_SUFFIX)) {
265b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                deleteAccountManagerAccount(accountManagerAccount);
266b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            }
267b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
268b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
269b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
270b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected String getTestAccountName(String name) {
271b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return TEST_ACCOUNT_PREFIX + name;
272b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
273b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
274b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected String getTestAccountEmailAddress(String name) {
275b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return TEST_ACCOUNT_PREFIX + name + TEST_ACCOUNT_SUFFIX;
276b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
277b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
278b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
279b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    /**
280b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     * Helper to retrieve account manager accounts *and* remove any preexisting accounts
281b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     * from the list, to "hide" them from the reconciler.
282b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook     */
283b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    protected Account[] getAccountManagerAccounts(Account[] baseline) {
284b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        Account[] rawList = getExchangeAccounts();
285b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        if (baseline.length == 0) {
286b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            return rawList;
287b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
288b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        HashSet<Account> set = new HashSet<Account>();
289b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (Account addAccount : rawList) {
290b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            set.add(addAccount);
291b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
292b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        for (Account removeAccount : baseline) {
293b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook            set.remove(removeAccount);
294b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        }
295b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return set.toArray(new Account[0]);
296b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
297b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook}
298