ContentProvider.java revision 75ea64fc54f328d37b115cfb1ded1e45c30380ed
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
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
202af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackbornimport android.content.pm.PathPermission;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ProviderInfo;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Configuration;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.SQLException;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
2723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport android.os.AsyncTask;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
291877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrickimport android.os.Bundle;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
312af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackbornimport android.os.Process;
3275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brownimport android.os.RemoteException;
330c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Noriimport android.util.Log;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
3618cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissenimport java.io.FileDescriptor;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
3823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.IOException;
3918cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissenimport java.io.PrintWriter;
4003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanaimport java.util.ArrayList;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Content providers are one of the primary building blocks of Android applications, providing
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * content to applications. They encapsulate data and provide it to applications through the single
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ContentResolver} interface. A content provider is only required if you need to share
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data between multiple applications. For example, the contacts data is used by multiple
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * applications and must be stored in a content provider. If you don't need to share data amongst
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * multiple applications you can use a database directly via
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.database.sqlite.SQLiteDatabase}.
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When a request is made via
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * request to the content provider registered with the authority. The content provider can interpret
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * URIs.</p>
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The primary methods that need to be implemented are:
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
596fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor *   <li>{@link #onCreate} which is called to initialize the provider</li>
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #query} which returns data to the caller</li>
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #insert} which inserts new data into the content provider</li>
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #update} which updates existing data in the content provider</li>
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #delete} which deletes data from the content provider</li>
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #getType} which returns the MIME type of data in the content provider</li>
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul></p>
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
676fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * <p class="caution">Data access methods (such as {@link #insert} and
686fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * {@link #update}) may be called from many threads at once, and must be thread-safe.
696fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * Other methods (such as {@link #onCreate}) are only called from the application
706fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * main thread, and must avoid performing lengthy operations.  See the method
716fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * descriptions for their expected thread behavior.</p>
726fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor *
736fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
746fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * ContentProvider instance, so subclasses don't have to worry about the details of
756fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor * cross-process calls.</p>
76558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez *
77558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <div class="special reference">
78558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <h3>Developer Guides</h3>
79558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <p>For more information about using content providers, read the
80558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
81558459fe85f56f29a6ed6a4d0adb4a0bd6665884Joe Fernandez * developer guide.</p>
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
83c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackbornpublic abstract class ContentProvider implements ComponentCallbacks2 {
840c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    private static final String TAG = "ContentProvider";
850c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori
868280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    /*
878280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * Note: if you add methods to ContentProvider, you must add similar methods to
888280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     *       MockContentProvider.
898280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     */
908280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext = null;
922af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    private int mMyUid;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mReadPermission;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mWritePermission;
952af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    private PathPermission[] mPathPermissions;
96b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn    private boolean mExported;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Transport mTransport = new Transport();
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1006fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor    /**
1016fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Construct a ContentProvider instance.  Content providers must be
1026fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <a href="{@docRoot}guide/topics/manifest/provider-element.html">declared
1036fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * in the manifest</a>, accessed with {@link ContentResolver}, and created
1046fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * automatically by the system, so applications usually do not create
1056fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * ContentProvider instances directly.
1066fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
1076fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>At construction time, the object is uninitialized, and most fields and
1086fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * methods are unavailable.  Subclasses should initialize themselves in
1096fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link #onCreate}, not the constructor.
1106fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
1116fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>Content providers are created on the application main thread at
1126fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * application launch time.  The constructor must not perform lengthy
1136fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * operations, or application startup will be delayed.
1146fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
1158280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    public ContentProvider() {
1168280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    }
1178280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa
1188280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    /**
1198280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * Constructor just for mocking.
1208280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     *
1218280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param context A Context object which should be some mock instance (like the
1228280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * instance of {@link android.test.mock.MockContext}).
1238280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param readPermission The read permision you want this instance should have in the
1248280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * test, which is available via {@link #getReadPermission()}.
1258280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param writePermission The write permission you want this instance should have
1268280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * in the test, which is available via {@link #getWritePermission()}.
1278280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @param pathPermissions The PathPermissions you want this instance should have
1288280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * in the test, which is available via {@link #getPathPermissions()}.
1298280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     * @hide
1308280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa     */
1318280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    public ContentProvider(
1328280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            Context context,
1338280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            String readPermission,
1348280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            String writePermission,
1358280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa            PathPermission[] pathPermissions) {
1368280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mContext = context;
1378280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mReadPermission = readPermission;
1388280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mWritePermission = writePermission;
1398280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa        mPathPermissions = pathPermissions;
1408280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa    }
1418280c2b15f6875b2d387c05df23d264864eb9cd5Daisuke Miyakawa
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Given an IContentProvider, try to coerce it back to the real
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider object if it is running in the local process.  This can
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be used if you know you are running in the same process as a provider,
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and want to get direct access to its implementation details.  Most
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clients should not nor have a reason to use it.
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param abstractInterface The ContentProvider interface that is to be
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              coerced.
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return If the IContentProvider is non-null and local, returns its actual
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider instance.  Otherwise returns null.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static ContentProvider coerceToLocalContentProvider(
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IContentProvider abstractInterface) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (abstractInterface instanceof Transport) {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ((Transport)abstractInterface).getContentProvider();
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Binder object that deals with remoting.
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class Transport extends ContentProviderNative {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ContentProvider getContentProvider() {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
173d2183654e03d589b120467f4e98da1b178ceeadbJeff Brown        @Override
174d2183654e03d589b120467f4e98da1b178ceeadbJeff Brown        public String getProviderName() {
175d2183654e03d589b120467f4e98da1b178ceeadbJeff Brown            return getContentProvider().getClass().getName();
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Cursor query(Uri uri, String[] projection,
18075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                String selection, String[] selectionArgs, String sortOrder,
18175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                ICancelationSignal cancelationSignal) {
1822af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceReadPermission(uri);
18375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
18475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                    CancelationSignal.fromTransport(cancelationSignal));
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getType(Uri uri) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.getType(uri);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Uri insert(Uri uri, ContentValues initialValues) {
1942af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.insert(uri, initialValues);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int bulkInsert(Uri uri, ContentValues[] initialValues) {
2002af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.bulkInsert(uri, initialValues);
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
20503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
2068943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                throws OperationApplicationException {
2078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            for (ContentProviderOperation operation : operations) {
2088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                if (operation.isReadOperation()) {
209e3f054411b9f025848f68389c4e2c325e76b3826Dianne Hackborn                    enforceReadPermission(operation.getUri());
2108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                }
2118943737692169f564cd34a9c8d471f3a5d438712Fred Quintana
2128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                if (operation.isWriteOperation()) {
213e3f054411b9f025848f68389c4e2c325e76b3826Dianne Hackborn                    enforceWritePermission(operation.getUri());
2148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana                }
2158943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            }
2168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            return ContentProvider.this.applyBatch(operations);
2176a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        }
2186a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
21975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int delete(Uri uri, String selection, String[] selectionArgs) {
2212af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.delete(uri, selection, selectionArgs);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int update(Uri uri, ContentValues values, String selection,
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] selectionArgs) {
2282af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.update(uri, values, selection, selectionArgs);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ParcelFileDescriptor openFile(Uri uri, String mode)
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
2352af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
2362af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            else enforceReadPermission(uri);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openFile(uri, mode);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AssetFileDescriptor openAssetFile(Uri uri, String mode)
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
2432af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
2442af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            else enforceReadPermission(uri);
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openAssetFile(uri, mode);
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
249534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick        public Bundle call(String method, String arg, Bundle extras) {
250534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick            return ContentProvider.this.call(method, arg, extras);
2511877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick        }
2521877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick
25323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        @Override
25423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
25523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
25623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
25723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
25823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        @Override
25923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeType, Bundle opts)
26023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                throws FileNotFoundException {
26123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            enforceReadPermission(uri);
26223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return ContentProvider.this.openTypedAssetFile(uri, mimeType, opts);
26323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
26423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
26575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        @Override
26675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        public ICancelationSignal createCancelationSignal() throws RemoteException {
26775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            return CancelationSignal.createTransport();
26875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        }
26975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
2702af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        private void enforceReadPermission(Uri uri) {
2712af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final int uid = Binder.getCallingUid();
2722af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (uid == mMyUid) {
2732af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return;
2742af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
2752af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2762af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final Context context = getContext();
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final String rperm = getReadPermission();
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
279b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn            if (mExported && (rperm == null
2802af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    || context.checkPermission(rperm, pid, uid)
281b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn                    == PackageManager.PERMISSION_GRANTED)) {
2822af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return;
2832af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
2842af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2852af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            PathPermission[] pps = getPathPermissions();
2862af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (pps != null) {
2872af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                final String path = uri.getPath();
2882af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                int i = pps.length;
2892af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                while (i > 0) {
2902af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    i--;
2912af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final PathPermission pp = pps[i];
2922af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final String pprperm = pp.getReadPermission();
2932af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    if (pprperm != null && pp.match(path)) {
2942af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        if (context.checkPermission(pprperm, pid, uid)
2952af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                                == PackageManager.PERMISSION_GRANTED) {
2962af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                            return;
2972af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        }
2982af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    }
2992af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                }
3002af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
3012af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3022af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (context.checkUriPermission(uri, pid, uid,
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Intent.FLAG_GRANT_READ_URI_PERMISSION)
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    == PackageManager.PERMISSION_GRANTED) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3072af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String msg = "Permission Denial: reading "
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ContentProvider.this.getClass().getName()
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " uri " + uri + " from pid=" + Binder.getCallingPid()
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid()
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " requires " + rperm;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException(msg);
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3162af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        private boolean hasWritePermission(Uri uri) {
3172af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final int uid = Binder.getCallingUid();
3182af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (uid == mMyUid) {
3192af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return true;
3202af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
3212af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3222af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final Context context = getContext();
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final String wperm = getWritePermission();
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
325b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn            if (mExported && (wperm == null
3262af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    || context.checkPermission(wperm, pid, uid)
327b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn                    == PackageManager.PERMISSION_GRANTED)) {
3282af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return true;
3292af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
3302af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3312af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            PathPermission[] pps = getPathPermissions();
3322af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (pps != null) {
3332af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                final String path = uri.getPath();
3342af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                int i = pps.length;
3352af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                while (i > 0) {
3362af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    i--;
3372af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final PathPermission pp = pps[i];
3382af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final String ppwperm = pp.getWritePermission();
3392af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    if (ppwperm != null && pp.match(path)) {
3402af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        if (context.checkPermission(ppwperm, pid, uid)
3412af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                                == PackageManager.PERMISSION_GRANTED) {
3422af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                            return true;
3432af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        }
3442af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    }
3452af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                }
3462af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
3472af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3482af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (context.checkUriPermission(uri, pid, uid,
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    == PackageManager.PERMISSION_GRANTED) {
3512af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return true;
3522af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
3532af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3542af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            return false;
3552af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        }
3562af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3572af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        private void enforceWritePermission(Uri uri) {
3582af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (hasWritePermission(uri)) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3612af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String msg = "Permission Denial: writing "
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ContentProvider.this.getClass().getName()
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " uri " + uri + " from pid=" + Binder.getCallingPid()
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid()
3662af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    + " requires " + getWritePermission();
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException(msg);
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3736fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Retrieves the Context this provider is running in.  Only available once
3746fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link #onCreate} has been called -- this will return null in the
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * constructor.
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Context getContext() {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContext;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read data from the content
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read-only access.
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setReadPermission(String permission) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReadPermission = permission;
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read-only access to
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
3967aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
3977aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getReadPermission() {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mReadPermission;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read and write data in the content
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read/write access.
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setWritePermission(String permission) {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWritePermission = permission;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read/write access to
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4187aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
4197aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getWritePermission() {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWritePermission;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4262af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * Change the path-based permission required to read and/or write data in
4272af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * the content provider.  This is normally set for you from its manifest
4282af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * information when the provider is first created.
4292af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     *
4302af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * @param permissions Array of path permission descriptions.
4312af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     */
4322af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    protected final void setPathPermissions(PathPermission[] permissions) {
4332af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        mPathPermissions = permissions;
4342af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    }
4352af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
4362af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    /**
4372af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * Return the path-based permissions required for read and/or write access to
4382af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * this content provider.  This method can be called from multiple
4392af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * threads, as described in
4407aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
4417aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
4422af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     */
4432af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    public final PathPermission[] getPathPermissions() {
4442af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        return mPathPermissions;
4452af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    }
4462af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
4472af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    /**
4486fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to initialize your content provider on startup.
4496fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method is called for all registered content providers on the
4506fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * application main thread at application launch time.  It must not perform
4516fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * lengthy operations, or application startup will be delayed.
4526fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
4536fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>You should defer nontrivial initialization (such as opening,
4546fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * upgrading, and scanning databases) until the content provider is used
4556fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * (via {@link #query}, {@link #insert}, etc).  Deferred initialization
4566fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * keeps application startup fast, avoids unnecessary work if the provider
4576fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * turns out not to be needed, and stops database errors (such as a full
4586fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * disk) from halting application launch.
4596fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
46017876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * <p>If you use SQLite, {@link android.database.sqlite.SQLiteOpenHelper}
4616fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * is a helpful utility class that makes it easy to manage databases,
4626fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * and will automatically defer opening until first use.  If you do use
4636fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * SQLiteOpenHelper, make sure to avoid calling
4646fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
4656fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
4666fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * from this method.  (Instead, override
4676fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
4686fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * database when it is first opened.)
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the provider was successfully loaded, false otherwise
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract boolean onCreate();
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4746fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor    /**
4756fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@inheritDoc}
4766fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method is always called on the application main thread, and must
4776fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * not perform lengthy operations.
4786fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
4796fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>The default content provider implementation does nothing.
4806fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Override this method to take appropriate action.
4816fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * (Content providers do not usually care about things like screen
4826fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * orientation, but may want to know about locale changes.)
4836fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4866fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor
4876fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor    /**
4886fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@inheritDoc}
4896fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method is always called on the application main thread, and must
4906fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * not perform lengthy operations.
4916fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
4926fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>The default content provider implementation does nothing.
4936fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Subclasses may override this method to take appropriate action.
4946fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onLowMemory() {
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
498c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackborn    public void onTrimMemory(int level) {
499c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackborn    }
500c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackborn
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5026fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle query requests from clients.
5036fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
5047aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
5057aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example client call:<p>
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// Request a specific record.
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Cursor managedCursor = managedQuery(
51081a476f654155df27aa564a4aebf931eab588e6dAlan Jones                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,    // Which columns to return.
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                null,          // WHERE clause.
51381a476f654155df27aa564a4aebf931eab588e6dAlan Jones                null,          // WHERE clause value substitution
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                People.NAME + " ASC");   // Sort order.</pre>
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example implementation:<p>
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// SQLiteQueryBuilder is a helper class that creates the
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // proper SQL syntax for us.
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the table we're querying.
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        qBuilder.setTables(DATABASE_TABLE_NAME);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the query ends in a specific record number, we're
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // being asked for a specific record, so set the
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // WHERE clause in our query.
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make the query.
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = qBuilder.query(mDb,
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selection,
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selectionArgs,
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                groupBy,
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                having,
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sortOrder);
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.setNotificationUri(getContext().getContentResolver(), uri);
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;</pre>
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This will be the full URI sent by the client;
54281a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      if the client is requesting a specific record, the URI will end in a record number
54381a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
54481a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      that _id value.
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param projection The list of columns to put into the cursor. If
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      null all columns are included.
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection A selection criteria to apply when filtering rows.
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      If null then all rows are included.
54981a476f654155df27aa564a4aebf931eab588e6dAlan Jones     * @param selectionArgs You may include ?s in selection, which will be replaced by
55081a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      the values from selectionArgs, in order that they appear in the selection.
55181a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      The values will be bound as Strings.
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sortOrder How the rows in the cursor should be sorted.
55381a476f654155df27aa564a4aebf931eab588e6dAlan Jones     *      If null then the provider is free to define the sort order.
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor or null.
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Cursor query(Uri uri, String[] projection,
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String selection, String[] selectionArgs, String sortOrder);
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5595bba632d877c2878384ff21566c8eb6a1a22f37bFred Quintana    /**
56075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * Implement this to handle query requests from clients with support for cancelation.
56175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * This method can be called from multiple threads, as described in
56275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
56375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * and Threads</a>.
56475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <p>
56575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * Example client call:<p>
56675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <pre>// Request a specific record.
56775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * Cursor managedCursor = managedQuery(
56875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
56975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                projection,    // Which columns to return.
57075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                null,          // WHERE clause.
57175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                null,          // WHERE clause value substitution
57275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                People.NAME + " ASC");   // Sort order.</pre>
57375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * Example implementation:<p>
57475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <pre>// SQLiteQueryBuilder is a helper class that creates the
57575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // proper SQL syntax for us.
57675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
57775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
57875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // Set the table we're querying.
57975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        qBuilder.setTables(DATABASE_TABLE_NAME);
58075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
58175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // If the query ends in a specific record number, we're
58275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // being asked for a specific record, so set the
58375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // WHERE clause in our query.
58475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
58575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
58675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        }
58775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
58875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        // Make the query.
58975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        Cursor c = qBuilder.query(mDb,
59075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                projection,
59175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                selection,
59275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                selectionArgs,
59375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                groupBy,
59475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                having,
59575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                sortOrder);
59675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        c.setNotificationUri(getContext().getContentResolver(), uri);
59775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        return c;</pre>
59875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * <p>
59975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * If you implement this method then you must also implement the version of
60075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * {@link #query(Uri, String[], String, String[], String)} that does not take a cancelation
60175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * provider to ensure correct operation on older versions of the Android Framework in
60275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * which the cancelation signal overload was not available.
60375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *
60475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param uri The URI to query. This will be the full URI sent by the client;
60575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      if the client is requesting a specific record, the URI will end in a record number
60675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
60775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      that _id value.
60875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param projection The list of columns to put into the cursor. If
60975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      null all columns are included.
61075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param selection A selection criteria to apply when filtering rows.
61175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      If null then all rows are included.
61275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param selectionArgs You may include ?s in selection, which will be replaced by
61375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      the values from selectionArgs, in order that they appear in the selection.
61475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      The values will be bound as Strings.
61575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param sortOrder How the rows in the cursor should be sorted.
61675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     *      If null then the provider is free to define the sort order.
61775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
61875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
61975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * when the query is executed.
62075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     * @return a Cursor or null.
62175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown     */
62275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    public Cursor query(Uri uri, String[] projection,
62375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            String selection, String[] selectionArgs, String sortOrder,
62475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            CancelationSignal cancelationSignal) {
62575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        return query(uri, projection, selection, selectionArgs, sortOrder);
62675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    }
62775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
62875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    /**
6296fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle requests for the MIME type of the data at the
6306fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * given URI.  The returned MIME type should start with
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>vnd.android.cursor.item</code> for a single record,
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or <code>vnd.android.cursor.dir/</code> for multiple items.
6336fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
6347aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
6357aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
637cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * <p>Note that there are no permissions needed for an application to
638cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * access this information; if your content provider requires read and/or
639cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * write permissions, or is not exported, all applications can still call
640cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * this method regardless of their access permissions.  This allows them
641cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     * to retrieve the MIME type for a URI when dispatching intents.
642cca1f0e3476edd09cdd81b075a6b7780a2959b46Dianne Hackborn     *
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri the URI to query.
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a MIME type string, or null if there is no type.
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract String getType(Uri uri);
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6496fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle requests to insert a new row.
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
6526fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
6537aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
6547aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A set of column_name/value pairs to add to the database.
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The URI for the newly inserted item.
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Uri insert(Uri uri, ContentValues values);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6626fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Override this to handle requests to insert a set of new rows, or the
6636fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * default implementation will iterate over the values and call
6646fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link #insert} on each of them.
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
6676fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
6687aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
6697aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values An array of sets of column_name/value pairs to add to the database.
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of values that were inserted.
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int bulkInsert(Uri uri, ContentValues[] values) {
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numValues = values.length;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < numValues; i++) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            insert(uri, values[i]);
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return numValues;
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6846fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * Implement this to handle requests to delete one or more rows.
6856fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * The implementation should apply the selection clause when performing
6866fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * deletion, allowing the operation to affect multiple rows in a directory.
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after deleting.
6896fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
6907aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
6917aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The implementation is responsible for parsing out a row ID at the end
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the URI, if a specific row is being deleted. That is, the client would
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pass in <code>content://contacts/people/22</code> and the implementation is
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * responsible for parsing the record number (22) when creating a SQL statement.
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The full URI to query, including a row ID (if a specific record is requested).
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional restriction to apply to rows when deleting.
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of rows affected.
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SQLException
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int delete(Uri uri, String selection, String[] selectionArgs);
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
70617876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * Implement this to handle requests to update one or more rows.
7076fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * The implementation should update all rows matching the selection
7086fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * to set the columns according to the provided values map.
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after updating.
7116fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
7127aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
7137aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This can potentially have a record ID if this
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is an update request for a specific record.
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A Bundle mapping from column names to new column values (NULL is a
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               valid value).
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional filter to match rows to update.
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the number of rows affected.
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int update(Uri uri, ContentValues values, String selection,
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] selectionArgs);
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
72617876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * Override this to handle requests to open a file blob.
7276fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * The default implementation always throws {@link FileNotFoundException}.
7286fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
7297aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
7307aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
7316fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
73217876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * <p>This method returns a ParcelFileDescriptor, which is returned directly
73317876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * to the caller.  This way large data (such as images and documents) can be
7346fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * returned without copying the content.
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their responsibility to close it when done.  That is, the implementation
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of this method should create a new ParcelFileDescriptor for each call.
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access, or "rwt" for read and write access
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that truncates any existing file.
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor which you can use to access
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
7526fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openAssetFile(Uri, String)
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
7556fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     */
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ParcelFileDescriptor openFile(Uri uri, String mode)
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw new FileNotFoundException("No files supported by provider at "
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + uri);
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7616fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is like {@link #openFile}, but can be implemented by providers
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that need to be able to return sub-sections of files, often assets
7656fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * inside of their .apk.
7666fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
7677aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
7687aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
7696fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
7706fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p>If you implement this, your clients must be able to deal with such
77117876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * file slices, either directly with
7726fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * methods.
7766fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
7776fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * <p class="note">If you are implementing this to return a full file, you
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should create the AssetFileDescriptor with
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
7806fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * applications that can not handle sub-sections of files.</p>
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new AssetFileDescriptor which you can use to access
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFile(Uri, String)
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AssetFileDescriptor openAssetFile(Uri uri, String mode)
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ParcelFileDescriptor fd = openFile(uri, mode);
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Convenience for subclasses that wish to implement {@link #openFile}
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by looking up a column named "_data" at the given URI.
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to be opened.
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode The file mode.  May be "r" for read-only access,
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor that can be used by the
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * client to access the file.
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final ParcelFileDescriptor openFileHelper(Uri uri,
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String mode) throws FileNotFoundException {
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = query(uri, new String[]{"_data"}, null, null, null);
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = (c != null) ? c.getCount() : 0;
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count != 1) {
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If there is not exactly one result, throw an appropriate
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // exception.
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != null) {
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c.close();
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (count == 0) {
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new FileNotFoundException("No entry for " + uri);
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Multiple items at " + uri);
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.moveToFirst();
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i = c.getColumnIndex("_data");
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String path = (i >= 0 ? c.getString(i) : null);
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.close();
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (path == null) {
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Column _data not found.");
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int modeBits = ContentResolver.modeToMode(uri, mode);
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ParcelFileDescriptor.open(new File(path), modeBits);
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
84923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Called by a client to determine the types of data streams that this
85023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * content provider supports for the given URI.  The default implementation
85123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * returns null, meaning no types.  If your content provider stores data
85223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * of a particular type, return that MIME type if it matches the given
85323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * mimeTypeFilter.  If it can perform type conversions, return an array
85423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * of all supported MIME types that match mimeTypeFilter.
85523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
85623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param uri The data in the content provider being queried.
85723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param mimeTypeFilter The type of data the client desires.  May be
85823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * a pattern, such as *\/* to retrieve all possible data types.
8593f00be5bd0b46e7937b68909baeff295b86215ccDianne Hackborn     * @return Returns null if there are no possible data streams for the
86023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * given mimeTypeFilter.  Otherwise returns an array of all available
86123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * concrete MIME types.
86223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
86323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #getType(Uri)
86423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #openTypedAssetFile(Uri, String, Bundle)
8651040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn     * @see ClipDescription#compareMimeTypes(String, String)
86623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
86723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
86823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        return null;
86923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
87023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
87123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
87223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Called by a client to open a read-only stream containing data of a
87323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * particular MIME type.  This is like {@link #openAssetFile(Uri, String)},
87423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * except the file can only be read-only and the content provider may
87523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * perform data conversions to generate data of the desired type.
87623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
87723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * <p>The default implementation compares the given mimeType against the
87823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * result of {@link #getType(Uri)} and, if the match, simple calls
87923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * {@link #openAssetFile(Uri, String)}.
88023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
8811040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn     * <p>See {@link ClipData} for examples of the use and implementation
88223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * of this method.
88323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
88423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param uri The data in the content provider being queried.
88523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param mimeTypeFilter The type of data the client desires.  May be
88623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * a pattern, such as *\/*, if the caller does not have specific type
88723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * requirements; in this case the content provider will pick its best
88823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * type matching the pattern.
88923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param opts Additional options from the client.  The definitions of
89023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * these are specific to the content provider being called.
89123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
89223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @return Returns a new AssetFileDescriptor from which the client can
89323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * read data of the desired type.
89423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
89523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @throws FileNotFoundException Throws FileNotFoundException if there is
89623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * no file associated with the given URI or the mode is invalid.
89723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @throws SecurityException Throws SecurityException if the caller does
89823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * not have permission to access the data.
89923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @throws IllegalArgumentException Throws IllegalArgumentException if the
90023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * content provider does not support the requested MIME type.
90123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
90223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #getStreamTypes(Uri, String)
90323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @see #openAssetFile(Uri, String)
9041040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn     * @see ClipDescription#compareMimeTypes(String, String)
90523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
90623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
90723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throws FileNotFoundException {
90802dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn        if ("*/*".equals(mimeTypeFilter)) {
90902dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            // If they can take anything, the untyped open call is good enough.
91002dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            return openAssetFile(uri, "r");
91102dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn        }
91223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        String baseType = getType(uri);
9131040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn        if (baseType != null && ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) {
91402dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            // Use old untyped open call if this provider has a type for this
91502dfd2630437ea5591942e503606fdeff29eb11eDianne Hackborn            // URI and it matches the request.
91623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return openAssetFile(uri, "r");
91723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
91823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
91923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
92023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
92123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
92223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Interface to write a stream of data to a pipe.  Use with
92323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * {@link ContentProvider#openPipeHelper}.
92423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
92523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public interface PipeDataWriter<T> {
92623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        /**
92723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * Called from a background thread to stream data out to a pipe.
92823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * Note that the pipe is blocking, so this thread can block on
92923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * writes for an arbitrary amount of time if the client is slow
93023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * at reading.
93123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         *
93223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param output The pipe where data should be written.  This will be
93323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * closed for you upon returning from this function.
93423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param uri The URI whose data is to be written.
93523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param mimeType The desired type of data to be written.
93623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param opts Options supplied by caller.
93723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * @param args Your own custom arguments.
93823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         */
93923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
94023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                Bundle opts, T args);
94123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
94223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
94323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
94423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * A helper function for implementing {@link #openTypedAssetFile}, for
94523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * creating a data pipe and background thread allowing you to stream
94623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * generated data back to the client.  This function returns a new
94723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * ParcelFileDescriptor that should be returned to the caller (the caller
94823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * is responsible for closing it).
94923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     *
95023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param uri The URI whose data is to be written.
95123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param mimeType The desired type of data to be written.
95223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param opts Options supplied by caller.
95323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param args Your own custom arguments.
95423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @param func Interface implementing the function that will actually
95523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * stream the data.
95623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * @return Returns a new ParcelFileDescriptor holding the read side of
95723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * the pipe.  This should be returned to the caller for reading; the caller
95823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * is responsible for closing it when done.
95923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
96023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public <T> ParcelFileDescriptor openPipeHelper(final Uri uri, final String mimeType,
96123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            final Bundle opts, final T args, final PipeDataWriter<T> func)
96223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throws FileNotFoundException {
96323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        try {
96423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
96523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
96623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
96723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                @Override
96823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                protected Object doInBackground(Object... params) {
96923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    func.writeDataToPipe(fds[1], uri, mimeType, opts, args);
97023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    try {
97123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                        fds[1].close();
97223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    } catch (IOException e) {
97323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                        Log.w(TAG, "Failure closing pipe", e);
97423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    }
97523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                    return null;
97623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn                }
97723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            };
9785d9d03a0234faa3cffd11502f973057045cafe82Dianne Hackborn            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null);
97923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
98023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            return fds[0];
98123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        } catch (IOException e) {
98223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throw new FileNotFoundException("failure making pipe");
98323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        }
98423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
98523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
98623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this instance is a temporary content provider.
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if this instance is a temporary content provider
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean isTemporary() {
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the Binder object for this provider.
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the Binder object for this provider
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IContentProvider getIContentProvider() {
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTransport;
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After being instantiated, this is called to tell the content provider
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * about itself.
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context this provider is running in
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Registered information about this content provider
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachInfo(Context context, ProviderInfo info) {
101223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        /*
101323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * We may be using AsyncTask from binder threads.  Make it init here
101423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         * so its static handler is on the main thread.
101523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn         */
101623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn        AsyncTask.init();
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Only allow it to be set once, so after the content service gives
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this to us clients can't change it.
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mContext == null) {
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
10242af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            mMyUid = Process.myUid();
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (info != null) {
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setReadPermission(info.readPermission);
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setWritePermission(info.writePermission);
10282af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                setPathPermissions(info.pathPermissions);
1029b424b633bb3664bed924d2ea89036290a57eb2bdDianne Hackborn                mExported = info.exported;
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ContentProvider.this.onCreate();
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1034ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana
1035ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana    /**
103617876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * Override this to handle requests to perform a batch of operations, or the
103717876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * default implementation will iterate over the operations and call
103817876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * {@link ContentProviderOperation#apply} on each of them.
103917876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * If all calls to {@link ContentProviderOperation#apply} succeed
104017876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * then a {@link ContentProviderResult} array with as many
104117876aa586cc9acfb3e5b909c14b9e73537a1a8dDan Egnor     * elements as there were operations will be returned.  If any of the calls
10426fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * fail, it is up to the implementation how many of the others take effect.
10436fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * This method can be called from multiple threads, as described in
10447aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
10457aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main     * and Threads</a>.
10466fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     *
1047ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana     * @param operations the operations to apply
1048ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana     * @return the results of the applications
10496fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * @throws OperationApplicationException thrown if any operation fails.
10506fcc0f073d8583cf1f485b9548cde41336a422beDan Egnor     * @see ContentProviderOperation#apply
1051ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana     */
105203d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
1053ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana            throws OperationApplicationException {
105403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        final int numOperations = operations.size();
105503d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        final ContentProviderResult[] results = new ContentProviderResult[numOperations];
105603d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana        for (int i = 0; i < numOperations; i++) {
105703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana            results[i] = operations.get(i).apply(this, results, i);
1058ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana        }
1059ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana        return results;
1060ce31b2361db630cf1347fa42dd77e610a4eeb96dFred Quintana    }
10611877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick
10621877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick    /**
10632c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Call a provider-defined method.  This can be used to implement
1064534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * interfaces that are cheaper and/or unnatural for a table-like
1065534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * model.
10661877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick     *
1067534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @param method method name to call.  Opaque to framework, but should not be null.
1068534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @param arg provider-defined String argument.  May be null.
1069534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @param extras provider-defined Bundle argument.  May be null.
1070534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     * @return provider-defined return value.  May be null.  Null is also
1071534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick     *   the default for providers which don't implement any call methods.
10721877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick     */
1073534c84c1ce19ae20ded249315c3c0558577eca6cBrad Fitzpatrick    public Bundle call(String method, String arg, Bundle extras) {
10741877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick        return null;
10751877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick    }
10760c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori
10770c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    /**
10782c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Implement this to shut down the ContentProvider instance. You can then
10792c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * invoke this method in unit tests.
10802c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     *
10810c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori     * <p>
10822c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Android normally handles ContentProvider startup and shutdown
10832c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * automatically. You do not need to start up or shut down a
10842c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * ContentProvider. When you invoke a test method on a ContentProvider,
10852c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * however, a ContentProvider instance is started and keeps running after
10862c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * the test finishes, even if a succeeding test instantiates another
10872c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * ContentProvider. A conflict develops because the two instances are
10882c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * usually running against the same underlying data source (for example, an
10892c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * sqlite database).
10902c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * </p>
10910c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori     * <p>
10922c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * Implementing shutDown() avoids this conflict by providing a way to
10932c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * terminate the ContentProvider. This method can also prevent memory leaks
10942c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * from multiple instantiations of the ContentProvider, and it can ensure
10952c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * unit test isolation by allowing you to completely clean up the test
10962c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * fixture before moving on to the next test.
10972c96a0c7acddb5f2e8027e9ffac73f82c297c4b9Manuel Roman     * </p>
10980c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori     */
10990c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    public void shutdown() {
11000c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori        Log.w(TAG, "implement ContentProvider shutdown() to make sure all database " +
11010c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori                "connections are gracefully shutdown");
11020c9e14aa4aa1370e01872dc05238f822f2dd552cVasu Nori    }
110318cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen
110418cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen    /**
110518cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * Print the Provider's state into the given stream.  This gets invoked if
110618cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * you run "adb shell dumpsys activity provider <provider_component_name>".
110718cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     *
110818cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param prefix Desired prefix to prepend at each line of output.
110918cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param fd The raw file descriptor that the dump is being sent to.
111018cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param writer The PrintWriter to which you should dump your state.  This will be
111118cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * closed for you after you return.
111218cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @param args additional arguments to the dump request.
111318cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     * @hide
111418cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen     */
111518cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
111618cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen        writer.println("nothing to dump");
111718cb28756caf02bf2b2f5e67c68451edaf719b47Marco Nelissen    }
11181877d0158b529663b8315482e7346a7bcaa96166Brad Fitzpatrick}
1119