19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 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 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.accounts.Account; 20a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.app.ActivityThread; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.CursorWrapper; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 30231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 33231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 34d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrickimport android.os.SystemClock; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 36231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Config; 37a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.util.EventLog; 38231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 47a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport java.util.Random; 4803d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanaimport java.util.ArrayList; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides applications access to the content model. 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentResolver { 55ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 56ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 57ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 58ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 594a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 60ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_ACCOUNT = "account"; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 62ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 63ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 64ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 65ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 664a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 6853bd2522ca7767f46646606123b6e2689b811850Fred Quintana 6953bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 7053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the sync settings (like getSyncAutomatically()) 7153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. 7253bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 7353bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_SETTINGS = "ignore_settings"; 7453bd2522ca7767f46646606123b6e2689b811850Fred Quintana 7553bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 7653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then any backoffs for the initial attempt (e.g. due to retries) 7753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. If this request fails and gets rescheduled then the 7853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * retries will still honor the backoff. 7953bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 8053bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_BACKOFF = "ignore_backoff"; 8153bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8253bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the request will not be retried if it fails. 8453bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 8553bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_DO_NOT_RETRY = "do_not_retry"; 8653bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8753bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Setting this extra is the equivalent of setting both {@link #SYNC_EXTRAS_IGNORE_SETTINGS} 8953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * and {@link #SYNC_EXTRAS_IGNORE_BACKOFF} 9053bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 91ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 9253bd2522ca7767f46646606123b6e2689b811850Fred Quintana 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 974a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana /** 984a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Set by the SyncManager to request that the SyncAdapter initialize itself for 994a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * the given account/authority pair. One required initialization step is to 1004a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been 1014a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * called with a >= 0 value. When this flag is set the SyncAdapter does not need to 1024a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * do a full sync, though it is allowed to do so. 1034a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana */ 1044a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; 1054a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 1190ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 1230ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 1330ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 141ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 142ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 143ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 144ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 145ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 146ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 147ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 148ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 149ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 150ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 151ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 152ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 153ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 154ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 155ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 156ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 157ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 158ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 159ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 160ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 161ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 162ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 163ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 16725880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 168a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 16925880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 170a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 171a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 172231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final String getType(Uri url) 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.getType(url); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (java.lang.Exception e) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2060ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 2080ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 2090ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 2100ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 2110ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 2120ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 2130ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 2140ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 2150ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 2160ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 2170ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 2180ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 2190ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 2240ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 244d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder); 246a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 250020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori // force query execution 251020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 252d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 253a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 254a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Wrap the cursor object into CursorWrapperInner object 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new CursorWrapperInner(qCursor, provider); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch(RuntimeException e) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2658943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2750ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 2780ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3330ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3680ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3840ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3890ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3960ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile()} method of the provider associated with the 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given URI, to retrieve any file stored there. 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No content provider: " + uri); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = provider.openAssetFile(uri, mode); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(fd == null) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getParcelFileDescriptor(), provider); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, fd.getStartOffset(), 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getDeclaredLength()); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Dead content provider: " + uri); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (FileNotFoundException e) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4894c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 4904c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 4914c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 4924c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 4934c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 4944c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 4954c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 4964c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4984c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 4994c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 5004c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 5014c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 5024c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 5034c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 5044c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5410ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5680ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 586d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 587a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri createdRow = provider.insert(url, values); 588d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 589a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 590a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5988943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 5998943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 6008943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 6018943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 6028943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 6038943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 6048943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 6058943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 6068943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 6078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 6088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 6098943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 6108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 6118943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 6128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 6138943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 6148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 61503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 6168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 6178943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 6186a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 6198943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 6206a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6216a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 6228943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 6236a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 6246a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 6256a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6266a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6276a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 645d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 646a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsCreated = provider.bulkInsert(url, values); 647d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 648a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 649a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 674d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 675a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsDeleted = provider.delete(url, where, selectionArgs); 676d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 677a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 678a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 694d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 696b0c6dbd53b26b172fe8eb7d117550e4edf7a0c9cJeff Hamilton * @return The number of rows updated. 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 706d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 707a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsUpdated = provider.update(uri, values, where, selectionArgs); 708d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 709a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 710a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the content provider for the given content URI.. 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(Uri uri) 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String auth = uri.getAuthority(); 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, uri.getAuthority()); 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 7411877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 748718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 749718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 750718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 751718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 752718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 753718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 754718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 755718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 756718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 757718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 758718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 759718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 760718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 761718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 762718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 763718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 764718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 765718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 766718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 767718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 768718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 769718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 770718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 771718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 772718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 773718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 774718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 775718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 776718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 777718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 778718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 779718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 780718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 781718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 782718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 783718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 784718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 785718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 786718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 787718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 804231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer.getContentObserver()); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 820231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 850231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer != null && observer.deliverSelfNotifications(), syncToNetwork); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 872ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 873ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8754a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 877ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 878ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 879ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 880ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 8813348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 882ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 883ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 884ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 885ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 886ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 887ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 888ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 889ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 890ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 891ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 892ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 893ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 894ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 895ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 896ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 897ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 898ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 899ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 900ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 901ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 902ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 903ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 904ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 905ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 908ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().requestSync(account, authority, extras); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 922d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 938d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 950ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 951ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 952ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 953ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 954ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 955ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 9564a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 958ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 959ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 960ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 961ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 962ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 963ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 964ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 965ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 966ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 967ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 968ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 969ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 970ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 971ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 972ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 973ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 974ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 975ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 976ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 977ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 978ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 979ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 980ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 981ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 982ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 983ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 984ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 985ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 986ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 987ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 988ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 989ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 990ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 991ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 992ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 993ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 994ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 995ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 996ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 997ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 998ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 999ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1000ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1001ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1002ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1003ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1004ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 1005ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1006ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1007ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1008ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1009ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1010ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1012ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1014ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 10155e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 10165e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10175e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10185e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 10195e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 1020c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 1021c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 1022c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 1023c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 1024c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 1025c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 1026c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 1027c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 1028c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 102953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 103053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 103153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 103253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 103353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 103453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 1035c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1036c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 1037c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 1038c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 1039c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 104053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 104153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 1042c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1043c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 1044c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 1045c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 104653bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 104753bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 104853bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 104953bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 105053bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 105153bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 105253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 105353bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 105453bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 105553bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 105653bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 105753bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 105853bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 105953bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 106053bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1061c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1062c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 1063c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1064c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1065c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 1066c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1067c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1068c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1069c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1070c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 1071c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 1072c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1073c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 1074c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 1075c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 1076c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1077c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 1078c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 107953bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 108053bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 108153bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 108253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 108353bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 108453bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1085c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1086c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 1087c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1088c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1089c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1090c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1091c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1092c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1093c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 1094c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1095c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 1096c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 1097c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 1098c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1099c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 110053bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 110153bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 110253bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 110353bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 110453bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 110553bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1106c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1107c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getContentService().getPeriodicSyncs(account, authority); 1108c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1109c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1110c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1111c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1112c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1113c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 11145e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 11155e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 11165e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 111720ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 11185e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 11195e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 11205e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 11215e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 11225e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 11235e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 11245e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 11255e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 11265e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 1127718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 11285e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 112920ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 11305e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 11315e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 11325e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 11335e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1134ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1138ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1139ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 1140ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 1141ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1142ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 1143ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1144ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 1145ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1146ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 1147ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1148ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1149ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1150ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1151ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1152ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1153ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 1154ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 1155ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1156ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 1157ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1158ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 1159ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1160ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 1161ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1162ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1163ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1167ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1168ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 1169ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 1170ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1171ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1172ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 1173ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1174ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 1175ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1176ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 1177ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1178ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1179ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1180ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1181ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1182ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1183ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If a sync is active returns the information about it, otherwise returns false. 1184d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 1185ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1186d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 1187ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1188d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana return getContentService().getCurrentSync(); 1189ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1190ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1191ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1192ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1193ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1194ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 11954a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 1196ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1197ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1198ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 1199ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1200ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1201ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 1202ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1203ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 1204ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1205ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1206ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1207ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1208ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1209ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1210ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 1211ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1212ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1213ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 1214ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1215ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 1216ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1217ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 1218ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1219ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1220ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1221ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1222ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 12231b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 12241b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 12251b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 12261b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 12271b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 12281b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 12291b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 12301b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 12311b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 12321b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 12331b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 12341b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 12351b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 12361b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1237ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 12381b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 12391b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 12401b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1241ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1242ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 1243ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 1244ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 1245ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1246ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 1247ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 1248ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 1249ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1250ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1251ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1252ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1253ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 12541b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 12551b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 12561b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 12571b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1258ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 12591b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 12601b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 12611b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1262ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1263ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 1264ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1265ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1266ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1267ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1268ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1269ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1270a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 1271a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 1272a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 1273a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 1274a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 1275a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 1276a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 1277a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 1278a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1279a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 1280a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1281a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1282a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 1283a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 1284a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 1285a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1286a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1287a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1288a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1289a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1290a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1291a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1292a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1293a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1294a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 1295a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 1296a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 1297a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 1298a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 1299a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 1300a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 1301a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 1302a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 1303a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1304a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1305a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1306a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 1307a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 1308a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 1309a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String blockingPackage = ActivityThread.currentPackageName(); 1310a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1311a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1312a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 1313a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1314a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 1315a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1316a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 1317a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1318a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1319a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1320a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1321a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1322a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 1323a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 1324a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1325a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1326a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1327a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1328a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1329a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1330a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1331a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1332a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String blockingPackage = ActivityThread.currentPackageName(); 1333a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1334a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 1335a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1336a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 1337a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1338a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1339a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1340a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1341a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1342ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class CursorWrapperInner extends CursorWrapper { 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mCloseFlag = false; 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCloseFlag = true; 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mCloseFlag) { 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="ParcelFileDescriptorInner"; 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1400231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 14010ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1402231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1403231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 1404231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 1405231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1406231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1407231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 1408231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service binder = " + b); 1409231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 1410231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service = " + sContentService); 1411231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1412231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 14130ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1414231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1418