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; 20673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkeyimport android.annotation.NonNull; 219f78f6528f1afad260be51d2058c37717851e3a2Scott Kennedyimport android.annotation.Nullable; 22cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackbornimport android.app.ActivityManagerNative; 2366a017b63461a22842b3678c9520f803d5ddadfcJeff Sharkeyimport android.app.ActivityThread; 2401e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackbornimport android.app.AppGlobals; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 29825c5132bff21e72c1448241f4c6868563c8d624Jeff Brownimport android.database.CrossProcessCursorWrapper; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 325b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkeyimport android.graphics.Point; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 35a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal; 366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackbornimport android.os.DeadObjectException; 37231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 38a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal; 39a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.OperationCanceledException; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 42231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 43d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrickimport android.os.SystemClock; 445e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackbornimport android.os.UserHandle; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 46a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport android.util.EventLog; 47231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 4808da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey 4908da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkeyimport dalvik.system.CloseGuard; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5137a40c24deb02bca3868a8085069afae112f22e4Amith Yamasaniimport com.android.internal.util.ArrayUtils; 52673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkeyimport com.android.internal.util.Preconditions; 53673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 6003f0292744094ec107ffce71301c394503a31dedGilles Debunneimport java.util.ArrayList; 6137a40c24deb02bca3868a8085069afae112f22e4Amith Yamasaniimport java.util.Collections; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 63a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrickimport java.util.Random; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides applications access to the content model. 67558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * 68558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <div class="special reference"> 69558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <h3>Developer Guides</h3> 70558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <p>For more information about using a ContentResolver with content providers, read the 71558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> 72558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * developer guide.</p> 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentResolver { 75ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 76ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 77ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 78ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 794a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 80ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_ACCOUNT = "account"; 81b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 82b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 83b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * If this extra is set to true, the sync request will be scheduled 84b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * at the front of the sync request queue and without any delay 85b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 87b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 88ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 89ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 90ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 91ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 924a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana @Deprecated 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 9453bd2522ca7767f46646606123b6e2689b811850Fred Quintana 9553bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 9653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the sync settings (like getSyncAutomatically()) 9753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. 9853bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 9953bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_SETTINGS = "ignore_settings"; 10053bd2522ca7767f46646606123b6e2689b811850Fred Quintana 10153bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 10253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then any backoffs for the initial attempt (e.g. due to retries) 10353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are ignored by the sync scheduler. If this request fails and gets rescheduled then the 10453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * retries will still honor the backoff. 10553bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 10653bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_IGNORE_BACKOFF = "ignore_backoff"; 10753bd2522ca7767f46646606123b6e2689b811850Fred Quintana 10853bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 10953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If this extra is set to true then the request will not be retried if it fails. 11053bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 11153bd2522ca7767f46646606123b6e2689b811850Fred Quintana public static final String SYNC_EXTRAS_DO_NOT_RETRY = "do_not_retry"; 11253bd2522ca7767f46646606123b6e2689b811850Fred Quintana 11353bd2522ca7767f46646606123b6e2689b811850Fred Quintana /** 11453bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Setting this extra is the equivalent of setting both {@link #SYNC_EXTRAS_IGNORE_SETTINGS} 11553bd2522ca7767f46646606123b6e2689b811850Fred Quintana * and {@link #SYNC_EXTRAS_IGNORE_BACKOFF} 11653bd2522ca7767f46646606123b6e2689b811850Fred Quintana */ 117ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 11853bd2522ca7767f46646606123b6e2689b811850Fred Quintana 119b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 120b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * Indicates that this sync is intended to only upload local changes to the server. 121b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * For example, this will be set to true if the sync is initiated by a call to 122b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)} 123b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 125b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 126b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 127b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * Indicates that the sync adapter should proceed with the delete operations, 128b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * even 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_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 132b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov 133b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov /** 134b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * Indicates that the sync adapter should not proceed with the delete operations, 135b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * if it determines that there are too many. 136b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov * See {@link SyncResult#tooManyDeletions} 137b3395575a3441d9339423a4e624cb9806dd07a49Georgi Nikolov */ 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 140fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /* Extensions to API. TODO: Not clear if we will keep these as public flags. */ 141fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} User-specified flag for expected upload size. */ 142fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static final String SYNC_EXTRAS_EXPECTED_UPLOAD = "expected_upload"; 143fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 144fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} User-specified flag for expected download size. */ 145fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static final String SYNC_EXTRAS_EXPECTED_DOWNLOAD = "expected_download"; 146fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 147fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} Priority of this sync with respect to other syncs scheduled for this application. */ 148fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static final String SYNC_EXTRAS_PRIORITY = "sync_priority"; 149fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 150fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** {@hide} Flag to allow sync to occur on metered network. */ 15156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public static final String SYNC_EXTRAS_DISALLOW_METERED = "allow_metered"; 152fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 1534a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana /** 1544a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Set by the SyncManager to request that the SyncAdapter initialize itself for 1554a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * the given account/authority pair. One required initialization step is to 1564a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been 1574a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * called with a >= 0 value. When this flag is set the SyncAdapter does not need to 1584a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * do a full sync, though it is allowed to do so. 1594a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana */ 1604a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; 1614a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana 1627a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey /** @hide */ 1637a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static final Intent ACTION_SYNC_CONN_STATUS_CHANGED = 1647a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); 1657a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1715b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey * An extra {@link Point} describing the optimal size for a requested image 1725b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey * resource, in pixels. If a provider has multiple sizes of the image, it 1735b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey * should return the image closest to this size. 1745b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey * 1755b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey * @see #openTypedAssetFileDescriptor(Uri, String, Bundle) 1765b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey * @see #openTypedAssetFileDescriptor(Uri, String, Bundle, 1775b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey * CancellationSignal) 1785b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey */ 1795b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey public static final String EXTRA_SIZE = "android.content.extra.SIZE"; 1805b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey 1815b836f29a3f56f9d13b6004417330c41ec0c18aeJeff Sharkey /** 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 1900ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 1940ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 2040ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 212ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 213bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey /** 214bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey * This is the Android platform's generic MIME type to match any MIME 215bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey * type of the form "{@link #CURSOR_ITEM_BASE_TYPE}/{@code SUB_TYPE}". 216bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey * {@code SUB_TYPE} is the sub-type of the application-dependent 217bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey * content, e.g., "audio", "video", "playlist". 218bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey */ 219bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey public static final String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*"; 220bd7bcf0fba1a991e80ea279b090aa584707fdabfMatt Casey 221ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 222ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 223ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 224ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 225ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 226ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 227ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 228ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 229ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 230ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 231ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 232ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 233ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 234ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 235ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 236ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 237ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 23857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert private static final String[] SYNC_ERROR_NAMES = new String[] { 23957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "already-in-progress", 24057286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "authentication-error", 24157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "io-error", 24257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "parse-error", 24357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "conflict", 24457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-deletions", 24557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "too-many-retries", 24657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert "internal-error", 24757286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert }; 24857286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 24957286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert /** @hide */ 2507a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public static String syncErrorToString(int error) { 25157286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert if (error < 1 || error > SYNC_ERROR_NAMES.length) { 25257286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return String.valueOf(error); 25357286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 25457286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert return SYNC_ERROR_NAMES[error - 1]; 25557286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert } 25657286f970641493b315b0b42aba7ac6b672cc8b8Alon Albert 2575c113faba6b644d1851c9281614aa0edd175fc48Alon Albert /** @hide */ 2585c113faba6b644d1851c9281614aa0edd175fc48Alon Albert public static int syncErrorStringToInt(String error) { 2595c113faba6b644d1851c9281614aa0edd175fc48Alon Albert for (int i = 0, n = SYNC_ERROR_NAMES.length; i < n; i++) { 2605c113faba6b644d1851c9281614aa0edd175fc48Alon Albert if (SYNC_ERROR_NAMES[i].equals(error)) { 2615c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return i + 1; 2625c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2635c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2645c113faba6b644d1851c9281614aa0edd175fc48Alon Albert if (error != null) { 2655c113faba6b644d1851c9281614aa0edd175fc48Alon Albert try { 2665c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return Integer.parseInt(error); 2675c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } catch (NumberFormatException e) { 2685c113faba6b644d1851c9281614aa0edd175fc48Alon Albert Log.d(TAG, "error parsing sync error: " + error); 2695c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2705c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2715c113faba6b644d1851c9281614aa0edd175fc48Alon Albert return 0; 2725c113faba6b644d1851c9281614aa0edd175fc48Alon Albert } 2735c113faba6b644d1851c9281614aa0edd175fc48Alon Albert 274ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 275ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 276ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 277ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 278ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 279ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 280ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 281ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 28225880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick // Always log queries which take 500ms+; shorter queries are 283a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // sampled accordingly. 2842b4d22cda3c44f5d731c15306b85045417071408Jeff Sharkey private static final boolean ENABLE_CONTENT_SAMPLE = false; 28525880968cbde25c9edb162c0d70d45dc75239456Brad Fitzpatrick private static final int SLOW_THRESHOLD_MILLIS = 500; 286a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private final Random mRandom = new Random(); // guarded by itself 287a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 288231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 28966a017b63461a22842b3678c9520f803d5ddadfcJeff Sharkey mContext = context != null ? context : ActivityThread.currentApplication(); 29095d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn mPackageName = mContext.getOpPackageName(); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 295e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey 296e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey /** 297e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * Providing a default implementation of this, to avoid having to change a 298e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * lot of other things, but implementations of ContentResolver should 299e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * implement it. 300e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * 301e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @hide 302e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey */ 303cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn protected IContentProvider acquireExistingProvider(Context c, String name) { 304cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return acquireProvider(c, name); 305cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 306e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 309652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 310652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn protected abstract IContentProvider acquireUnstableProvider(Context c, String name); 311652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** @hide */ 312652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public abstract boolean releaseUnstableProvider(IContentProvider icp); 3136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn /** @hide */ 3146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn public abstract void unstableProviderDied(IContentProvider icp); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3167aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey /** @hide */ 3177aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey public void appNotRespondingViaProvider(IContentProvider icp) { 3187aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey throw new UnsupportedOperationException("appNotRespondingViaProvider"); 3197aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } 3207aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 328673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable String getType(@NonNull Uri url) { 329673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(url, "url"); 330673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey 3316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // XXX would like to have an acquireExistingUnstableProvider for this. 332cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn IContentProvider provider = acquireExistingProvider(url); 333cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (provider != null) { 334cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn try { 335cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return provider.getType(url); 336cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (RemoteException e) { 337cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 338cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } catch (java.lang.Exception e) { 339145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 340cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 341cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } finally { 342cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn releaseProvider(provider); 343cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 344cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 345cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 346cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(url.getScheme())) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 349cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3515e03e2ca7d25b899b129baad2dd5eca6bf99d88aDianne Hackborn String type = ActivityManagerNative.getDefault().getProviderMimeType( 3521dddc7fc790f14208516b4551ff12b2db8528864Nicolas Prevot ContentProvider.getUriWithoutUserId(url), resolveUserId(url)); 353cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return type; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 355534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 356534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 358145e6c4975536d927e506634514a06c43313df17Ola Olsson } catch (java.lang.Exception e) { 359145e6c4975536d927e506634514a06c43313df17Ola Olsson Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")"); 360145e6c4975536d927e506634514a06c43313df17Ola Olsson return null; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 36523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Query for the possible MIME types for the representations the given 36623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URL can be returned when opened as as stream with 36723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link #openTypedAssetFileDescriptor}. Note that the types here are 36823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * not necessarily a superset of the type returned by {@link #getType} -- 369bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * many content providers cannot return a raw stream for the structured 37023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data that they contain. 37123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 37223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param url A Uri identifying content (either a list or specific type), 37323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * using the content:// scheme. 37423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeTypeFilter The desired MIME type. This may be a pattern, 3753390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * such as */*, to query for all available MIME types that match the 37623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * pattern. 377acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns an array of MIME type strings for all available 37823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data streams that match the given mimeTypeFilter. If there are none, 37923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * null is returned. 38023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 381673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public @Nullable String[] getStreamTypes(@NonNull Uri url, @NonNull String mimeTypeFilter) { 382673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(url, "url"); 383673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(mimeTypeFilter, "mimeTypeFilter"); 384673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey 38523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn IContentProvider provider = acquireProvider(url); 38623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (provider == null) { 38723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 38823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 38964bbbb471ed78ae06f411224849a4556a30fd362Dianne Hackborn 39023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 39123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return provider.getStreamTypes(url, mimeTypeFilter); 39223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (RemoteException e) { 393534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 394534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 39523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return null; 39623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 397534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 398534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 39923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 40023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 40123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 4030ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <p> 4040ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * For best performance, the caller should follow these guidelines: 4050ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <ul> 4060ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Provide an explicit projection, to prevent 4070ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * reading data from storage that aren't going to be used.</li> 4080ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * <li>Use question mark parameter markers such as 'phone=?' instead of 4090ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * explicit values in the {@code selection} parameter, so that queries 4100ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * that differ only by those values will be recognized as the same 4110ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * for caching purposes.</li> 4120ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </ul> 4130ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * </p> 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 4180ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * return all columns, which is inefficient. 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 431673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection, 432673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable String selection, @Nullable String[] selectionArgs, 433673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable String sortOrder) { 43475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return query(uri, projection, selection, selectionArgs, sortOrder, null); 43575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 43675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 43775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 438c64ff3782c71ce7b5a92b7d91199a922ea0a37d9Jeff Brown * Query the given URI, returning a {@link Cursor} over the result set 439c64ff3782c71ce7b5a92b7d91199a922ea0a37d9Jeff Brown * with optional support for cancellation. 44075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <p> 44175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * For best performance, the caller should follow these guidelines: 44275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <ul> 44375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Provide an explicit projection, to prevent 44475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * reading data from storage that aren't going to be used.</li> 44575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * <li>Use question mark parameter markers such as 'phone=?' instead of 44675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * explicit values in the {@code selection} parameter, so that queries 44775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * that differ only by those values will be recognized as the same 44875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * for caching purposes.</li> 44975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </ul> 45075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * </p> 45175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 45275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param uri The URI, using the content:// scheme, for the content to 45375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * retrieve. 45475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param projection A list of which columns to return. Passing null will 45575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is inefficient. 45675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 45775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null will 45875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all rows for the given URI. 45975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 46075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in the order that they 46175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 46275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 46375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the ORDER BY itself). Passing null will use the 46475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 4654c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 46675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 46775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 46875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A Cursor object, which is positioned before the first entry, or null 46975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 47075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 471673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable Cursor query(final @NonNull Uri uri, @Nullable String[] projection, 472673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable String selection, @Nullable String[] selectionArgs, 473673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable String sortOrder, @Nullable CancellationSignal cancellationSignal) { 474673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 4756ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 4766ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 480c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown Cursor qCursor = null; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 482d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 48375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 4844c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown ICancellationSignal remoteCancellationSignal = null; 4854c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown if (cancellationSignal != null) { 4864c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.throwIfCanceled(); 4876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn remoteCancellationSignal = unstableProvider.createCancellationSignal(); 4884c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown cancellationSignal.setRemote(remoteCancellationSignal); 48975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 4906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 49135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn qCursor = unstableProvider.query(mPackageName, uri, projection, 4926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 4936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 4946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 4956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 4966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 4976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 4986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 4996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 5006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 5016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 50235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn qCursor = stableProvider.query(mPackageName, uri, projection, 5036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn selection, selectionArgs, sortOrder, remoteCancellationSignal); 5046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 505a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (qCursor == null) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 508c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown 509c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // Force query execution. Might fail and throw a runtime exception here. 510020e5345795a157d7829ebbe4d7864595dafc576Vasu Nori qCursor.getCount(); 511d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 512a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder); 513c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown 514c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown // Wrap the cursor object into CursorWrapperInner object. 5156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, 5166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider != null ? stableProvider : acquireProvider(uri)); 5176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 518c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown qCursor = null; 5196ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return wrapper; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 521534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 522534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 525c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown if (qCursor != null) { 526c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown qCursor.close(); 527c21b5a019c1da00b6d861cd2859e3c349a44b3a7Jeff Brown } 528bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 529bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(null); 530bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 5316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 5326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 5336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 5346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 5356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 5366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5408943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 54138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Transform the given <var>url</var> to a canonical representation of 54238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * its referenced resource, which can be used across devices, persisted, 54338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * backed up and restored, etc. The returned Uri is still a fully capable 54438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Uri for use with its content provider, allowing you to do all of the 54538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * same content provider operations as with the original Uri -- 54638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * {@link #query}, {@link #openInputStream(android.net.Uri)}, etc. The 54738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * only difference in behavior between the original and new Uris is that 54838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * the content provider may need to do some additional work at each call 54938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * using it to resolve it to the correct resource, especially if the 55038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * canonical Uri has been moved to a different environment. 55138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 55238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * <p>If you are moving a canonical Uri between environments, you should 55338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * perform another call to {@link #canonicalize} with that original Uri to 55438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * re-canonicalize it for the current environment. Alternatively, you may 55538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * want to use {@link #uncanonicalize} to transform it to a non-canonical 55638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Uri that works only in the current environment but potentially more 55738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * efficiently than the canonical representation.</p> 55838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 55938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @param url The {@link Uri} that is to be transformed to a canonical 56038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * representation. Like all resolver calls, the input can be either 56138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * a non-canonical or canonical Uri. 56238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 56338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @return Returns the official canonical representation of <var>url</var>, 56438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * or null if the content provider does not support a canonical representation 56538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * of the given Uri. Many providers may not support canonicalization of some 56638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * or all of their Uris. 56738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 56838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @see #uncanonicalize 56938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn */ 570673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable Uri canonicalize(@NonNull Uri url) { 571673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(url, "url"); 57238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn IContentProvider provider = acquireProvider(url); 57338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn if (provider == null) { 57438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 57538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 57638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 57738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn try { 57838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return provider.canonicalize(mPackageName, url); 57938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } catch (RemoteException e) { 58038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Arbitrary and not worth documenting, as Activity 58138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Manager will kill this process shortly anyway. 58238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 58338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } finally { 58438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn releaseProvider(provider); 58538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 58638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 58738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 58838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn /** 58938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * Given a canonical Uri previously generated by {@link #canonicalize}, convert 59038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * it to its local non-canonical form. This can be useful in some cases where 59138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * you know that you will only be using the Uri in the current environment and 59238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * want to avoid any possible overhead when using it with the content 593b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * provider or want to verify that the referenced data exists at all in the 594b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * new environment. 59538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 59638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @param url The canonical {@link Uri} that is to be convered back to its 59738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * non-canonical form. 59838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 599b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * @return Returns the non-canonical representation of <var>url</var>. This will 600b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * return null if data identified by the canonical Uri can not be found in 601b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * the current environment; callers must always check for null and deal with 602b3ac67a0ece71bcf484dd92914dc3599dadffb05Dianne Hackborn * that by appropriately falling back to an alternative. 60338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * 60438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn * @see #canonicalize 60538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn */ 606673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable Uri uncanonicalize(@NonNull Uri url) { 607673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(url, "url"); 60838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn IContentProvider provider = acquireProvider(url); 60938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn if (provider == null) { 61038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 61138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 61238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 61338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn try { 61438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return provider.uncanonicalize(mPackageName, url); 61538ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } catch (RemoteException e) { 61638ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Arbitrary and not worth documenting, as Activity 61738ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn // Manager will kill this process shortly anyway. 61838ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn return null; 61938ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } finally { 62038ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn releaseProvider(provider); 62138ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 62238ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn } 62338ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn 62438ed2a471a2291383821fb187bfa18450f0581c2Dianne Hackborn /** 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6340ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 6370ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 643673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable InputStream openInputStream(@NonNull Uri uri) 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 645673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 662bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r", null); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 676673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable OutputStream openOutputStream(@NonNull Uri uri) 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 6930ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 700673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable OutputStream openOutputStream(@NonNull Uri uri, @NonNull String mode) 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 702bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode, null); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 71123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 728bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 729bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If opening with the exclusive "r" or "w" modes, the returned 730bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ParcelFileDescriptor could be a pipe or socket pair to enable streaming 731bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * of data. Opening with the "rw" mode implies a file on disk that supports 732bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * seeking. If possible, always use an exclusive mode to give the underlying 733bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link ContentProvider} the most flexibility. 734bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 735bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If you are writing a file, and need to communicate an error to the 736bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. 737bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 738bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param uri The desired URI to open. 739bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param mode The file mode to use, as per {@link ContentProvider#openFile 740bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ContentProvider.openFile}. 741bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @return Returns a new ParcelFileDescriptor pointing to the file. You 742bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * own this descriptor and are responsible for closing it when done. 743bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @throws FileNotFoundException Throws FileNotFoundException if no 744bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * file exists under the URI or the mode is invalid. 745bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @see #openAssetFileDescriptor(Uri, String) 746bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey */ 747673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable ParcelFileDescriptor openFileDescriptor(@NonNull Uri uri, 748673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String mode) throws FileNotFoundException { 749bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openFileDescriptor(uri, mode, null); 750bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 751bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 752bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey /** 753bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Open a raw file descriptor to access data under a URI. This 754bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 755bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * underlying {@link ContentProvider#openFile} 756bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ContentProvider.openFile()} method, so will <em>not</em> work with 757bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * providers that return sub-sections of files. If at all possible, 758bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 759bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * will receive a FileNotFoundException exception if the provider returns a 760bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * sub-section of a file. 761bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 762bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <h5>Accepts the following URI schemes:</h5> 763bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <ul> 764bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>content ({@link #SCHEME_CONTENT})</li> 765bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>file ({@link #SCHEME_FILE})</li> 766bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </ul> 767bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 768bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 769bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * on these schemes. 770bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 771bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If opening with the exclusive "r" or "w" modes, the returned 772bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ParcelFileDescriptor could be a pipe or socket pair to enable streaming 773bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * of data. Opening with the "rw" mode implies a file on disk that supports 774bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * seeking. If possible, always use an exclusive mode to give the underlying 775bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link ContentProvider} the most flexibility. 776bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 777bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * If you are writing a file, and need to communicate an error to the 778bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. 7790ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill * 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 78394366313331a789440a3c077173aafcb85cabe78Ying Wang * @param cancellationSignal A signal to cancel the operation in progress, 78494366313331a789440a3c077173aafcb85cabe78Ying Wang * or null if none. If the operation is canceled, then 78594366313331a789440a3c077173aafcb85cabe78Ying Wang * {@link OperationCanceledException} will be thrown. 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 788f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich * @throws FileNotFoundException Throws FileNotFoundException if no 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 792673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable ParcelFileDescriptor openFileDescriptor(@NonNull Uri uri, 793673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String mode, @Nullable CancellationSignal cancellationSignal) 794673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey throws FileNotFoundException { 795bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode, cancellationSignal); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7990ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8040ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8110ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 81623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access data under a URI. This 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 81803f0292744094ec107ffce71301c394503a31dedGilles Debunne * method of the provider associated with the given URI, to retrieve any file stored there. 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 85023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note that if this function is called for read-only input (mode is "r") 85123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 8523390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * for you with a MIME type of "*/*". This allows such callers to benefit 85323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * from any built-in data conversion that a provider implements. 85423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 863673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable AssetFileDescriptor openAssetFileDescriptor(@NonNull Uri uri, 864673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String mode) throws FileNotFoundException { 865bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openAssetFileDescriptor(uri, mode, null); 866bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 867bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 868bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey /** 869bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Open a raw file descriptor to access data under a URI. This 870bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * interacts with the underlying {@link ContentProvider#openAssetFile} 871bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * method of the provider associated with the given URI, to retrieve any file stored there. 872bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 873bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <h5>Accepts the following URI schemes:</h5> 874bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <ul> 875bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>content ({@link #SCHEME_CONTENT})</li> 876bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 877bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li>file ({@link #SCHEME_FILE})</li> 878bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </ul> 879bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 880bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p> 881bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * A Uri object can be used to reference a resource in an APK file. The 882bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Uri should be one of the following formats: 883bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <ul> 884bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li><code>android.resource://package_name/id_number</code><br/> 885bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 886bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * For example <code>com.example.myapp</code><br/> 887bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>id_number</code> is the int form of the ID.<br/> 888bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * The easiest way to construct this form is 889bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 890bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </li> 891bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <li><code>android.resource://package_name/type/name</code><br/> 892bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 893bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * For example <code>com.example.myapp</code><br/> 894bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 895bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * or <code>drawable</code>. 896bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <code>name</code> is the string form of the resource name. That is, whatever the file 897bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * name was in your res directory, without the type extension. 898bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * The easiest way to construct this form is 899bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 900bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </li> 901bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * </ul> 902bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 903bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>Note that if this function is called for read-only input (mode is "r") 904bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor} 9053390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * for you with a MIME type of "*/*". This allows such callers to benefit 906bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * from any built-in data conversion that a provider implements. 907bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 908bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param uri The desired URI to open. 909bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 910bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * ContentProvider.openAssetFile}. 91194366313331a789440a3c077173aafcb85cabe78Ying Wang * @param cancellationSignal A signal to cancel the operation in progress, or null if 912bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * none. If the operation is canceled, then 913bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link OperationCanceledException} will be thrown. 914bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @return Returns a new ParcelFileDescriptor pointing to the file. You 915bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * own this descriptor and are responsible for closing it when done. 916bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @throws FileNotFoundException Throws FileNotFoundException of no 917bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * file exists under the URI or the mode is invalid. 918bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey */ 919673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable AssetFileDescriptor openAssetFileDescriptor(@NonNull Uri uri, 920673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String mode, @Nullable CancellationSignal cancellationSignal) 921673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey throws FileNotFoundException { 922673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 923673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(mode, "mode"); 924673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 938eb8c3f93edc826413ff4143284dec01c1061d5ccAdam Lesinski new File(uri.getPath()), ParcelFileDescriptor.parseMode(mode)); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 94123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if ("r".equals(mode)) { 942bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openTypedAssetFileDescriptor(uri, "*/*", null, cancellationSignal); 94323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } else { 9446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 9456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 9466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 9476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 9486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 9496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 9506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 952bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey ICancellationSignal remoteCancellationSignal = null; 953bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 954bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.throwIfCanceled(); 955bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey remoteCancellationSignal = unstableProvider.createCancellationSignal(); 956bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(remoteCancellationSignal); 957bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 958bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 959652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 960bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = unstableProvider.openAssetFile( 961bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mode, remoteCancellationSignal); 962652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 963652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 964652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 965652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 9666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 9676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 9686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 9696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 9706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 9716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 9726ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 9736ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 974652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 975bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = stableProvider.openAssetFile( 976bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mode, remoteCancellationSignal); 9776ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 9786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 9796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 980652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 98123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 9826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 9846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 9856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 9866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 9876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 9886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 9896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 9916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 9926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 9936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 9956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 9966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 9976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 9986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 9996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 10006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 10016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 10026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 10036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 1004bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 1005bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(null); 1006bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 10076ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 10086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 10096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 10106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 10116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 10126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 101323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 101423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 101523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 101623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 101723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 101823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 101923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Open a raw file descriptor to access (potentially type transformed) 102023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data from a "content:" URI. This interacts with the underlying 102123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile} method of the provider 102223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * associated with the given URI, to retrieve retrieve any appropriate 102323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream for the data stored there. 102423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 102523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 102623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with "content:" URIs, because content providers are the only facility 102723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * with an associated MIME type to ensure that the returned data stream 102823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is of the desired type. 102923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 103023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>All text/* streams are encoded in UTF-8. 103123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 103223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param uri The desired URI to open. 103323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param mimeType The desired MIME type of the returned data. This can 10343390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * be a pattern such as */*, which will allow the content provider to 103523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * select a type, though there is no way for you to determine what type 103623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it is returning. 103723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param opts Additional provider-dependent options. 103823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns a new ParcelFileDescriptor from which you can read the 103923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data stream from the provider. Note that this may be a pipe, meaning 104023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * you can't seek in it. The only seek you should do is if the 104123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * AssetFileDescriptor contains an offset, to move to that offset before 104223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * reading. You own this descriptor and are responsible for closing it when done. 104323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @throws FileNotFoundException Throws FileNotFoundException of no 104423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * data of the desired type exists under the URI. 104523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 1046673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull Uri uri, 1047673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String mimeType, @Nullable Bundle opts) throws FileNotFoundException { 1048bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey return openTypedAssetFileDescriptor(uri, mimeType, opts, null); 1049bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 1050bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 1051bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey /** 1052bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * Open a raw file descriptor to access (potentially type transformed) 1053bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data from a "content:" URI. This interacts with the underlying 1054bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * {@link ContentProvider#openTypedAssetFile} method of the provider 1055bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * associated with the given URI, to retrieve retrieve any appropriate 1056bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data stream for the data stored there. 1057bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 1058bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>Unlike {@link #openAssetFileDescriptor}, this function only works 1059bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * with "content:" URIs, because content providers are the only facility 1060bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * with an associated MIME type to ensure that the returned data stream 1061bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * is of the desired type. 1062bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 1063bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * <p>All text/* streams are encoded in UTF-8. 1064bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * 1065bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param uri The desired URI to open. 1066bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param mimeType The desired MIME type of the returned data. This can 10673390018c6b45acffa6edf97a4174ca49f1e8c76dJohn Spurlock * be a pattern such as */*, which will allow the content provider to 1068bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * select a type, though there is no way for you to determine what type 1069bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * it is returning. 1070bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @param opts Additional provider-dependent options. 107194366313331a789440a3c077173aafcb85cabe78Ying Wang * @param cancellationSignal A signal to cancel the operation in progress, 107294366313331a789440a3c077173aafcb85cabe78Ying Wang * or null if none. If the operation is canceled, then 107394366313331a789440a3c077173aafcb85cabe78Ying Wang * {@link OperationCanceledException} will be thrown. 1074bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @return Returns a new ParcelFileDescriptor from which you can read the 1075bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data stream from the provider. Note that this may be a pipe, meaning 1076bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * you can't seek in it. The only seek you should do is if the 1077bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * AssetFileDescriptor contains an offset, to move to that offset before 1078bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * reading. You own this descriptor and are responsible for closing it when done. 1079bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * @throws FileNotFoundException Throws FileNotFoundException of no 1080bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey * data of the desired type exists under the URI. 1081bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey */ 1082673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull Uri uri, 1083673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String mimeType, @Nullable Bundle opts, 1084673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable CancellationSignal cancellationSignal) throws FileNotFoundException { 1085673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 1086673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(mimeType, "mimeType"); 1087673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey 10886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider unstableProvider = acquireUnstableProvider(uri); 10896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider == null) { 10906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 10916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 10926ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider stableProvider = null; 10936ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn AssetFileDescriptor fd = null; 10946ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 10956ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn try { 1096bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey ICancellationSignal remoteCancellationSignal = null; 1097bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 1098bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.throwIfCanceled(); 1099bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey remoteCancellationSignal = unstableProvider.createCancellationSignal(); 1100bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(remoteCancellationSignal); 1101bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 1102bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey 1103652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn try { 1104bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = unstableProvider.openTypedAssetFile( 1105bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mimeType, opts, remoteCancellationSignal); 1106652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (fd == null) { 1107652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn // The provider will be released by the finally{} clause 1108652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1109652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 11106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (DeadObjectException e) { 11116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The remote process has died... but we only hold an unstable 11126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // reference though, so we might recover!!! Let's try!!!! 11136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // This is exciting!!1!!1!!!!1 11146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn unstableProviderDied(unstableProvider); 11156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 11166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 11176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException("No content provider: " + uri); 1118652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1119bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey fd = stableProvider.openTypedAssetFile( 1120bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey mPackageName, uri, mimeType, opts, remoteCancellationSignal); 11216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (fd == null) { 11226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // The provider will be released by the finally{} clause 11236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return null; 1124652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 11276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider == null) { 11286ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = acquireProvider(uri); 11296ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 11306ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 11316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 11326ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getParcelFileDescriptor(), stableProvider); 11336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 11346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Success! Don't release the provider when exiting, let 11356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // ParcelFileDescriptorInner do that when it is closed. 11366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn stableProvider = null; 11376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 11386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return new AssetFileDescriptor(pfd, fd.getStartOffset(), 11396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn fd.getDeclaredLength()); 11406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn 11416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (RemoteException e) { 11426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn // Whatever, whatever, we'll go away. 11436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw new FileNotFoundException( 11446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn "Failed opening content provider: " + uri); 11456ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } catch (FileNotFoundException e) { 11466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn throw e; 11476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } finally { 1148bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey if (cancellationSignal != null) { 1149bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey cancellationSignal.setRemote(null); 1150bd3b902567b09379e1b62c60b3319ad82102efadJeff Sharkey } 11516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (stableProvider != null) { 11526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseProvider(stableProvider); 11536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 11546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn if (unstableProvider != null) { 11556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn releaseUnstableProvider(unstableProvider); 11566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn } 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11604c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 11614c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * A resource identified by the {@link Resources} that contains it, and a resource id. 11624c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 11634c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 11644c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 11654c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public class OpenResourceIdResult { 11664c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public Resources r; 11674c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public int id; 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11694c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert 11704c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert /** 11714c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * Resolves an android.resource URI to a {@link Resources} and a resource id. 11724c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * 11734c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert * @hide 11744c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert */ 11754c87a3f26a7c0c75fa371024a8726b59a108fd0fBjorn Bringert public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12120ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 122334796bd07f871bc762d8ebd55cfbb80fcff4aecaJeff Sharkey public final @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues values) { 1224673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(url, "url"); 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1230d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 123135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Uri createdRow = provider.insert(mPackageName, url, values); 1232d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1233a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); 1234a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return createdRow; 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1236534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1237534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12448943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 12458943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 12468943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 12478943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 12488943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 12498943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 12508943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 12518943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 12528943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 12538943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 12548943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 12558943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 12568943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 12578943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 12588943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 12598943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 1260673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public @NonNull ContentProviderResult[] applyBatch(@NonNull String authority, 1261673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull ArrayList<ContentProviderOperation> operations) 1262673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey throws RemoteException, OperationApplicationException { 1263673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(authority, "authority"); 1264673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(operations, "operations"); 12658943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 12666a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 12678943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 12686a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 12696a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 12708943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 12716a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 12726a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 12736a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 12746a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 12756a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1286673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final int bulkInsert(@NonNull Uri url, @NonNull ContentValues[] values) { 1287673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(url, "url"); 1288673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(values, "values"); 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1294d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 129535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsCreated = provider.bulkInsert(mPackageName, url, values); 1296d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1297a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */); 1298a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsCreated; 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1300534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1301534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1318673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final int delete(@NonNull Uri url, @Nullable String where, 1319673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable String[] selectionArgs) { 1320673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(url, "url"); 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1326d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 132735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsDeleted = provider.delete(mPackageName, url, where, selectionArgs); 1328d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1329a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, url, "delete", where); 1330a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsDeleted; 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1332534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1333534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 1348d2a2daaa89865d19e881ab9af133ce0f3902c820Omari Stephens * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 1350534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return the number of rows updated. 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 135334796bd07f871bc762d8ebd55cfbb80fcff4aecaJeff Sharkey public final int update(@NonNull Uri uri, @Nullable ContentValues values, 1354673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable String where, @Nullable String[] selectionArgs) { 1355673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1361d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long startTime = SystemClock.uptimeMillis(); 136235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int rowsUpdated = provider.update(mPackageName, uri, values, where, selectionArgs); 1363d72f718c9cc4bd5e4701f4c5cdab51b4d8cf6435Brad Fitzpatrick long durationMillis = SystemClock.uptimeMillis() - startTime; 1364a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick maybeLogUpdateToEventLog(durationMillis, uri, "update", where); 1365a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return rowsUpdated; 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1367534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1368534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1376f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa * Call a provider-defined method. This can be used to implement 1377534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * read or write interfaces which are cheaper than using a Cursor and/or 1378534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * do not fit into the traditional table model. 1379534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * 1380534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param method provider-defined method name to call. Opaque to 1381534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * framework, but must be non-null. 1382534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param arg provider-defined String argument. May be null. 1383534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @param extras provider-defined Bundle argument. May be null. 1384534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @return a result Bundle, possibly null. Will be null if the ContentProvider 1385534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * does not implement call. 1386534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws NullPointerException if uri or method is null 1387534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick * @throws IllegalArgumentException if uri is not known 1388534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick */ 1389673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable Bundle call(@NonNull Uri uri, @NonNull String method, 1390673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Nullable String arg, @Nullable Bundle extras) { 1391673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 1392673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(method, "method"); 1393534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick IContentProvider provider = acquireProvider(uri); 1394534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick if (provider == null) { 1395534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick throw new IllegalArgumentException("Unknown URI " + uri); 1396534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1397534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick try { 139835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return provider.call(mPackageName, method, arg, extras); 1399534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } catch (RemoteException e) { 1400534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Arbitrary and not worth documenting, as Activity 1401534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick // Manager will kill this process shortly anyway. 1402534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick return null; 1403534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } finally { 1404534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick releaseProvider(provider); 1405534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1406534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick } 1407534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick 1408534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick /** 1409cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI. 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1415cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireProvider(Uri uri) { 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich final String auth = uri.getAuthority(); 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 1421f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich return acquireProvider(mContext, auth); 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1427cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * Returns the content provider for the given content URI if the process 1428cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * already has a reference on it. 1429cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * 1430cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @param uri The URI to a content provider 1431cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1432cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn * @hide 1433cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn */ 1434cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn public final IContentProvider acquireExistingProvider(Uri uri) { 1435cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1436cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1437cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1438f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich final String auth = uri.getAuthority(); 1439cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn if (auth != null) { 1440f9c5176a51a49fea18712338429b4d125e550a4aYury Zhauniarovich return acquireExistingProvider(mContext, auth); 1441cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1442cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn return null; 1443cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn } 1444cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn 1445cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn /** 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 14491877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick if (name == null) { 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1456652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Returns the content provider for the given content URI. 1457652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * 1458652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @param uri The URI to a content provider 1459652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @return The ContentProvider for the given URI, or null if no content provider is found. 1460652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1461652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1462652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(Uri uri) { 1463652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (!SCHEME_CONTENT.equals(uri.getScheme())) { 1464652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1465652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1466652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn String auth = uri.getAuthority(); 1467652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (auth != null) { 1468652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return acquireUnstableProvider(mContext, uri.getAuthority()); 1469652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1470652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1471652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1472652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1473652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1474652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * @hide 1475652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1476652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn public final IContentProvider acquireUnstableProvider(String name) { 1477652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (name == null) { 1478652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1479652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 14806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn return acquireUnstableProvider(mContext, name); 1481652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1482652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1483652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1484718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1485718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 1486718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1487718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1488718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1489718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1490718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 1491718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1492718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 1493718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1494673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable ContentProviderClient acquireContentProviderClient(@NonNull Uri uri) { 1495673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 1496718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 1497718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1498652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1499718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1500718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1501718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1502718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1503718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 1504718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1505718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 1506718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 1507718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 1508718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 1509718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 1510718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 1511718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 1512718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 1513718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 1514673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable ContentProviderClient acquireContentProviderClient( 1515673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String name) { 1516673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(name, "name"); 1517718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 1518718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 1519652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, true); 1520652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1521652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1522652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1523652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1524652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1525652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1526652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(Uri)}, but for use when you do 1527652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1528652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1529652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1530652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1531652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1532652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1533652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 15346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 15356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 15366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 15376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 15386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 15396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1540652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1541673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable ContentProviderClient acquireUnstableContentProviderClient( 1542673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull Uri uri) { 1543673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 15446ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(uri); 1545652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1546652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1547652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1548652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1549652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return null; 1550652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn } 1551652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn 1552652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn /** 1553652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * Like {@link #acquireContentProviderClient(String)}, but for use when you do 1554652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * not trust the stability of the target content provider. This turns off 1555652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * the mechanism in the platform clean up processes that are dependent on 1556652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * a content provider if that content provider's process goes away. Normally 1557652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * you can safely assume that once you have acquired a provider, you can freely 1558652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * use it as needed and it won't disappear, even if your process is in the 1559652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * background. If using this method, you need to take care to deal with any 1560652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn * failures when communicating with the provider, and be sure to close it 15616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * so that it can be re-opened later. In particular, catching a 15626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link android.os.DeadObjectException} from the calls there will let you 15636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * know that the content provider has gone away; at that point the current 15646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * ContentProviderClient object is invalid, and you should release it. You 15656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * can acquire a new one if you would like to try to restart the provider 15666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * and perform new operations on it. 1567652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn */ 1568673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final @Nullable ContentProviderClient acquireUnstableContentProviderClient( 1569673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull String name) { 1570673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(name, "name"); 15716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn IContentProvider provider = acquireUnstableProvider(name); 1572652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn if (provider != null) { 1573652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn return new ContentProviderClient(this, provider, false); 1574718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1575718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1576718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 1577718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 1578718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 1579718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 1585143739cb6b0468804f83f2398b3666eb21280de6Jeff Brown * @param notifyForDescendents When false, the observer will be notified whenever a 1586143739cb6b0468804f83f2398b3666eb21280de6Jeff Brown * change occurs to the exact URI specified by <code>uri</code> or to one of the 1587143739cb6b0468804f83f2398b3666eb21280de6Jeff Brown * URI's ancestors in the path hierarchy. When true, the observer will also be notified 1588143739cb6b0468804f83f2398b3666eb21280de6Jeff Brown * whenever a change occurs to the URI's descendants in the path hierarchy. 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1592673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final void registerContentObserver(@NonNull Uri uri, boolean notifyForDescendents, 1593673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @NonNull ContentObserver observer) { 1594673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 1595673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(observer, "observer"); 1596adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz registerContentObserver( 1597adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz ContentProvider.getUriWithoutUserId(uri), 1598adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz notifyForDescendents, 1599adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz observer, 1600adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId())); 160116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 160216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 160316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** @hide - designated user version */ 160416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 1605143739cb6b0468804f83f2398b3666eb21280de6Jeff Brown ContentObserver observer, int userHandle) { 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1607231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 160816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer.getContentObserver(), userHandle); 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1619673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public final void unregisterContentObserver(@NonNull ContentObserver observer) { 1620673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(observer, "observer"); 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 1624231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1632d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * Notify registered observers that a row was updated and attempt to sync changes 1633d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * to the network. 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 163786de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 163886de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 163986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 164086de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 164186de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1643673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) { 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 1651d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * If syncToNetwork is true, this will attempt to schedule a local sync using the sync 1652d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * adapter that's registered for the authority of the provided uri. No account will be 1653d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * passed to the sync adapter, so all matching accounts will be synchronized. 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 165586de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param uri The uri of the content that was changed. 165686de0590b94bcce27e3038c27464bed510bb564aJeff Brown * @param observer The observer that originated the change, may be <code>null</null>. 165786de0590b94bcce27e3038c27464bed510bb564aJeff Brown * The observer that originated the change will only receive the notification if it 165886de0590b94bcce27e3038c27464bed510bb564aJeff Brown * has requested to receive self-change notifications by implementing 165986de0590b94bcce27e3038c27464bed510bb564aJeff Brown * {@link ContentObserver#deliverSelfNotifications()} to return true. 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 1661d7a1aada2d1245eaeef973bc3e37619ce8e6d593Steve Pomeroy * @see #requestSync(android.accounts.Account, String, android.os.Bundle) 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1663673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer, 1664673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey boolean syncToNetwork) { 1665673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 1666adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz notifyChange( 1667adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz ContentProvider.getUriWithoutUserId(uri), 1668adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz observer, 1669adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz syncToNetwork, 1670adea1918bef942b6214cf549b1316affd2b10280Benjamin Franz ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId())); 167116aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate } 167216aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate 167316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate /** 167416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * Notify registered observers within the designated user(s) that a row was updated. 167516aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * 167616aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate * @hide 167716aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate */ 167816aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 167916aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate int userHandle) { 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1681231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 168316aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate observer != null && observer.deliverSelfNotifications(), syncToNetwork, 168416aa9736175f5bbe924a6e5587a2ca47c2dd702bChristopher Tate userHandle); 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1690adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Take a persistable URI permission grant that has been offered. Once 1691e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * taken, the permission grant will be remembered across device reboots. 1692adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Only URI permissions granted with 1693e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION} can be persisted. If 1694e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * the grant has already been persisted, taking it again will touch 1695e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link UriPermission#getPersistedTime()}. 169608da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey * 1697e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #getPersistedUriPermissions() 169808da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey */ 1699673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public void takePersistableUriPermission(@NonNull Uri uri, 1700673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Intent.AccessUriMode int modeFlags) { 1701673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 170208da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey try { 1703d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot ActivityManagerNative.getDefault().takePersistableUriPermission( 1704d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri)); 170508da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } catch (RemoteException e) { 170608da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 170708da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 170808da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey 170908da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey /** 1710adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Relinquish a persisted URI permission grant. The URI must have been 1711e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * previously made persistent with 1712e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link #takePersistableUriPermission(Uri, int)}. Any non-persistent 1713e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * grants to the calling package will remain intact. 171408da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey * 1715e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #getPersistedUriPermissions() 1716e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey */ 1717673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public void releasePersistableUriPermission(@NonNull Uri uri, 1718673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey @Intent.AccessUriMode int modeFlags) { 1719673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey Preconditions.checkNotNull(uri, "uri"); 1720e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey try { 1721d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot ActivityManagerNative.getDefault().releasePersistableUriPermission( 1722d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri)); 1723e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey } catch (RemoteException e) { 1724e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey } 1725e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey } 1726e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey 1727e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey /** 1728adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Return list of all URI permission grants that have been persisted by the 1729bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * calling app. That is, the returned permissions have been granted 1730bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * <em>to</em> the calling app. Only persistable grants taken with 1731e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * {@link #takePersistableUriPermission(Uri, int)} are returned. 173208da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey * 1733e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #takePersistableUriPermission(Uri, int) 1734e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey * @see #releasePersistableUriPermission(Uri, int) 173508da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey */ 1736673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public @NonNull List<UriPermission> getPersistedUriPermissions() { 173708da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey try { 1738bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey return ActivityManagerNative.getDefault() 1739bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey .getPersistedUriPermissions(mPackageName, true).getList(); 1740bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey } catch (RemoteException e) { 1741bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey throw new RuntimeException("Activity manager has died", e); 1742bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey } 1743bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey } 1744bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey 1745bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey /** 1746adef88a0a9d65e7f5ae812594e8c039747388cddJeff Sharkey * Return list of all persisted URI permission grants that are hosted by the 1747bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * calling app. That is, the returned permissions have been granted 1748bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * <em>from</em> the calling app. Only grants taken with 1749bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey * {@link #takePersistableUriPermission(Uri, int)} are returned. 1750bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey */ 1751673db44fb3da4558059ef9746a496a63157f10bcJeff Sharkey public @NonNull List<UriPermission> getOutgoingPersistedUriPermissions() { 1752bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey try { 1753bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey return ActivityManagerNative.getDefault() 1754bcaac0adecc8f9d7e66548df39e0f5c9f759e38cJeff Sharkey .getPersistedUriPermissions(mPackageName, false).getList(); 175508da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } catch (RemoteException e) { 1756e66c1778f80f4b18e29e018eca3a338f125f23b9Jeff Sharkey throw new RuntimeException("Activity manager has died", e); 175708da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 175808da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey } 175908da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey 176008da7a1143b0c9cfb703971d882e0886bbd7d9deJeff Sharkey /** 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1771fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>Account</li> 1772fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>null</li> 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 1777ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 1778ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17804a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 1782ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 1783ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 1784ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 1785ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 17863348f14b3d46b172a5b557f81aac526b7e8bf5fbCostin Manolache account = new Account(accountName, "com.google"); 1787ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1788ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 1789ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1790ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 1791ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1792ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1793ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1794ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 1795ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 1796ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 1797ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 1798ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 1799ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 1800ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 1801ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 1802ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 1803ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 1804fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>Account</li> 1805fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * <li>null</li> 1806ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 1807ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1808ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 1809ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 1810ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 1811ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1812ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 181303e1e836976f44ed729fa0a41898d7ce4df34788Alexandra Gherghina requestSyncAsUser(account, authority, UserHandle.myUserId(), extras); 18140363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 18150363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 18160363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 18170363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #requestSync(Account, String, Bundle) 18180363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 18190363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 18200363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static void requestSyncAsUser(Account account, String authority, int userId, 18210363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina Bundle extras) { 1822d8abd6a163f8ab4332b88035e77080c48b4b71b9Matthew Williams if (extras == null) { 1823d8abd6a163f8ab4332b88035e77080c48b4b71b9Matthew Williams throw new IllegalArgumentException("Must specify extras."); 1824d8abd6a163f8ab4332b88035e77080c48b4b71b9Matthew Williams } 1825fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams SyncRequest request = 1826fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams new SyncRequest.Builder() 1827fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams .setSyncAdapter(account, authority) 1828fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams .setExtras(extras) 182969002ae2a2afd0f759c22ea47d669ddc33b3255aNick Kralevich .syncOnce() // Immediate sync. 1830fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams .build(); 18310363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 18320363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina getContentService().syncAsUser(request, userId); 18330363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch(RemoteException e) { 18340363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina // Shouldn't happen. 18350363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 1836fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 1837fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 1838fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** 1839fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * Register a sync with the SyncManager. These requests are built using the 1840fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * {@link SyncRequest.Builder}. 1841fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams */ 1842fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static void requestSync(SyncRequest request) { 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1844fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams getContentService().sync(request); 1845fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } catch(RemoteException e) { 1846fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams // Shouldn't happen. 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 1859d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 1875d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1886ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1887ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 1888ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 1889ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1890ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 1891ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 1892ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 18934a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 1895ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 1896ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1897ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1898ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1899ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 1900ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 1901ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 1902ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1903ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 1904ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 1905ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1906ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 1907ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 190856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams getContentService().cancelSync(account, authority, null); 1909ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1910ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1911ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1912ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1913ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 19140363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #cancelSync(Account, String) 19150363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 19160363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 19170363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static void cancelSyncAsUser(Account account, String authority, int userId) { 19180363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 19190363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina getContentService().cancelSyncAsUser(account, authority, null, userId); 19200363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch (RemoteException e) { 19210363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 19220363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 19230363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 19240363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 1925ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 1926ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 1927ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1928ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 1929ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1930ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 1931ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1932ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1933ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1934ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1935ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1936ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 19370363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #getSyncAdapterTypes() 19380363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 19390363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 19400363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) { 19410363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 19420363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina return getContentService().getSyncAdapterTypesAsUser(userId); 19430363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch (RemoteException e) { 19440363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina throw new RuntimeException("the ContentService should always be reachable", e); 19450363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 19460363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 19470363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 19480363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 194937a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani * @hide 195037a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani * Returns the package names of syncadapters that match a given user and authority. 195137a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani */ 195237a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani public static String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, 195337a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani int userId) { 195437a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani try { 195537a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani return getContentService().getSyncAdapterPackagesForAuthorityAsUser(authority, userId); 195637a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani } catch (RemoteException e) { 195737a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani } 195837a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani return ArrayUtils.emptyArray(String.class); 195937a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani } 196037a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani 196137a40c24deb02bca3868a8085069afae112f22e4Amith Yamasani /** 1962ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 19639530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 19649530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 1965ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1966ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1967ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 1968ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 1969ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1970ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 1971ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1972ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 1973ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1974ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1975ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1976ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1977ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1978ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 19790363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #getSyncAutomatically(Account, String) 19800363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 19810363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 19820363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static boolean getSyncAutomaticallyAsUser(Account account, String authority, 19830363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina int userId) { 19840363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 19850363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina return getContentService().getSyncAutomaticallyAsUser(account, authority, userId); 19860363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch (RemoteException e) { 19870363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina throw new RuntimeException("the ContentService should always be reachable", e); 19880363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 19890363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 19900363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 19910363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 1992ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 19939530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 19949530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 1995ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1996ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1997ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1998ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1999ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2000ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 200103e1e836976f44ed729fa0a41898d7ce4df34788Alexandra Gherghina setSyncAutomaticallyAsUser(account, authority, sync, UserHandle.myUserId()); 2002cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina } 2003cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina 2004cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina /** 2005cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina * @see #setSyncAutomatically(Account, String, boolean) 2006cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina * @hide 2007cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina */ 2008cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina public static void setSyncAutomaticallyAsUser(Account account, String authority, boolean sync, 2009cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina int userId) { 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2011cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina getContentService().setSyncAutomaticallyAsUser(account, authority, sync, userId); 20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2013ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 20145e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 20155e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 20165e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 20175e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 20185e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 2019c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Specifies that a sync should be requested with the specified the account, authority, 2020c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * and extras at the given frequency. If there is already another periodic sync scheduled 2021c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * with the account, authority and extras then a new periodic sync won't be added, instead 2022c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * the frequency of the previous one will be updated. 2023c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * <p> 2024c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * These periodic syncs honor the "syncAutomatically" and "masterSyncAutomatically" settings. 2025c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Although these sync are scheduled at the specified frequency, it may take longer for it to 2026c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * actually be started if other syncs are ahead of it in the sync operation queue. This means 2027c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * that the actual start time may drift. 202853bd2522ca7767f46646606123b6e2689b811850Fred Quintana * <p> 202953bd2522ca7767f46646606123b6e2689b811850Fred Quintana * Periodic syncs are not allowed to have any of {@link #SYNC_EXTRAS_DO_NOT_RETRY}, 203053bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_IGNORE_BACKOFF}, {@link #SYNC_EXTRAS_IGNORE_SETTINGS}, 203153bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE}, 203253bd2522ca7767f46646606123b6e2689b811850Fred Quintana * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true. 203353bd2522ca7767f46646606123b6e2689b811850Fred Quintana * If any are supplied then an {@link IllegalArgumentException} will be thrown. 2034c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 20359530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 20369530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 203756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * <p>The bundle for a periodic sync can be queried by applications with the correct 203856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * permissions using 203956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no 204056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * sensitive data should be transferred here. 20419530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * 2042c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account to specify in the sync 2043c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider to specify in the sync request 2044c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras extra parameters to go along with the sync request 2045c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param pollFrequency how frequently the sync should be performed, in seconds. 204653bd2522ca7767f46646606123b6e2689b811850Fred Quintana * @throws IllegalArgumentException if an illegal extra was set or if any of the parameters 204753bd2522ca7767f46646606123b6e2689b811850Fred Quintana * are null. 2048c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 2049c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void addPeriodicSync(Account account, String authority, Bundle extras, 2050c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 2051c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 205253bd2522ca7767f46646606123b6e2689b811850Fred Quintana if (extras.getBoolean(SYNC_EXTRAS_MANUAL, false) 205353bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_DO_NOT_RETRY, false) 205453bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_BACKOFF, false) 205553bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_IGNORE_SETTINGS, false) 205653bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_INITIALIZE, false) 205753bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_FORCE, false) 205853bd2522ca7767f46646606123b6e2689b811850Fred Quintana || extras.getBoolean(SYNC_EXTRAS_EXPEDITED, false)) { 205953bd2522ca7767f46646606123b6e2689b811850Fred Quintana throw new IllegalArgumentException("illegal extras were set"); 206053bd2522ca7767f46646606123b6e2689b811850Fred Quintana } 2061c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 2062fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams getContentService().addPeriodicSync(account, authority, extras, pollFrequency); 2063c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 2064c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 2065c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana // being restarted 2066c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 2067c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 2068c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 2069c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 207056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * {@hide} 207156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * Helper function to throw an <code>IllegalArgumentException</code> if any illegal 207256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * extras were set for a periodic sync. 207356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * 207456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * @param extras bundle to validate. 207556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams */ 207656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams public static boolean invalidPeriodicExtras(Bundle extras) { 207756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false) 207856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false) 207956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false) 208056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false) 208156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false) 208256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false) 208356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams || extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) { 208456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return true; 208556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 208656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return false; 208756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 208856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 208956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams /** 2090c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Remove a periodic sync. Has no affect if account, authority and extras don't match 2091c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * an existing periodic sync. 20929530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 20939530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 2094c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 2095c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account of the periodic sync to remove 2096c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider of the periodic sync to remove 2097c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param extras the extras of the periodic sync to remove 2098c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 2099c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static void removePeriodicSync(Account account, String authority, Bundle extras) { 2100c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana validateSyncExtrasBundle(extras); 2101c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 2102c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getContentService().removePeriodicSync(account, authority, extras); 2103c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } catch (RemoteException e) { 2104c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2105c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 2106c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 2107c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 2108c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana /** 210956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * Remove the specified sync. This will cancel any pending or active syncs. If the request is 211056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * for a periodic sync, this call will remove any future occurrences. 21115a9decd589f3f6a512168fd669ee2c5d8daa238bMatthew Williams * <p> 21125a9decd589f3f6a512168fd669ee2c5d8daa238bMatthew Williams * If a periodic sync is specified, the caller must hold the permission 21135a9decd589f3f6a512168fd669ee2c5d8daa238bMatthew Williams * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 21145a9decd589f3f6a512168fd669ee2c5d8daa238bMatthew Williams *</p> 21155a9decd589f3f6a512168fd669ee2c5d8daa238bMatthew Williams * It is possible to cancel a sync using a SyncRequest object that is not the same object 211656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * with which you requested the sync. Do so by building a SyncRequest with the same 21175a9decd589f3f6a512168fd669ee2c5d8daa238bMatthew Williams * adapter, frequency, <b>and</b> extras bundle. 2118fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * 2119fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams * @param request SyncRequest object containing information about sync to cancel. 2120fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams */ 2121fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams public static void cancelSync(SyncRequest request) { 212256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (request == null) { 212356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams throw new IllegalArgumentException("request cannot be null"); 212456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 212556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams try { 212656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams getContentService().cancelRequest(request); 212756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch (RemoteException e) { 212856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // exception ignored; if this is thrown then it means the runtime is in the midst of 212956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams // being restarted 213056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 2131fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams } 2132fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams 2133fa77418134c6f1f80af225a78819f069e9c974fbMatthew Williams /** 2134c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * Get the list of information about the periodic syncs for the given account and authority. 21359530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 21369530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 2137c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * 2138c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param account the account whose periodic syncs we are querying 2139c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @param authority the provider whose periodic syncs we are querying 2140c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana * @return a list of PeriodicSync objects. This list may be empty but will never be null. 2141c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana */ 2142c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) { 2143c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 214456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return getContentService().getPeriodicSyncs(account, authority, null); 214556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch (RemoteException e) { 214656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams throw new RuntimeException("the ContentService should always be reachable", e); 214756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 214856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 214956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 215056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams /** 21515e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 21529530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 21539530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 21545e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 21555e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 215620ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static int getIsSyncable(Account account, String authority) { 21575e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 21585e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 21595e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 21605e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 21615e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 21625e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 21635e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 21645e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 21650363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #getIsSyncable(Account, String) 21660363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 21670363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 21680363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static int getIsSyncableAsUser(Account account, String authority, int userId) { 21690363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 21700363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina return getContentService().getIsSyncableAsUser(account, authority, userId); 21710363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch (RemoteException e) { 21720363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina throw new RuntimeException("the ContentService should always be reachable", e); 21730363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 21740363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 21750363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 21760363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 21775e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 21789530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 21799530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 2180718671b441c6318276e6d954a41a95db0d7e6c49Fred Quintana * @param syncable >0 denotes syncable, 0 means not syncable, <0 means unknown 21815e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 218220ea6ce0e8a758cc5c33eb2577495bf9f4dce16eJim Miller public static void setIsSyncable(Account account, String authority, int syncable) { 21835e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 21845e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 21855e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 21865e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 2187ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2191ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 2192ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 2193ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 21949530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 21959530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_SETTINGS}. 2196ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 2197ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 2198ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2199ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 2200ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2201ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 2202ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2203ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2204ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2205ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2206ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2207ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 22080363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #getMasterSyncAutomatically() 22090363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 22100363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 22110363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static boolean getMasterSyncAutomaticallyAsUser(int userId) { 22120363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 22130363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina return getContentService().getMasterSyncAutomaticallyAsUser(userId); 22140363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch (RemoteException e) { 22150363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina throw new RuntimeException("the ContentService should always be reachable", e); 22160363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 22170363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 22180363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 22190363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 2220ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 2221ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 22229530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 22239530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. 2224ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 2225ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 2226ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2227ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 222803e1e836976f44ed729fa0a41898d7ce4df34788Alexandra Gherghina setMasterSyncAutomaticallyAsUser(sync, UserHandle.myUserId()); 22290e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina } 22300e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina 22310e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina /** 22320e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina * @see #setMasterSyncAutomatically(boolean) 22330e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina * @hide 22340e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina */ 22350e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina public static void setMasterSyncAutomaticallyAsUser(boolean sync, int userId) { 2236ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 22370e9ac20d7e0c9aca8cd342d97465adfac4c7e6e1Alexandra Gherghina getContentService().setMasterSyncAutomaticallyAsUser(sync, userId); 2238ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2239ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 2240ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 2241ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2242ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2243ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2244ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 224556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * Returns true if there is currently a sync operation for the given account or authority 224656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams * actively being processed. 22479530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 22489530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 2249ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 2250ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 2251ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 2252ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2253ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 225456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (account == null) { 225556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams throw new IllegalArgumentException("account must not be null"); 225656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 225756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams if (authority == null) { 225856dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams throw new IllegalArgumentException("authority must not be null"); 225956dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 226056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 2261ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 226256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return getContentService().isSyncActive(account, authority, null); 226356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch (RemoteException e) { 226456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams throw new RuntimeException("the ContentService should always be reachable", e); 226556dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 226656dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 226756dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 2268ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 2269c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * If a sync is active returns the information about it, otherwise returns null. 2270c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * <p> 22719530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 22729530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 22739530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 2274d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana * @return the SyncInfo for the currently active sync or null if one is not active. 2275c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @deprecated 2276c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Since multiple concurrent syncs are now supported you should use 2277c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * {@link #getCurrentSyncs()} to get the accurate list of current syncs. 2278c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * This method returns the first item from the list of current syncs 2279c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * or null if there are none. 2280ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2281c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana @Deprecated 2282d5e4fdc8a4743abc0d9fe3cb952a78f9ad078c6bFred Quintana public static SyncInfo getCurrentSync() { 2283ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2284c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana final List<SyncInfo> syncs = getContentService().getCurrentSyncs(); 2285c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana if (syncs.isEmpty()) { 2286c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return null; 2287c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 2288c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return syncs.get(0); 2289c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } catch (RemoteException e) { 2290c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2291c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 2292c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana } 2293c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana 2294c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana /** 2295c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * Returns a list with information about all the active syncs. This list will be empty 2296c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * if there are no active syncs. 22979530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 22989530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * This method requires the caller to hold the permission 22999530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 23009530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p> 2301c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana * @return a List of SyncInfo objects for the currently active syncs. 2302c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana */ 2303c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana public static List<SyncInfo> getCurrentSyncs() { 2304c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana try { 2305c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return getContentService().getCurrentSyncs(); 2306ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2307ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2308ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2309ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2310ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2311ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 23120363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #getCurrentSyncs() 23130363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 23140363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 23150363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static List<SyncInfo> getCurrentSyncsAsUser(int userId) { 23160363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 23170363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina return getContentService().getCurrentSyncsAsUser(userId); 23180363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch (RemoteException e) { 23190363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina throw new RuntimeException("the ContentService should always be reachable", e); 23200363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 23210363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 23220363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 23230363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 23244a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana * Returns the status that matches the authority. 2325ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 2326ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 2327ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 2328ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 2329ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2330ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 2331ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 233256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams return getContentService().getSyncStatus(account, authority, null); 2333ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2334ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2335ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2336ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2337ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2338ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 23390363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @see #getSyncStatus(Account, String) 23400363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina * @hide 23410363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina */ 23420363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina public static SyncStatusInfo getSyncStatusAsUser(Account account, String authority, 23430363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina int userId) { 23440363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina try { 23450363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina return getContentService().getSyncStatusAsUser(account, authority, null, userId); 23460363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } catch (RemoteException e) { 23470363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina throw new RuntimeException("the ContentService should always be reachable", e); 23480363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 23490363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina } 23500363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina 23510363c3eb089afd4474bfd6ae6ee8a500d6e97614Alexandra Gherghina /** 2352ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 23539530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * <p>This method requires the caller to hold the permission 23549530e3a22d5ffa2019d1a5177b6a441d4d6d048bNicolas Falliere * {@link android.Manifest.permission#READ_SYNC_STATS}. 2355ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 2356ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 2357ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 2358ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 2359ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 236003e1e836976f44ed729fa0a41898d7ce4df34788Alexandra Gherghina return isSyncPendingAsUser(account, authority, UserHandle.myUserId()); 2361cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina } 2362cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina 2363cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina /** 2364cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina * @see #requestSync(Account, String, Bundle) 2365cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina * @hide 2366cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina */ 2367cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina public static boolean isSyncPendingAsUser(Account account, String authority, int userId) { 2368ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2369cb22807ffcf79db1b62162842d0a90251a463ea7Alexandra Gherghina return getContentService().isSyncPendingAsUser(account, authority, null, userId); 237056dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } catch (RemoteException e) { 237156dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams throw new RuntimeException("the ContentService should always be reachable", e); 237256dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 237356dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams } 237456dbf8f23677d28615e61ef2fbb0e738cca02528Matthew Williams 23751b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 23761b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Request notifications when the different aspects of the SyncManager change. The 23771b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * different items that can be requested are: 23781b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <ul> 23791b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_PENDING} 23801b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE} 23811b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS} 23821b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * </ul> 23831b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * The caller can set one or more of the status types in the mask for any 23841b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * given listener registration. 23851b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param mask the status change types that will cause the callback to be invoked 23861b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param callback observer to be invoked when the status changes 23871b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @return a handle that can be used to remove the listener at a later time 23881b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 2389ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 23901b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (callback == null) { 23911b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null callback"); 23921b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 2393ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2394ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 2395ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 2396ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 2397ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2398ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 2399ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 2400ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 2401ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2402ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 2403ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2404ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2405ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 24061b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana /** 24071b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * Remove a previously registered status change listener. 24081b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana * @param handle the handle that was returned by {@link #addStatusChangeListener} 24091b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana */ 2410ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 24111b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (handle == null) { 24121b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana throw new IllegalArgumentException("you passed in a null handle"); 24131b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana } 2414ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 2415ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 2416ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 2417ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 2418ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 2419ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2420ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2421ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2422a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick /** 2423a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Returns sampling percentage for a given duration. 2424a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * 2425a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick * Always returns at least 1%. 2426a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick */ 2427a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private int samplePercentForDuration(long durationMillis) { 2428a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (durationMillis >= SLOW_THRESHOLD_MILLIS) { 2429a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return 100; 2430a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2431a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1; 2432a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2433a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2434a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogQueryToEventLog(long durationMillis, 2435a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick Uri uri, String[] projection, 2436a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick String selection, String sortOrder) { 24372b4d22cda3c44f5d731c15306b85045417071408Jeff Sharkey if (!ENABLE_CONTENT_SAMPLE) return; 2438a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 2439a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 2440a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 2441a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 2442a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 2443a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2444a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2445a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2446a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2447a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick StringBuilder projectionBuffer = new StringBuilder(100); 2448a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (projection != null) { 2449a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick for (int i = 0; i < projection.length; ++i) { 2450a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // Note: not using a comma delimiter here, as the 2451a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // multiple arguments to EventLog.writeEvent later 2452a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // stringify with a comma delimiter, which would make 2453a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // parsing uglier later. 2454a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (i != 0) projectionBuffer.append('/'); 2455a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.append(projection[i]); 2456a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2457a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2458a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2459a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // ActivityThread.currentPackageName() only returns non-null if the 2460a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // current thread is an application main thread. This parameter tells 2461a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick // us whether an event loop is blocked, and if so, which app it is. 246201e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 2463a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2464a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 2465a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_QUERY_SAMPLE, 2466a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 2467a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick projectionBuffer.toString(), 2468a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 2469a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick sortOrder != null ? sortOrder : "", 2470a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 2471a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 2472a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 2473a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2474a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick 2475a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick private void maybeLogUpdateToEventLog( 2476a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick long durationMillis, Uri uri, String operation, String selection) { 24772b4d22cda3c44f5d731c15306b85045417071408Jeff Sharkey if (!ENABLE_CONTENT_SAMPLE) return; 2478a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick int samplePercent = samplePercentForDuration(durationMillis); 2479a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (samplePercent < 100) { 2480a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick synchronized (mRandom) { 2481a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick if (mRandom.nextInt(100) >= samplePercent) { 2482a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick return; 2483a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2484a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2485a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 248601e4cfc47d0a2c7e7ab383d2fb23224ec52c0301Dianne Hackborn String blockingPackage = AppGlobals.getInitialPackage(); 2487a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick EventLog.writeEvent( 2488a8fbedbf5e274581ba0cbb20da34ade286fc1cfcBrad Fitzpatrick EventLogTags.CONTENT_UPDATE_SAMPLE, 2489a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick uri.toString(), 2490a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick operation, 2491a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick selection != null ? selection : "", 2492a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick durationMillis, 2493a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick blockingPackage != null ? blockingPackage : "", 2494a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick samplePercent); 2495a63730d1f103f78589faef461d2af7351fc49f42Brad Fitzpatrick } 2496ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 2497825c5132bff21e72c1448241f4c6868563c8d624Jeff Brown private final class CursorWrapperInner extends CrossProcessCursorWrapper { 249803f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 2500baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 2501baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private final CloseGuard mCloseGuard = CloseGuard.get(); 2502baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown private boolean mProviderReleased; 25039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 25059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 25069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 2507baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.open("close"); 25089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 25119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 25129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 25139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 2514baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mProviderReleased = true; 2515baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 2516baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 2517baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.close(); 2518baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 25199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 25229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 25239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2524baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (mCloseGuard != null) { 2525baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown mCloseGuard.warnIfOpen(); 2526baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown } 2527baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown 2528baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown if (!mProviderReleased && mContentProvider != null) { 2529baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // Even though we are using CloseGuard, log this anyway so that 2530baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown // application developers always see the message in the log. 2531872a52c6b637faf75262b83fe68ff4e0d9fe044cJohannes Carlsson Log.w(TAG, "Cursor finalized without prior close()"); 2532baaf8c3f55d9d95b9d2cd9279e2ce1725da0dc52Jeff Brown ContentResolver.this.releaseProvider(mContentProvider); 25339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 25359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 25369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 254103f0292744094ec107ffce71301c394503a31dedGilles Debunne private final IContentProvider mContentProvider; 2542da5a3e12f4f8f965c57d6f93c74190f43ea233f3Jeff Sharkey private boolean mProviderReleased; 25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 25469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 25479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2550487c11a3101c6cd9fc18758b3032383666f55e46Amith Yamasani public void releaseResources() { 2551da5a3e12f4f8f965c57d6f93c74190f43ea233f3Jeff Sharkey if (!mProviderReleased) { 25526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn ContentResolver.this.releaseProvider(mContentProvider); 2553da5a3e12f4f8f965c57d6f93c74190f43ea233f3Jeff Sharkey mProviderReleased = true; 25549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2558231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 2559231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 25600ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 2561231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 2562231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 2563231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 2564231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 2565231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 2566231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 256743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service binder = " + b); 2568231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 256943a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v("ContentService", "default service = " + sContentService); 2570231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 2571231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 25720ba1cb06c6a0332b76c469bd54dcf6f98128ac82Tom O'Neill 257335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn /** @hide */ 257435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public String getPackageName() { 257535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return mPackageName; 257635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 257735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 2578231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 258035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final String mPackageName; 25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 2582d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot 2583d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot /** @hide */ 2584d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot public int resolveUserId(Uri uri) { 2585d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot return ContentProvider.getUserIdFromUri(uri, mContext.getUserId()); 2586d85fc72fb810858f7502e7e7f1bad53e1bf03eddNicolas Prevot } 25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2588