• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.content;
18 
19 import android.database.Cursor;
20 import android.database.sqlite.SQLiteDatabase;
21 import android.net.Uri;
22 import android.accounts.Account;
23 
24 import java.util.Map;
25 
26 /**
27  * A specialization of the ContentProvider that centralizes functionality
28  * used by ContentProviders that are syncable. It also wraps calls to the ContentProvider
29  * inside of database transactions.
30  *
31  * @hide
32  */
33 public abstract class SyncableContentProvider extends ContentProvider {
isTemporary()34     protected abstract boolean isTemporary();
35 
36     private volatile TempProviderSyncAdapter mTempProviderSyncAdapter;
37 
setTempProviderSyncAdapter(TempProviderSyncAdapter syncAdapter)38     public void setTempProviderSyncAdapter(TempProviderSyncAdapter syncAdapter) {
39         mTempProviderSyncAdapter = syncAdapter;
40     }
41 
getTempProviderSyncAdapter()42     public TempProviderSyncAdapter getTempProviderSyncAdapter() {
43         return mTempProviderSyncAdapter;
44     }
45 
46     /**
47      * Close resources that must be closed. You must call this to properly release
48      * the resources used by the SyncableContentProvider.
49      */
close()50     public abstract void close();
51 
52     /**
53      * Override to create your schema and do anything else you need to do with a new database.
54      * This is run inside a transaction (so you don't need to use one).
55      * This method may not use getDatabase(), or call content provider methods, it must only
56      * use the database handle passed to it.
57      */
bootstrapDatabase(SQLiteDatabase db)58     protected abstract void bootstrapDatabase(SQLiteDatabase db);
59 
60     /**
61      * Override to upgrade your database from an old version to the version you specified.
62      * Don't set the DB version, this will automatically be done after the method returns.
63      * This method may not use getDatabase(), or call content provider methods, it must only
64      * use the database handle passed to it.
65      *
66      * @param oldVersion version of the existing database
67      * @param newVersion current version to upgrade to
68      * @return true if the upgrade was lossless, false if it was lossy
69      */
upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion)70     protected abstract boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
71 
72     /**
73      * Override to do anything (like cleanups or checks) you need to do after opening a database.
74      * Does nothing by default.  This is run inside a transaction (so you don't need to use one).
75      * This method may not use getDatabase(), or call content provider methods, it must only
76      * use the database handle passed to it.
77      */
onDatabaseOpened(SQLiteDatabase db)78     protected abstract void onDatabaseOpened(SQLiteDatabase db);
79 
80     /**
81      * Get a non-persistent instance of this content provider.
82      * You must call {@link #close} on the returned
83      * SyncableContentProvider when you are done with it.
84      *
85      * @return a non-persistent content provider with the same layout as this
86      * provider.
87      */
getTemporaryInstance()88     public abstract SyncableContentProvider getTemporaryInstance();
89 
getDatabase()90     public abstract SQLiteDatabase getDatabase();
91 
getContainsDiffs()92     public abstract boolean getContainsDiffs();
93 
setContainsDiffs(boolean containsDiffs)94     public abstract void setContainsDiffs(boolean containsDiffs);
95 
96     /**
97      * Each subclass of this class should define a subclass of {@link
98      * AbstractTableMerger} for each table they wish to merge.  It
99      * should then override this method and return one instance of
100      * each merger, in sequence.  Their {@link
101      * AbstractTableMerger#merge merge} methods will be called, one at a
102      * time, in the order supplied.
103      *
104      * <p>The default implementation returns an empty list, so that no
105      * merging will occur.
106      * @return A sequence of subclasses of {@link
107      * AbstractTableMerger}, one for each table that should be merged.
108      */
getMergers()109     protected abstract Iterable<? extends AbstractTableMerger> getMergers();
110 
111     /**
112      * Check if changes to this URI can be syncable changes.
113      * @param uri the URI of the resource that was changed
114      * @return true if changes to this URI can be syncable changes, false otherwise
115      */
changeRequiresLocalSync(Uri uri)116     public abstract boolean changeRequiresLocalSync(Uri uri);
117 
118     /**
119      * Called right before a sync is started.
120      *
121      * @param context the sync context for the operation
122      * @param account
123      */
onSyncStart(SyncContext context, Account account)124     public abstract void onSyncStart(SyncContext context, Account account);
125 
126     /**
127      * Called right after a sync is completed
128      *
129      * @param context the sync context for the operation
130      * @param success true if the sync succeeded, false if an error occurred
131      */
onSyncStop(SyncContext context, boolean success)132     public abstract void onSyncStop(SyncContext context, boolean success);
133 
134     /**
135      * The account of the most recent call to onSyncStart()
136      * @return the account
137      */
getSyncingAccount()138     public abstract Account getSyncingAccount();
139 
140     /**
141      * Merge diffs from a sync source with this content provider.
142      *
143      * @param context the SyncContext within which this merge is taking place
144      * @param diffs A temporary content provider containing diffs from a sync
145      *   source.
146      * @param result a MergeResult that contains information about the merge, including
147      *   a temporary content provider with the same layout as this provider containing
148      * @param syncResult
149      */
merge(SyncContext context, SyncableContentProvider diffs, TempProviderSyncResult result, SyncResult syncResult)150     public abstract void merge(SyncContext context, SyncableContentProvider diffs,
151             TempProviderSyncResult result, SyncResult syncResult);
152 
153 
154     /**
155      * Invoked when the active sync has been canceled. The default
156      * implementation doesn't do anything (except ensure that this
157      * provider is syncable). Subclasses of ContentProvider
158      * that support canceling of sync should override this.
159      */
onSyncCanceled()160     public abstract void onSyncCanceled();
161 
162 
isMergeCancelled()163     public abstract boolean isMergeCancelled();
164 
165     /**
166      * Subclasses should override this instead of update(). See update()
167      * for details.
168      *
169      * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
170      * which means a database transaction will be active during the call;
171      */
updateInternal(Uri url, ContentValues values, String selection, String[] selectionArgs)172     protected abstract int updateInternal(Uri url, ContentValues values,
173             String selection, String[] selectionArgs);
174 
175     /**
176      * Subclasses should override this instead of delete(). See delete()
177      * for details.
178      *
179      * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
180      * which means a database transaction will be active during the call;
181      */
deleteInternal(Uri url, String selection, String[] selectionArgs)182     protected abstract int deleteInternal(Uri url, String selection, String[] selectionArgs);
183 
184     /**
185      * Subclasses should override this instead of insert(). See insert()
186      * for details.
187      *
188      * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
189      * which means a database transaction will be active during the call;
190      */
insertInternal(Uri url, ContentValues values)191     protected abstract Uri insertInternal(Uri url, ContentValues values);
192 
193     /**
194      * Subclasses should override this instead of query(). See query()
195      * for details.
196      *
197      * <p> This method is *not* called within a acquireDbLock()/releaseDbLock()
198      * block for performance reasons. If an implementation needs atomic access
199      * to the database the lock can be acquired then.
200      */
queryInternal(Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder)201     protected abstract Cursor queryInternal(Uri url, String[] projection,
202             String selection, String[] selectionArgs, String sortOrder);
203 
204     /**
205      * Make sure that there are no entries for accounts that no longer exist
206      * @param accountsArray the array of currently-existing accounts
207      */
onAccountsChanged(Account[] accountsArray)208     protected abstract void onAccountsChanged(Account[] accountsArray);
209 
210     /**
211      * A helper method to delete all rows whose account is not in the accounts
212      * map. The accountColumnName is the name of the column that is expected
213      * to hold the account. If a row has an empty account it is never deleted.
214      *
215      * @param accounts a map of existing accounts
216      * @param table the table to delete from
217      */
deleteRowsForRemovedAccounts(Map<Account, Boolean> accounts, String table)218     protected abstract void deleteRowsForRemovedAccounts(Map<Account, Boolean> accounts,
219             String table);
220 
221     /**
222      * Called when the sync system determines that this provider should no longer
223      * contain records for the specified account.
224      */
wipeAccount(Account account)225     public abstract void wipeAccount(Account account);
226 
227     /**
228      * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
229      */
readSyncDataBytes(Account account)230     public abstract byte[] readSyncDataBytes(Account account);
231 
232     /**
233      * Sets the SyncData bytes for the given account. The bytes array may be null.
234      */
writeSyncDataBytes(Account account, byte[] data)235     public abstract void writeSyncDataBytes(Account account, byte[] data);
236 }
237 
238