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