blob: 93ebbeaac8fa7f70d0d9c452131fc2c0fe9320c3 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.content;
18
19import android.database.Cursor;
20import android.database.sqlite.SQLiteDatabase;
21import android.net.Uri;
Fred Quintanad9d2f112009-04-23 13:36:27 -070022import android.accounts.Account;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
24import 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 */
33public abstract class SyncableContentProvider extends ContentProvider {
34 protected abstract boolean isTemporary();
35
36 /**
37 * Close resources that must be closed. You must call this to properly release
38 * the resources used by the SyncableContentProvider.
39 */
40 public abstract void close();
41
42 /**
43 * Override to create your schema and do anything else you need to do with a new database.
44 * This is run inside a transaction (so you don't need to use one).
45 * This method may not use getDatabase(), or call content provider methods, it must only
46 * use the database handle passed to it.
47 */
48 protected abstract void bootstrapDatabase(SQLiteDatabase db);
49
50 /**
51 * Override to upgrade your database from an old version to the version you specified.
52 * Don't set the DB version, this will automatically be done after the method returns.
53 * This method may not use getDatabase(), or call content provider methods, it must only
54 * use the database handle passed to it.
55 *
56 * @param oldVersion version of the existing database
57 * @param newVersion current version to upgrade to
58 * @return true if the upgrade was lossless, false if it was lossy
59 */
60 protected abstract boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
61
62 /**
63 * Override to do anything (like cleanups or checks) you need to do after opening a database.
64 * Does nothing by default. This is run inside a transaction (so you don't need to use one).
65 * This method may not use getDatabase(), or call content provider methods, it must only
66 * use the database handle passed to it.
67 */
68 protected abstract void onDatabaseOpened(SQLiteDatabase db);
69
70 /**
71 * Get a non-persistent instance of this content provider.
72 * You must call {@link #close} on the returned
73 * SyncableContentProvider when you are done with it.
74 *
75 * @return a non-persistent content provider with the same layout as this
76 * provider.
77 */
78 public abstract SyncableContentProvider getTemporaryInstance();
79
80 public abstract SQLiteDatabase getDatabase();
81
82 public abstract boolean getContainsDiffs();
83
84 public abstract void setContainsDiffs(boolean containsDiffs);
85
86 /**
87 * Each subclass of this class should define a subclass of {@link
88 * AbstractTableMerger} for each table they wish to merge. It
89 * should then override this method and return one instance of
90 * each merger, in sequence. Their {@link
91 * AbstractTableMerger#merge merge} methods will be called, one at a
92 * time, in the order supplied.
93 *
94 * <p>The default implementation returns an empty list, so that no
95 * merging will occur.
96 * @return A sequence of subclasses of {@link
97 * AbstractTableMerger}, one for each table that should be merged.
98 */
99 protected abstract Iterable<? extends AbstractTableMerger> getMergers();
100
101 /**
102 * Check if changes to this URI can be syncable changes.
103 * @param uri the URI of the resource that was changed
104 * @return true if changes to this URI can be syncable changes, false otherwise
105 */
106 public abstract boolean changeRequiresLocalSync(Uri uri);
107
108 /**
109 * Called right before a sync is started.
110 *
111 * @param context the sync context for the operation
112 * @param account
113 */
Fred Quintanad9d2f112009-04-23 13:36:27 -0700114 public abstract void onSyncStart(SyncContext context, Account account);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115
116 /**
117 * Called right after a sync is completed
118 *
119 * @param context the sync context for the operation
120 * @param success true if the sync succeeded, false if an error occurred
121 */
122 public abstract void onSyncStop(SyncContext context, boolean success);
123
124 /**
125 * The account of the most recent call to onSyncStart()
126 * @return the account
127 */
Fred Quintanad9d2f112009-04-23 13:36:27 -0700128 public abstract Account getSyncingAccount();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129
130 /**
131 * Merge diffs from a sync source with this content provider.
132 *
133 * @param context the SyncContext within which this merge is taking place
134 * @param diffs A temporary content provider containing diffs from a sync
135 * source.
136 * @param result a MergeResult that contains information about the merge, including
137 * a temporary content provider with the same layout as this provider containing
138 * @param syncResult
139 */
140 public abstract void merge(SyncContext context, SyncableContentProvider diffs,
141 TempProviderSyncResult result, SyncResult syncResult);
142
143
144 /**
145 * Invoked when the active sync has been canceled. The default
146 * implementation doesn't do anything (except ensure that this
147 * provider is syncable). Subclasses of ContentProvider
148 * that support canceling of sync should override this.
149 */
150 public abstract void onSyncCanceled();
151
152
153 public abstract boolean isMergeCancelled();
154
155 /**
156 * Subclasses should override this instead of update(). See update()
157 * for details.
158 *
159 * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
160 * which means a database transaction will be active during the call;
161 */
162 protected abstract int updateInternal(Uri url, ContentValues values,
163 String selection, String[] selectionArgs);
164
165 /**
166 * Subclasses should override this instead of delete(). See delete()
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 */
172 protected abstract int deleteInternal(Uri url, String selection, String[] selectionArgs);
173
174 /**
175 * Subclasses should override this instead of insert(). See insert()
176 * for details.
177 *
178 * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
179 * which means a database transaction will be active during the call;
180 */
181 protected abstract Uri insertInternal(Uri url, ContentValues values);
182
183 /**
184 * Subclasses should override this instead of query(). See query()
185 * for details.
186 *
187 * <p> This method is *not* called within a acquireDbLock()/releaseDbLock()
188 * block for performance reasons. If an implementation needs atomic access
189 * to the database the lock can be acquired then.
190 */
191 protected abstract Cursor queryInternal(Uri url, String[] projection,
192 String selection, String[] selectionArgs, String sortOrder);
193
194 /**
195 * Make sure that there are no entries for accounts that no longer exist
196 * @param accountsArray the array of currently-existing accounts
197 */
Fred Quintanad9d2f112009-04-23 13:36:27 -0700198 protected abstract void onAccountsChanged(Account[] accountsArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199
200 /**
201 * A helper method to delete all rows whose account is not in the accounts
202 * map. The accountColumnName is the name of the column that is expected
203 * to hold the account. If a row has an empty account it is never deleted.
204 *
205 * @param accounts a map of existing accounts
206 * @param table the table to delete from
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 */
Fred Quintanad9d2f112009-04-23 13:36:27 -0700208 protected abstract void deleteRowsForRemovedAccounts(Map<Account, Boolean> accounts,
209 String table);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210
211 /**
212 * Called when the sync system determines that this provider should no longer
213 * contain records for the specified account.
214 */
Fred Quintanad9d2f112009-04-23 13:36:27 -0700215 public abstract void wipeAccount(Account account);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216
217 /**
218 * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
219 */
Fred Quintanad9d2f112009-04-23 13:36:27 -0700220 public abstract byte[] readSyncDataBytes(Account account);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221
222 /**
223 * Sets the SyncData bytes for the given account. The bytes array may be null.
224 */
Fred Quintanad9d2f112009-04-23 13:36:27 -0700225 public abstract void writeSyncDataBytes(Account account, byte[] data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226}
227