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
19110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkeyimport static android.content.pm.PackageManager.PERMISSION_GRANTED;
20110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
222af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackbornimport android.content.pm.PathPermission;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ProviderInfo;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Configuration;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.SQLException;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
2923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport android.os.AsyncTask;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
311877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrickimport android.os.Bundle;
32a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal;
33a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal;
34a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.OperationCanceledException;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
362af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackbornimport android.os.Process;
3775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brownimport android.os.RemoteException;
38f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle;
390c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Noriimport android.util.Log;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
4218cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissenimport java.io.FileDescriptor;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
4423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.IOException;
4518cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissenimport java.io.PrintWriter;
4603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanaimport java.util.ArrayList;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Content providers are one of the primary building blocks of Android applications, providing
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * content to applications. They encapsulate data and provide it to applications through the single
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ContentResolver} interface. A content provider is only required if you need to share
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data between multiple applications. For example, the contacts data is used by multiple
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * applications and must be stored in a content provider. If you don't need to share data amongst
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * multiple applications you can use a database directly via
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.database.sqlite.SQLiteDatabase}.
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When a request is made via
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * request to the content provider registered with the authority. The content provider can interpret
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * URIs.</p>
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The primary methods that need to be implemented are:
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
656fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor *   <li>{@link #onCreate} which is called to initialize the provider</li>
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #query} which returns data to the caller</li>
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #insert} which inserts new data into the content provider</li>
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #update} which updates existing data in the content provider</li>
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #delete} which deletes data from the content provider</li>
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #getType} which returns the MIME type of data in the content provider</li>
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul></p>
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
736fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * <p class="caution">Data access methods (such as {@link #insert} and
746fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * {@link #update}) may be called from many threads at once, and must be thread-safe.
756fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * Other methods (such as {@link #onCreate}) are only called from the application
766fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * main thread, and must avoid performing lengthy operations.  See the method
776fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * descriptions for their expected thread behavior.</p>
786fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor *
796fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
806fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * ContentProvider instance, so subclasses don't have to worry about the details of
816fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * cross-process calls.</p>
82558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez *
83558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <div class="special reference">
84558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <h3>Developer Guides</h3>
85558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <p>For more information about using content providers, read the
86558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
87558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * developer guide.</p>
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
89c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackbornpublic abstract class ContentProvider implements ComponentCallbacks2 {
900c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    private static final String TAG = "ContentProvider";
910c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori
928280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    /*
938280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * Note: if you add methods to ContentProvider, you must add similar methods to
948280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     *       MockContentProvider.
958280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     */
968280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext = null;
982af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    private int mMyUid;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mReadPermission;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mWritePermission;
1012af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    private PathPermission[] mPathPermissions;
102b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn    private boolean mExported;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Transport mTransport = new Transport();
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1066fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor    /**
1076fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Construct a ContentProvider instance.  Content providers must be
1086fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <a href="{@docRoot}guide/topics/manifest/provider-element.html">declared
1096fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * in the manifest</a>, accessed with {@link ContentResolver}, and created
1106fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * automatically by the system, so applications usually do not create
1116fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * ContentProvider instances directly.
1126fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
1136fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>At construction time, the object is uninitialized, and most fields and
1146fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * methods are unavailable.  Subclasses should initialize themselves in
1156fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link #onCreate}, not the constructor.
1166fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
1176fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>Content providers are created on the application main thread at
1186fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * application launch time.  The constructor must not perform lengthy
1196fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * operations, or application startup will be delayed.
1206fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
1218280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    public ContentProvider() {
1228280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    }
1238280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa
1248280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    /**
1258280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * Constructor just for mocking.
1268280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     *
1278280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param context A Context object which should be some mock instance (like the
1288280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * instance of {@link android.test.mock.MockContext}).
1298280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param readPermission The read permision you want this instance should have in the
1308280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * test, which is available via {@link #getReadPermission()}.
1318280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param writePermission The write permission you want this instance should have
1328280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * in the test, which is available via {@link #getWritePermission()}.
1338280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param pathPermissions The PathPermissions you want this instance should have
1348280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * in the test, which is available via {@link #getPathPermissions()}.
1358280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @hide
1368280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     */
1378280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    public ContentProvider(
1388280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            Context context,
1398280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            String readPermission,
1408280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            String writePermission,
1418280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            PathPermission[] pathPermissions) {
1428280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mContext = context;
1438280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mReadPermission = readPermission;
1448280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mWritePermission = writePermission;
1458280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mPathPermissions = pathPermissions;
1468280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    }
1478280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Given an IContentProvider, try to coerce it back to the real
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider object if it is running in the local process.  This can
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be used if you know you are running in the same process as a provider,
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and want to get direct access to its implementation details.  Most
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clients should not nor have a reason to use it.
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param abstractInterface The ContentProvider interface that is to be
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              coerced.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return If the IContentProvider is non-null and local, returns its actual
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider instance.  Otherwise returns null.
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static ContentProvider coerceToLocalContentProvider(
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IContentProvider abstractInterface) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (abstractInterface instanceof Transport) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ((Transport)abstractInterface).getContentProvider();
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Binder object that deals with remoting.
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class Transport extends ContentProviderNative {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ContentProvider getContentProvider() {
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179d2183654e03d589b120467f4e98da1b178ceeadbJeff Brown        @Override
180d2183654e03d589b120467f4e98da1b178ceeadbJeff Brown        public String getProviderName() {
181d2183654e03d589b120467f4e98da1b178ceeadbJeff Brown            return getContentProvider().getClass().getName();
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Cursor query(Uri uri, String[] projection,
18675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                String selection, String[] selectionArgs, String sortOrder,
1874c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown                ICancellationSignal cancellationSignal) {
1882af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceReadPermission(uri);
18975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
1904c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown                    CancellationSignal.fromTransport(cancellationSignal));
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getType(Uri uri) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.getType(uri);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Uri insert(Uri uri, ContentValues initialValues) {
2002af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.insert(uri, initialValues);
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int bulkInsert(Uri uri, ContentValues[] initialValues) {
2062af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.bulkInsert(uri, initialValues);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
21103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
2128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                throws OperationApplicationException {
2138943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            for (ContentProviderOperation operation : operations) {
2148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                if (operation.isReadOperation()) {
215e3f054411b9f025848f68389c4e2c325e76b3826Dianne Hackborn                    enforceReadPermission(operation.getUri());
2168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                }
2178943737692169f564cd34a9c8d471f3a5d438712Fred Quintana
2188943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                if (operation.isWriteOperation()) {
219e3f054411b9f025848f68389c4e2c325e76b3826Dianne Hackborn                    enforceWritePermission(operation.getUri());
2208943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                }
2218943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            }
2228943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            return ContentProvider.this.applyBatch(operations);
2236a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        }
2246a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
22575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int delete(Uri uri, String selection, String[] selectionArgs) {
2272af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.delete(uri, selection, selectionArgs);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int update(Uri uri, ContentValues values, String selection,
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] selectionArgs) {
2342af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.update(uri, values, selection, selectionArgs);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ParcelFileDescriptor openFile(Uri uri, String mode)
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
2412af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
2422af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            else enforceReadPermission(uri);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openFile(uri, mode);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AssetFileDescriptor openAssetFile(Uri uri, String mode)
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
2492af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
2502af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            else enforceReadPermission(uri);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openAssetFile(uri, mode);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
255534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick        public Bundle call(String method, String arg, Bundle extras) {
256534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick            return ContentProvider.this.call(method, arg, extras);
2571877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick        }
2581877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick
25923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        @Override
26023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
26123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
26223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
26323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
26423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        @Override
26523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeType, Bundle opts)
26623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                throws FileNotFoundException {
26723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            enforceReadPermission(uri);
26823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return ContentProvider.this.openTypedAssetFile(uri, mimeType, opts);
26923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
27023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
27175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2724c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown        public ICancellationSignal createCancellationSignal() throws RemoteException {
2734c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown            return CancellationSignal.createTransport();
27475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        }
27575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
276e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey        private void enforceReadPermission(Uri uri) throws SecurityException {
2772af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final Context context = getContext();
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
279110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey            final int uid = Binder.getCallingUid();
280e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            String missingPerm = null;
281110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
2820d8af78b748d0279756c1ea8ae1659f6c2c802bbDianne Hackborn            if (UserHandle.isSameApp(uid, mMyUid)) {
283e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                return;
284e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            }
285110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
286e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            if (mExported) {
287110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                final String componentPerm = getReadPermission();
288e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                if (componentPerm != null) {
289e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
290e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                        return;
291e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    } else {
292e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                        missingPerm = componentPerm;
293e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    }
294110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                }
295110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
296110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // track if unprotected read is allowed; any denied
297110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // <path-permission> below removes this ability
298110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                boolean allowDefaultRead = (componentPerm == null);
299110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
300110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                final PathPermission[] pps = getPathPermissions();
301110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                if (pps != null) {
302110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                    final String path = uri.getPath();
303110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                    for (PathPermission pp : pps) {
304110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                        final String pathPerm = pp.getReadPermission();
305110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                        if (pathPerm != null && pp.match(path)) {
306110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                            if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
307e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                                return;
308110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                            } else {
309110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                                // any denied <path-permission> means we lose
310110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                                // default <provider> access.
311110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                                allowDefaultRead = false;
312e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                                missingPerm = pathPerm;
313110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                            }
3142af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        }
3152af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    }
3162af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                }
317110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
318110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // if we passed <path-permission> checks above, and no default
319110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // <provider> permission, then allow access.
320e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                if (allowDefaultRead) return;
3212af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
322110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
323110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey            // last chance, check against any uri grants
324110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey            if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
325110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                    == PERMISSION_GRANTED) {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
328110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
329e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            final String failReason = mExported
330e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    ? " requires " + missingPerm + ", or grantUriPermission()"
331e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    : " requires the provider be exported, or grantUriPermission()";
332e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            throw new SecurityException("Permission Denial: reading "
333e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
334e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    + ", uid=" + uid + failReason);
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
337e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey        private void enforceWritePermission(Uri uri) throws SecurityException {
3382af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final Context context = getContext();
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
340110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey            final int uid = Binder.getCallingUid();
341e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            String missingPerm = null;
342110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
3430d8af78b748d0279756c1ea8ae1659f6c2c802bbDianne Hackborn            if (UserHandle.isSameApp(uid, mMyUid)) {
344e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                return;
345e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            }
346110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
347e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            if (mExported) {
348110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                final String componentPerm = getWritePermission();
349e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                if (componentPerm != null) {
350e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
351e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                        return;
352e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    } else {
353e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                        missingPerm = componentPerm;
354e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    }
355110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                }
356110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
357110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // track if unprotected write is allowed; any denied
358110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // <path-permission> below removes this ability
359110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                boolean allowDefaultWrite = (componentPerm == null);
360110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
361110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                final PathPermission[] pps = getPathPermissions();
362110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                if (pps != null) {
363110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                    final String path = uri.getPath();
364110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                    for (PathPermission pp : pps) {
365110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                        final String pathPerm = pp.getWritePermission();
366110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                        if (pathPerm != null && pp.match(path)) {
367110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                            if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
368e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                                return;
369110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                            } else {
370110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                                // any denied <path-permission> means we lose
371110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                                // default <provider> access.
372110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                                allowDefaultWrite = false;
373e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                                missingPerm = pathPerm;
374110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                            }
3752af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        }
3762af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    }
3772af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                }
378110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
379110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // if we passed <path-permission> checks above, and no default
380110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                // <provider> permission, then allow access.
381e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                if (allowDefaultWrite) return;
3822af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
383110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey
384110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey            // last chance, check against any uri grants
385110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey            if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
386110a6b6252d6daf9882ece7595bd3613b82448a8Jeff Sharkey                    == PERMISSION_GRANTED) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
389e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey
390e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            final String failReason = mExported
391e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    ? " requires " + missingPerm + ", or grantUriPermission()"
392e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    : " requires the provider be exported, or grantUriPermission()";
393e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey            throw new SecurityException("Permission Denial: writing "
394e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
395e5d4933692343d082912856198fc3d207865d1ccJeff Sharkey                    + ", uid=" + uid + failReason);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4006fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Retrieves the Context this provider is running in.  Only available once
4016fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link #onCreate} has been called -- this will return null in the
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * constructor.
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Context getContext() {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContext;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read data from the content
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read-only access.
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setReadPermission(String permission) {
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReadPermission = permission;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read-only access to
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4237aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
4247aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getReadPermission() {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mReadPermission;
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read and write data in the content
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read/write access.
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setWritePermission(String permission) {
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWritePermission = permission;
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read/write access to
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4457aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
4467aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getWritePermission() {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWritePermission;
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4532af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * Change the path-based permission required to read and/or write data in
4542af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * the content provider.  This is normally set for you from its manifest
4552af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * information when the provider is first created.
4562af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     *
4572af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * @param permissions Array of path permission descriptions.
4582af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     */
4592af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    protected final void setPathPermissions(PathPermission[] permissions) {
4602af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        mPathPermissions = permissions;
4612af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    }
4622af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
4632af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    /**
4642af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * Return the path-based permissions required for read and/or write access to
4652af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * this content provider.  This method can be called from multiple
4662af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * threads, as described in
4677aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
4687aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
4692af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     */
4702af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    public final PathPermission[] getPathPermissions() {
4712af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        return mPathPermissions;
4722af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    }
4732af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
4742af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    /**
4756fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to initialize your content provider on startup.
4766fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method is called for all registered content providers on the
4776fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * application main thread at application launch time.  It must not perform
4786fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * lengthy operations, or application startup will be delayed.
4796fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
4806fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>You should defer nontrivial initialization (such as opening,
4816fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * upgrading, and scanning databases) until the content provider is used
4826fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * (via {@link #query}, {@link #insert}, etc).  Deferred initialization
4836fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * keeps application startup fast, avoids unnecessary work if the provider
4846fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * turns out not to be needed, and stops database errors (such as a full
4856fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * disk) from halting application launch.
4866fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
48717876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * <p>If you use SQLite, {@link android.database.sqlite.SQLiteOpenHelper}
4886fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * is a helpful utility class that makes it easy to manage databases,
4896fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * and will automatically defer opening until first use.  If you do use
4906fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * SQLiteOpenHelper, make sure to avoid calling
4916fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
4926fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
4936fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * from this method.  (Instead, override
4946fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
4956fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * database when it is first opened.)
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the provider was successfully loaded, false otherwise
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract boolean onCreate();
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5016fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor    /**
5026fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@inheritDoc}
5036fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method is always called on the application main thread, and must
5046fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * not perform lengthy operations.
5056fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
5066fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>The default content provider implementation does nothing.
5076fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Override this method to take appropriate action.
5086fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * (Content providers do not usually care about things like screen
5096fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * orientation, but may want to know about locale changes.)
5106fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5136fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor
5146fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor    /**
5156fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@inheritDoc}
5166fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method is always called on the application main thread, and must
5176fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * not perform lengthy operations.
5186fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
5196fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>The default content provider implementation does nothing.
5206fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Subclasses may override this method to take appropriate action.
5216fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onLowMemory() {
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
525c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackborn    public void onTrimMemory(int level) {
526c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackborn    }
527c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackborn
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5296fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle query requests from clients.
5306fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
5317aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
5327aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example client call:<p>
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// Request a specific record.
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Cursor managedCursor = managedQuery(
53781a476f654155df27aa564a4aebf931eab588e6dAlan Jones                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,    // Which columns to return.
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                null,          // WHERE clause.
54081a476f654155df27aa564a4aebf931eab588e6dAlan Jones                null,          // WHERE clause value substitution
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                People.NAME + " ASC");   // Sort order.</pre>
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example implementation:<p>
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// SQLiteQueryBuilder is a helper class that creates the
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // proper SQL syntax for us.
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the table we're querying.
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        qBuilder.setTables(DATABASE_TABLE_NAME);
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the query ends in a specific record number, we're
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // being asked for a specific record, so set the
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // WHERE clause in our query.
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make the query.
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = qBuilder.query(mDb,
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selection,
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selectionArgs,
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                groupBy,
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                having,
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sortOrder);
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.setNotificationUri(getContext().getContentResolver(), uri);
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;</pre>
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This will be the full URI sent by the client;
56981a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      if the client is requesting a specific record, the URI will end in a record number
57081a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
57181a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      that _id value.
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param projection The list of columns to put into the cursor. If
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      null all columns are included.
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection A selection criteria to apply when filtering rows.
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      If null then all rows are included.
57681a476f654155df27aa564a4aebf931eab588e6dAlan Jones     * @param selectionArgs You may include ?s in selection, which will be replaced by
57781a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      the values from selectionArgs, in order that they appear in the selection.
57881a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      The values will be bound as Strings.
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sortOrder How the rows in the cursor should be sorted.
58081a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      If null then the provider is free to define the sort order.
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor or null.
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Cursor query(Uri uri, String[] projection,
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String selection, String[] selectionArgs, String sortOrder);
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5865bba632d877c2878384ff21566c8eb6a1a22f37bFred Quintana    /**
5874c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown     * Implement this to handle query requests from clients with support for cancellation.
58875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * This method can be called from multiple threads, as described in
58975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
59075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * and Threads</a>.
59175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <p>
59275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * Example client call:<p>
59375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <pre>// Request a specific record.
59475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * Cursor managedCursor = managedQuery(
59575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
59675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                projection,    // Which columns to return.
59775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                null,          // WHERE clause.
59875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                null,          // WHERE clause value substitution
59975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                People.NAME + " ASC");   // Sort order.</pre>
60075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * Example implementation:<p>
60175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <pre>// SQLiteQueryBuilder is a helper class that creates the
60275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // proper SQL syntax for us.
60375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
60475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
60575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // Set the table we're querying.
60675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        qBuilder.setTables(DATABASE_TABLE_NAME);
60775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
60875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // If the query ends in a specific record number, we're
60975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // being asked for a specific record, so set the
61075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // WHERE clause in our query.
61175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
61275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
61375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        }
61475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
61575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // Make the query.
61675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        Cursor c = qBuilder.query(mDb,
61775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                projection,
61875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                selection,
61975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                selectionArgs,
62075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                groupBy,
62175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                having,
62275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                sortOrder);
62375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        c.setNotificationUri(getContext().getContentResolver(), uri);
62475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        return c;</pre>
62575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <p>
62675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * If you implement this method then you must also implement the version of
6274c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown     * {@link #query(Uri, String[], String, String[], String)} that does not take a cancellation
6284c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown     * signal to ensure correct operation on older versions of the Android Framework in
6294c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown     * which the cancellation signal overload was not available.
63075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *
63175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param uri The URI to query. This will be the full URI sent by the client;
63275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      if the client is requesting a specific record, the URI will end in a record number
63375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
63475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      that _id value.
63575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param projection The list of columns to put into the cursor. If
63675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      null all columns are included.
63775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param selection A selection criteria to apply when filtering rows.
63875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      If null then all rows are included.
63975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param selectionArgs You may include ?s in selection, which will be replaced by
64075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      the values from selectionArgs, in order that they appear in the selection.
64175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      The values will be bound as Strings.
64275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param sortOrder How the rows in the cursor should be sorted.
64375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      If null then the provider is free to define the sort order.
6444c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
64575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
64675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * when the query is executed.
64775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @return a Cursor or null.
64875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     */
64975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    public Cursor query(Uri uri, String[] projection,
65075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            String selection, String[] selectionArgs, String sortOrder,
6514c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown            CancellationSignal cancellationSignal) {
65275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        return query(uri, projection, selection, selectionArgs, sortOrder);
65375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    }
65475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
65575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    /**
6566fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle requests for the MIME type of the data at the
6576fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * given URI.  The returned MIME type should start with
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>vnd.android.cursor.item</code> for a single record,
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or <code>vnd.android.cursor.dir/</code> for multiple items.
6606fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
6617aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
6627aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
664cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * <p>Note that there are no permissions needed for an application to
665cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * access this information; if your content provider requires read and/or
666cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * write permissions, or is not exported, all applications can still call
667cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * this method regardless of their access permissions.  This allows them
668cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * to retrieve the MIME type for a URI when dispatching intents.
669cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     *
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri the URI to query.
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a MIME type string, or null if there is no type.
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract String getType(Uri uri);
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6766fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle requests to insert a new row.
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
6796fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
6807aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
6817aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A set of column_name/value pairs to add to the database.
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The URI for the newly inserted item.
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Uri insert(Uri uri, ContentValues values);
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6896fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Override this to handle requests to insert a set of new rows, or the
6906fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * default implementation will iterate over the values and call
6916fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link #insert} on each of them.
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
6946fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
6957aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
6967aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values An array of sets of column_name/value pairs to add to the database.
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of values that were inserted.
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int bulkInsert(Uri uri, ContentValues[] values) {
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numValues = values.length;
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < numValues; i++) {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            insert(uri, values[i]);
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return numValues;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7116fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle requests to delete one or more rows.
7126fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * The implementation should apply the selection clause when performing
7136fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * deletion, allowing the operation to affect multiple rows in a directory.
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after deleting.
7166fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
7177aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
7187aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The implementation is responsible for parsing out a row ID at the end
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the URI, if a specific row is being deleted. That is, the client would
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pass in <code>content://contacts/people/22</code> and the implementation is
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * responsible for parsing the record number (22) when creating a SQL statement.
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The full URI to query, including a row ID (if a specific record is requested).
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional restriction to apply to rows when deleting.
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of rows affected.
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SQLException
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int delete(Uri uri, String selection, String[] selectionArgs);
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
73317876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * Implement this to handle requests to update one or more rows.
7346fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * The implementation should update all rows matching the selection
7356fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * to set the columns according to the provided values map.
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after updating.
7386fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
7397aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
7407aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This can potentially have a record ID if this
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is an update request for a specific record.
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A Bundle mapping from column names to new column values (NULL is a
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               valid value).
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional filter to match rows to update.
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the number of rows affected.
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int update(Uri uri, ContentValues values, String selection,
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] selectionArgs);
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
75317876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * Override this to handle requests to open a file blob.
7546fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * The default implementation always throws {@link FileNotFoundException}.
7556fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
7567aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
7577aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
7586fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
75917876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * <p>This method returns a ParcelFileDescriptor, which is returned directly
76017876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * to the caller.  This way large data (such as images and documents) can be
7616fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * returned without copying the content.
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their responsibility to close it when done.  That is, the implementation
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of this method should create a new ParcelFileDescriptor for each call.
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access, or "rwt" for read and write access
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that truncates any existing file.
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor which you can use to access
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
7796fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openAssetFile(Uri, String)
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
7826fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ParcelFileDescriptor openFile(Uri uri, String mode)
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw new FileNotFoundException("No files supported by provider at "
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + uri);
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7886fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is like {@link #openFile}, but can be implemented by providers
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that need to be able to return sub-sections of files, often assets
7926fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * inside of their .apk.
7936fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
7947aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
7957aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
7966fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
7976fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>If you implement this, your clients must be able to deal with such
79817876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * file slices, either directly with
7996fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * methods.
8036fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
8046fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p class="note">If you are implementing this to return a full file, you
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should create the AssetFileDescriptor with
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
8076fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * applications that can not handle sub-sections of files.</p>
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new AssetFileDescriptor which you can use to access
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFile(Uri, String)
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AssetFileDescriptor openAssetFile(Uri uri, String mode)
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ParcelFileDescriptor fd = openFile(uri, mode);
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Convenience for subclasses that wish to implement {@link #openFile}
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by looking up a column named "_data" at the given URI.
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to be opened.
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode The file mode.  May be "r" for read-only access,
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor that can be used by the
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * client to access the file.
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final ParcelFileDescriptor openFileHelper(Uri uri,
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String mode) throws FileNotFoundException {
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = query(uri, new String[]{"_data"}, null, null, null);
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = (c != null) ? c.getCount() : 0;
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count != 1) {
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If there is not exactly one result, throw an appropriate
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // exception.
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != null) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c.close();
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (count == 0) {
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new FileNotFoundException("No entry for " + uri);
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Multiple items at " + uri);
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.moveToFirst();
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i = c.getColumnIndex("_data");
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String path = (i >= 0 ? c.getString(i) : null);
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.close();
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (path == null) {
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Column _data not found.");
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int modeBits = ContentResolver.modeToMode(uri, mode);
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ParcelFileDescriptor.open(new File(path), modeBits);
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
87623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Called by a client to determine the types of data streams that this
87723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * content provider supports for the given URI.  The default implementation
87823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * returns null, meaning no types.  If your content provider stores data
87923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * of a particular type, return that MIME type if it matches the given
88023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * mimeTypeFilter.  If it can perform type conversions, return an array
88123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * of all supported MIME types that match mimeTypeFilter.
88223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
88323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param uri The data in the content provider being queried.
88423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param mimeTypeFilter The type of data the client desires.  May be
88523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * a pattern, such as *\/* to retrieve all possible data types.
8863f00be5bd0b46e7937b68909baeff295b86215ccDianne Hackborn     * @return Returns null if there are no possible data streams for the
88723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * given mimeTypeFilter.  Otherwise returns an array of all available
88823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * concrete MIME types.
88923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
89023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #getType(Uri)
89123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #openTypedAssetFile(Uri, String, Bundle)
8921040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn     * @see ClipDescription#compareMimeTypes(String, String)
89323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
89423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
89523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        return null;
89623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
89723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
89823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
89923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Called by a client to open a read-only stream containing data of a
90023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * particular MIME type.  This is like {@link #openAssetFile(Uri, String)},
90123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * except the file can only be read-only and the content provider may
90223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * perform data conversions to generate data of the desired type.
90323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
90423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * <p>The default implementation compares the given mimeType against the
90523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * result of {@link #getType(Uri)} and, if the match, simple calls
90623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * {@link #openAssetFile(Uri, String)}.
90723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
9081040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn     * <p>See {@link ClipData} for examples of the use and implementation
90923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * of this method.
91023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
91123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param uri The data in the content provider being queried.
91223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param mimeTypeFilter The type of data the client desires.  May be
91323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * a pattern, such as *\/*, if the caller does not have specific type
91423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * requirements; in this case the content provider will pick its best
91523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * type matching the pattern.
91623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param opts Additional options from the client.  The definitions of
91723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * these are specific to the content provider being called.
91823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
91923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @return Returns a new AssetFileDescriptor from which the client can
92023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * read data of the desired type.
92123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
92223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @throws FileNotFoundException Throws FileNotFoundException if there is
92323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * no file associated with the given URI or the mode is invalid.
92423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @throws SecurityException Throws SecurityException if the caller does
92523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * not have permission to access the data.
92623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @throws IllegalArgumentException Throws IllegalArgumentException if the
92723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * content provider does not support the requested MIME type.
92823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
92923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #getStreamTypes(Uri, String)
93023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #openAssetFile(Uri, String)
9311040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn     * @see ClipDescription#compareMimeTypes(String, String)
93223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
93323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
93423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throws FileNotFoundException {
93502dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn        if ("*/*".equals(mimeTypeFilter)) {
93602dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            // If they can take anything, the untyped open call is good enough.
93702dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            return openAssetFile(uri, "r");
93802dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn        }
93923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        String baseType = getType(uri);
9401040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn        if (baseType != null && ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) {
94102dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            // Use old untyped open call if this provider has a type for this
94202dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            // URI and it matches the request.
94323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return openAssetFile(uri, "r");
94423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
94523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
94623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
94723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
94823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
94923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Interface to write a stream of data to a pipe.  Use with
95023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * {@link ContentProvider#openPipeHelper}.
95123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
95223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public interface PipeDataWriter<T> {
95323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        /**
95423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * Called from a background thread to stream data out to a pipe.
95523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * Note that the pipe is blocking, so this thread can block on
95623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * writes for an arbitrary amount of time if the client is slow
95723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * at reading.
95823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         *
95923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param output The pipe where data should be written.  This will be
96023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * closed for you upon returning from this function.
96123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param uri The URI whose data is to be written.
96223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param mimeType The desired type of data to be written.
96323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param opts Options supplied by caller.
96423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param args Your own custom arguments.
96523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         */
96623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
96723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                Bundle opts, T args);
96823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
96923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
97023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
97123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * A helper function for implementing {@link #openTypedAssetFile}, for
97223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * creating a data pipe and background thread allowing you to stream
97323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * generated data back to the client.  This function returns a new
97423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * ParcelFileDescriptor that should be returned to the caller (the caller
97523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * is responsible for closing it).
97623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
97723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param uri The URI whose data is to be written.
97823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param mimeType The desired type of data to be written.
97923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param opts Options supplied by caller.
98023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param args Your own custom arguments.
98123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param func Interface implementing the function that will actually
98223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * stream the data.
98323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @return Returns a new ParcelFileDescriptor holding the read side of
98423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * the pipe.  This should be returned to the caller for reading; the caller
98523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * is responsible for closing it when done.
98623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
98723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public <T> ParcelFileDescriptor openPipeHelper(final Uri uri, final String mimeType,
98823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            final Bundle opts, final T args, final PipeDataWriter<T> func)
98923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throws FileNotFoundException {
99023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        try {
99123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
99223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
99323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
99423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                @Override
99523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                protected Object doInBackground(Object... params) {
99623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    func.writeDataToPipe(fds[1], uri, mimeType, opts, args);
99723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    try {
99823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                        fds[1].close();
99923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    } catch (IOException e) {
100023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                        Log.w(TAG, "Failure closing pipe", e);
100123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    }
100223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    return null;
100323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                }
100423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            };
10055d9d03a0234faa3cffd11502f973057045cafe82Dianne Hackborn            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null);
100623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
100723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return fds[0];
100823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        } catch (IOException e) {
100923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throw new FileNotFoundException("failure making pipe");
101023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
101123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
101223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
101323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this instance is a temporary content provider.
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if this instance is a temporary content provider
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean isTemporary() {
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the Binder object for this provider.
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the Binder object for this provider
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IContentProvider getIContentProvider() {
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTransport;
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After being instantiated, this is called to tell the content provider
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * about itself.
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context this provider is running in
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Registered information about this content provider
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachInfo(Context context, ProviderInfo info) {
103923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        /*
104023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * We may be using AsyncTask from binder threads.  Make it init here
104123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * so its static handler is on the main thread.
104223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         */
104323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        AsyncTask.init();
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Only allow it to be set once, so after the content service gives
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this to us clients can't change it.
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mContext == null) {
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
10512af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            mMyUid = Process.myUid();
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (info != null) {
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setReadPermission(info.readPermission);
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setWritePermission(info.writePermission);
10552af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                setPathPermissions(info.pathPermissions);
1056b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn                mExported = info.exported;
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ContentProvider.this.onCreate();
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1061ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana
1062ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana    /**
106317876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * Override this to handle requests to perform a batch of operations, or the
106417876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * default implementation will iterate over the operations and call
106517876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * {@link ContentProviderOperation#apply} on each of them.
106617876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * If all calls to {@link ContentProviderOperation#apply} succeed
106717876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * then a {@link ContentProviderResult} array with as many
106817876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * elements as there were operations will be returned.  If any of the calls
10696fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * fail, it is up to the implementation how many of the others take effect.
10706fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
10717aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
10727aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
10736fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
1074ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana     * @param operations the operations to apply
1075ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana     * @return the results of the applications
10766fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * @throws OperationApplicationException thrown if any operation fails.
10776fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * @see ContentProviderOperation#apply
1078ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana     */
107903d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
1080ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana            throws OperationApplicationException {
108103d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        final int numOperations = operations.size();
108203d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        final ContentProviderResult[] results = new ContentProviderResult[numOperations];
108303d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        for (int i = 0; i < numOperations; i++) {
108403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana            results[i] = operations.get(i).apply(this, results, i);
1085ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana        }
1086ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana        return results;
1087ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana    }
10881877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick
10891877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick    /**
10902c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Call a provider-defined method.  This can be used to implement
1091534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * interfaces that are cheaper and/or unnatural for a table-like
1092534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * model.
10931877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick     *
1094534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @param method method name to call.  Opaque to framework, but should not be null.
1095534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @param arg provider-defined String argument.  May be null.
1096534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @param extras provider-defined Bundle argument.  May be null.
1097534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @return provider-defined return value.  May be null.  Null is also
1098534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     *   the default for providers which don't implement any call methods.
10991877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick     */
1100534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick    public Bundle call(String method, String arg, Bundle extras) {
11011877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick        return null;
11021877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick    }
11030c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori
11040c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    /**
11052c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Implement this to shut down the ContentProvider instance. You can then
11062c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * invoke this method in unit tests.
11072c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     *
11080c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori     * <p>
11092c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Android normally handles ContentProvider startup and shutdown
11102c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * automatically. You do not need to start up or shut down a
11112c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * ContentProvider. When you invoke a test method on a ContentProvider,
11122c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * however, a ContentProvider instance is started and keeps running after
11132c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * the test finishes, even if a succeeding test instantiates another
11142c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * ContentProvider. A conflict develops because the two instances are
11152c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * usually running against the same underlying data source (for example, an
11162c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * sqlite database).
11172c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * </p>
11180c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori     * <p>
11192c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Implementing shutDown() avoids this conflict by providing a way to
11202c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * terminate the ContentProvider. This method can also prevent memory leaks
11212c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * from multiple instantiations of the ContentProvider, and it can ensure
11222c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * unit test isolation by allowing you to completely clean up the test
11232c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * fixture before moving on to the next test.
11242c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * </p>
11250c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori     */
11260c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    public void shutdown() {
11270c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori        Log.w(TAG, "implement ContentProvider shutdown() to make sure all database " +
11280c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori                "connections are gracefully shutdown");
11290c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    }
113018cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen
113118cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen    /**
113218cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * Print the Provider's state into the given stream.  This gets invoked if
11335554b7082220d37496e30f39a0d9146afc177ab4Jeff Sharkey     * you run "adb shell dumpsys activity provider &lt;provider_component_name&gt;".
113418cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     *
113518cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param prefix Desired prefix to prepend at each line of output.
113618cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param fd The raw file descriptor that the dump is being sent to.
113718cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param writer The PrintWriter to which you should dump your state.  This will be
113818cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * closed for you after you return.
113918cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param args additional arguments to the dump request.
114018cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @hide
114118cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     */
114218cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
114318cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen        writer.println("nothing to dump");
114418cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen    }
11451877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick}
1146