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; 2366a017b63461a22842b3678c9520f803d5ddadfcJeff Sharkeyimport android.app.ActivityThread; 2401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.app.AppGlobals; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 29825c5132bff21e72c1448241f4c6868563c8d624Jeff Brownimport android.database.CrossProcessCursorWrapper; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 34a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal; 356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackbornimport android.os.DeadObjectException; 36231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 37a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal; 38a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.OperationCanceledException; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 41231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 42d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrickimport android.os.SystemClock; 435e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackbornimport android.os.UserHandle; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 45a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.util.EventLog; 46231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 5403f0292744094ec107ffce71301c394503a31dedGilles Debunneimport java.util.ArrayList; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 56a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport java.util.Random; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides applications access to the content model. 61558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * 62558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <div class="special reference"> 63558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <h3>Developer Guides</h3> 64558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <p>For more information about using a ContentResolver with content providers, read the 65558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> 66558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * developer guide.</p> 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentResolver { 69ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 70ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 71ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 72ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 734a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 74ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_ACCOUNT = "account"; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 76ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 77ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 78ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 79ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 804a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 8253bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8353bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the sync settings (like getSyncAutomatically()) 8553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. 8653bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 8753bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_SETTINGS = "ignore_settings"; 8853bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8953bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 9053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then any backoffs for the initial attempt (e.g. due to retries) 9153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. If this request fails and gets rescheduled then the 9253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * retries will still honor the backoff. 9353bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9453bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_BACKOFF = "ignore_backoff"; 9553bd2522ca7767f46646606123b6e2689b811850Fred Quintana 9653bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 9753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the request will not be retried if it fails. 9853bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9953bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_DO_NOT_RETRY = "do_not_retry"; 10053bd2522ca7767f46646606123b6e2689b811850Fred Quintana 10153bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 10253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Setting this extra is the equivalent of setting both {@link #SYNC_EXTRAS_IGNORE_SETTINGS} 10353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * and {@link #SYNC_EXTRAS_IGNORE_BACKOFF} 10453bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 105ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 10653bd2522ca7767f46646606123b6e2689b811850Fred Quintana 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1114a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana /** 1124a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Set by the SyncManager to request that the SyncAdapter initialize itself for 1134a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * the given account/authority pair. One required initialization step is to 1144a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been 1154a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * called with a >= 0 value. When this flag is set the SyncAdapter does not need to 1164a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * do a full sync, though it is allowed to do so. 1174a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana */ 1184a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; 1194a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana 1207a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey /** @hide */ 1217a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static final Intent ACTION_SYNC_CONN_STATUS_CHANGED = 1227a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); 1237a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 1370ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 1410ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 1510ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 159ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 160ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 161ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 162ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 163ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 167ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 168ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 169ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 170ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 171ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 172ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 173ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 174ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 175ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 176ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private static final String[] SYNC_ERROR_NAMES = new String[] { 17857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "already-in-progress", 17957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "authentication-error", 18057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "io-error", 18157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "parse-error", 18257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "conflict", 18357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-deletions", 18457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-retries", 18557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "internal-error", 18657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert }; 18757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 18857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert /** @hide */ 1897a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static String syncErrorToString(int error) { 19057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (error < 1 || error > SYNC_ERROR_NAMES.length) { 19157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return String.valueOf(error); 19257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 19357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return SYNC_ERROR_NAMES[error - 1]; 19457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 19557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 1965c113faba6b644d1851c9281614aa0edd175fc48Alon Albert /** @hide */ 1975c113faba6b644d1851c9281614aa0edd175fc48Alon Albert public static int syncErrorStringToInt(String error) { 1985c113faba6b644d1851c9281614aa0edd175fc48Alon Albert for (int i = 0, n = SYNC_ERROR_NAMES.length; i < n; i++) { 1995c113faba6b644d1851c9281614aa0edd175fc48Alon Albert if (SYNC_ERROR_NAMES[i].equals(error)) { 2005c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return i + 1; 2015c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2025c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2035c113faba6b644d1851c9281614aa0edd175fc48Alon Albert if (error != null) { 2045c113faba6b644d1851c9281614aa0edd175fc48Alon Albert try { 2055c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return Integer.parseInt(error); 2065c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } catch (NumberFormatException e) { 2075c113faba6b644d1851c9281614aa0edd175fc48Alon Albert Log.d(TAG, "error parsing sync error: " + error); 2085c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2095c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2105c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return 0; 2115c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2125c113faba6b644d1851c9281614aa0edd175fc48Alon Albert 213ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 214ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 215ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 216ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 217ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 218ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 219ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 220ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 22125880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 222a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 22325880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 224a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 225a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 226231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 22766a017b63461a22842b3678c9520f803d5ddadfcJeff Sharkey mContext = context != null ? context : ActivityThread.currentApplication(); 228e564a325bec501fd66a163d32312e93981f3fe91Jeff Sharkey mPackageName = mContext.getBasePackageName(); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 233cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** Providing a default implementation of this, to avoid having to change 234cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * a lot of other things, but implementations of ContentResolver should 235cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * implement it. @hide */ 236cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn protected IContentProvider acquireExistingProvider(Context c, String name) { 237cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireProvider(c, name); 238cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 241652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 242652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn protected abstract IContentProvider acquireUnstableProvider(Context c, String name); 243652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 244652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public abstract boolean releaseUnstableProvider(IContentProvider icp); 2456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn /** @hide */ 2466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn public abstract void unstableProviderDied(IContentProvider icp); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final String getType(Uri url) { 2566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // XXX would like to have an acquireExistingUnstableProvider for this. 257cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn IContentProvider provider = acquireExistingProvider(url); 258cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (provider != null) { 259cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn try { 260cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return provider.getType(url); 261cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (RemoteException e) { 262cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 263cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (java.lang.Exception e) { 264145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 265cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 266cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } finally { 267cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn releaseProvider(provider); 268cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 269cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 270cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 271cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(url.getScheme())) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 274cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2765e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn String type = ActivityManagerNative.getDefault().getProviderMimeType( 2775e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn url, UserHandle.myUserId()); 278cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return type; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 280534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 281534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 283145e6c4975536d927e506634514a06c43313df17Ola Olsson } catch (java.lang.Exception e) { 284145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 285145e6c4975536d927e506634514a06c43313df17Ola Olsson return null; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 29023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Query for the possible MIME types for the representations the given 29123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URL can be returned when opened as as stream with 29223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link #openTypedAssetFileDescriptor}. Note that the types here are 29323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * not necessarily a superset of the type returned by {@link #getType} -- 29423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * many content providers can not return a raw stream for the structured 29523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data that they contain. 29623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 29723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param url A Uri identifying content (either a list or specific type), 29823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * using the content:// scheme. 29923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeTypeFilter The desired MIME type. This may be a pattern, 30023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * such as *\/*, to query for all available MIME types that match the 30123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * pattern. 302acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns an array of MIME type strings for all available 30323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data streams that match the given mimeTypeFilter. If there are none, 30423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * null is returned. 30523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 30623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public String[] getStreamTypes(Uri url, String mimeTypeFilter) { 30723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn IContentProvider provider = acquireProvider(url); 30823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (provider == null) { 30923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 31023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 31164bbbb471ed78ae06f411224849a4556a30fd362Dianne Hackborn 31223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 31323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return provider.getStreamTypes(url, mimeTypeFilter); 31423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (RemoteException e) { 315534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 316534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 31723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 31823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 319534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 320534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 32123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 32223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 32323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 3240ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 3260ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3270ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3280ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 3290ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 3300ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 3310ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 3320ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 3330ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 3340ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 3350ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 3360ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 3370ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 3420ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 35775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return query(uri, projection, selection, selectionArgs, sortOrder, null); 35875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 35975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 36075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 36175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 36275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Query the given URI, returning a {@link Cursor} over the result set. 36375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 36475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 36575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * For best performance, the caller should follow these guidelines: 36675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <ul> 36775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Provide an explicit projection, to prevent 36875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * reading data from storage that aren't going to be used.</li> 36975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Use question mark parameter markers such as 'phone=?' instead of 37075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * explicit values in the {@code selection} parameter, so that queries 37175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * that differ only by those values will be recognized as the same 37275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * for caching purposes.</li> 37375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </ul> 37475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 37575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 37675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param uri The URI, using the content:// scheme, for the content to 37775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * retrieve. 37875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param projection A list of which columns to return. Passing null will 37975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is inefficient. 38075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 38175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null will 38275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all rows for the given URI. 38375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 38475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in the order that they 38575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 38675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 38775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the ORDER BY itself). Passing null will use the 38875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 3894c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 39075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 39175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 39275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A Cursor object, which is positioned before the first entry, or null 39375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 39475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 39575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public final Cursor query(final Uri uri, String[] projection, 39675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown String selection, String[] selectionArgs, String sortOrder, 3974c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown CancellationSignal cancellationSignal) { 3986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 3996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 403c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown Cursor qCursor = null; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 405d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 40675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 4074c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown ICancellationSignal remoteCancellationSignal = null; 4084c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown if (cancellationSignal != null) { 4094c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.throwIfCanceled(); 4106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn remoteCancellationSignal = unstableProvider.createCancellationSignal(); 4114c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.setRemote(remoteCancellationSignal); 41275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 4136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 41435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn qCursor = unstableProvider.query(mPackageName, uri, projection, 4156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 4166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 4176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 4186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 4196ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 4206ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 4216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 4226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 4236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 4246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 42535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn qCursor = stableProvider.query(mPackageName, uri, projection, 4266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 4276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 428a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 431c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown 432c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // Force query execution. Might fail and throw a runtime exception here. 433020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 434d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 435a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 436c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown 437c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // Wrap the cursor object into CursorWrapperInner object. 4386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, 4396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider != null ? stableProvider : acquireProvider(uri)); 4406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 441c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown qCursor = null; 4426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return wrapper; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 444534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 445534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 448c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown if (qCursor != null) { 449c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown qCursor.close(); 450c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown } 4516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 4526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 4536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 4556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 4566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4608943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4700ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 4730ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 5280ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 54623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 5630ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 569f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich * @throws FileNotFoundException Throws FileNotFoundException if no 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5790ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5840ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5910ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 59623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 59803f0292744094ec107ffce71301c394503a31dedGilles Debunne * method of the provider associated with the given URI, to retrieve any file stored there. 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 63023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note that if this function is called for read-only input (mode is "r") 63123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 63223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * for you with a MIME type of "*\/*". This allows such callers to benefit 63323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * from any built-in data conversion that a provider implements. 63423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 66123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if ("r".equals(mode)) { 66223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return openTypedAssetFileDescriptor(uri, "*/*", null); 66323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } else { 6646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 6656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 6666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 6676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 6696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 6706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 672652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 67335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn fd = unstableProvider.openAssetFile(mPackageName, uri, mode); 674652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 675652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 676652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 677652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 6786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 6796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 6806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 6816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 6826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 6836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 686652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 68735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn fd = stableProvider.openAssetFile(mPackageName, uri, mode); 6886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 6896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 6906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 691652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 69223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 6936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 6986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 6996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 7006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 7026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 7036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 7046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7056ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 7066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 7076ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 7096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 7106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 7116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 7126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 7136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 7146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 7156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 7166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 7176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 7196ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7206ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 72123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 72223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 72323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 72423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 72523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 72623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 72723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access (potentially type transformed) 72823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data from a "content:" URI. This interacts with the underlying 72923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile} method of the provider 73023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * associated with the given URI, to retrieve retrieve any appropriate 73123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream for the data stored there. 73223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 73323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 73423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with "content:" URIs, because content providers are the only facility 73523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with an associated MIME type to ensure that the returned data stream 73623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is of the desired type. 73723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 73823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>All text/* streams are encoded in UTF-8. 73923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 74023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param uri The desired URI to open. 74123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeType The desired MIME type of the returned data. This can 74223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * be a pattern such as *\/*, which will allow the content provider to 74323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * select a type, though there is no way for you to determine what type 74423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it is returning. 74523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param opts Additional provider-dependent options. 74623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns a new ParcelFileDescriptor from which you can read the 74723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream from the provider. Note that this may be a pipe, meaning 74823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * you can't seek in it. The only seek you should do is if the 74923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * AssetFileDescriptor contains an offset, to move to that offset before 75023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * reading. You own this descriptor and are responsible for closing it when done. 75123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @throws FileNotFoundException Throws FileNotFoundException of no 75223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data of the desired type exists under the URI. 75323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 75423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri, 75523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn String mimeType, Bundle opts) throws FileNotFoundException { 7566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 7576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 7586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 7596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 7616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 7626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 764652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 76535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn fd = unstableProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts); 766652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 767652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 768652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 769652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 7716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 7726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 7736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 7746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 7756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7776ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 778652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 77935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn fd = stableProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts); 7806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 7816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 7826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 783652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 7916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 7926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 7946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 7956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 7966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 7986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 7996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 8006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 8016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 8026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 8036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 8046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 8056ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 8066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 8076ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 8086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 8096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 8106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 8116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 8126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8164c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 8174c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 8184c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 8194c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 8204c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 8214c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 8224c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 8234c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8254c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 8264c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 8274c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 8284c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 8294c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 8304c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 8314c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8680ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8950ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 913d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 91435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Uri createdRow = provider.insert(mPackageName, url, values); 915d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 916a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 917a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 919534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 920534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9278943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 9288943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 9298943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 9308943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 9318943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 9328943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 9338943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 9348943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 9358943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 9368943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 9378943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 9388943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 9398943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 9408943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 9418943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 9428943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 9438943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 94403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 9458943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 9468943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 9476a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 9488943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 9496a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9506a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 9518943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 9526a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 9536a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 9546a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9556a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9566a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 974d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 97535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsCreated = provider.bulkInsert(mPackageName, url, values); 976d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 977a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 978a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 980534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 981534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1005d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 100635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsDeleted = provider.delete(mPackageName, url, where, selectionArgs); 1007d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1008a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 1009a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1011534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1012534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 1027d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 1029534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return the number of rows updated. 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1039d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 104035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsUpdated = provider.update(mPackageName, uri, values, where, selectionArgs); 1041d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1042a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 1043a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1045534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1046534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1054f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * Call a provider-defined method. This can be used to implement 1055534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * read or write interfaces which are cheaper than using a Cursor and/or 1056534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * do not fit into the traditional table model. 1057534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * 1058534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param method provider-defined method name to call. Opaque to 1059534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * framework, but must be non-null. 1060534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param arg provider-defined String argument. May be null. 1061534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param extras provider-defined Bundle argument. May be null. 1062534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return a result Bundle, possibly null. Will be null if the ContentProvider 1063534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * does not implement call. 1064534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws NullPointerException if uri or method is null 1065534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws IllegalArgumentException if uri is not known 1066534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick */ 1067534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick public final Bundle call(Uri uri, String method, String arg, Bundle extras) { 1068534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (uri == null) { 1069534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("uri == null"); 1070534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1071534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (method == null) { 1072534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("method == null"); 1073534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1074534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick IContentProvider provider = acquireProvider(uri); 1075534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (provider == null) { 1076534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new IllegalArgumentException("Unknown URI " + uri); 1077534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1078534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick try { 107935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return provider.call(mPackageName, method, arg, extras); 1080534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } catch (RemoteException e) { 1081534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1082534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 1083534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return null; 1084534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } finally { 1085534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 1086534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1087534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1088534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick 1089534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick /** 1090cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI. 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1096cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireProvider(Uri uri) { 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1100f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich final String auth = uri.getAuthority(); 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 1102f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich return acquireProvider(mContext, auth); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1108cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI if the process 1109cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * already has a reference on it. 1110cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * 1111cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @param uri The URI to a content provider 1112cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1113cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @hide 1114cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn */ 1115cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireExistingProvider(Uri uri) { 1116cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1117cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1118cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1119f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich final String auth = uri.getAuthority(); 1120cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (auth != null) { 1121f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich return acquireExistingProvider(mContext, auth); 1122cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1123cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1124cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1125cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 1126cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 11301877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1137652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Returns the content provider for the given content URI. 1138652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * 1139652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @param uri The URI to a content provider 1140652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1141652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1142652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1143652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(Uri uri) { 1144652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1145652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1146652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1147652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn String auth = uri.getAuthority(); 1148652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (auth != null) { 1149652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return acquireUnstableProvider(mContext, uri.getAuthority()); 1150652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1151652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1152652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1153652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1154652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1155652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1156652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1157652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(String name) { 1158652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (name == null) { 1159652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1160652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 11616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return acquireUnstableProvider(mContext, name); 1162652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1163652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1164652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1165718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1166718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 1167718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1168718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1169718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1170718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1171718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 1172718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1173718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 1174718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1175718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 1176718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 1177718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1178652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1179718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1180718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1181718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1182718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1183718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1184718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 1185718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1186718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 1187718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1188718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1189718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1190718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1191718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 1192718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1193718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 1194718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1195718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 1196718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 1197718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1198652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1199652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1200652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1201652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1202652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1203652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1204652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1205652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(Uri)}, 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(Uri uri) { 12216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(uri); 1222652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1223652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1224652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1225652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1226652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1227652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1228652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1229652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1230652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(String)}, but for use when you do 1231652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1232652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1233652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1234652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1235652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1236652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1237652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 12386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 12396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 12406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 12416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 12426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 12436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1244652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1245652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(String name) { 12466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(name); 1247652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1248652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1249718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1250718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1251718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1252718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1253718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1254718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1270afccaa84c8d1b9aa45040ddeb0edd42ba80e80d6Christopher Tate registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId()); 127116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 127216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 127316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** @hide - designated user version */ 127416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 127516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate ContentObserver observer, int userHandle) 127616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate { 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1278231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 127916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer.getContentObserver(), userHandle); 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 1294231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1302d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * Notify registered observers that a row was updated and attempt to sync changes 1303d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * to the network. 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 130786de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 130886de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 130986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 131086de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 131186de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 1321d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * If syncToNetwork is true, this will attempt to schedule a local sync using the sync 1322d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * adapter that's registered for the authority of the provided uri. No account will be 1323d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * passed to the sync adapter, so all matching accounts will be synchronized. 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 132586de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 132686de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 132786de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 132886de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 132986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 1331d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * @see #requestSync(android.accounts.Account, String, android.os.Bundle) 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 1334b7564454297ba1706670ccab0562cac6676d0a77Christopher Tate notifyChange(uri, observer, syncToNetwork, UserHandle.getCallingUserId()); 133516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 133616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 133716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** 133816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * Notify registered observers within the designated user(s) that a row was updated. 133916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * 134016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * @hide 134116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate */ 134216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 134316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate int userHandle) { 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1345231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 134716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer != null && observer.deliverSelfNotifications(), syncToNetwork, 134816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate userHandle); 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 1368ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 1369ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13714a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 1373ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 1374ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 1375ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 1376ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 13773348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 1378ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1379ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 1380ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1381ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 1382ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1383ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1384ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1385ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 1386ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 1387ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 1388ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 1389ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 1390ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 1391ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 1392ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 1393ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 1394ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 1395ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 1396ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1397ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 1398ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 1399ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 1400ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1401ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1404ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().requestSync(account, authority, extras); 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1418d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 1434d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1445ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1446ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 1447ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 1448ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1449ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 1450ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 1451ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 14524a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 1454ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 1455ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1456ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1457ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1458ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 1459ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 1460ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 1461ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1462ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 1463ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 1464ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1465ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 1466ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1467ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 1468ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1469ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1470ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1471ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1472ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1473ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 1474ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 1475ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1476ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 1477ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1478ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 1479ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1480ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1481ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1482ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1483ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1484ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1485ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 14869530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14879530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1488ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1489ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1490ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 1491ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 1492ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1493ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 1494ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1495ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 1496ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1497ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1498ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1499ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1500ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1501ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1502ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 15039530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15049530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1505ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1506ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1507ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1508ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1509ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1510ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1512ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1514ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 15155e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 15165e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 15175e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 15185e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 15195e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 1520c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 1521c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 1522c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 1523c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 1524c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 1525c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 1526c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 1527c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 1528c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 152953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 153053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 153153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 153253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 153353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 153453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 1535c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 15369530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15379530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 15389530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * 1539c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 1540c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 1541c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 1542c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 154353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 154453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 1545c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1546c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 1547c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 1548c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 154953bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 155053bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 155153bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 155253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 155353bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 155453bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 155553bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 155653bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 155753bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 155853bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 155953bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 156053bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 156153bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 156253bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 156353bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1564c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1565c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 1566c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1567c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1568c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 1569c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1570c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1571c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1572c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1573c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 1574c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 15759530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15769530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1577c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1578c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 1579c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 1580c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 1581c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1582c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 1583c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 158453bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 158553bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 158653bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 158753bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 158853bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 158953bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1590c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1591c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 1592c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1593c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1594c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1595c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1596c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1597c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1598c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 15999530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16009530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1601c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1602c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 1603c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 1604c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 1605c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1606c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 160753bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 160853bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 160953bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 161053bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 161153bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 161253bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1613c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1614c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getContentService().getPeriodicSyncs(account, authority); 1615c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1616c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1617c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1618c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1619c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1620c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 16215e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 16229530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16239530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 16245e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 16255e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 162620ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 16275e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 16285e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 16295e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 16305e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 16315e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 16325e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 16335e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 16345e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 16355e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 16369530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16379530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1638718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 16395e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 164020ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 16415e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 16425e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 16435e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 16445e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1645ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1650ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 1651ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16529530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16539530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1654ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1655ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 1656ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1657ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 1658ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1659ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 1660ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1661ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1662ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1663ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1664ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1665ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1666ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 1667ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16689530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16699530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1670ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1671ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 1672ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1673ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 1674ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1675ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 1676ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1677ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1678ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1679ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1680ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1681ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1682ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1683ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 1684ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 16859530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16869530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1687ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1688ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1689ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 1690ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1691ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 1692ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1693ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 1694ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1695ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1696ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1697ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1698ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1699ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1700c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * If a sync is active returns the information about it, otherwise returns null. 1701c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * <p> 17029530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 17039530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 17049530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1705d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 1706c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @deprecated 1707c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Since multiple concurrent syncs are now supported you should use 1708c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * {@link #getCurrentSyncs()} to get the accurate list of current syncs. 1709c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * This method returns the first item from the list of current syncs 1710c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * or null if there are none. 1711ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1712c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana @Deprecated 1713d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 1714ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1715c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana final List<SyncInfo> syncs = getContentService().getCurrentSyncs(); 1716c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana if (syncs.isEmpty()) { 1717c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return null; 1718c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1719c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return syncs.get(0); 1720c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } catch (RemoteException e) { 1721c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1722c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1723c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1724c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana 1725c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana /** 1726c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Returns a list with information about all the active syncs. This list will be empty 1727c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * if there are no active syncs. 17289530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 17299530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 17309530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 17319530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1732c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @return a List of SyncInfo objects for the currently active syncs. 1733c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana */ 1734c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana public static List<SyncInfo> getCurrentSyncs() { 1735c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana try { 1736c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return getContentService().getCurrentSyncs(); 1737ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1738ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1739ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1740ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1741ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1742ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 17434a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 1744ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1745ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1746ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 1747ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1748ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1749ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 1750ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1751ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 1752ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1753ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1754ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1755ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1756ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1757ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1758ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 17599530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 17609530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1761ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1762ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1763ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 1764ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1765ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 1766ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1767ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 1768ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1769ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1770ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1771ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1772ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17731b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 17741b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 17751b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 17761b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 17771b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 17781b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 17791b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 17801b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 17811b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 17821b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 17831b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 17841b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 17851b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 17861b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1787ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 17881b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 17891b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 17901b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1791ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1792ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 1793ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 1794ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 1795ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1796ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 1797ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 1798ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 1799ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1800ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1801ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1802ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1803ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 18041b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 18051b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 18061b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 18071b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1808ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 18091b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 18101b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 18111b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1812ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1813ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 1814ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1815ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1816ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1817ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1818ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1819ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1820a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 1821a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 1822a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 1823a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 1824a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 1825a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 1826a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 1827a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 1828a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1829a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 1830a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1831a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1832a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 1833a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 1834a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 1835a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1836a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1837a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1838a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1839a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1840a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1841a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1842a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1843a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1844a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 1845a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 1846a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 1847a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 1848a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 1849a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 1850a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 1851a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 1852a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 1853a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1854a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1855a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1856a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 1857a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 1858a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 185901e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1860a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1861a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1862a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 1863a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1864a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 1865a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1866a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 1867a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1868a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1869a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1870a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1871a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1872a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 1873a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 1874a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1875a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1876a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1877a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1878a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1879a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1880a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1881a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 188201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1883a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1884a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 1885a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1886a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 1887a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1888a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1889a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1890a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1891a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1892ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1893825c5132bff21e72c1448241f4c6868563c8d624Jeff Brown private final class CursorWrapperInner extends CrossProcessCursorWrapper { 189403f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 1896baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1897baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private final CloseGuard mCloseGuard = CloseGuard.get(); 1898baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private boolean mProviderReleased; 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 1903baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.open("close"); 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 1910baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mProviderReleased = true; 1911baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1912baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1913baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.close(); 1914baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1920baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1921baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.warnIfOpen(); 1922baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 1923baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1924baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (!mProviderReleased && mContentProvider != null) { 1925baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // Even though we are using CloseGuard, log this anyway so that 1926baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // application developers always see the message in the log. 1927872a52c6b637faf75262b83fe68ff4e0d9fe044cJohannes Carlsson Log.w(TAG, "Cursor finalized without prior close()"); 1928baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown ContentResolver.this.releaseProvider(mContentProvider); 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 193703f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 19496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ContentResolver.this.releaseProvider(mContentProvider); 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1962231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1963231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 19640ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1965231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1966231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 1967231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 1968231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1969231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1970231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 197143a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service binder = " + b); 1972231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 197343a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service = " + sContentService); 1974231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1975231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 19760ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 197735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn /** @hide */ 197835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public String getPackageName() { 197935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return mPackageName; 198035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 198135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 1982231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 198435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final String mPackageName; 19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1987