ContentResolver.java revision 145e6c4975536d927e506634514a06c43313df17
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; 208313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackbornimport android.app.ActivityManagerNative; 21a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.app.ActivityThread; 2201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.app.AppGlobals; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.CursorWrapper; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 32231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 35231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 36d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrickimport android.os.SystemClock; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 38231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Config; 39a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.util.EventLog; 40231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 49a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport java.util.Random; 5003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanaimport java.util.ArrayList; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides applications access to the content model. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentResolver { 57ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 58ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 59ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 60ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 614a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 62ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_ACCOUNT = "account"; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 64ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 65ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 66ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 67ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 684a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 7053bd2522ca7767f46646606123b6e2689b811850Fred Quintana 7153bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 7253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the sync settings (like getSyncAutomatically()) 7353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. 7453bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 7553bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_SETTINGS = "ignore_settings"; 7653bd2522ca7767f46646606123b6e2689b811850Fred Quintana 7753bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 7853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then any backoffs for the initial attempt (e.g. due to retries) 7953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. If this request fails and gets rescheduled then the 8053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * retries will still honor the backoff. 8153bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 8253bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_BACKOFF = "ignore_backoff"; 8353bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8453bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the request will not be retried if it fails. 8653bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 8753bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_DO_NOT_RETRY = "do_not_retry"; 8853bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8953bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 9053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Setting this extra is the equivalent of setting both {@link #SYNC_EXTRAS_IGNORE_SETTINGS} 9153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * and {@link #SYNC_EXTRAS_IGNORE_BACKOFF} 9253bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 93ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 9453bd2522ca7767f46646606123b6e2689b811850Fred Quintana 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 994a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana /** 1004a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Set by the SyncManager to request that the SyncAdapter initialize itself for 1014a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * the given account/authority pair. One required initialization step is to 1024a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been 1034a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * called with a >= 0 value. When this flag is set the SyncAdapter does not need to 1044a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * do a full sync, though it is allowed to do so. 1054a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana */ 1064a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; 1074a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 1210ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 1250ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 1350ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 143ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 144ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 145ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 146ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 147ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 148ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 149ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 150ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 151ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 152ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 153ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 154ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 155ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 156ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 157ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 158ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 159ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 160ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 161ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 162ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 163ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 167ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 168ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 16925880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 170a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 17125880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 172a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 173a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 174231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 1808313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn /** Providing a default implementation of this, to avoid having to change 1818313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * a lot of other things, but implementations of ContentResolver should 1828313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * implement it. @hide */ 1838313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn protected IContentProvider acquireExistingProvider(Context c, String name) { 1848313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return acquireProvider(c, name); 1858313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1968313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn public final String getType(Uri url) { 1978313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn IContentProvider provider = acquireExistingProvider(url); 1988313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn if (provider != null) { 1998313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn try { 2008313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return provider.getType(url); 2018313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } catch (RemoteException e) { 2028313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return null; 2038313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } catch (java.lang.Exception e) { 204145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 2058313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return null; 2068313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } finally { 2078313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn releaseProvider(provider); 2088313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } 2098313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } 2108313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn 2118313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn if (!SCHEME_CONTENT.equals(url.getScheme())) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2148313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2168313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn String type = ActivityManagerNative.getDefault().getProviderMimeType(url); 2178313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return type; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 220145e6c4975536d927e506634514a06c43313df17Ola Olsson } catch (java.lang.Exception e) { 221145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 222145e6c4975536d927e506634514a06c43313df17Ola Olsson return null; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2270ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 2290ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 2300ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 2310ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 2320ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 2330ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 2340ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 2350ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 2360ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 2370ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 2380ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 2390ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 2400ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 2450ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 265d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder); 267a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 271020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori // force query execution 272020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 273d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 274a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 275a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Wrap the cursor object into CursorWrapperInner object 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new CursorWrapperInner(qCursor, provider); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch(RuntimeException e) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2868943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2960ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 2990ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3540ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3890ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4050ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4100ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4170ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile()} method of the provider associated with the 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given URI, to retrieve any file stored there. 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No content provider: " + uri); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = provider.openAssetFile(uri, mode); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(fd == null) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getParcelFileDescriptor(), provider); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, fd.getStartOffset(), 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getDeclaredLength()); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Dead content provider: " + uri); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (FileNotFoundException e) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5104c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 5114c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 5124c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 5134c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 5144c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 5154c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 5164c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 5174c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5194c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 5204c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 5214c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 5224c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 5234c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 5244c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 5254c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5620ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5890ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 607d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 608a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri createdRow = provider.insert(url, values); 609d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 610a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 611a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6198943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 6208943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 6218943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 6228943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 6238943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 6248943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 6258943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 6268943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 6278943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 6288943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 6298943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 6308943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 6318943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 6328943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 6338943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 6348943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 6358943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 63603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 6378943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 6388943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 6396a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 6408943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 6416a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6426a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 6438943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 6446a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 6456a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 6466a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6476a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6486a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 666d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 667a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsCreated = provider.bulkInsert(url, values); 668d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 669a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 670a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 695d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 696a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsDeleted = provider.delete(url, where, selectionArgs); 697d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 698a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 699a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 715d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 717b0c6dbd53b26b172fe8eb7d117550e4edf7a0c9cJeff Hamilton * @return The number of rows updated. 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 727d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 728a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsUpdated = provider.update(uri, values, where, selectionArgs); 729d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 730a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 731a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7408313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * Returns the content provider for the given content URI. 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7468313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn public final IContentProvider acquireProvider(Uri uri) { 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String auth = uri.getAuthority(); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, uri.getAuthority()); 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7588313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * Returns the content provider for the given content URI if the process 7598313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * already has a reference on it. 7608313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * 7618313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * @param uri The URI to a content provider 7628313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 7638313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn * @hide 7648313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn */ 7658313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn public final IContentProvider acquireExistingProvider(Uri uri) { 7668313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 7678313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return null; 7688313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } 7698313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn String auth = uri.getAuthority(); 7708313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn if (auth != null) { 7718313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return acquireExistingProvider(mContext, uri.getAuthority()); 7728313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } 7738313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn return null; 7748313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn } 7758313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn 7768313fc7e94e46e5cc09f457a15a771a325b9f74fDianne Hackborn /** 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 7801877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 787718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 788718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 789718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 790718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 791718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 792718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 793718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 794718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 795718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 796718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 797718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 798718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 799718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 800718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 801718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 802718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 803718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 804718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 805718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 806718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 807718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 808718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 809718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 810718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 811718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 812718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 813718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 814718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 815718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 816718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 817718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 818718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 819718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 820718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 821718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 822718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 823718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 824718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 825718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 826718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 843231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer.getContentObserver()); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 859231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 889231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer != null && observer.deliverSelfNotifications(), syncToNetwork); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 911ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 912ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9144a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 916ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 917ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 918ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 919ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 9203348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 921ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 922ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 923ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 924ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 925ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 926ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 927ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 928ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 929ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 930ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 931ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 932ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 933ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 934ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 935ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 936ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 937ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 938ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 939ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 940ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 941ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 942ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 943ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 944ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 947ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().requestSync(account, authority, extras); 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 961d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 977d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 988ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 989ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 990ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 991ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 992ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 993ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 994ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 9954a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 997ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 998ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 999ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1000ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1001ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 1002ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 1003ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 1004ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1005ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 1006ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 1007ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1008ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 1009ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1010ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 1011ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1012ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1013ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1014ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1015ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1016ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 1017ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 1018ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1019ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 1020ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1021ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 1022ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1023ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1024ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1025ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1026ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1027ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1028ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 1029ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1030ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1031ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 1032ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 1033ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1034ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 1035ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1036ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 1037ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1038ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1039ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1040ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1041ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1042ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1043ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 1044ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1045ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1046ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1047ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1048ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1049ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1051ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1053ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 10545e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 10555e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10565e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10575e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 10585e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 1059c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 1060c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 1061c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 1062c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 1063c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 1064c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 1065c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 1066c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 1067c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 106853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 106953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 107053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 107153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 107253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 107353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 1074c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1075c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 1076c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 1077c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 1078c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 107953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 108053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 1081c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1082c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 1083c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 1084c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 108553bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 108653bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 108753bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 108853bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 108953bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 109053bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 109153bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 109253bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 109353bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 109453bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 109553bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 109653bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 109753bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 109853bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 109953bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1100c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1101c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 1102c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1103c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1104c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 1105c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1106c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1107c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1108c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1109c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 1110c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 1111c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1112c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 1113c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 1114c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 1115c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1116c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 1117c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 111853bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 111953bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 112053bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 112153bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 112253bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 112353bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1124c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1125c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 1126c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1127c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1128c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1129c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1130c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1131c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1132c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 1133c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1134c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 1135c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 1136c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 1137c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1138c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 113953bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 114053bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 114153bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 114253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 114353bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 114453bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1145c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1146c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getContentService().getPeriodicSyncs(account, authority); 1147c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1148c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1149c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1150c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1151c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1152c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 11535e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 11545e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 11555e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 115620ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 11575e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 11585e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 11595e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 11605e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 11615e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 11625e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 11635e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 11645e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 11655e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 1166718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 11675e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 116820ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 11695e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 11705e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 11715e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 11725e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1173ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1177ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1178ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 1179ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 1180ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1181ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 1182ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1183ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 1184ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1185ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 1186ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1187ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1188ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1189ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1190ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1191ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1192ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 1193ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 1194ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1195ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 1196ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1197ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 1198ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1199ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 1200ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1201ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1202ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1203ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1204ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1205ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1206ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1207ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 1208ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 1209ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1210ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1211ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 1212ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1213ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 1214ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1215ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 1216ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1217ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1218ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1219ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1220ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1221ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1222ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If a sync is active returns the information about it, otherwise returns false. 1223d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 1224ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1225d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 1226ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1227d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana return getContentService().getCurrentSync(); 1228ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1229ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1230ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1231ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1232ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1233ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 12344a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 1235ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1236ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1237ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 1238ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1239ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1240ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 1241ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1242ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 1243ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1244ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1245ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1246ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1247ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1248ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1249ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 1250ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1251ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1252ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 1253ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1254ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 1255ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1256ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 1257ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1258ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1259ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1260ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1261ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 12621b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 12631b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 12641b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 12651b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 12661b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 12671b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 12681b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 12691b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 12701b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 12711b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 12721b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 12731b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 12741b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 12751b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1276ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 12771b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 12781b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 12791b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1280ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1281ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 1282ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 1283ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 1284ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1285ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 1286ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 1287ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 1288ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1289ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1290ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1291ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1292ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 12931b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 12941b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 12951b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 12961b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1297ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 12981b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 12991b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 13001b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1301ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1302ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 1303ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1304ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1305ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1306ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1307ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1308ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1309a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 1310a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 1311a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 1312a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 1313a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 1314a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 1315a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 1316a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 1317a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1318a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 1319a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1320a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1321a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 1322a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 1323a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 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 1333a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 1334a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 1335a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 1336a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 1337a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 1338a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 1339a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 1340a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 1341a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 1342a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1343a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1344a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1345a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 1346a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 1347a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 134801e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1349a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1350a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1351a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 1352a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1353a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 1354a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1355a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 1356a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1357a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1358a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1359a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1360a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1361a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 1362a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 1363a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1364a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1365a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1366a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1367a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1368a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1369a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1370a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 137101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1372a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1373a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 1374a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1375a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 1376a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1377a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1378a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1379a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1380a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1381ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class CursorWrapperInner extends CursorWrapper { 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mCloseFlag = false; 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCloseFlag = true; 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mCloseFlag) { 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="ParcelFileDescriptorInner"; 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1438231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1439231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 14400ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1441231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1442231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 1443231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 1444231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1445231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1446231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 1447231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service binder = " + b); 1448231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 1449231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service = " + sContentService); 1450231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1451231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 14520ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1453231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1457