SynchronousContactsProvider2.java revision 767e109d6f08749b9ed202c0b71f3459eaae2115
1619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey/*
2619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Copyright (C) 2009 The Android Open Source Project
3619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey *
4619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * you may not use this file except in compliance with the License.
6619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * You may obtain a copy of the License at
7619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey *
8619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey *
10619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Unless required by applicable law or agreed to in writing, software
11619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * See the License for the specific language governing permissions and
14619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * limitations under the License.
15619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */
16619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey
1728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarpackage com.android.providers.contacts;
18619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey
19caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikovimport android.accounts.Account;
20d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.Context;
212482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikovimport android.database.sqlite.SQLiteDatabase;
22d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey/**
26619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * A version of {@link ContactsProvider2} class that performs aggregation
27619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * synchronously and wipes all data at construction time.
28619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */
29619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeypublic class SynchronousContactsProvider2 extends ContactsProvider2 {
3073f1f396c155b247b903d8f4111db17d3e13dc4dDmitri Plotnikov    public static final String READ_ONLY_ACCOUNT_TYPE = "ro";
3173f1f396c155b247b903d8f4111db17d3e13dc4dDmitri Plotnikov
32619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    private static Boolean sDataWiped = false;
33b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov    private static ContactsDatabaseHelper mDbHelper;
342482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    private boolean mDataWipeEnabled = true;
35caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov    private Account mAccount;
3681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    private boolean mNetworkNotified;
37619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey
38619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    @Override
39b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov    protected ContactsDatabaseHelper getDatabaseHelper(final Context context) {
40b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov        if (mDbHelper == null) {
41b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov            mDbHelper = new ContactsDatabaseHelper(context);
42d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
43b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov        return mDbHelper;
44d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
45d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
463d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov    public static void resetOpenHelper() {
47b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov        mDbHelper = null;
483d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov    }
493d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov
502482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    public void setDataWipeEnabled(boolean flag) {
512482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov        mDataWipeEnabled = flag;
522482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    }
532482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov
54d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    @Override
5581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    protected void onBeginTransaction() {
5681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        super.onBeginTransaction();
5781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        mNetworkNotified = false;
5881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    }
5981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov
6081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    @Override
6181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    protected void notifyChange(boolean syncToNetwork) {
6281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        mNetworkNotified |= syncToNetwork;
6381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    }
6481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov
6581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    public boolean isNetworkNotified() {
6681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        return mNetworkNotified;
6781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    }
6881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov
6981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov    @Override
70619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    public boolean onCreate() {
71619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey        boolean created = super.onCreate();
722482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov        if (mDataWipeEnabled) {
732482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov            synchronized (sDataWiped) {
742482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov                if (!sDataWiped) {
752482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov                    sDataWiped = true;
762482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov                    wipeData();
772482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov                }
78619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey            }
79619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey        }
80619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey        return created;
81619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    }
8253056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov
833d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov    @Override
84c1778ef6fa53b6bf08fd715b3ad70c052c5f1ce9Dmitri Plotnikov    protected void verifyAccounts() {
85c1778ef6fa53b6bf08fd715b3ad70c052c5f1ce9Dmitri Plotnikov    }
86c1778ef6fa53b6bf08fd715b3ad70c052c5f1ce9Dmitri Plotnikov
87c1778ef6fa53b6bf08fd715b3ad70c052c5f1ce9Dmitri Plotnikov    @Override
8889f1f71495aedc58252b3f58a46a036986c319d2Dmitri Plotnikov    protected void verifyLocale() {
8989f1f71495aedc58252b3f58a46a036986c319d2Dmitri Plotnikov    }
9089f1f71495aedc58252b3f58a46a036986c319d2Dmitri Plotnikov
9189f1f71495aedc58252b3f58a46a036986c319d2Dmitri Plotnikov    @Override
92caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov    protected Account getDefaultAccount() {
93caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov        if (mAccount == null) {
94c76cdd0723b99f478c9ba5329d14a971cd8dfb3dCostin Manolache            mAccount = new Account("androidtest@gmail.com", "com.google");
95caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov        }
96caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov        return mAccount;
97caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov    }
98caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov
99767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov    /**
100767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov     * Creates a mock PhotoPriorityResolver
101767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov     */
102767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov    @Override
103767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov    PhotoPriorityResolver createPhotoPriorityResolver(Context context) {
104767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov        return new PhotoPriorityResolver(context) {
105767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov            @Override
106767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov            public synchronized int getPhotoPriority(String accountType) {
107767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                if ("cupcake".equals(accountType)) {
108767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                    return 3;
109767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                }
110767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                if ("donut".equals(accountType)) {
111767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                    return 2;
112767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                }
113767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                if ("froyo".equals(accountType)) {
114767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                    return 1;
115767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                }
116767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov                return 0;
117767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov            }
118767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov        };
119767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov    }
120767e109d6f08749b9ed202c0b71f3459eaae2115Dmitri Plotnikov
121627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    @Override
1225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    protected Locale getLocale() {
1235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        return Locale.US;
1245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
1255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
1265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    @Override
12773f1f396c155b247b903d8f4111db17d3e13dc4dDmitri Plotnikov    protected boolean isWritableAccount(String accountType) {
12873f1f396c155b247b903d8f4111db17d3e13dc4dDmitri Plotnikov        return !READ_ONLY_ACCOUNT_TYPE.equals(accountType);
129627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    }
130627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov
1312482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    public void prepareForFullAggregation(int maxContact) {
132b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov        SQLiteDatabase db = getDatabaseHelper().getWritableDatabase();
133c1778ef6fa53b6bf08fd715b3ad70c052c5f1ce9Dmitri Plotnikov        db.execSQL("UPDATE raw_contacts SET aggregation_mode=0,aggregation_needed=1;");
1342482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov        long rowId =
1352482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov            db.compileStatement("SELECT _id FROM raw_contacts LIMIT 1 OFFSET " + maxContact)
1362482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov                .simpleQueryForLong();
1372482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov        db.execSQL("DELETE FROM raw_contacts WHERE _id > " + rowId + ";");
1382482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    }
1392482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov
1402482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    public long getRawContactCount() {
141b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov        SQLiteDatabase db = getDatabaseHelper().getReadableDatabase();
1422482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov        return db.compileStatement("SELECT COUNT(*) FROM raw_contacts").simpleQueryForLong();
1432482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    }
1442482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov
1452482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    public long getContactCount() {
146b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov        SQLiteDatabase db = getDatabaseHelper().getReadableDatabase();
1472482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov        return db.compileStatement("SELECT COUNT(*) FROM contacts").simpleQueryForLong();
1482482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov    }
1492482dd0309794d57233d0af37a7c12fc647e7bf9Dmitri Plotnikov
150caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov    @Override
1514e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void wipeData() {
1524e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        super.wipeData();
1534e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        SQLiteDatabase db = getDatabaseHelper().getWritableDatabase();
1544e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('raw_contacts', 42)");
1554e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('contacts', 2009)");
1564e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('data', 777)");
1574e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
1584e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
1594e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    @Override
1603d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov    protected boolean isLegacyContactImportNeeded() {
1613d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov
1623d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov        // We have an explicit test for data conversion - no need to do it every time
1633d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov        return false;
1643d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov    }
165619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey}
166