ContentResolver.java revision 7a96c39c510923ef73bbb06ab20109f0168b8eb1
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 19baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brownimport dalvik.system.CloseGuard; 20baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 21a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.accounts.Account; 22cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackbornimport android.app.ActivityManagerNative; 2301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.app.AppGlobals; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 28825c5132bff21e72c1448241f4c6868563c8d624Jeff Brownimport android.database.CrossProcessCursorWrapper; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 33a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal; 346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackbornimport android.os.DeadObjectException; 35231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 36a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal; 37a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.OperationCanceledException; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 40231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 41d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrickimport android.os.SystemClock; 425e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackbornimport android.os.UserHandle; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 44a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.util.EventLog; 45231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 5303f0292744094ec107ffce71301c394503a31dedGilles Debunneimport java.util.ArrayList; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 55a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport java.util.Random; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides applications access to the content model. 60558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * 61558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <div class="special reference"> 62558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <h3>Developer Guides</h3> 63558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <p>For more information about using a ContentResolver with content providers, read the 64558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> 65558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * developer guide.</p> 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentResolver { 68ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 69ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 70ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 71ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 724a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 73ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_ACCOUNT = "account"; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 75ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 76ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 77ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 78ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 794a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 8153bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8253bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the sync settings (like getSyncAutomatically()) 8453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. 8553bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 8653bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_SETTINGS = "ignore_settings"; 8753bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8853bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then any backoffs for the initial attempt (e.g. due to retries) 9053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. If this request fails and gets rescheduled then the 9153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * retries will still honor the backoff. 9253bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9353bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_BACKOFF = "ignore_backoff"; 9453bd2522ca7767f46646606123b6e2689b811850Fred Quintana 9553bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 9653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the request will not be retried if it fails. 9753bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9853bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_DO_NOT_RETRY = "do_not_retry"; 9953bd2522ca7767f46646606123b6e2689b811850Fred Quintana 10053bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 10153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Setting this extra is the equivalent of setting both {@link #SYNC_EXTRAS_IGNORE_SETTINGS} 10253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * and {@link #SYNC_EXTRAS_IGNORE_BACKOFF} 10353bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 104ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 10553bd2522ca7767f46646606123b6e2689b811850Fred Quintana 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1104a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana /** 1114a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Set by the SyncManager to request that the SyncAdapter initialize itself for 1124a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * the given account/authority pair. One required initialization step is to 1134a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been 1144a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * called with a >= 0 value. When this flag is set the SyncAdapter does not need to 1154a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * do a full sync, though it is allowed to do so. 1164a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana */ 1174a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; 1184a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana 1197a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey /** @hide */ 1207a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static final Intent ACTION_SYNC_CONN_STATUS_CHANGED = 1217a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); 1227a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 1360ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 1400ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 1500ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 158ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 159ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 160ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 161ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 162ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 163ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 167ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 168ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 169ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 170ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 171ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 172ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 173ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 174ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 175ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private static final String[] SYNC_ERROR_NAMES = new String[] { 17757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "already-in-progress", 17857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "authentication-error", 17957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "io-error", 18057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "parse-error", 18157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "conflict", 18257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-deletions", 18357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-retries", 18457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "internal-error", 18557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert }; 18657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 18757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert /** @hide */ 1887a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static String syncErrorToString(int error) { 18957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (error < 1 || error > SYNC_ERROR_NAMES.length) { 19057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return String.valueOf(error); 19157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 19257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return SYNC_ERROR_NAMES[error - 1]; 19357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 19457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 195ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 196ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 197ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 198ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 199ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 200ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 201ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 202ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 20325880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 204a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 20525880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 206a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 207a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 208231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 214cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** Providing a default implementation of this, to avoid having to change 215cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * a lot of other things, but implementations of ContentResolver should 216cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * implement it. @hide */ 217cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn protected IContentProvider acquireExistingProvider(Context c, String name) { 218cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireProvider(c, name); 219cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 222652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 223652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn protected abstract IContentProvider acquireUnstableProvider(Context c, String name); 224652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 225652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public abstract boolean releaseUnstableProvider(IContentProvider icp); 2266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn /** @hide */ 2276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn public abstract void unstableProviderDied(IContentProvider icp); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final String getType(Uri url) { 2376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // XXX would like to have an acquireExistingUnstableProvider for this. 238cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn IContentProvider provider = acquireExistingProvider(url); 239cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (provider != null) { 240cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn try { 241cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return provider.getType(url); 242cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (RemoteException e) { 243cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 244cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (java.lang.Exception e) { 245145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 246cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 247cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } finally { 248cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn releaseProvider(provider); 249cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 250cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 251cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 252cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(url.getScheme())) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 255cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2575e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn String type = ActivityManagerNative.getDefault().getProviderMimeType( 2585e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn url, UserHandle.myUserId()); 259cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return type; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 261534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 262534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 264145e6c4975536d927e506634514a06c43313df17Ola Olsson } catch (java.lang.Exception e) { 265145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 266145e6c4975536d927e506634514a06c43313df17Ola Olsson return null; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 27123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Query for the possible MIME types for the representations the given 27223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URL can be returned when opened as as stream with 27323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link #openTypedAssetFileDescriptor}. Note that the types here are 27423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * not necessarily a superset of the type returned by {@link #getType} -- 27523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * many content providers can not return a raw stream for the structured 27623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data that they contain. 27723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 27823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param url A Uri identifying content (either a list or specific type), 27923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * using the content:// scheme. 28023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeTypeFilter The desired MIME type. This may be a pattern, 28123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * such as *\/*, to query for all available MIME types that match the 28223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * pattern. 283acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns an array of MIME type strings for all available 28423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data streams that match the given mimeTypeFilter. If there are none, 28523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * null is returned. 28623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 28723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public String[] getStreamTypes(Uri url, String mimeTypeFilter) { 28823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn IContentProvider provider = acquireProvider(url); 28923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (provider == null) { 29023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 29123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 29264bbbb471ed78ae06f411224849a4556a30fd362Dianne Hackborn 29323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 29423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return provider.getStreamTypes(url, mimeTypeFilter); 29523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (RemoteException e) { 296534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 297534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 29823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 29923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 300534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 301534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 30223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 30323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 30423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 3050ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 3070ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3080ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3090ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 3100ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 3110ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 3120ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 3130ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 3140ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 3150ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 3160ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 3170ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 3180ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 3230ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 33875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return query(uri, projection, selection, selectionArgs, sortOrder, null); 33975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 34075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 34175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 34275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 34375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Query the given URI, returning a {@link Cursor} over the result set. 34475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 34575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 34675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * For best performance, the caller should follow these guidelines: 34775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <ul> 34875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Provide an explicit projection, to prevent 34975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * reading data from storage that aren't going to be used.</li> 35075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Use question mark parameter markers such as 'phone=?' instead of 35175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * explicit values in the {@code selection} parameter, so that queries 35275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * that differ only by those values will be recognized as the same 35375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * for caching purposes.</li> 35475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </ul> 35575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 35675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 35775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param uri The URI, using the content:// scheme, for the content to 35875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * retrieve. 35975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param projection A list of which columns to return. Passing null will 36075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is inefficient. 36175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 36275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null will 36375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all rows for the given URI. 36475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 36575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in the order that they 36675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 36775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 36875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the ORDER BY itself). Passing null will use the 36975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 3704c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 37175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 37275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 37375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A Cursor object, which is positioned before the first entry, or null 37475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 37575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 37675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public final Cursor query(final Uri uri, String[] projection, 37775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown String selection, String[] selectionArgs, String sortOrder, 3784c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown CancellationSignal cancellationSignal) { 3796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 3806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 385d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 38675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 3874c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown ICancellationSignal remoteCancellationSignal = null; 3884c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown if (cancellationSignal != null) { 3894c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.throwIfCanceled(); 3906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn remoteCancellationSignal = unstableProvider.createCancellationSignal(); 3914c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.setRemote(remoteCancellationSignal); 39275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 3936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn Cursor qCursor; 3946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 3956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn qCursor = unstableProvider.query(uri, projection, 3966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 3976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 3986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 3996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 4006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 4016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 4026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 4036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 4046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 4056ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn qCursor = stableProvider.query(uri, projection, 4076ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 4086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 409a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 412020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori // force query execution 413020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 414d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 415a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 416a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Wrap the cursor object into CursorWrapperInner object 4176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, 4186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider != null ? stableProvider : acquireProvider(uri)); 4196ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 4206ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return wrapper; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 422534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 423534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4256ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 4266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 4276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 4286ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4296ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 4306ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 4316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4358943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4450ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 4480ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 5030ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 52123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 5380ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5540ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5590ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5660ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 57123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 57303f0292744094ec107ffce71301c394503a31dedGilles Debunne * method of the provider associated with the given URI, to retrieve any file stored there. 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 60523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note that if this function is called for read-only input (mode is "r") 60623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 60723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * for you with a MIME type of "*\/*". This allows such callers to benefit 60823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * from any built-in data conversion that a provider implements. 60923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 63623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if ("r".equals(mode)) { 63723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return openTypedAssetFileDescriptor(uri, "*/*", null); 63823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } else { 6396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 6406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 6416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 6426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 6446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 6456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 647652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 6486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = unstableProvider.openAssetFile(uri, mode); 649652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 650652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 651652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 652652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 6536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 6546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 6556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 6566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 6576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 6586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 661652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 6626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = stableProvider.openAssetFile(uri, mode); 6636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 6646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 6656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 666652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 66723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 6686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 6736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 6746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 6756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 6776ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 6786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 6796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 6816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 6826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 6846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 6856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 6866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 6876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 6886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 6896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 6906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 6916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 6926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 6946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 6956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 69623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 69723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 69823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 69923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 70023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 70123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 70223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access (potentially type transformed) 70323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data from a "content:" URI. This interacts with the underlying 70423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile} method of the provider 70523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * associated with the given URI, to retrieve retrieve any appropriate 70623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream for the data stored there. 70723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 70823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 70923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with "content:" URIs, because content providers are the only facility 71023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with an associated MIME type to ensure that the returned data stream 71123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is of the desired type. 71223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 71323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>All text/* streams are encoded in UTF-8. 71423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 71523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param uri The desired URI to open. 71623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeType The desired MIME type of the returned data. This can 71723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * be a pattern such as *\/*, which will allow the content provider to 71823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * select a type, though there is no way for you to determine what type 71923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it is returning. 72023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param opts Additional provider-dependent options. 72123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns a new ParcelFileDescriptor from which you can read the 72223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream from the provider. Note that this may be a pipe, meaning 72323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * you can't seek in it. The only seek you should do is if the 72423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * AssetFileDescriptor contains an offset, to move to that offset before 72523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * reading. You own this descriptor and are responsible for closing it when done. 72623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @throws FileNotFoundException Throws FileNotFoundException of no 72723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data of the desired type exists under the URI. 72823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 72923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri, 73023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn String mimeType, Bundle opts) throws FileNotFoundException { 7316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 7326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 7336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 7346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 7366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 7376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 739652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 7406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = unstableProvider.openTypedAssetFile(uri, mimeType, opts); 741652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 742652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 743652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 744652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 7466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 7476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 7486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 7496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 7506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 753652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = stableProvider.openTypedAssetFile(uri, mimeType, opts); 7556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 7566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 7576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 758652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 7666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 7676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 7696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 7706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 7716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 7736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 7746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 7766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 7776ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 7786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 7796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 7806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 7816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 7826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 7836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 7846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 7866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7914c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 7924c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 7934c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 7944c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 7954c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 7964c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 7974c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 7984c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8004c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 8014c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 8024c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 8034c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 8044c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 8054c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 8064c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8430ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8700ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 888d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 889a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri createdRow = provider.insert(url, values); 890d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 891a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 892a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 894534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 895534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9028943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 9038943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 9048943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 9058943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 9068943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 9078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 9088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 9098943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 9108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 9118943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 9128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 9138943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 9148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 9158943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 9168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 9178943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 9188943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 91903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 9208943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 9218943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 9226a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 9238943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 9246a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9256a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 9268943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 9276a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 9286a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 9296a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9306a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9316a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 949d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 950a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsCreated = provider.bulkInsert(url, values); 951d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 952a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 953a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 955534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 956534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 980d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 981a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsDeleted = provider.delete(url, where, selectionArgs); 982d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 983a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 984a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 986534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 987534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 1002d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 1004534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return the number of rows updated. 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1014d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 1015a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsUpdated = provider.update(uri, values, where, selectionArgs); 1016d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1017a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 1018a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1020534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1021534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1029f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * Call a provider-defined method. This can be used to implement 1030534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * read or write interfaces which are cheaper than using a Cursor and/or 1031534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * do not fit into the traditional table model. 1032534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * 1033534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param method provider-defined method name to call. Opaque to 1034534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * framework, but must be non-null. 1035534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param arg provider-defined String argument. May be null. 1036534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param extras provider-defined Bundle argument. May be null. 1037534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return a result Bundle, possibly null. Will be null if the ContentProvider 1038534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * does not implement call. 1039534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws NullPointerException if uri or method is null 1040534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws IllegalArgumentException if uri is not known 1041534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick */ 1042534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick public final Bundle call(Uri uri, String method, String arg, Bundle extras) { 1043534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (uri == null) { 1044534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("uri == null"); 1045534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1046534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (method == null) { 1047534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("method == null"); 1048534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1049534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick IContentProvider provider = acquireProvider(uri); 1050534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (provider == null) { 1051534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new IllegalArgumentException("Unknown URI " + uri); 1052534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1053534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick try { 1054534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return provider.call(method, arg, extras); 1055534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } catch (RemoteException e) { 1056534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1057534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 1058534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return null; 1059534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } finally { 1060534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 1061534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1062534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1063534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick 1064534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick /** 1065cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI. 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1071cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireProvider(Uri uri) { 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String auth = uri.getAuthority(); 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, uri.getAuthority()); 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1083cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI if the process 1084cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * already has a reference on it. 1085cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * 1086cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @param uri The URI to a content provider 1087cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1088cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @hide 1089cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn */ 1090cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireExistingProvider(Uri uri) { 1091cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1092cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1093cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1094cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn String auth = uri.getAuthority(); 1095cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (auth != null) { 1096cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireExistingProvider(mContext, uri.getAuthority()); 1097cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1098cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1099cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1100cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 1101cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 11051877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1112652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Returns the content provider for the given content URI. 1113652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * 1114652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @param uri The URI to a content provider 1115652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1116652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1117652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1118652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(Uri uri) { 1119652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1120652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1121652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1122652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn String auth = uri.getAuthority(); 1123652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (auth != null) { 1124652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return acquireUnstableProvider(mContext, uri.getAuthority()); 1125652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1126652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1127652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1128652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1129652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1130652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1131652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1132652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(String name) { 1133652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (name == null) { 1134652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1135652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 11366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return acquireUnstableProvider(mContext, name); 1137652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1138652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1139652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1140718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1141718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 1142718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1143718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1144718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1145718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1146718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 1147718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1148718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 1149718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1150718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 1151718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 1152718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1153652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1154718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1155718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1156718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1157718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1158718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1159718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 1160718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1161718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 1162718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1163718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1164718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1165718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1166718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 1167718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1168718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 1169718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1170718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 1171718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 1172718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1173652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1174652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1175652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1176652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1177652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1178652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1179652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1180652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(Uri)}, but for use when you do 1181652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1182652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1183652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1184652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1185652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1186652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1187652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 11886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 11896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 11906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 11916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 11926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 11936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1194652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1195652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) { 11966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(uri); 1197652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1198652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1199652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1200652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1201652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1202652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1203652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1204652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1205652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(String)}, but for use when you do 1206652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1207652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1208652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1209652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1210652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1211652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1212652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 12136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 12146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 12156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 12166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 12176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 12186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1219652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1220652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(String name) { 12216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(name); 1222652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1223652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1224718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1225718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1226718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1227718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1228718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1229718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1245afccaa84c8d1b9aa45040ddeb0edd42ba80e80d6Christopher Tate registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId()); 124616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 124716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 124816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** @hide - designated user version */ 124916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 125016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate ContentObserver observer, int userHandle) 125116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate { 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1253231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 125416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer.getContentObserver(), userHandle); 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 1269231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1277d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * Notify registered observers that a row was updated and attempt to sync changes 1278d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * to the network. 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 128286de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 128386de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 128486de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 128586de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 128686de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 1296d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * If syncToNetwork is true, this will attempt to schedule a local sync using the sync 1297d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * adapter that's registered for the authority of the provided uri. No account will be 1298d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * passed to the sync adapter, so all matching accounts will be synchronized. 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 130086de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 130186de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 130286de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 130386de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 130486de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 1306d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * @see #requestSync(android.accounts.Account, String, android.os.Bundle) 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 1309b7564454297ba1706670ccab0562cac6676d0a77Christopher Tate notifyChange(uri, observer, syncToNetwork, UserHandle.getCallingUserId()); 131016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 131116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 131216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** 131316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * Notify registered observers within the designated user(s) that a row was updated. 131416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * 131516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * @hide 131616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate */ 131716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 131816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate int userHandle) { 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1320231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 132216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer != null && observer.deliverSelfNotifications(), syncToNetwork, 132316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate userHandle); 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 1343ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 1344ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13464a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 1348ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 1349ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 1350ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 1351ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 13523348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 1353ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1354ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 1355ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1356ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 1357ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1358ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1359ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1360ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 1361ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 1362ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 1363ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 1364ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 1365ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 1366ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 1367ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 1368ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 1369ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 1370ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 1371ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1372ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 1373ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 1374ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 1375ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1376ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1379ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().requestSync(account, authority, extras); 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1393d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 1409d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1420ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1421ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 1422ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 1423ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1424ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 1425ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 1426ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 14274a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 1429ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 1430ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1431ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1432ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1433ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 1434ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 1435ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 1436ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1437ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 1438ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 1439ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1440ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 1441ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1442ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 1443ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1444ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1445ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1446ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1447ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1448ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 1449ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 1450ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1451ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 1452ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1453ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 1454ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1455ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1456ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1457ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1458ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1459ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1460ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 14619530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14629530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1463ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1464ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1465ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 1466ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 1467ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1468ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 1469ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1470ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 1471ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1472ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1473ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1474ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1475ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1476ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1477ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 14789530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14799530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1480ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1481ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1482ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1483ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1484ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1485ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1487ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1489ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 14905e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 14915e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 14925e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 14935e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 14945e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 1495c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 1496c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 1497c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 1498c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 1499c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 1500c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 1501c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 1502c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 1503c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 150453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 150553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 150653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 150753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 150853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 150953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 1510c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 15119530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15129530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 15139530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * 1514c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 1515c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 1516c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 1517c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 151853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 151953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 1520c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1521c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 1522c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 1523c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 152453bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 152553bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 152653bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 152753bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 152853bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 152953bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 153053bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 153153bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 153253bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 153353bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 153453bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 153553bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 153653bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 153753bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 153853bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1539c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1540c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 1541c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1542c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1543c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 1544c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1545c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1546c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1547c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1548c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 1549c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 15509530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15519530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1552c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1553c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 1554c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 1555c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 1556c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1557c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 1558c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 155953bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 156053bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 156153bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 156253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 156353bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 156453bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1565c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1566c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 1567c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1568c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1569c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1570c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1571c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1572c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1573c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 15749530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15759530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1576c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1577c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 1578c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 1579c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 1580c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1581c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 158253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 158353bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 158453bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 158553bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 158653bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 158753bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1588c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1589c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getContentService().getPeriodicSyncs(account, authority); 1590c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1591c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1592c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1593c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1594c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1595c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 15965e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 15979530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15989530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 15995e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 16005e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 160120ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 16025e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 16035e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 16045e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 16055e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 16065e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 16075e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 16085e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 16095e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 16105e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 16119530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16129530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1613718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 16145e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 161520ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 16165e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 16175e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 16185e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 16195e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1620ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1624ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1625ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 1626ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16279530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16289530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1629ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1630ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 1631ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1632ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 1633ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1634ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 1635ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1636ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1637ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1638ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1639ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1640ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1641ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 1642ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16439530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16449530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1645ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1646ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 1647ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1648ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 1649ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1650ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 1651ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1652ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1653ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1654ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1655ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1656ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1657ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1658ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 1659ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 16609530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16619530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1662ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1663ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1664ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 1665ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1666ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 1667ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1668ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 1669ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1670ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1671ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1672ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1673ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1674ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1675c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * If a sync is active returns the information about it, otherwise returns null. 1676c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * <p> 16779530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 16789530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 16799530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1680d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 1681c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @deprecated 1682c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Since multiple concurrent syncs are now supported you should use 1683c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * {@link #getCurrentSyncs()} to get the accurate list of current syncs. 1684c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * This method returns the first item from the list of current syncs 1685c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * or null if there are none. 1686ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1687c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana @Deprecated 1688d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 1689ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1690c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana final List<SyncInfo> syncs = getContentService().getCurrentSyncs(); 1691c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana if (syncs.isEmpty()) { 1692c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return null; 1693c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1694c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return syncs.get(0); 1695c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } catch (RemoteException e) { 1696c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1697c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1698c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1699c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana 1700c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana /** 1701c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Returns a list with information about all the active syncs. This list will be empty 1702c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * if there are no active syncs. 17039530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 17049530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 17059530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 17069530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1707c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @return a List of SyncInfo objects for the currently active syncs. 1708c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana */ 1709c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana public static List<SyncInfo> getCurrentSyncs() { 1710c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana try { 1711c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return getContentService().getCurrentSyncs(); 1712ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1713ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1714ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1715ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1716ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1717ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 17184a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 1719ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1720ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1721ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 1722ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1723ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1724ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 1725ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1726ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 1727ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1728ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1729ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1730ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1731ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1732ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1733ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 17349530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 17359530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1736ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1737ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1738ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 1739ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1740ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 1741ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1742ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 1743ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1744ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1745ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1746ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1747ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17481b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 17491b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 17501b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 17511b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 17521b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 17531b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 17541b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 17551b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 17561b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 17571b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 17581b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 17591b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 17601b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 17611b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1762ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 17631b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 17641b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 17651b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1766ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1767ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 1768ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 1769ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 1770ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1771ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 1772ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 1773ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 1774ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1775ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1776ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1777ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1778ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17791b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 17801b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 17811b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 17821b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1783ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 17841b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 17851b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 17861b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1787ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1788ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 1789ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1790ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1791ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1792ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1793ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1794ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1795a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 1796a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 1797a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 1798a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 1799a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 1800a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 1801a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 1802a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 1803a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1804a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 1805a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1806a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1807a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 1808a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 1809a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 1810a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1811a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1812a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1813a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1814a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1815a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1816a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1817a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1818a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1819a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 1820a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 1821a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 1822a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 1823a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 1824a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 1825a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 1826a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 1827a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 1828a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1829a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1830a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1831a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 1832a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 1833a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 183401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1835a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1836a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1837a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 1838a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1839a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 1840a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1841a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 1842a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1843a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1844a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1845a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1846a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1847a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 1848a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 1849a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1850a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1851a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1852a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1853a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1854a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1855a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1856a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 185701e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1858a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1859a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 1860a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1861a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 1862a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1863a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1864a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1865a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1866a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1867ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1868825c5132bff21e72c1448241f4c6868563c8d624Jeff Brown private final class CursorWrapperInner extends CrossProcessCursorWrapper { 186903f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 1871baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1872baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private final CloseGuard mCloseGuard = CloseGuard.get(); 1873baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private boolean mProviderReleased; 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 1878baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.open("close"); 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 1885baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mProviderReleased = true; 1886baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1887baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1888baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.close(); 1889baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1895baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1896baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.warnIfOpen(); 1897baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 1898baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1899baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (!mProviderReleased && mContentProvider != null) { 1900baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // Even though we are using CloseGuard, log this anyway so that 1901baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // application developers always see the message in the log. 1902872a52c6b637faf75262b83fe68ff4e0d9fe044cJohannes Carlsson Log.w(TAG, "Cursor finalized without prior close()"); 1903baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown ContentResolver.this.releaseProvider(mContentProvider); 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 191203f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 19246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ContentResolver.this.releaseProvider(mContentProvider); 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1937231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1938231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 19390ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1940231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1941231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 1942231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 1943231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1944231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1945231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 194643a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service binder = " + b); 1947231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 194843a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service = " + sContentService); 1949231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1950231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 19510ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1952231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1956