ContentResolver.java revision 57286f970641493b315b0b42aba7ac6b672cc8b8
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brownimport dalvik.system.CloseGuard; 20baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 21a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.accounts.Account; 22cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackbornimport android.app.ActivityManagerNative; 2301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.app.AppGlobals; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 28825c5132bff21e72c1448241f4c6868563c8d624Jeff Brownimport android.database.CrossProcessCursorWrapper; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 33a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal; 346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackbornimport android.os.DeadObjectException; 35231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 36a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal; 37a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.OperationCanceledException; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 40231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 41d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrickimport android.os.SystemClock; 425e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackbornimport android.os.UserHandle; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 44a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.util.EventLog; 45231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 5303f0292744094ec107ffce71301c394503a31dedGilles Debunneimport java.util.ArrayList; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 55a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport java.util.Random; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides applications access to the content model. 60558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * 61558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <div class="special reference"> 62558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <h3>Developer Guides</h3> 63558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <p>For more information about using a ContentResolver with content providers, read the 64558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> 65558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * developer guide.</p> 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentResolver { 68ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 69ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 70ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 71ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 724a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 73ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_ACCOUNT = "account"; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 75ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 76ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 77ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 78ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 794a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 8153bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8253bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the sync settings (like getSyncAutomatically()) 8453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. 8553bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 8653bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_SETTINGS = "ignore_settings"; 8753bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8853bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then any backoffs for the initial attempt (e.g. due to retries) 9053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. If this request fails and gets rescheduled then the 9153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * retries will still honor the backoff. 9253bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9353bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_BACKOFF = "ignore_backoff"; 9453bd2522ca7767f46646606123b6e2689b811850Fred Quintana 9553bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 9653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the request will not be retried if it fails. 9753bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9853bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_DO_NOT_RETRY = "do_not_retry"; 9953bd2522ca7767f46646606123b6e2689b811850Fred Quintana 10053bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 10153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Setting this extra is the equivalent of setting both {@link #SYNC_EXTRAS_IGNORE_SETTINGS} 10253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * and {@link #SYNC_EXTRAS_IGNORE_BACKOFF} 10353bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 104ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 10553bd2522ca7767f46646606123b6e2689b811850Fred Quintana 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1104a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana /** 1114a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Set by the SyncManager to request that the SyncAdapter initialize itself for 1124a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * the given account/authority pair. One required initialization step is to 1134a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been 1144a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * called with a >= 0 value. When this flag is set the SyncAdapter does not need to 1154a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * do a full sync, though it is allowed to do so. 1164a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana */ 1174a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; 1184a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 1320ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 1360ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 1460ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 154ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 155ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 156ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 157ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 158ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 159ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 160ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 161ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 162ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 163ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 167ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 168ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 169ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 170ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 171ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private static final String[] SYNC_ERROR_NAMES = new String[] { 17357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "already-in-progress", 17457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "authentication-error", 17557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "io-error", 17657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "parse-error", 17757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "conflict", 17857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-deletions", 17957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-retries", 18057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "internal-error", 18157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert }; 18257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 18357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert /** @hide */ 18457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert static String syncErrorToString(int error) { 18557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (error < 1 || error > SYNC_ERROR_NAMES.length) { 18657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return String.valueOf(error); 18757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 18857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return SYNC_ERROR_NAMES[error - 1]; 18957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 19057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 191ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 192ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 193ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 194ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 195ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 196ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 197ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 198ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 19925880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 200a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 20125880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 202a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 203a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 204231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 210cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** Providing a default implementation of this, to avoid having to change 211cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * a lot of other things, but implementations of ContentResolver should 212cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * implement it. @hide */ 213cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn protected IContentProvider acquireExistingProvider(Context c, String name) { 214cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireProvider(c, name); 215cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 218652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 219652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn protected abstract IContentProvider acquireUnstableProvider(Context c, String name); 220652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 221652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public abstract boolean releaseUnstableProvider(IContentProvider icp); 2226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn /** @hide */ 2236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn public abstract void unstableProviderDied(IContentProvider icp); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final String getType(Uri url) { 2336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // XXX would like to have an acquireExistingUnstableProvider for this. 234cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn IContentProvider provider = acquireExistingProvider(url); 235cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (provider != null) { 236cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn try { 237cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return provider.getType(url); 238cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (RemoteException e) { 239cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 240cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (java.lang.Exception e) { 241145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 242cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 243cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } finally { 244cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn releaseProvider(provider); 245cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 246cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 247cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 248cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(url.getScheme())) { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 251cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2535e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn String type = ActivityManagerNative.getDefault().getProviderMimeType( 2545e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn url, UserHandle.myUserId()); 255cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return type; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 257534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 258534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 260145e6c4975536d927e506634514a06c43313df17Ola Olsson } catch (java.lang.Exception e) { 261145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 262145e6c4975536d927e506634514a06c43313df17Ola Olsson return null; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Query for the possible MIME types for the representations the given 26823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URL can be returned when opened as as stream with 26923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link #openTypedAssetFileDescriptor}. Note that the types here are 27023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * not necessarily a superset of the type returned by {@link #getType} -- 27123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * many content providers can not return a raw stream for the structured 27223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data that they contain. 27323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 27423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param url A Uri identifying content (either a list or specific type), 27523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * using the content:// scheme. 27623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeTypeFilter The desired MIME type. This may be a pattern, 27723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * such as *\/*, to query for all available MIME types that match the 27823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * pattern. 279acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns an array of MIME type strings for all available 28023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data streams that match the given mimeTypeFilter. If there are none, 28123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * null is returned. 28223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 28323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public String[] getStreamTypes(Uri url, String mimeTypeFilter) { 28423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn IContentProvider provider = acquireProvider(url); 28523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (provider == null) { 28623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 28723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 28864bbbb471ed78ae06f411224849a4556a30fd362Dianne Hackborn 28923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 29023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return provider.getStreamTypes(url, mimeTypeFilter); 29123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (RemoteException e) { 292534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 293534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 29423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 29523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 296534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 297534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 29823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 29923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 30023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 3010ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 3030ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3040ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3050ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 3060ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 3070ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 3080ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 3090ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 3100ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 3110ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 3120ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 3130ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 3140ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 3190ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 33475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return query(uri, projection, selection, selectionArgs, sortOrder, null); 33575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 33675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 33775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 33875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 33975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Query the given URI, returning a {@link Cursor} over the result set. 34075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 34175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 34275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * For best performance, the caller should follow these guidelines: 34375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <ul> 34475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Provide an explicit projection, to prevent 34575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * reading data from storage that aren't going to be used.</li> 34675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Use question mark parameter markers such as 'phone=?' instead of 34775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * explicit values in the {@code selection} parameter, so that queries 34875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * that differ only by those values will be recognized as the same 34975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * for caching purposes.</li> 35075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </ul> 35175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 35275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 35375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param uri The URI, using the content:// scheme, for the content to 35475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * retrieve. 35575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param projection A list of which columns to return. Passing null will 35675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is inefficient. 35775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 35875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null will 35975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all rows for the given URI. 36075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 36175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in the order that they 36275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 36375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 36475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the ORDER BY itself). Passing null will use the 36575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 3664c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 36775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 36875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 36975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A Cursor object, which is positioned before the first entry, or null 37075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 37175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 37275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public final Cursor query(final Uri uri, String[] projection, 37375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown String selection, String[] selectionArgs, String sortOrder, 3744c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown CancellationSignal cancellationSignal) { 3756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 3766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 381d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 38275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 3834c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown ICancellationSignal remoteCancellationSignal = null; 3844c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown if (cancellationSignal != null) { 3854c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.throwIfCanceled(); 3866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn remoteCancellationSignal = unstableProvider.createCancellationSignal(); 3874c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.setRemote(remoteCancellationSignal); 38875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 3896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn Cursor qCursor; 3906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 3916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn qCursor = unstableProvider.query(uri, projection, 3926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 3936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 3946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 3956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 3966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 3976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 3986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 3996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 4006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 4016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn qCursor = stableProvider.query(uri, projection, 4036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 4046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 405a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 408020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori // force query execution 409020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 410d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 411a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 412a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Wrap the cursor object into CursorWrapperInner object 4136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, 4146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider != null ? stableProvider : acquireProvider(uri)); 4156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 4166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return wrapper; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 418534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 419534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 4226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 4236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 4246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4256ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 4266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 4276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4318943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4410ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 4440ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 4990ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 51723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 5340ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5500ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5550ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5620ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 56723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 56903f0292744094ec107ffce71301c394503a31dedGilles Debunne * method of the provider associated with the given URI, to retrieve any file stored there. 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 60123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note that if this function is called for read-only input (mode is "r") 60223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 60323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * for you with a MIME type of "*\/*". This allows such callers to benefit 60423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * from any built-in data conversion that a provider implements. 60523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 63223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if ("r".equals(mode)) { 63323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return openTypedAssetFileDescriptor(uri, "*/*", null); 63423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } else { 6356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 6366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 6376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 6386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 6406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 6416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 643652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 6446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = unstableProvider.openAssetFile(uri, mode); 645652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 646652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 647652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 648652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 6496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 6506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 6516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 6526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 6536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 6546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 657652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 6586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = stableProvider.openAssetFile(uri, mode); 6596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 6606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 6616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 662652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 66323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 6646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 6696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 6706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 6716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 6736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 6746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 6756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 6776ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 6786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 6806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 6816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 6826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 6836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 6846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 6856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 6866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 6876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 6886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 6906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 6916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 69223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 69323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 69423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 69523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 69623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 69723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 69823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access (potentially type transformed) 69923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data from a "content:" URI. This interacts with the underlying 70023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile} method of the provider 70123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * associated with the given URI, to retrieve retrieve any appropriate 70223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream for the data stored there. 70323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 70423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 70523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with "content:" URIs, because content providers are the only facility 70623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with an associated MIME type to ensure that the returned data stream 70723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is of the desired type. 70823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 70923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>All text/* streams are encoded in UTF-8. 71023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 71123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param uri The desired URI to open. 71223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeType The desired MIME type of the returned data. This can 71323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * be a pattern such as *\/*, which will allow the content provider to 71423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * select a type, though there is no way for you to determine what type 71523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it is returning. 71623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param opts Additional provider-dependent options. 71723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns a new ParcelFileDescriptor from which you can read the 71823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream from the provider. Note that this may be a pipe, meaning 71923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * you can't seek in it. The only seek you should do is if the 72023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * AssetFileDescriptor contains an offset, to move to that offset before 72123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * reading. You own this descriptor and are responsible for closing it when done. 72223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @throws FileNotFoundException Throws FileNotFoundException of no 72323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data of the desired type exists under the URI. 72423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 72523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri, 72623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn String mimeType, Bundle opts) throws FileNotFoundException { 7276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 7286ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 7296ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 7306ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 7326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 7336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 735652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 7366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = unstableProvider.openTypedAssetFile(uri, mimeType, opts); 737652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 738652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 739652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 740652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 7426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 7436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 7446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 7456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 7466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 749652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = stableProvider.openTypedAssetFile(uri, mimeType, opts); 7516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 7526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 7536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 754652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 7626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 7636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 7656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 7666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 7676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 7696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 7706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 7726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 7736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 7746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 7756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 7766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 7776ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 7786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 7796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 7806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 7826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7874c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 7884c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 7894c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 7904c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 7914c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 7924c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 7934c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 7944c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7964c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 7974c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 7984c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 7994c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 8004c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 8014c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 8024c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8390ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8660ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 884d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 885a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri createdRow = provider.insert(url, values); 886d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 887a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 888a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 890534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 891534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8988943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 8998943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 9008943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 9018943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 9028943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 9038943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 9048943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 9058943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 9068943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 9078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 9088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 9098943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 9108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 9118943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 9128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 9138943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 9148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 91503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 9168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 9178943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 9186a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 9198943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 9206a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9216a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 9228943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 9236a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 9246a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 9256a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9266a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9276a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 945d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 946a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsCreated = provider.bulkInsert(url, values); 947d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 948a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 949a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 951534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 952534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 976d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 977a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsDeleted = provider.delete(url, where, selectionArgs); 978d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 979a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 980a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 982534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 983534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 998d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 1000534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return the number of rows updated. 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1010d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 1011a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsUpdated = provider.update(uri, values, where, selectionArgs); 1012d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1013a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 1014a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1016534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1017534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1025f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * Call a provider-defined method. This can be used to implement 1026534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * read or write interfaces which are cheaper than using a Cursor and/or 1027534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * do not fit into the traditional table model. 1028534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * 1029534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param method provider-defined method name to call. Opaque to 1030534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * framework, but must be non-null. 1031534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param arg provider-defined String argument. May be null. 1032534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param extras provider-defined Bundle argument. May be null. 1033534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return a result Bundle, possibly null. Will be null if the ContentProvider 1034534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * does not implement call. 1035534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws NullPointerException if uri or method is null 1036534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws IllegalArgumentException if uri is not known 1037534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick */ 1038534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick public final Bundle call(Uri uri, String method, String arg, Bundle extras) { 1039534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (uri == null) { 1040534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("uri == null"); 1041534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1042534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (method == null) { 1043534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("method == null"); 1044534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1045534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick IContentProvider provider = acquireProvider(uri); 1046534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (provider == null) { 1047534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new IllegalArgumentException("Unknown URI " + uri); 1048534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1049534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick try { 1050534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return provider.call(method, arg, extras); 1051534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } catch (RemoteException e) { 1052534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1053534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 1054534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return null; 1055534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } finally { 1056534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 1057534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1058534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1059534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick 1060534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick /** 1061cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI. 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1067cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireProvider(Uri uri) { 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String auth = uri.getAuthority(); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, uri.getAuthority()); 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1079cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI if the process 1080cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * already has a reference on it. 1081cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * 1082cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @param uri The URI to a content provider 1083cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1084cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @hide 1085cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn */ 1086cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireExistingProvider(Uri uri) { 1087cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1088cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1089cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1090cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn String auth = uri.getAuthority(); 1091cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (auth != null) { 1092cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireExistingProvider(mContext, uri.getAuthority()); 1093cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1094cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1095cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1096cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 1097cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 11011877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1108652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Returns the content provider for the given content URI. 1109652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * 1110652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @param uri The URI to a content provider 1111652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1112652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1113652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1114652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(Uri uri) { 1115652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1116652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1117652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1118652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn String auth = uri.getAuthority(); 1119652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (auth != null) { 1120652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return acquireUnstableProvider(mContext, uri.getAuthority()); 1121652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1122652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1123652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1124652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1125652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1126652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1127652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1128652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(String name) { 1129652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (name == null) { 1130652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1131652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 11326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return acquireUnstableProvider(mContext, name); 1133652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1134652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1135652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1136718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1137718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 1138718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1139718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1140718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1141718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1142718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 1143718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1144718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 1145718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1146718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 1147718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 1148718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1149652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1150718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1151718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1152718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1153718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1154718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1155718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 1156718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1157718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 1158718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1159718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1160718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1161718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1162718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 1163718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1164718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 1165718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1166718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 1167718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 1168718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1169652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1170652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1171652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1172652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1173652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1174652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1175652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1176652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(Uri)}, but for use when you do 1177652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1178652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1179652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1180652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1181652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1182652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1183652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 11846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 11856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 11866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 11876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 11886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 11896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1190652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1191652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) { 11926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(uri); 1193652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1194652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1195652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1196652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1197652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1198652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1199652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1200652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1201652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(String)}, but for use when you do 1202652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1203652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1204652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1205652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1206652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1207652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1208652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 12096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 12106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 12116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 12126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 12136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 12146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1215652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1216652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(String name) { 12176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(name); 1218652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1219652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1220718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1221718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1222718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1223718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1224718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1225718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1241afccaa84c8d1b9aa45040ddeb0edd42ba80e80d6Christopher Tate registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId()); 124216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 124316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 124416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** @hide - designated user version */ 124516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 124616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate ContentObserver observer, int userHandle) 124716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate { 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1249231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 125016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer.getContentObserver(), userHandle); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 1265231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1273d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * Notify registered observers that a row was updated and attempt to sync changes 1274d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * to the network. 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 127886de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 127986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 128086de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 128186de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 128286de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 1292d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * If syncToNetwork is true, this will attempt to schedule a local sync using the sync 1293d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * adapter that's registered for the authority of the provided uri. No account will be 1294d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * passed to the sync adapter, so all matching accounts will be synchronized. 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 129686de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 129786de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 129886de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 129986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 130086de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 1302d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * @see #requestSync(android.accounts.Account, String, android.os.Bundle) 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 1305b7564454297ba1706670ccab0562cac6676d0a77Christopher Tate notifyChange(uri, observer, syncToNetwork, UserHandle.getCallingUserId()); 130616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 130716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 130816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** 130916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * Notify registered observers within the designated user(s) that a row was updated. 131016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * 131116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * @hide 131216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate */ 131316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 131416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate int userHandle) { 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1316231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 131816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer != null && observer.deliverSelfNotifications(), syncToNetwork, 131916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate userHandle); 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 1339ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 1340ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13424a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 1344ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 1345ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 1346ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 1347ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 13483348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 1349ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1350ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 1351ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1352ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 1353ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1354ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1355ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1356ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 1357ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 1358ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 1359ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 1360ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 1361ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 1362ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 1363ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 1364ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 1365ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 1366ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 1367ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1368ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 1369ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 1370ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 1371ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1372ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1375ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().requestSync(account, authority, extras); 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1389d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 1405d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1416ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1417ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 1418ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 1419ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1420ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 1421ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 1422ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 14234a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 1425ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 1426ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1427ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1428ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1429ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 1430ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 1431ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 1432ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1433ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 1434ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 1435ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1436ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 1437ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1438ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 1439ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1440ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1441ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1442ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1443ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1444ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 1445ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 1446ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1447ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 1448ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1449ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 1450ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1451ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1452ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1453ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1454ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1455ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1456ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 14579530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14589530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1459ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1460ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1461ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 1462ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 1463ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1464ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 1465ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1466ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 1467ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1468ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1469ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1470ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1471ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1472ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1473ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 14749530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14759530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1476ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1477ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1478ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1479ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1480ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1481ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1483ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1485ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 14865e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 14875e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 14885e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 14895e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 14905e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 1491c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 1492c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 1493c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 1494c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 1495c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 1496c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 1497c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 1498c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 1499c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 150053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 150153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 150253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 150353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 150453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 150553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 1506c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 15079530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15089530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 15099530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * 1510c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 1511c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 1512c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 1513c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 151453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 151553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 1516c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1517c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 1518c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 1519c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 152053bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 152153bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 152253bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 152353bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 152453bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 152553bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 152653bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 152753bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 152853bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 152953bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 153053bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 153153bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 153253bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 153353bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 153453bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1535c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1536c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 1537c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1538c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1539c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 1540c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1541c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1542c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1543c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1544c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 1545c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 15469530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15479530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1548c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1549c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 1550c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 1551c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 1552c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1553c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 1554c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 155553bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 155653bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 155753bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 155853bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 155953bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 156053bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1561c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1562c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 1563c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1564c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1565c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1566c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1567c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1568c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1569c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 15709530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15719530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1572c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1573c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 1574c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 1575c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 1576c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1577c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 157853bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 157953bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 158053bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 158153bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 158253bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 158353bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1584c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1585c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getContentService().getPeriodicSyncs(account, authority); 1586c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1587c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1588c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1589c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1590c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1591c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 15925e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 15939530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15949530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 15955e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 15965e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 159720ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 15985e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 15995e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 16005e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 16015e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 16025e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 16035e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 16045e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 16055e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 16065e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 16079530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16089530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1609718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 16105e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 161120ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 16125e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 16135e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 16145e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 16155e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1616ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1620ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1621ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 1622ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16239530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16249530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1625ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1626ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 1627ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1628ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 1629ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1630ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 1631ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1632ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1633ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1634ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1635ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1636ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1637ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 1638ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16399530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16409530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1641ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1642ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 1643ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1644ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 1645ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1646ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 1647ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1648ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1649ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1650ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1651ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1652ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1653ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1654ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 1655ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 16569530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16579530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1658ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1659ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1660ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 1661ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1662ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 1663ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1664ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 1665ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1666ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1667ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1668ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1669ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1670ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1671c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * If a sync is active returns the information about it, otherwise returns null. 1672c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * <p> 16739530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 16749530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 16759530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1676d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 1677c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @deprecated 1678c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Since multiple concurrent syncs are now supported you should use 1679c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * {@link #getCurrentSyncs()} to get the accurate list of current syncs. 1680c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * This method returns the first item from the list of current syncs 1681c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * or null if there are none. 1682ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1683c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana @Deprecated 1684d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 1685ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1686c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana final List<SyncInfo> syncs = getContentService().getCurrentSyncs(); 1687c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana if (syncs.isEmpty()) { 1688c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return null; 1689c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1690c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return syncs.get(0); 1691c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } catch (RemoteException e) { 1692c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1693c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1694c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1695c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana 1696c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana /** 1697c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Returns a list with information about all the active syncs. This list will be empty 1698c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * if there are no active syncs. 16999530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 17009530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 17019530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 17029530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1703c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @return a List of SyncInfo objects for the currently active syncs. 1704c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana */ 1705c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana public static List<SyncInfo> getCurrentSyncs() { 1706c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana try { 1707c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return getContentService().getCurrentSyncs(); 1708ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1709ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1710ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1711ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1712ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1713ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 17144a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 1715ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1716ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1717ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 1718ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1719ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1720ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 1721ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1722ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 1723ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1724ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1725ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1726ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1727ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1728ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1729ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 17309530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 17319530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1732ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1733ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1734ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 1735ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1736ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 1737ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1738ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 1739ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1740ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1741ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1742ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1743ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17441b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 17451b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 17461b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 17471b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 17481b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 17491b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 17501b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 17511b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 17521b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 17531b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 17541b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 17551b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 17561b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 17571b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1758ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 17591b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 17601b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 17611b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1762ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1763ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 1764ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 1765ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 1766ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1767ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 1768ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 1769ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 1770ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1771ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1772ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1773ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1774ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17751b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 17761b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 17771b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 17781b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1779ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 17801b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 17811b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 17821b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1783ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1784ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 1785ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1786ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1787ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1788ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1789ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1790ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1791a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 1792a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 1793a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 1794a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 1795a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 1796a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 1797a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 1798a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 1799a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1800a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 1801a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1802a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1803a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 1804a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 1805a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 1806a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1807a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1808a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1809a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1810a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1811a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1812a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1813a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1814a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1815a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 1816a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 1817a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 1818a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 1819a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 1820a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 1821a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 1822a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 1823a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 1824a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1825a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1826a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1827a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 1828a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 1829a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 183001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1831a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1832a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1833a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 1834a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1835a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 1836a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1837a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 1838a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1839a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1840a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1841a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1842a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1843a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 1844a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 1845a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1846a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1847a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1848a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1849a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1850a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1851a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1852a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 185301e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1854a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1855a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 1856a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1857a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 1858a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1859a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1860a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1861a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1862a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1863ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1864825c5132bff21e72c1448241f4c6868563c8d624Jeff Brown private final class CursorWrapperInner extends CrossProcessCursorWrapper { 186503f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 1867baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1868baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private final CloseGuard mCloseGuard = CloseGuard.get(); 1869baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private boolean mProviderReleased; 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 1874baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.open("close"); 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 1881baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mProviderReleased = true; 1882baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1883baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1884baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.close(); 1885baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1891baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1892baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.warnIfOpen(); 1893baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 1894baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1895baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (!mProviderReleased && mContentProvider != null) { 1896baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // Even though we are using CloseGuard, log this anyway so that 1897baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // application developers always see the message in the log. 1898872a52c6b637faf75262b83fe68ff4e0d9fe044cJohannes Carlsson Log.w(TAG, "Cursor finalized without prior close()"); 1899baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown ContentResolver.this.releaseProvider(mContentProvider); 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 190803f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 19206ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ContentResolver.this.releaseProvider(mContentProvider); 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1933231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1934231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 19350ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1936231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1937231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 1938231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 1939231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1940231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1941231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 194243a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service binder = " + b); 1943231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 194443a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service = " + sContentService); 1945231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1946231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 19470ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1948231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1952