19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
178ff9a156c04c24458d94c716a64a5b7327f0e987Amith Yamasanipackage com.android.server.content;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.accounts.Account;
2056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williamsimport android.content.ComponentName;
218ff9a156c04c24458d94c716a64a5b7327f0e987Amith Yamasaniimport android.content.ContentResolver;
228ff9a156c04c24458d94c716a64a5b7327f0e987Amith Yamasaniimport android.content.Context;
238ff9a156c04c24458d94c716a64a5b7327f0e987Amith Yamasaniimport android.content.ContextWrapper;
248ff9a156c04c24458d94c716a64a5b7327f0e987Amith Yamasaniimport android.content.Intent;
258ff9a156c04c24458d94c716a64a5b7327f0e987Amith Yamasaniimport android.content.PeriodicSync;
26fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williamsimport android.content.res.Resources;
27f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.os.Bundle;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.AndroidTestCase;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.RenamingDelegatingContext;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.mock.MockContentResolver;
31f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.test.mock.MockContext;
32f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.test.suitebuilder.annotation.LargeTest;
33f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.test.suitebuilder.annotation.MediumTest;
34f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.test.suitebuilder.annotation.SmallTest;
35c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
3656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williamsimport com.android.server.content.SyncStorageEngine.EndPoint;
3756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams
3857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albertimport com.android.internal.os.AtomicFile;
3957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert
40c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintanaimport java.io.File;
41c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintanaimport java.io.FileOutputStream;
42f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport java.util.List;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SyncStorageEngineTest extends AndroidTestCase {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
46fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    protected Account account1;
4706485a7c6e3bbea1f427f345ac3a18b2346750e0Matthew Williams    protected Account account2;
4856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams    protected ComponentName syncService1;
49fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    protected String authority1 = "testprovider";
50fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    protected Bundle defaultBundle;
51fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    protected final int DEFAULT_USER = 0;
5256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams
5356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams    /* Some default poll frequencies. */
5456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams    final long dayPoll = (60 * 60 * 24);
5556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams    final long dayFuzz = 60;
5656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams    final long thousandSecs = 1000;
5756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams    final long thousandSecsFuzz = 100;
5856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams
59fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    MockContentResolver mockResolver;
60fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    SyncStorageEngine engine;
6156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams
6204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani    private File getSyncDir() {
6304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        return new File(new File(getContext().getFilesDir(), "system"), "sync");
6404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani    }
6504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
66fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    @Override
67fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    public void setUp() {
68fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        account1 = new Account("a@example.com", "example.type");
6906485a7c6e3bbea1f427f345ac3a18b2346750e0Matthew Williams        account2 = new Account("b@example.com", "example.type");
7056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams        syncService1 = new ComponentName("com.example", "SyncService");
71fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        // Default bundle.
72fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        defaultBundle = new Bundle();
73fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        defaultBundle.putInt("int_key", 0);
74fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        defaultBundle.putString("string_key", "hello");
75fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        // Set up storage engine.
76fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        mockResolver = new MockContentResolver();
77fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        engine = SyncStorageEngine.newTestInstance(
78fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams                new TestContext(mockResolver, getContext()));
79fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    }
80fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Test that we handle the case of a history row being old enough to purge before the
83ba35271e91648c9cde2bb606aaf2001282231b07Matthew Williams     * corresponding sync is finished. This can happen if the clock changes while we are syncing.
84c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana     *
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
862ad24f944ee68c6e14f3a214f0eef60f8cdb9eb8Brett Chabot    // TODO: this test causes AidlTest to fail. Omit for now
872ad24f944ee68c6e14f3a214f0eef60f8cdb9eb8Brett Chabot    // @SmallTest
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testPurgeActiveSync() throws Exception {
89d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana        final Account account = new Account("a@example.com", "example.type");
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final String authority = "testprovider";
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MockContentResolver mockResolver = new MockContentResolver();
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new TestContext(mockResolver, getContext()));
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long time0 = 1000;
97bef28feba57be7fd6a4d14a85a8229154338b2edDianne Hackborn        SyncOperation op = new SyncOperation(account, 0, 0, "foo",
9856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams                SyncOperation.REASON_PERIODIC,
9956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams                SyncStorageEngine.SOURCE_LOCAL,
10056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams                authority,
1018c834c07675052c984728cbf79f7c2e0d8246e43Shreyas Basarge                Bundle.EMPTY, true);
10256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams        long historyId = engine.insertStartSyncEvent(op, time0);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
10477c560f3d7891d9ae1ad714b5f65a22ff4f4c06bFred Quintana        engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0);
105c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    }
106c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
107f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @LargeTest
108c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    public void testAuthorityPersistence() throws Exception {
109c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        final Account account1 = new Account("a@example.com", "example.type");
110c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        final Account account2 = new Account("b@example.com", "example.type.2");
111c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        final String authority1 = "testprovider1";
112c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        final String authority2 = "testprovider2";
113c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
11404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setMasterSyncAutomatically(false, 0);
115c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
11604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setIsSyncable(account1, 0, authority1, 1);
11704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setSyncAutomatically(account1, 0, authority1, true);
118c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
11904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setIsSyncable(account2, 0, authority1, 1);
12004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setSyncAutomatically(account2, 0, authority1, true);
121c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
12204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setIsSyncable(account1, 0, authority2, 1);
12304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setSyncAutomatically(account1, 0, authority2, false);
124c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
12504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setIsSyncable(account2, 0, authority2, 0);
12604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        engine.setSyncAutomatically(account2, 0, authority2, true);
127c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
128c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        engine.writeAllState();
129c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        engine.clearAndReadState();
130c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
13104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getSyncAutomatically(account1, 0, authority1));
13204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getSyncAutomatically(account2, 0, authority1));
13304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getSyncAutomatically(account1, 0, authority2));
13404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getSyncAutomatically(account2, 0, authority2));
135c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
13604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(1, engine.getIsSyncable(account1, 0, authority1));
13704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(1, engine.getIsSyncable(account2, 0, authority1));
13804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(1, engine.getIsSyncable(account1, 0, authority2));
13904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(0, engine.getIsSyncable(account2, 0, authority2));
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
141c2e4691d788088b22eadc9b2d35e9bdf0b6a0ffcFred Quintana
142f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
14304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani    public void testListenForTicklesParsing() throws Exception {
14404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
14504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani                + "<accounts>\n"
14604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani                + "<listenForTickles user=\"0\" enabled=\"false\" />"
14704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani                + "<listenForTickles user=\"1\" enabled=\"true\" />"
14804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani                + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
14904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani                + "<authority id=\"1\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
15004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani                + "</accounts>\n").getBytes();
15104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
15204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        MockContentResolver mockResolver = new MockContentResolver();
15304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        final TestContext testContext = new TestContext(mockResolver, getContext());
15404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
15504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        File syncDir = getSyncDir();
15604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        syncDir.mkdirs();
15704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
15804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        FileOutputStream fos = accountInfoFile.startWrite();
15904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        fos.write(accountsFileData);
16004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        accountInfoFile.finishWrite(fos);
16104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
16204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
16304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
16404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getMasterSyncAutomatically(0));
16504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getMasterSyncAutomatically(1));
16604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getMasterSyncAutomatically(2));
16704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
16804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani    }
16904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
17004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani    @MediumTest
171fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana    public void testAuthorityRenaming() throws Exception {
172fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final Account account1 = new Account("acc1", "type1");
173fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final Account account2 = new Account("acc2", "type2");
174fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final String authorityContacts = "contacts";
175fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final String authorityCalendar = "calendar";
176fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final String authorityOther = "other";
177fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final String authorityContactsNew = "com.android.contacts";
178fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final String authorityCalendarNew = "com.android.calendar";
179fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
180fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        MockContentResolver mockResolver = new MockContentResolver();
181fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
182fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final TestContext testContext = new TestContext(mockResolver, getContext());
183fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
184fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
185fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<accounts>\n"
186fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"0\" account=\"acc1\" type=\"type1\" authority=\"contacts\" />\n"
187fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"1\" account=\"acc1\" type=\"type1\" authority=\"calendar\" />\n"
188fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"2\" account=\"acc1\" type=\"type1\" authority=\"other\" />\n"
189fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"3\" account=\"acc2\" type=\"type2\" authority=\"contacts\" />\n"
190fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"4\" account=\"acc2\" type=\"type2\" authority=\"calendar\" />\n"
191fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"5\" account=\"acc2\" type=\"type2\" authority=\"other\" />\n"
192fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"6\" account=\"acc2\" type=\"type2\" enabled=\"false\""
193fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + " authority=\"com.android.calendar\" />\n"
194fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"7\" account=\"acc2\" type=\"type2\" enabled=\"false\""
195fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + " authority=\"com.android.contacts\" />\n"
196fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "</accounts>\n").getBytes();
197fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
198fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync");
199fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        syncDir.mkdirs();
200fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
201fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        FileOutputStream fos = accountInfoFile.startWrite();
202fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        fos.write(accountsFileData);
203fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        accountInfoFile.finishWrite(fos);
204fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
205fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
206fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
20704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityContacts));
20804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getSyncAutomatically(account1, 0, authorityCalendar));
20904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityOther));
21004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityContactsNew));
21104e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getSyncAutomatically(account1, 0, authorityCalendarNew));
21204e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani
21304e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContacts));
21404e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendar));
21504e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(true, engine.getSyncAutomatically(account2, 0, authorityOther));
21604e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityContactsNew));
21704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(false, engine.getSyncAutomatically(account2, 0, authorityCalendarNew));
218fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana    }
219fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
220fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana    @SmallTest
221fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana    public void testSyncableMigration() throws Exception {
222fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final Account account = new Account("acc", "type");
223fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
224fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        MockContentResolver mockResolver = new MockContentResolver();
225fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
226fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        final TestContext testContext = new TestContext(mockResolver, getContext());
227fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
228fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
229fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<accounts>\n"
230fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"0\" account=\"acc\" authority=\"other1\" />\n"
231fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"1\" account=\"acc\" type=\"type\" authority=\"other2\" />\n"
232fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"2\" account=\"acc\" type=\"type\" syncable=\"false\""
233fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + " authority=\"other3\" />\n"
234fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "<authority id=\"3\" account=\"acc\" type=\"type\" syncable=\"true\""
235fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + " authority=\"other4\" />\n"
236fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana                + "</accounts>\n").getBytes();
237fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
238fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync");
239fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        syncDir.mkdirs();
240fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
241fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        FileOutputStream fos = accountInfoFile.startWrite();
242fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        fos.write(accountsFileData);
243fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        accountInfoFile.finishWrite(fos);
244fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
245fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
246fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana
24704e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(-1, engine.getIsSyncable(account, 0, "other1"));
24804e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(1, engine.getIsSyncable(account, 0, "other2"));
24904e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(0, engine.getIsSyncable(account, 0, "other3"));
25004e0d265e3385e9d1fbc35e43c4e8caffbbe3290Amith Yamasani        assertEquals(1, engine.getIsSyncable(account, 0, "other4"));
251fb084400d6afa6443a421117fbcaee0265d38fb6Fred Quintana    }
252632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
253632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams    /**
254632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams     * Verify that the API cannot cause a run-time reboot by passing in the empty string as an
255632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams     * authority. The problem here is that
256632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams     * {@link SyncStorageEngine#getOrCreateAuthorityLocked(account, provider)} would register
257632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams     * an empty authority which causes a RTE in {@link SyncManager#scheduleReadyPeriodicSyncs()}.
258632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams     * This is not strictly a SSE test, but it does depend on the SSE data structures.
259632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams     */
260632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams    @SmallTest
261632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams    public void testExpectedIllegalArguments() throws Exception {
262632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
263632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.setSyncAutomatically(account1, "", true);
264632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
265632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
266632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
267632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
268632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.addPeriodicSync(account1, "", Bundle.EMPTY, 84000L);
269632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
270632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
271632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
272632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
273632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.removePeriodicSync(account1, "", Bundle.EMPTY);
274632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
275632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
276632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
277632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
278632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.cancelSync(account1, "");
279632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
280632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
281632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
282632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
283632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.setIsSyncable(account1, "", 0);
284632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
285632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
286632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
287632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
288632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.cancelSync(account1, "");
289632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
290632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
291632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
292632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
293632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.requestSync(account1, "", Bundle.EMPTY);
294632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
295632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
296632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
297632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        try {
298632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            ContentResolver.getSyncStatus(account1, "");
299632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams            fail("empty provider string should throw IllegalArgumentException");
300632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        } catch (IllegalArgumentException expected) {}
301632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams
302632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        // Make sure we aren't blocking null account/provider for those functions that use it
303632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        // to specify ALL accounts/providers.
304632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        ContentResolver.requestSync(null, null, Bundle.EMPTY);
305632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams        ContentResolver.cancelSync(null, null);
306632515b9d0960749ddb1636677d7f12f196d73f7Matthew Williams    }
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass TestContext extends ContextWrapper {
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ContentResolver mResolver;
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
313c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    private final Context mRealContext;
314c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public TestContext(ContentResolver resolver, Context realContext) {
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(new RenamingDelegatingContext(new MockContext(), realContext, "test."));
317c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        mRealContext = realContext;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mResolver = resolver;
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
322fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    public Resources getResources() {
323fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams        return mRealContext.getResources();
324fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    }
325fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams
326fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams    @Override
327c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    public File getFilesDir() {
328c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana        return mRealContext.getFilesDir();
329c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    }
330c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana
331c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    @Override
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void enforceCallingOrSelfPermission(String permission, String message) {
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
335c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    @Override
336c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    public void sendBroadcast(Intent intent) {
337c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana    }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ContentResolver getContentResolver() {
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mResolver;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
344