ContentResolver.java revision 3390018c6b45acffa6edf97a4174ca49f1e8c76d
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.accounts.Account; 20cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackbornimport android.app.ActivityManagerNative; 2166a017b63461a22842b3678c9520f803d5ddadfcJeff Sharkeyimport android.app.ActivityThread; 2201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.app.AppGlobals; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 27825c5132bff21e72c1448241f4c6868563c8d624Jeff Brownimport android.database.CrossProcessCursorWrapper; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 32a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal; 336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackbornimport android.os.DeadObjectException; 34231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 35a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal; 36a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.OperationCanceledException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 39231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 40d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrickimport android.os.SystemClock; 415e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackbornimport android.os.UserHandle; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 43a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.util.EventLog; 44231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 4508da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey 4608da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkeyimport dalvik.system.CloseGuard; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 5403f0292744094ec107ffce71301c394503a31dedGilles Debunneimport java.util.ArrayList; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 56a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport java.util.Random; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 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"; 74b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 75b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 76b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * If this extra is set to true, the sync request will be scheduled 77b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * at the front of the sync request queue and without any delay 78b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov */ 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 80b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 81ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 82ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 83ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 84ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 854a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 8753bd2522ca7767f46646606123b6e2689b811850Fred Quintana 8853bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 8953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the sync settings (like getSyncAutomatically()) 9053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. 9153bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9253bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_SETTINGS = "ignore_settings"; 9353bd2522ca7767f46646606123b6e2689b811850Fred Quintana 9453bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 9553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then any backoffs for the initial attempt (e.g. due to retries) 9653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. If this request fails and gets rescheduled then the 9753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * retries will still honor the backoff. 9853bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9953bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_BACKOFF = "ignore_backoff"; 10053bd2522ca7767f46646606123b6e2689b811850Fred Quintana 10153bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 10253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the request will not be retried if it fails. 10353bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 10453bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_DO_NOT_RETRY = "do_not_retry"; 10553bd2522ca7767f46646606123b6e2689b811850Fred Quintana 10653bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 10753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Setting this extra is the equivalent of setting both {@link #SYNC_EXTRAS_IGNORE_SETTINGS} 10853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * and {@link #SYNC_EXTRAS_IGNORE_BACKOFF} 10953bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 110ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 11153bd2522ca7767f46646606123b6e2689b811850Fred Quintana 112b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 113b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * Indicates that this sync is intended to only upload local changes to the server. 114b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * For example, this will be set to true if the sync is initiated by a call to 115b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)} 116b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov */ 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 118b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 119b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 120b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * Indicates that the sync adapter should proceed with the delete operations, 121b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * even if it determines that there are too many. 122b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * See {@link SyncResult#tooManyDeletions} 123b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 125b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 126b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 127b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * Indicates that the sync adapter should not proceed with the delete operations, 128b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * if it determines that there are too many. 129b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * See {@link SyncResult#tooManyDeletions} 130b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 133fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /* Extensions to API. TODO: Not clear if we will keep these as public flags. */ 134fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} User-specified flag for expected upload size. */ 135fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static final String SYNC_EXTRAS_EXPECTED_UPLOAD = "expected_upload"; 136fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 137fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} User-specified flag for expected download size. */ 138fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static final String SYNC_EXTRAS_EXPECTED_DOWNLOAD = "expected_download"; 139fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 140fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} Priority of this sync with respect to other syncs scheduled for this application. */ 141fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static final String SYNC_EXTRAS_PRIORITY = "sync_priority"; 142fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 143fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} Flag to allow sync to occur on metered network. */ 1446222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams public static final String SYNC_EXTRAS_DISALLOW_METERED = "disallow_metered"; 145fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 1464a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana /** 1474a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Set by the SyncManager to request that the SyncAdapter initialize itself for 1484a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * the given account/authority pair. One required initialization step is to 1494a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been 1504a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * called with a >= 0 value. When this flag is set the SyncAdapter does not need to 1514a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * do a full sync, though it is allowed to do so. 1524a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana */ 1534a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; 1544a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana 1557a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey /** @hide */ 1567a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static final Intent ACTION_SYNC_CONN_STATUS_CHANGED = 1577a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); 1587a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 1720ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 1760ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 1860ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 194ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 195ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 196ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 197ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 198ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 199ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 200ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 201ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 202ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 203ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 204ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 205ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 206ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 207ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 208ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 209ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 210ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 211ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 21257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private static final String[] SYNC_ERROR_NAMES = new String[] { 21357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "already-in-progress", 21457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "authentication-error", 21557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "io-error", 21657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "parse-error", 21757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "conflict", 21857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-deletions", 21957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-retries", 22057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "internal-error", 22157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert }; 22257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 22357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert /** @hide */ 2247a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static String syncErrorToString(int error) { 22557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (error < 1 || error > SYNC_ERROR_NAMES.length) { 22657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return String.valueOf(error); 22757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 22857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return SYNC_ERROR_NAMES[error - 1]; 22957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 23057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 2315c113faba6b644d1851c9281614aa0edd175fc48Alon Albert /** @hide */ 2325c113faba6b644d1851c9281614aa0edd175fc48Alon Albert public static int syncErrorStringToInt(String error) { 2335c113faba6b644d1851c9281614aa0edd175fc48Alon Albert for (int i = 0, n = SYNC_ERROR_NAMES.length; i < n; i++) { 2345c113faba6b644d1851c9281614aa0edd175fc48Alon Albert if (SYNC_ERROR_NAMES[i].equals(error)) { 2355c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return i + 1; 2365c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2375c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2385c113faba6b644d1851c9281614aa0edd175fc48Alon Albert if (error != null) { 2395c113faba6b644d1851c9281614aa0edd175fc48Alon Albert try { 2405c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return Integer.parseInt(error); 2415c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } catch (NumberFormatException e) { 2425c113faba6b644d1851c9281614aa0edd175fc48Alon Albert Log.d(TAG, "error parsing sync error: " + error); 2435c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2445c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2455c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return 0; 2465c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2475c113faba6b644d1851c9281614aa0edd175fc48Alon Albert 248ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 249ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 250ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 251ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 252ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 253ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 254ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 255ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 25625880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 257a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 2582b4d22cda3c44f5d731c15306b85045417071408Jeff Sharkey private static final boolean ENABLE_CONTENT_SAMPLE = false; 25925880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 260a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 261a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 262231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 26366a017b63461a22842b3678c9520f803d5ddadfcJeff Sharkey mContext = context != null ? context : ActivityThread.currentApplication(); 26495d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn mPackageName = mContext.getOpPackageName(); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 269e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey 270e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey /** 271e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * Providing a default implementation of this, to avoid having to change a 272e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * lot of other things, but implementations of ContentResolver should 273e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * implement it. 274e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * 275e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @hide 276e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey */ 277cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn protected IContentProvider acquireExistingProvider(Context c, String name) { 278cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireProvider(c, name); 279cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 280e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 283652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 284652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn protected abstract IContentProvider acquireUnstableProvider(Context c, String name); 285652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 286652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public abstract boolean releaseUnstableProvider(IContentProvider icp); 2876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn /** @hide */ 2886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn public abstract void unstableProviderDied(IContentProvider icp); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2907aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey /** @hide */ 2917aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey public void appNotRespondingViaProvider(IContentProvider icp) { 2927aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey throw new UnsupportedOperationException("appNotRespondingViaProvider"); 2937aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } 2947aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 30223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final String getType(Uri url) { 3036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // XXX would like to have an acquireExistingUnstableProvider for this. 304cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn IContentProvider provider = acquireExistingProvider(url); 305cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (provider != null) { 306cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn try { 307cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return provider.getType(url); 308cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (RemoteException e) { 309cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 310cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (java.lang.Exception e) { 311145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 312cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 313cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } finally { 314cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn releaseProvider(provider); 315cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 316cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 317cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 318cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(url.getScheme())) { 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 321cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3235e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn String type = ActivityManagerNative.getDefault().getProviderMimeType( 3245e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn url, UserHandle.myUserId()); 325cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return type; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 327534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 328534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 330145e6c4975536d927e506634514a06c43313df17Ola Olsson } catch (java.lang.Exception e) { 331145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 332145e6c4975536d927e506634514a06c43313df17Ola Olsson return null; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 33723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Query for the possible MIME types for the representations the given 33823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URL can be returned when opened as as stream with 33923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link #openTypedAssetFileDescriptor}. Note that the types here are 34023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * not necessarily a superset of the type returned by {@link #getType} -- 341bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * many content providers cannot return a raw stream for the structured 34223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data that they contain. 34323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 34423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param url A Uri identifying content (either a list or specific type), 34523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * using the content:// scheme. 34623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeTypeFilter The desired MIME type. This may be a pattern, 3473390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * such as */*, to query for all available MIME types that match the 34823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * pattern. 349acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns an array of MIME type strings for all available 35023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data streams that match the given mimeTypeFilter. If there are none, 35123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * null is returned. 35223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 35323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public String[] getStreamTypes(Uri url, String mimeTypeFilter) { 35423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn IContentProvider provider = acquireProvider(url); 35523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (provider == null) { 35623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 35723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 35864bbbb471ed78ae06f411224849a4556a30fd362Dianne Hackborn 35923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 36023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return provider.getStreamTypes(url, mimeTypeFilter); 36123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (RemoteException e) { 362534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 363534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 36423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 36523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 366534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 367534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 36823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 36923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 37023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 3710ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 3730ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3740ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 3750ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 3760ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 3770ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 3780ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 3790ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 3800ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 3810ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 3820ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 3830ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 3840ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 3890ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 40475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return query(uri, projection, selection, selectionArgs, sortOrder, null); 40575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 40675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 40775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 40875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 40975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Query the given URI, returning a {@link Cursor} over the result set. 41075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 41175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 41275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * For best performance, the caller should follow these guidelines: 41375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <ul> 41475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Provide an explicit projection, to prevent 41575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * reading data from storage that aren't going to be used.</li> 41675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Use question mark parameter markers such as 'phone=?' instead of 41775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * explicit values in the {@code selection} parameter, so that queries 41875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * that differ only by those values will be recognized as the same 41975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * for caching purposes.</li> 42075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </ul> 42175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 42275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 42375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param uri The URI, using the content:// scheme, for the content to 42475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * retrieve. 42575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param projection A list of which columns to return. Passing null will 42675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is inefficient. 42775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 42875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null will 42975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all rows for the given URI. 43075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 43175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in the order that they 43275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 43375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 43475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the ORDER BY itself). Passing null will use the 43575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 4364c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 43775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 43875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 43975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A Cursor object, which is positioned before the first entry, or null 44075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 44175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 44275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public final Cursor query(final Uri uri, String[] projection, 44375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown String selection, String[] selectionArgs, String sortOrder, 4444c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown CancellationSignal cancellationSignal) { 4456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 4466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 450c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown Cursor qCursor = null; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 452d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 45375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 4544c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown ICancellationSignal remoteCancellationSignal = null; 4554c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown if (cancellationSignal != null) { 4564c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.throwIfCanceled(); 4576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn remoteCancellationSignal = unstableProvider.createCancellationSignal(); 4584c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.setRemote(remoteCancellationSignal); 45975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 4606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 46135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn qCursor = unstableProvider.query(mPackageName, uri, projection, 4626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 4636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 4646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 4656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 4666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 4676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 4686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 4696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 4706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 4716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 47235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn qCursor = stableProvider.query(mPackageName, uri, projection, 4736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 4746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 475a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 478c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown 479c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // Force query execution. Might fail and throw a runtime exception here. 480020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 481d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 482a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 483c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown 484c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // Wrap the cursor object into CursorWrapperInner object. 4856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, 4866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider != null ? stableProvider : acquireProvider(uri)); 4876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 488c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown qCursor = null; 4896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return wrapper; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 491534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 492534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 495c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown if (qCursor != null) { 496c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown qCursor.close(); 497c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown } 498bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 499bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(null); 500bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 5016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 5026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 5036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 5046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 5056ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 5066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 51138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Transform the given <var>url</var> to a canonical representation of 51238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * its referenced resource, which can be used across devices, persisted, 51338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * backed up and restored, etc. The returned Uri is still a fully capable 51438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Uri for use with its content provider, allowing you to do all of the 51538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * same content provider operations as with the original Uri -- 51638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * {@link #query}, {@link #openInputStream(android.net.Uri)}, etc. The 51738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * only difference in behavior between the original and new Uris is that 51838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * the content provider may need to do some additional work at each call 51938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * using it to resolve it to the correct resource, especially if the 52038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * canonical Uri has been moved to a different environment. 52138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 52238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * <p>If you are moving a canonical Uri between environments, you should 52338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * perform another call to {@link #canonicalize} with that original Uri to 52438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * re-canonicalize it for the current environment. Alternatively, you may 52538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * want to use {@link #uncanonicalize} to transform it to a non-canonical 52638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Uri that works only in the current environment but potentially more 52738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * efficiently than the canonical representation.</p> 52838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 52938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @param url The {@link Uri} that is to be transformed to a canonical 53038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * representation. Like all resolver calls, the input can be either 53138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * a non-canonical or canonical Uri. 53238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 53338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @return Returns the official canonical representation of <var>url</var>, 53438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * or null if the content provider does not support a canonical representation 53538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * of the given Uri. Many providers may not support canonicalization of some 53638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * or all of their Uris. 53738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 53838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @see #uncanonicalize 53938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn */ 54038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn public final Uri canonicalize(Uri url) { 54138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn IContentProvider provider = acquireProvider(url); 54238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn if (provider == null) { 54338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 54438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 54538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 54638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn try { 54738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return provider.canonicalize(mPackageName, url); 54838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } catch (RemoteException e) { 54938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Arbitrary and not worth documenting, as Activity 55038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Manager will kill this process shortly anyway. 55138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 55238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } finally { 55338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn releaseProvider(provider); 55438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 55538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 55638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 55738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn /** 55838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Given a canonical Uri previously generated by {@link #canonicalize}, convert 55938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * it to its local non-canonical form. This can be useful in some cases where 56038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * you know that you will only be using the Uri in the current environment and 56138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * want to avoid any possible overhead when using it with the content 562b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * provider or want to verify that the referenced data exists at all in the 563b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * new environment. 56438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 56538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @param url The canonical {@link Uri} that is to be convered back to its 56638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * non-canonical form. 56738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 568b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * @return Returns the non-canonical representation of <var>url</var>. This will 569b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * return null if data identified by the canonical Uri can not be found in 570b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * the current environment; callers must always check for null and deal with 571b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * that by appropriately falling back to an alternative. 57238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 57338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @see #canonicalize 57438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn */ 57538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn public final Uri uncanonicalize(Uri url) { 57638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn IContentProvider provider = acquireProvider(url); 57738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn if (provider == null) { 57838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 57938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 58038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 58138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn try { 58238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return provider.uncanonicalize(mPackageName, url); 58338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } catch (RemoteException e) { 58438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Arbitrary and not worth documenting, as Activity 58538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Manager will kill this process shortly anyway. 58638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 58738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } finally { 58838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn releaseProvider(provider); 58938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 59038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 59138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 59238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn /** 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6020ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 6050ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 629bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r", null); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 6600ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 669bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode, null); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 67823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 695bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 696bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If opening with the exclusive "r" or "w" modes, the returned 697bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ParcelFileDescriptor could be a pipe or socket pair to enable streaming 698bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * of data. Opening with the "rw" mode implies a file on disk that supports 699bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * seeking. If possible, always use an exclusive mode to give the underlying 700bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link ContentProvider} the most flexibility. 701bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 702bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If you are writing a file, and need to communicate an error to the 703bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. 704bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 705bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param uri The desired URI to open. 706bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param mode The file mode to use, as per {@link ContentProvider#openFile 707bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ContentProvider.openFile}. 708bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @return Returns a new ParcelFileDescriptor pointing to the file. You 709bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * own this descriptor and are responsible for closing it when done. 710bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @throws FileNotFoundException Throws FileNotFoundException if no 711bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * file exists under the URI or the mode is invalid. 712bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @see #openAssetFileDescriptor(Uri, String) 713bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey */ 714bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey public final ParcelFileDescriptor openFileDescriptor(Uri uri, String mode) 715bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey throws FileNotFoundException { 716bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openFileDescriptor(uri, mode, null); 717bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 718bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 719bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey /** 720bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Open a raw file descriptor to access data under a URI. This 721bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 722bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * underlying {@link ContentProvider#openFile} 723bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ContentProvider.openFile()} method, so will <em>not</em> work with 724bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * providers that return sub-sections of files. If at all possible, 725bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 726bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * will receive a FileNotFoundException exception if the provider returns a 727bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * sub-section of a file. 728bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 729bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <h5>Accepts the following URI schemes:</h5> 730bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <ul> 731bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>content ({@link #SCHEME_CONTENT})</li> 732bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>file ({@link #SCHEME_FILE})</li> 733bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </ul> 734bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 735bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 736bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * on these schemes. 737bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 738bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If opening with the exclusive "r" or "w" modes, the returned 739bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ParcelFileDescriptor could be a pipe or socket pair to enable streaming 740bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * of data. Opening with the "rw" mode implies a file on disk that supports 741bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * seeking. If possible, always use an exclusive mode to give the underlying 742bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link ContentProvider} the most flexibility. 743bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 744bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If you are writing a file, and need to communicate an error to the 745bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. 7460ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 75094366313331a789440a3c077173aafcb85cabe78Ying Wang * @param cancellationSignal A signal to cancel the operation in progress, 75194366313331a789440a3c077173aafcb85cabe78Ying Wang * or null if none. If the operation is canceled, then 75294366313331a789440a3c077173aafcb85cabe78Ying Wang * {@link OperationCanceledException} will be thrown. 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 755f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich * @throws FileNotFoundException Throws FileNotFoundException if no 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 760bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey String mode, CancellationSignal cancellationSignal) throws FileNotFoundException { 761bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode, cancellationSignal); 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7650ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7700ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7770ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 78223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 78403f0292744094ec107ffce71301c394503a31dedGilles Debunne * method of the provider associated with the given URI, to retrieve any file stored there. 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 81623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note that if this function is called for read-only input (mode is "r") 81723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 8183390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * for you with a MIME type of "*/*". This allows such callers to benefit 81923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * from any built-in data conversion that a provider implements. 82023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 829bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, String mode) 830bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey throws FileNotFoundException { 831bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openAssetFileDescriptor(uri, mode, null); 832bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 833bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 834bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey /** 835bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Open a raw file descriptor to access data under a URI. This 836bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * interacts with the underlying {@link ContentProvider#openAssetFile} 837bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * method of the provider associated with the given URI, to retrieve any file stored there. 838bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 839bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <h5>Accepts the following URI schemes:</h5> 840bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <ul> 841bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>content ({@link #SCHEME_CONTENT})</li> 842bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 843bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>file ({@link #SCHEME_FILE})</li> 844bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </ul> 845bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 846bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 847bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * A Uri object can be used to reference a resource in an APK file. The 848bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Uri should be one of the following formats: 849bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <ul> 850bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li><code>android.resource://package_name/id_number</code><br/> 851bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 852bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * For example <code>com.example.myapp</code><br/> 853bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>id_number</code> is the int form of the ID.<br/> 854bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * The easiest way to construct this form is 855bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 856bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </li> 857bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li><code>android.resource://package_name/type/name</code><br/> 858bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 859bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * For example <code>com.example.myapp</code><br/> 860bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 861bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * or <code>drawable</code>. 862bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>name</code> is the string form of the resource name. That is, whatever the file 863bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * name was in your res directory, without the type extension. 864bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * The easiest way to construct this form is 865bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 866bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </li> 867bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </ul> 868bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 869bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>Note that if this function is called for read-only input (mode is "r") 870bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 8713390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * for you with a MIME type of "*/*". This allows such callers to benefit 872bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * from any built-in data conversion that a provider implements. 873bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 874bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param uri The desired URI to open. 875bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 876bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ContentProvider.openAssetFile}. 87794366313331a789440a3c077173aafcb85cabe78Ying Wang * @param cancellationSignal A signal to cancel the operation in progress, or null if 878bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * none. If the operation is canceled, then 879bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link OperationCanceledException} will be thrown. 880bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @return Returns a new ParcelFileDescriptor pointing to the file. You 881bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * own this descriptor and are responsible for closing it when done. 882bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @throws FileNotFoundException Throws FileNotFoundException of no 883bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * file exists under the URI or the mode is invalid. 884bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey */ 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 886bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey String mode, CancellationSignal cancellationSignal) throws FileNotFoundException { 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 900eb8c3f93edc826413ff4143284dec01c1061d5ccAdam Lesinski new File(uri.getPath()), ParcelFileDescriptor.parseMode(mode)); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 90323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if ("r".equals(mode)) { 904bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openTypedAssetFileDescriptor(uri, "*/*", null, cancellationSignal); 90523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } else { 9066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 9076ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 9086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 9096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 9106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 9116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 9126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 914bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey ICancellationSignal remoteCancellationSignal = null; 915bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 916bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.throwIfCanceled(); 917bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey remoteCancellationSignal = unstableProvider.createCancellationSignal(); 918bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(remoteCancellationSignal); 919bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 920bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 921652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 922bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = unstableProvider.openAssetFile( 923bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mode, remoteCancellationSignal); 924652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 925652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 926652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 927652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 9286ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 9296ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 9306ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 9316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 9326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 9336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 9346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 9356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 936652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 937bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = stableProvider.openAssetFile( 938bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mode, remoteCancellationSignal); 9396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 9406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 9416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 942652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 94323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 9446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 9466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 9476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 9486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 9496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 9506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 9516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 9536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 9546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 9556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 9576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 9586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 9606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 9616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 9626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 9636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 9646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 9656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 966bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 967bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(null); 968bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 9696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 9706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 9716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 9726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 9736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 9746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 97523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 97623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 97723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 97823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 97923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 98023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 98123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access (potentially type transformed) 98223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data from a "content:" URI. This interacts with the underlying 98323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile} method of the provider 98423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * associated with the given URI, to retrieve retrieve any appropriate 98523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream for the data stored there. 98623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 98723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 98823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with "content:" URIs, because content providers are the only facility 98923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with an associated MIME type to ensure that the returned data stream 99023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is of the desired type. 99123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 99223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>All text/* streams are encoded in UTF-8. 99323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 99423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param uri The desired URI to open. 99523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeType The desired MIME type of the returned data. This can 9963390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * be a pattern such as */*, which will allow the content provider to 99723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * select a type, though there is no way for you to determine what type 99823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it is returning. 99923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param opts Additional provider-dependent options. 100023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns a new ParcelFileDescriptor from which you can read the 100123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream from the provider. Note that this may be a pipe, meaning 100223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * you can't seek in it. The only seek you should do is if the 100323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * AssetFileDescriptor contains an offset, to move to that offset before 100423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * reading. You own this descriptor and are responsible for closing it when done. 100523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @throws FileNotFoundException Throws FileNotFoundException of no 100623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data of the desired type exists under the URI. 100723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 1008bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey public final AssetFileDescriptor openTypedAssetFileDescriptor( 1009bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey Uri uri, String mimeType, Bundle opts) throws FileNotFoundException { 1010bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openTypedAssetFileDescriptor(uri, mimeType, opts, null); 1011bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 1012bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 1013bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey /** 1014bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Open a raw file descriptor to access (potentially type transformed) 1015bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data from a "content:" URI. This interacts with the underlying 1016bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link ContentProvider#openTypedAssetFile} method of the provider 1017bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * associated with the given URI, to retrieve retrieve any appropriate 1018bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data stream for the data stored there. 1019bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 1020bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 1021bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * with "content:" URIs, because content providers are the only facility 1022bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * with an associated MIME type to ensure that the returned data stream 1023bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * is of the desired type. 1024bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 1025bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>All text/* streams are encoded in UTF-8. 1026bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 1027bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param uri The desired URI to open. 1028bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param mimeType The desired MIME type of the returned data. This can 10293390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * be a pattern such as */*, which will allow the content provider to 1030bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * select a type, though there is no way for you to determine what type 1031bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * it is returning. 1032bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param opts Additional provider-dependent options. 103394366313331a789440a3c077173aafcb85cabe78Ying Wang * @param cancellationSignal A signal to cancel the operation in progress, 103494366313331a789440a3c077173aafcb85cabe78Ying Wang * or null if none. If the operation is canceled, then 103594366313331a789440a3c077173aafcb85cabe78Ying Wang * {@link OperationCanceledException} will be thrown. 1036bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @return Returns a new ParcelFileDescriptor from which you can read the 1037bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data stream from the provider. Note that this may be a pipe, meaning 1038bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * you can't seek in it. The only seek you should do is if the 1039bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * AssetFileDescriptor contains an offset, to move to that offset before 1040bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * reading. You own this descriptor and are responsible for closing it when done. 1041bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @throws FileNotFoundException Throws FileNotFoundException of no 1042bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data of the desired type exists under the URI. 1043bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey */ 104423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri, 1045bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey String mimeType, Bundle opts, CancellationSignal cancellationSignal) 1046bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey throws FileNotFoundException { 10476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 10486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 10496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 10506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 10516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 10526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 10536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 10546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 1055bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey ICancellationSignal remoteCancellationSignal = null; 1056bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 1057bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.throwIfCanceled(); 1058bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey remoteCancellationSignal = unstableProvider.createCancellationSignal(); 1059bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(remoteCancellationSignal); 1060bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 1061bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 1062652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 1063bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = unstableProvider.openTypedAssetFile( 1064bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mimeType, opts, remoteCancellationSignal); 1065652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 1066652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 1067652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1068652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 10696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 10706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 10716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 10726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 10736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 10746ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 10756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 10766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 1077652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1078bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = stableProvider.openTypedAssetFile( 1079bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mimeType, opts, remoteCancellationSignal); 10806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 10816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 10826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 1083652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 10866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 10876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 10886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 10896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 10906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 10916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 10926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 10936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 10946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 10956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 10966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 10976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 10986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 10996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 11006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 11016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 11026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 11036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 11046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 11056ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 11066ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 1107bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 1108bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(null); 1109bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 11106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 11116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 11126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 11136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 11146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 11156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11194c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 11204c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 11214c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 11224c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 11234c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 11244c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 11254c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 11264c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11284c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 11294c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 11304c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 11314c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 11324c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 11334c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 11344c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11710ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1189d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 119035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Uri createdRow = provider.insert(mPackageName, url, values); 1191d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1192a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 1193a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1195534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1196534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12038943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 12048943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 12058943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 12068943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 12078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 12088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 12098943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 12108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 12118943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 12128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 12138943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 12148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 12158943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 12168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 12178943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 12188943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 12198943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 122003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 12218943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 12228943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 12236a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 12248943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 12256a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 12266a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 12278943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 12286a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 12296a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 12306a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 12316a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 12326a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1250d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 125135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsCreated = provider.bulkInsert(mPackageName, url, values); 1252d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1253a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 1254a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1256534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1257534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1281d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 128235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsDeleted = provider.delete(mPackageName, url, where, selectionArgs); 1283d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1284a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 1285a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1287534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1288534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 1303d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 1305534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return the number of rows updated. 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1315d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 131635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsUpdated = provider.update(mPackageName, uri, values, where, selectionArgs); 1317d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1318a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 1319a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1321534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1322534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1330f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * Call a provider-defined method. This can be used to implement 1331534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * read or write interfaces which are cheaper than using a Cursor and/or 1332534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * do not fit into the traditional table model. 1333534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * 1334534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param method provider-defined method name to call. Opaque to 1335534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * framework, but must be non-null. 1336534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param arg provider-defined String argument. May be null. 1337534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param extras provider-defined Bundle argument. May be null. 1338534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return a result Bundle, possibly null. Will be null if the ContentProvider 1339534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * does not implement call. 1340534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws NullPointerException if uri or method is null 1341534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws IllegalArgumentException if uri is not known 1342534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick */ 1343534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick public final Bundle call(Uri uri, String method, String arg, Bundle extras) { 1344534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (uri == null) { 1345534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("uri == null"); 1346534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1347534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (method == null) { 1348534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new NullPointerException("method == null"); 1349534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1350534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick IContentProvider provider = acquireProvider(uri); 1351534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (provider == null) { 1352534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new IllegalArgumentException("Unknown URI " + uri); 1353534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1354534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick try { 135535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return provider.call(mPackageName, method, arg, extras); 1356534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } catch (RemoteException e) { 1357534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1358534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 1359534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return null; 1360534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } finally { 1361534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 1362534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1363534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1364534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick 1365534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick /** 1366cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI. 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1372cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireProvider(Uri uri) { 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1376f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich final String auth = uri.getAuthority(); 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 1378f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich return acquireProvider(mContext, auth); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1384cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI if the process 1385cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * already has a reference on it. 1386cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * 1387cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @param uri The URI to a content provider 1388cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1389cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @hide 1390cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn */ 1391cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireExistingProvider(Uri uri) { 1392cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1393cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1394cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1395f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich final String auth = uri.getAuthority(); 1396cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (auth != null) { 1397f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich return acquireExistingProvider(mContext, auth); 1398cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1399cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1400cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1401cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 1402cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 14061877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1413652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Returns the content provider for the given content URI. 1414652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * 1415652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @param uri The URI to a content provider 1416652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1417652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1418652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1419652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(Uri uri) { 1420652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1421652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1422652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1423652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn String auth = uri.getAuthority(); 1424652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (auth != null) { 1425652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return acquireUnstableProvider(mContext, uri.getAuthority()); 1426652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1427652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1428652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1429652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1430652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1431652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1432652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1433652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(String name) { 1434652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (name == null) { 1435652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1436652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 14376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return acquireUnstableProvider(mContext, name); 1438652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1439652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1440652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1441718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1442718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 1443718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1444718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1445718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1446718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1447718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 1448718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1449718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 1450718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1451718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 1452718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 1453718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1454652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1455718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1456718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1457718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1458718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1459718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1460718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 1461718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1462718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 1463718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1464718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1465718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1466718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1467718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 1468718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1469718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 1470718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1471718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 1472718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 1473718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1474652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1475652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1476652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1477652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1478652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1479652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1480652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1481652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(Uri)}, but for use when you do 1482652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1483652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1484652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1485652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1486652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1487652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1488652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 14896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 14906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 14916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 14926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 14936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 14946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1495652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1496652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) { 14976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(uri); 1498652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1499652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1500652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1501652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1502652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1503652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1504652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1505652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1506652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(String)}, but for use when you do 1507652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1508652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1509652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1510652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1511652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1512652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1513652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 15146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 15156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 15166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 15176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 15186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 15196ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1520652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1521652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final ContentProviderClient acquireUnstableContentProviderClient(String name) { 15226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(name); 1523652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1524652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1525718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1526718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1527718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1528718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1529718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1530718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1546afccaa84c8d1b9aa45040ddeb0edd42ba80e80d6Christopher Tate registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId()); 154716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 154816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 154916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** @hide - designated user version */ 155016aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 155116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate ContentObserver observer, int userHandle) 155216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate { 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1554231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 155516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer.getContentObserver(), userHandle); 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 1570231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1578d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * Notify registered observers that a row was updated and attempt to sync changes 1579d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * to the network. 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 158386de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 158486de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 158586de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 158686de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 158786de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 1597d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * If syncToNetwork is true, this will attempt to schedule a local sync using the sync 1598d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * adapter that's registered for the authority of the provided uri. No account will be 1599d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * passed to the sync adapter, so all matching accounts will be synchronized. 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 160186de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 160286de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 160386de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 160486de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 160586de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 1607d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * @see #requestSync(android.accounts.Account, String, android.os.Bundle) 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 1610b7564454297ba1706670ccab0562cac6676d0a77Christopher Tate notifyChange(uri, observer, syncToNetwork, UserHandle.getCallingUserId()); 161116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 161216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 161316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** 161416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * Notify registered observers within the designated user(s) that a row was updated. 161516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * 161616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * @hide 161716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate */ 161816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 161916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate int userHandle) { 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1621231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 162316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer != null && observer.deliverSelfNotifications(), syncToNetwork, 162416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate userHandle); 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1630adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Take a persistable URI permission grant that has been offered. Once 1631e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * taken, the permission grant will be remembered across device reboots. 1632adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Only URI permissions granted with 1633e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION} can be persisted. If 1634e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * the grant has already been persisted, taking it again will touch 1635e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link UriPermission#getPersistedTime()}. 163608da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey * 1637e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #getPersistedUriPermissions() 163808da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey */ 1639e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey public void takePersistableUriPermission(Uri uri, int modeFlags) { 164008da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey try { 1641e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey ActivityManagerNative.getDefault().takePersistableUriPermission(uri, modeFlags); 164208da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } catch (RemoteException e) { 164308da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 164408da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 164508da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey 164608da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey /** 1647adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Relinquish a persisted URI permission grant. The URI must have been 1648e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * previously made persistent with 1649e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link #takePersistableUriPermission(Uri, int)}. Any non-persistent 1650e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * grants to the calling package will remain intact. 165108da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey * 1652e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #getPersistedUriPermissions() 1653e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey */ 1654e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey public void releasePersistableUriPermission(Uri uri, int modeFlags) { 1655e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey try { 1656e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey ActivityManagerNative.getDefault().releasePersistableUriPermission(uri, modeFlags); 1657e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey } catch (RemoteException e) { 1658e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey } 1659e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey } 1660e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey 1661e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey /** 1662adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Return list of all URI permission grants that have been persisted by the 1663bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * calling app. That is, the returned permissions have been granted 1664bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * <em>to</em> the calling app. Only persistable grants taken with 1665e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link #takePersistableUriPermission(Uri, int)} are returned. 166608da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey * 1667e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #takePersistableUriPermission(Uri, int) 1668e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #releasePersistableUriPermission(Uri, int) 166908da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey */ 1670e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey public List<UriPermission> getPersistedUriPermissions() { 167108da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey try { 1672bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey return ActivityManagerNative.getDefault() 1673bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey .getPersistedUriPermissions(mPackageName, true).getList(); 1674bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey } catch (RemoteException e) { 1675bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey throw new RuntimeException("Activity manager has died", e); 1676bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey } 1677bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey } 1678bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey 1679bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey /** 1680adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Return list of all persisted URI permission grants that are hosted by the 1681bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * calling app. That is, the returned permissions have been granted 1682bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * <em>from</em> the calling app. Only grants taken with 1683bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * {@link #takePersistableUriPermission(Uri, int)} are returned. 1684bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey */ 1685bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey public List<UriPermission> getOutgoingPersistedUriPermissions() { 1686bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey try { 1687bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey return ActivityManagerNative.getDefault() 1688bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey .getPersistedUriPermissions(mPackageName, false).getList(); 168908da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } catch (RemoteException e) { 1690e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey throw new RuntimeException("Activity manager has died", e); 169108da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 169208da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 169308da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey 169408da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey /** 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1705fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>Account</li> 1706fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>null</li> 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 1711ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 1712ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17144a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 1716ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 1717ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 1718ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 1719ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 17203348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 1721ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1722ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 1723ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1724ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 1725ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1726ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1727ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1728ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 1729ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 1730ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 1731ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 1732ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 1733ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 1734ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 1735ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 1736ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 1737ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 1738fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>Account</li> 1739fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>null</li> 1740ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 1741ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1742ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 1743ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 1744ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 1745ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1746ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 1747d8abd6a163f8ab4332b88035e77080c48b4b71b9Matthew Williams if (extras == null) { 1748d8abd6a163f8ab4332b88035e77080c48b4b71b9Matthew Williams throw new IllegalArgumentException("Must specify extras."); 1749d8abd6a163f8ab4332b88035e77080c48b4b71b9Matthew Williams } 1750fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams SyncRequest request = 1751fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams new SyncRequest.Builder() 1752fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams .setSyncAdapter(account, authority) 1753fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams .setExtras(extras) 17546222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams .syncOnce() 1755fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams .build(); 1756fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams requestSync(request); 1757fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 1758fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 1759fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** 1760fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * Register a sync with the SyncManager. These requests are built using the 1761fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * {@link SyncRequest.Builder}. 17626222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams * 17636222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams * @param request The immutable SyncRequest object containing the sync parameters. Use 17646222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams * {@link SyncRequest.Builder} to construct these. 1765fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams */ 1766fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static void requestSync(SyncRequest request) { 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1768fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams getContentService().sync(request); 1769fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } catch(RemoteException e) { 1770fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Shouldn't happen. 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1783d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 1799d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1810ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1811ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 1812ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 1813ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1814ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 1815ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 1816ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 18174a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 1819ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 1820ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1821ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1822ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1823ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 1824ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 1825ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 1826ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1827ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 1828ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 1829ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1830ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 1831ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1832ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 1833ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1834ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1835ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1836ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1837ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1838ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 1839ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 1840ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1841ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 1842ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1843ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 1844ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1845ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1846ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1847ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1848ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1849ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1850ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 18519530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 18529530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1853ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1854ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1855ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 1856ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 1857ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1858ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 1859ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1860ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 1861ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1862ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1863ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1864ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1865ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1866ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1867ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 18689530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 18699530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1870ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1871ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1872ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1873ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1874ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1875ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1877ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1879ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 18805e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 18815e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 18825e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 18835e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 18845e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 1885c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 1886c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 1887c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 1888c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 1889c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 1890c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 1891c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 1892c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 1893c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 189453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 189553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 189653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 189753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 189853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 189953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 19006222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams * <p>As of API level 19 this function introduces a default flexibility of ~4% (up to a maximum 19016222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams * of one hour in the day) into the requested period. Use 19026222288bfbae46550b4914ef1eb12c69dc1f716cMatthew Williams * {@link SyncRequest.Builder#syncPeriodic(long, long)} to set this flexibility manually. 1903c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 19049530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 19059530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 19069530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * 1907c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 1908c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 1909c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 1910c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 191153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 191253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 1913c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1914c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 1915c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 1916c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 191753bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 191853bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 191953bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 192053bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 192153bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 192253bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 192353bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 192453bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 192553bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 1926c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1927fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 1928c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1929c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1930c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 1931c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1932c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1933c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1934c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1935c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 1936c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 19379530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 19389530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1939c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1940c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 1941c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 1942c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 1943c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1944c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 1945c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 1946c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1947c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 1948c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1949c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1950c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1951c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1952c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1953c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 1954c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 19559530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 19569530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1957c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 1958c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 1959c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 1960c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 1961c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 1962c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 1963c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 1964c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getContentService().getPeriodicSyncs(account, authority); 1965c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 1966c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1967c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1968c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 1969c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 1970c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 19715e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 19729530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 19739530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 19745e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 19755e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 197620ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 19775e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 19785e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 19795e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 19805e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 19815e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 19825e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 19835e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 19845e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 19855e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 19869530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 19879530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1988718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 19895e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 199020ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 19915e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 19925e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 19935e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 19945e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1995ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 2000ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 2001ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 20029530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 20039530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 2004ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 2005ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 2006ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2007ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 2008ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2009ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 2010ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2011ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2012ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2013ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2014ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2015ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 2016ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 2017ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 20189530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 20199530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 2020ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 2021ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 2022ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2023ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 2024ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2025ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 2026ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2027ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 2028ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 2029ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2030ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2031ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2032ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 2033ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 2034ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 20359530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 20369530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 2037ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 2038ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 2039ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 2040ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2041ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 2042ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2043ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 2044ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2045ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2046ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2047ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2048ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2049ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 2050c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * If a sync is active returns the information about it, otherwise returns null. 2051c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * <p> 20529530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 20539530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 20549530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 2055d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 2056c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @deprecated 2057c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Since multiple concurrent syncs are now supported you should use 2058c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * {@link #getCurrentSyncs()} to get the accurate list of current syncs. 2059c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * This method returns the first item from the list of current syncs 2060c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * or null if there are none. 2061ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2062c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana @Deprecated 2063d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 2064ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2065c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana final List<SyncInfo> syncs = getContentService().getCurrentSyncs(); 2066c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana if (syncs.isEmpty()) { 2067c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return null; 2068c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 2069c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return syncs.get(0); 2070c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } catch (RemoteException e) { 2071c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2072c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 2073c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 2074c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana 2075c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana /** 2076c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Returns a list with information about all the active syncs. This list will be empty 2077c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * if there are no active syncs. 20789530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 20799530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 20809530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 20819530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 2082c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @return a List of SyncInfo objects for the currently active syncs. 2083c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana */ 2084c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana public static List<SyncInfo> getCurrentSyncs() { 2085c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana try { 2086c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return getContentService().getCurrentSyncs(); 2087ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2088ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2089ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2090ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2091ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2092ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 20934a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 2094ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 2095ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 2096ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 2097ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 2098ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2099ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 2100ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2101ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 2102ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2103ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2104ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2105ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2106ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2107ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 2108ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 21099530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 21109530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 2111ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 2112ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 2113ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 2114ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2115ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 2116ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2117ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 2118ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2119ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2120ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2121ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2122ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 21231b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 21241b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 21251b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 21261b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 21271b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 21281b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 21291b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 21301b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 21311b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 21321b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 21331b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 21341b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 21351b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 21361b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 2137ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 21381b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 21391b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 21401b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 2141ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2142ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 2143ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 2144ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 2145ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2146ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 2147ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 2148ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 2149ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2150ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2151ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2152ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2153ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 21541b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 21551b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 21561b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 21571b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 2158ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 21591b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 21601b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 21611b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 2162ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2163ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 2164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 2166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 2167ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2168ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2169ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2170a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 2171a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 2172a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 2173a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 2174a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 2175a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 2176a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 2177a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 2178a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2179a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 2180a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2181a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2182a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 2183a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 2184a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 21852b4d22cda3c44f5d731c15306b85045417071408Jeff Sharkey if (!ENABLE_CONTENT_SAMPLE) return; 2186a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 2187a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 2188a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 2189a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 2190a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 2191a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2192a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2193a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2194a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2195a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 2196a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 2197a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 2198a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 2199a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 2200a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 2201a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 2202a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 2203a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 2204a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2205a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2206a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2207a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 2208a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 2209a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 221001e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 2211a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2212a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 2213a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 2214a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 2215a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 2216a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 2217a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 2218a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 2219a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 2220a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 2221a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2222a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2223a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 2224a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 22252b4d22cda3c44f5d731c15306b85045417071408Jeff Sharkey if (!ENABLE_CONTENT_SAMPLE) return; 2226a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 2227a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 2228a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 2229a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 2230a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 2231a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2232a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2233a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 223401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 2235a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 2236a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 2237a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 2238a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 2239a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 2240a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 2241a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 2242a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 2243a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2244ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2245825c5132bff21e72c1448241f4c6868563c8d624Jeff Brown private final class CursorWrapperInner extends CrossProcessCursorWrapper { 224603f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 2248baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 2249baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private final CloseGuard mCloseGuard = CloseGuard.get(); 2250baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private boolean mProviderReleased; 22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 2255baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.open("close"); 22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 2262baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mProviderReleased = true; 2263baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 2264baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 2265baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.close(); 2266baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2272baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 2273baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.warnIfOpen(); 2274baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 2275baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 2276baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (!mProviderReleased && mContentProvider != null) { 2277baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // Even though we are using CloseGuard, log this anyway so that 2278baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // application developers always see the message in the log. 2279872a52c6b637faf75262b83fe68ff4e0d9fe044cJohannes Carlsson Log.w(TAG, "Cursor finalized without prior close()"); 2280baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown ContentResolver.this.releaseProvider(mContentProvider); 22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 228903f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 2290da5a3e12f4f8f965c57d6f93c74190f43ea233f3Jeff Sharkey private boolean mProviderReleased; 22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2298487c11a3101c6cd9fc18758b3032383666f55e46Amith Yamasani public void releaseResources() { 2299da5a3e12f4f8f965c57d6f93c74190f43ea233f3Jeff Sharkey if (!mProviderReleased) { 23006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ContentResolver.this.releaseProvider(mContentProvider); 2301da5a3e12f4f8f965c57d6f93c74190f43ea233f3Jeff Sharkey mProviderReleased = true; 23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2306231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 2307231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 23080ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 2309231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 2310231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 2311231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 2312231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 2313231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2314231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 231543a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service binder = " + b); 2316231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 231743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service = " + sContentService); 2318231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 2319231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 23200ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 232135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn /** @hide */ 232235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public String getPackageName() { 232335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return mPackageName; 232435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 232535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 2326231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 232835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final String mPackageName; 23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2331