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 172ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 173ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 174ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 175ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 176ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 177ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 178ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 179ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 18025880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 181a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 18225880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 183a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 184a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 185231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 191cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** Providing a default implementation of this, to avoid having to change 192cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * a lot of other things, but implementations of ContentResolver should 193cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * implement it. @hide */ 194cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn protected IContentProvider acquireExistingProvider(Context c, String name) { 195cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireProvider(c, name); 196cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 199652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 200652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn protected abstract IContentProvider acquireUnstableProvider(Context c, String name); 201652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 202652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public abstract boolean releaseUnstableProvider(IContentProvider icp); 2036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn /** @hide */ 2046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn public abstract void unstableProviderDied(IContentProvider icp); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final String getType(Uri url) { 2146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // XXX would like to have an acquireExistingUnstableProvider for this. 215cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn IContentProvider provider = acquireExistingProvider(url); 216cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (provider != null) { 217cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn try { 218cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return provider.getType(url); 219cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (RemoteException e) { 220cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 221cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (java.lang.Exception e) { 222145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 223cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 224cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } finally { 225cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn releaseProvider(provider); 226cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 227cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 228cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 229cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(url.getScheme())) { 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 232cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2345e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn String type = ActivityManagerNative.getDefault().getProviderMimeType( 2355e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn url, UserHandle.myUserId()); 236cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return type; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 238534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 239534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 241145e6c4975536d927e506634514a06c43313df17Ola Olsson } catch (java.lang.Exception e) { 242145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 243145e6c4975536d927e506634514a06c43313df17Ola Olsson return null; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Query for the possible MIME types for the representations the given 24923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URL can be returned when opened as as stream with 25023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link #openTypedAssetFileDescriptor}. Note that the types here are 25123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * not necessarily a superset of the type returned by {@link #getType} -- 25223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * many content providers can not return a raw stream for the structured 25323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data that they contain. 25423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 25523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param url A Uri identifying content (either a list or specific type), 25623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * using the content:// scheme. 25723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeTypeFilter The desired MIME type. This may be a pattern, 25823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * such as *\/*, to query for all available MIME types that match the 25923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * pattern. 260acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns an array of MIME type strings for all available 26123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data streams that match the given mimeTypeFilter. If there are none, 26223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * null is returned. 26323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 26423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public String[] getStreamTypes(Uri url, String mimeTypeFilter) { 26523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn IContentProvider provider = acquireProvider(url); 26623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (provider == null) { 26723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 26823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 26964bbbb471ed78ae06f411224849a4556a30fd362Dianne Hackborn 27023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 27123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return provider.getStreamTypes(url, mimeTypeFilter); 27223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (RemoteException e) { 273534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 274534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 27523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 27623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 277534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 278534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 27923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 28023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 28123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 2820ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 2840ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 2850ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 2860ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 2870ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 2880ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 2890ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 2900ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 2910ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 2920ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 2930ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 2940ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 2950ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 3000ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 31575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return query(uri, projection, selection, selectionArgs, sortOrder, null); 31675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 31775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 31875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 31975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 32075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Query the given URI, returning a {@link Cursor} over the result set. 32175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 32275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 32375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * For best performance, the caller should follow these guidelines: 32475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <ul> 32575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Provide an explicit projection, to prevent 32675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * reading data from storage that aren't going to be used.</li> 32775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Use question mark parameter markers such as 'phone=?' instead of 32875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * explicit values in the {@code selection} parameter, so that queries 32975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * that differ only by those values will be recognized as the same 33075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * for caching purposes.</li> 33175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </ul> 33275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 33375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 33475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param uri The URI, using the content:// scheme, for the content to 33575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * retrieve. 33675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param projection A list of which columns to return. Passing null will 33775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is inefficient. 33875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 33975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null will 34075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all rows for the given URI. 34175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 34275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in the order that they 34375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 34475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 34575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the ORDER BY itself). Passing null will use the 34675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 3474c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 34875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 34975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 35075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A Cursor object, which is positioned before the first entry, or null 35175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 35275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 35375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public final Cursor query(final Uri uri, String[] projection, 35475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown String selection, String[] selectionArgs, String sortOrder, 3554c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown CancellationSignal cancellationSignal) { 3566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 3576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 362d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 36375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 3644c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown ICancellationSignal remoteCancellationSignal = null; 3654c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown if (cancellationSignal != null) { 3664c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.throwIfCanceled(); 3676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn remoteCancellationSignal = unstableProvider.createCancellationSignal(); 3684c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.setRemote(remoteCancellationSignal); 36975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 3706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn Cursor qCursor; 3716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 3726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn qCursor = unstableProvider.query(uri, projection, 3736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 3746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 3756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 3766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 3776ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 3786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 3796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 3806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 3816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 3826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 3836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn qCursor = stableProvider.query(uri, projection, 3846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 3856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 386a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 389020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori // force query execution 390020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 391d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 392a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 393a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Wrap the cursor object into CursorWrapperInner object 3946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, 3956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider != null ? stableProvider : acquireProvider(uri)); 3966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 3976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return wrapper; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 399534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 400534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 4036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 4046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 4056ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 4076ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 4086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4220ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 4250ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 4800ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 49823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 5150ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5310ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5360ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5430ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 54823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 55003f0292744094ec107ffce71301c394503a31dedGilles Debunne * method of the provider associated with the given URI, to retrieve any file stored there. 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 58223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note that if this function is called for read-only input (mode is "r") 58323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 58423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * for you with a MIME type of "*\/*". This allows such callers to benefit 58523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * from any built-in data conversion that a provider implements. 58623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 61323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if ("r".equals(mode)) { 61423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return openTypedAssetFileDescriptor(uri, "*/*", null); 61523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } else { 6166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 6176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 6186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 6196ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6206ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 6216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 6226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 624652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 6256ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = unstableProvider.openAssetFile(uri, mode); 626652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 627652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 628652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 629652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 6306ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 6316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 6326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 6336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 6346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 6356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 638652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 6396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = stableProvider.openAssetFile(uri, mode); 6406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 6416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 6426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 643652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 64423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 6456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 6476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 6486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 6506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 6516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 6526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 6546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 6556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 6566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 6586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 6596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 6606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 6616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 6626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 6636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 6646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 6656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 6666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 6676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 6686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 6696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 6706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 6716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 6726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 67323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 67423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 67523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 67623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 67723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 67823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 67923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access (potentially type transformed) 68023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data from a "content:" URI. This interacts with the underlying 68123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile} method of the provider 68223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * associated with the given URI, to retrieve retrieve any appropriate 68323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream for the data stored there. 68423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 68523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 68623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with "content:" URIs, because content providers are the only facility 68723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with an associated MIME type to ensure that the returned data stream 68823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is of the desired type. 68923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 69023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>All text/* streams are encoded in UTF-8. 69123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 69223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param uri The desired URI to open. 69323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeType The desired MIME type of the returned data. This can 69423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * be a pattern such as *\/*, which will allow the content provider to 69523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * select a type, though there is no way for you to determine what type 69623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it is returning. 69723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param opts Additional provider-dependent options. 69823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns a new ParcelFileDescriptor from which you can read the 69923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream from the provider. Note that this may be a pipe, meaning 70023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * you can't seek in it. The only seek you should do is if the 70123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * AssetFileDescriptor contains an offset, to move to that offset before 70223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * reading. You own this descriptor and are responsible for closing it when done. 70323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @throws FileNotFoundException Throws FileNotFoundException of no 70423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data of the desired type exists under the URI. 70523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 70623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri, 70723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn String mimeType, Bundle opts) throws FileNotFoundException { 7086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 7096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 7106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 7116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 7136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 7146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 716652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 7176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = unstableProvider.openTypedAssetFile(uri, mimeType, opts); 718652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 719652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 720652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 721652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 7236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 7246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 7256ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 7266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 7276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7286ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7296ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 730652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd = stableProvider.openTypedAssetFile(uri, mimeType, opts); 7326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 7336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 7346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 735652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 7396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 7406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 7436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 7446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 7466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 7476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 7486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 7506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 7516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 7526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 7536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 7546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 7556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 7566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 7576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 7586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 7596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 7606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 7616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 7636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 7646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7684c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 7694c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 7704c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 7714c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 7724c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 7734c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 7744c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 7754c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7774c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 7784c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 7794c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 7804c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 7814c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 7824c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 7834c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8200ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8470ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 865d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 866a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri createdRow = provider.insert(url, values); 867d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 868a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 869a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 871534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 872534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8798943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 8808943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 8818943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 8828943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 8838943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 8848943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 8858943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 8868943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 8878943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 8888943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 8898943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 8908943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 8918943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 8928943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 8938943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 8948943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 8958943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 89603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 8978943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 8988943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 8996a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 9008943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 9016a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9026a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 9038943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 9046a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 9056a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 9066a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9076a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 9086a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 926d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 927a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsCreated = provider.bulkInsert(url, values); 928d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 929a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 930a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 932534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 933534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 957d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 958a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsDeleted = provider.delete(url, where, selectionArgs); 959d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 960a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 961a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 963534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 964534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 979d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 981534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return the number of rows updated. 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 991d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 992a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int rowsUpdated = provider.update(uri, values, where, selectionArgs); 993d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 994a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 995a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 997534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 998534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1006f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * Call a provider-defined method. This can be used to implement 1007534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * read or write interfaces which are cheaper than using a Cursor and/or 1008534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * do not fit into the traditional table model. 1009534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * 1010534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param method provider-defined method name to call. Opaque to 1011534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * framework, but must be non-null. 1012534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param arg provider-defined String argument. May be null. 1013534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param extras provider-defined Bundle argument. May be null. 1014534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return a result Bundle, possibly null. Will be null if the ContentProvider 1015534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * does not implement call. 1016534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws NullPointerException if uri or method is null 1017534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws IllegalArgumentException if uri is not known 1018534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick */ 1019534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick public final Bundle call(Uri uri, String method, String arg, Bundle extras) { 1020534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (uri == null) { 1021534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("uri == null"); 1022534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1023534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (method == null) { 1024534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("method == null"); 1025534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1026534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick IContentProvider provider = acquireProvider(uri); 1027534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (provider == null) { 1028534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new IllegalArgumentException("Unknown URI " + uri); 1029534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1030534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick try { 1031534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return provider.call(method, arg, extras); 1032534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } catch (RemoteException e) { 1033534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1034534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 1035534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return null; 1036534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } finally { 1037534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 1038534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1039534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1040534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick 1041534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick /** 1042cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI. 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1048cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireProvider(Uri uri) { 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String auth = uri.getAuthority(); 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, uri.getAuthority()); 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1060cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI if the process 1061cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * already has a reference on it. 1062cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * 1063cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @param uri The URI to a content provider 1064cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1065cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @hide 1066cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn */ 1067cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireExistingProvider(Uri uri) { 1068cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1069cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1070cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1071cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn String auth = uri.getAuthority(); 1072cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (auth != null) { 1073cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireExistingProvider(mContext, uri.getAuthority()); 1074cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1075cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1076cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1077cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 1078cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 10821877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1089652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Returns the content provider for the given content URI. 1090652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * 1091652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @param uri The URI to a content provider 1092652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1093652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1094652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1095652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(Uri uri) { 1096652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1097652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1098652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1099652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn String auth = uri.getAuthority(); 1100652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (auth != null) { 1101652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return acquireUnstableProvider(mContext, uri.getAuthority()); 1102652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1103652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1104652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1105652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1106652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1107652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1108652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1109652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(String name) { 1110652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (name == null) { 1111652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1112652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 11136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return acquireUnstableProvider(mContext, name); 1114652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1115652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1116652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1117718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1118718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 1119718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1120718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1121718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1122718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1123718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 1124718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1125718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 1126718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1127718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 1128718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 1129718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1130652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1131718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1132718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1133718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1134718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1135718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1136718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 1137718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1138718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 1139718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1140718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1141718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1142718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1143718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 1144718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1145718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 1146718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1147718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 1148718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 1149718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1150652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1151652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1152652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1153652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1154652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1155652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1156652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1157652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(Uri)}, but for use when you do 1158652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1159652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1160652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1161652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1162652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1163652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1164652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 11656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 11666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 11676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 11686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 11696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 11706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1171652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1172652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) { 11736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(uri); 1174652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1175652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1176652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1177652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1178652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1179652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1180652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1181652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1182652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(String)}, but for use when you do 1183652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1184652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1185652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1186652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1187652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1188652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1189652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 11906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 11916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 11926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 11936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 11946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 11956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1196652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1197652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(String name) { 11986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(name); 1199652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1200652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1201718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1202718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1203718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1204718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1205718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1206718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1222afccaa84c8d1b9aa45040ddeb0edd42ba80e80d6Christopher Tate registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId()); 122316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 122416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 122516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** @hide - designated user version */ 122616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 122716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate ContentObserver observer, int userHandle) 122816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate { 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1230231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 123116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer.getContentObserver(), userHandle); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 1246231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1254d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * Notify registered observers that a row was updated and attempt to sync changes 1255d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * to the network. 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 125986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 126086de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 126186de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 126286de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 126386de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 1273d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * If syncToNetwork is true, this will attempt to schedule a local sync using the sync 1274d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * adapter that's registered for the authority of the provided uri. No account will be 1275d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * passed to the sync adapter, so all matching accounts will be synchronized. 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 127786de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 127886de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 127986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 128086de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 128186de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 1283d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * @see #requestSync(android.accounts.Account, String, android.os.Bundle) 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 1286b7564454297ba1706670ccab0562cac6676d0a77Christopher Tate notifyChange(uri, observer, syncToNetwork, UserHandle.getCallingUserId()); 128716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 128816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 128916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** 129016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * Notify registered observers within the designated user(s) that a row was updated. 129116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * 129216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * @hide 129316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate */ 129416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 129516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate int userHandle) { 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1297231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 129916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer != null && observer.deliverSelfNotifications(), syncToNetwork, 130016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate userHandle); 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 1320ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 1321ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13234a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 1325ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 1326ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 1327ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 1328ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 13293348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 1330ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1331ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 1332ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1333ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 1334ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1335ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1336ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1337ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 1338ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 1339ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 1340ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 1341ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 1342ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 1343ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 1344ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 1345ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 1346ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 1347ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 1348ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1349ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 1350ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 1351ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 1352ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1353ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1356ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().requestSync(account, authority, extras); 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1370d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 1386d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1397ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1398ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 1399ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 1400ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1401ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 1402ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 1403ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 14044a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 1406ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 1407ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1408ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1409ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1410ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 1411ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 1412ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 1413ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1414ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 1415ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 1416ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1417ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 1418ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1419ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 1420ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1421ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1422ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1423ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1424ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1425ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 1426ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 1427ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1428ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 1429ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1430ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 1431ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1432ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1433ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1434ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1435ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1436ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1437ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 14389530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14399530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1440ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1441ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1442ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 1443ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 1444ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1445ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 1446ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1447ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 1448ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1449ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1450ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1451ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1452ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1453ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1454ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 14559530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14569530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1457ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1458ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1459ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1460ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1461ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1462ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1464ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1466ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 14675e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 14685e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 14695e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 14705e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 14715e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 1472c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 1473c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 1474c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 1475c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 1476c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 1477c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 1478c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 1479c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 1480c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 148153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 148253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 148353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 148453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 148553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 148653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 1487c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 14889530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 14899530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 14909530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * 1491c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 1492c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 1493c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 1494c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 149553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 149653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 1497c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1498c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 1499c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 1500c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 150153bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 150253bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 150353bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 150453bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 150553bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 150653bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 150753bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 150853bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 150953bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 151053bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 151153bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 151253bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 151353bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 151453bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 151553bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1516c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1517c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 1518c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1519c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1520c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 1521c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1522c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1523c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1524c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1525c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 1526c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 15279530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15289530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1529c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1530c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 1531c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 1532c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 1533c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1534c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 1535c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 153653bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 153753bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 153853bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 153953bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 154053bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 154153bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1542c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1543c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 1544c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1545c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1546c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1547c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1548c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1549c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1550c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 15519530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15529530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1553c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1554c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 1555c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 1556c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 1557c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1558c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 155953bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (account == null) { 156053bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("account must not be null"); 156153bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 156253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (authority == null) { 156353bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("authority must not be null"); 156453bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1565c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1566c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getContentService().getPeriodicSyncs(account, authority); 1567c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1568c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1569c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1570c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1571c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1572c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 15735e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 15749530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15759530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 15765e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 15775e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 157820ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 15795e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 15805e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 15815e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 15825e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 15835e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 15845e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 15855e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 15865e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 15875e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 15889530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 15899530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1590718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 15915e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 159220ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 15935e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 15945e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 15955e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 15965e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1597ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1601ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1602ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 1603ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16049530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16059530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1606ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1607ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 1608ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1609ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 1610ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1611ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 1612ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1613ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1614ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1615ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1616ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1617ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1618ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 1619ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 16209530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16219530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1622ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1623ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 1624ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1625ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 1626ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1627ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 1628ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1629ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1630ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1631ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1632ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1633ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1634ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1635ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 1636ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 16379530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 16389530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1639ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1640ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1641ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 1642ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1643ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 1644ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1645ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 1646ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1647ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1648ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1649ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1650ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1651ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1652c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * If a sync is active returns the information about it, otherwise returns null. 1653c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * <p> 16549530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 16559530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 16569530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1657d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 1658c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @deprecated 1659c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Since multiple concurrent syncs are now supported you should use 1660c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * {@link #getCurrentSyncs()} to get the accurate list of current syncs. 1661c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * This method returns the first item from the list of current syncs 1662c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * or null if there are none. 1663ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1664c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana @Deprecated 1665d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 1666ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1667c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana final List<SyncInfo> syncs = getContentService().getCurrentSyncs(); 1668c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana if (syncs.isEmpty()) { 1669c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return null; 1670c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1671c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return syncs.get(0); 1672c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } catch (RemoteException e) { 1673c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1674c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1675c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 1676c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana 1677c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana /** 1678c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Returns a list with information about all the active syncs. This list will be empty 1679c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * if there are no active syncs. 16809530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 16819530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 16829530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 16839530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 1684c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @return a List of SyncInfo objects for the currently active syncs. 1685c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana */ 1686c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana public static List<SyncInfo> getCurrentSyncs() { 1687c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana try { 1688c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return getContentService().getCurrentSyncs(); 1689ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1690ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1691ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1692ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1693ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1694ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 16954a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 1696ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1697ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1698ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 1699ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1700ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1701ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 1702ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1703ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 1704ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1705ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1706ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1707ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1708ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1709ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1710ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 17119530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 17129530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 1713ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1714ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1715ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 1716ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1717ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 1718ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1719ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 1720ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1721ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1722ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1723ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1724ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17251b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 17261b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 17271b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 17281b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 17291b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 17301b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 17311b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 17321b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 17331b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 17341b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 17351b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 17361b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 17371b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 17381b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1739ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 17401b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 17411b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 17421b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1743ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1744ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 1745ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 1746ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 1747ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1748ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 1749ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 1750ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 1751ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1752ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1753ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1754ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1755ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 17561b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 17571b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 17581b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 17591b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 1760ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 17611b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 17621b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 17631b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 1764ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1765ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 1766ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1767ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1768ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1769ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1770ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1771ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1772a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 1773a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 1774a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 1775a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 1776a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 1777a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 1778a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 1779a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 1780a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1781a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 1782a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1783a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1784a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 1785a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 1786a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 1787a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1788a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1789a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1790a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1791a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1792a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1793a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1794a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1795a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1796a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 1797a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 1798a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 1799a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 1800a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 1801a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 1802a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 1803a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 1804a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 1805a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1806a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1807a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1808a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 1809a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 1810a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 181101e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1812a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1813a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1814a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 1815a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1816a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 1817a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1818a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 1819a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1820a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1821a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1822a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1823a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 1824a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 1825a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 1826a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 1827a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 1828a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 1829a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 1830a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 1831a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1832a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1833a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 183401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 1835a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 1836a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 1837a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 1838a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 1839a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 1840a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 1841a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 1842a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 1843a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 1844ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1845825c5132bff21e72c1448241f4c6868563c8d624Jeff Brown private final class CursorWrapperInner extends CrossProcessCursorWrapper { 184603f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 1848baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1849baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private final CloseGuard mCloseGuard = CloseGuard.get(); 1850baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private boolean mProviderReleased; 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 1855baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.open("close"); 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 1862baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mProviderReleased = true; 1863baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1864baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1865baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.close(); 1866baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1872baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 1873baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.warnIfOpen(); 1874baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 1875baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 1876baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (!mProviderReleased && mContentProvider != null) { 1877baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // Even though we are using CloseGuard, log this anyway so that 1878baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // application developers always see the message in the log. 1879872a52c6b637faf75262b83fe68ff4e0d9fe044cJohannes Carlsson Log.w(TAG, "Cursor finalized without prior close()"); 1880baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown ContentResolver.this.releaseProvider(mContentProvider); 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 188903f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 19016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ContentResolver.this.releaseProvider(mContentProvider); 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1914231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1915231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 19160ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1917231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1918231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 1919231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 1920231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1921231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1922231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 192343a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service binder = " + b); 1924231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 192543a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service = " + sContentService); 1926231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1927231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 19280ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1929231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1933