ContentProvider.java revision 2af632f87d487deaa5b2eb71341cfc4f0c0d1173
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.CursorToBulkCursorAdaptor;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.CursorWindow;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IBulkCursor;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.SQLException;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
332af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackbornimport android.os.Process;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Content providers are one of the primary building blocks of Android applications, providing
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * content to applications. They encapsulate data and provide it to applications through the single
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ContentResolver} interface. A content provider is only required if you need to share
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data between multiple applications. For example, the contacts data is used by multiple
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * applications and must be stored in a content provider. If you don't need to share data amongst
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * multiple applications you can use a database directly via
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.database.sqlite.SQLiteDatabase}.
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>For more information, read <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Providers</a>.</p>
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When a request is made via
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * request to the content provider registered with the authority. The content provider can interpret
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * URIs.</p>
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The primary methods that need to be implemented are:
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #query} which returns data to the caller</li>
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #insert} which inserts new data into the content provider</li>
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #update} which updates existing data in the content provider</li>
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #delete} which deletes data from the content provider</li>
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #getType} which returns the MIME type of data in the content provider</li>
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul></p>
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This class takes care of cross process calls so subclasses don't have to worry about which
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * process a request is coming from.</p>
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentProvider implements ComponentCallbacks {
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext = null;
702af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    private int mMyUid;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mReadPermission;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mWritePermission;
732af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    private PathPermission[] mPathPermissions;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Transport mTransport = new Transport();
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Given an IContentProvider, try to coerce it back to the real
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider object if it is running in the local process.  This can
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be used if you know you are running in the same process as a provider,
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and want to get direct access to its implementation details.  Most
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clients should not nor have a reason to use it.
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param abstractInterface The ContentProvider interface that is to be
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              coerced.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return If the IContentProvider is non-null and local, returns its actual
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider instance.  Otherwise returns null.
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static ContentProvider coerceToLocalContentProvider(
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IContentProvider abstractInterface) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (abstractInterface instanceof Transport) {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ((Transport)abstractInterface).getContentProvider();
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Binder object that deals with remoting.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class Transport extends ContentProviderNative {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ContentProvider getContentProvider() {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Remote version of a query, which returns an IBulkCursor. The bulk
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * cursor should be wrapped with BulkCursorToCursorAdaptor before use.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public IBulkCursor bulkQuery(Uri uri, String[] projection,
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String selection, String[] selectionArgs, String sortOrder,
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IContentObserver observer, CursorWindow window) {
1152af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceReadPermission(uri);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Cursor cursor = ContentProvider.this.query(uri, projection,
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    selection, selectionArgs, sortOrder);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cursor == null) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new CursorToBulkCursorAdaptor(cursor, observer,
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ContentProvider.this.getClass().getName(),
1232af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    hasWritePermission(uri), window);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Cursor query(Uri uri, String[] projection,
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String selection, String[] selectionArgs, String sortOrder) {
1282af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceReadPermission(uri);
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.query(uri, projection, selection,
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    selectionArgs, sortOrder);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getType(Uri uri) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.getType(uri);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Uri insert(Uri uri, ContentValues initialValues) {
1392af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.insert(uri, initialValues);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int bulkInsert(Uri uri, ContentValues[] initialValues) {
1442af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.bulkInsert(uri, initialValues);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int delete(Uri uri, String selection, String[] selectionArgs) {
1492af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.delete(uri, selection, selectionArgs);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int update(Uri uri, ContentValues values, String selection,
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] selectionArgs) {
1552af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(uri);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.update(uri, values, selection, selectionArgs);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ParcelFileDescriptor openFile(Uri uri, String mode)
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
1612af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
1622af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            else enforceReadPermission(uri);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openFile(uri, mode);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AssetFileDescriptor openAssetFile(Uri uri, String mode)
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
1682af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
1692af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            else enforceReadPermission(uri);
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openAssetFile(uri, mode);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ISyncAdapter getSyncAdapter() {
1742af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            enforceWritePermission(null);
1759e728e082e6060612691b726e6fe264a0d37276fBjorn Bringert            SyncAdapter sa = ContentProvider.this.getSyncAdapter();
1769e728e082e6060612691b726e6fe264a0d37276fBjorn Bringert            return sa != null ? sa.getISyncAdapter() : null;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1792af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        private void enforceReadPermission(Uri uri) {
1802af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final int uid = Binder.getCallingUid();
1812af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (uid == mMyUid) {
1822af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return;
1832af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
1842af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
1852af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final Context context = getContext();
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final String rperm = getReadPermission();
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
1882af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (rperm == null
1892af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    || context.checkPermission(rperm, pid, uid)
1902af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    == PackageManager.PERMISSION_GRANTED) {
1912af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return;
1922af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
1932af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
1942af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            PathPermission[] pps = getPathPermissions();
1952af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (pps != null) {
1962af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                final String path = uri.getPath();
1972af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                int i = pps.length;
1982af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                while (i > 0) {
1992af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    i--;
2002af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final PathPermission pp = pps[i];
2012af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final String pprperm = pp.getReadPermission();
2022af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    if (pprperm != null && pp.match(path)) {
2032af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        if (context.checkPermission(pprperm, pid, uid)
2042af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                                == PackageManager.PERMISSION_GRANTED) {
2052af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                            return;
2062af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        }
2072af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    }
2082af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                }
2092af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
2102af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2112af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (context.checkUriPermission(uri, pid, uid,
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Intent.FLAG_GRANT_READ_URI_PERMISSION)
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    == PackageManager.PERMISSION_GRANTED) {
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2162af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String msg = "Permission Denial: reading "
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ContentProvider.this.getClass().getName()
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " uri " + uri + " from pid=" + Binder.getCallingPid()
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid()
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " requires " + rperm;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException(msg);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2252af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        private boolean hasWritePermission(Uri uri) {
2262af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final int uid = Binder.getCallingUid();
2272af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (uid == mMyUid) {
2282af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return true;
2292af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
2302af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2312af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            final Context context = getContext();
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final String wperm = getWritePermission();
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
2342af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (wperm == null
2352af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    || context.checkPermission(wperm, pid, uid)
2362af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    == PackageManager.PERMISSION_GRANTED) {
2372af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return true;
2382af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
2392af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2402af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            PathPermission[] pps = getPathPermissions();
2412af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (pps != null) {
2422af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                final String path = uri.getPath();
2432af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                int i = pps.length;
2442af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                while (i > 0) {
2452af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    i--;
2462af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final PathPermission pp = pps[i];
2472af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    final String ppwperm = pp.getWritePermission();
2482af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    if (ppwperm != null && pp.match(path)) {
2492af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        if (context.checkPermission(ppwperm, pid, uid)
2502af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                                == PackageManager.PERMISSION_GRANTED) {
2512af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                            return true;
2522af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                        }
2532af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    }
2542af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                }
2552af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
2562af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2572af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (context.checkUriPermission(uri, pid, uid,
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    == PackageManager.PERMISSION_GRANTED) {
2602af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                return true;
2612af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            }
2622af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2632af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            return false;
2642af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        }
2652af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2662af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        private void enforceWritePermission(Uri uri) {
2672af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            if (hasWritePermission(uri)) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2702af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String msg = "Permission Denial: writing "
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ContentProvider.this.getClass().getName()
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " uri " + uri + " from pid=" + Binder.getCallingPid()
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid()
2752af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                    + " requires " + getWritePermission();
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException(msg);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Retrieve the Context this provider is running in.  Only available once
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * onCreate(Map icicle) has been called -- this will be null in the
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * constructor.
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Context getContext() {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContext;
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read data from the content
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read-only access.
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setReadPermission(String permission) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReadPermission = permission;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read-only access to
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getReadPermission() {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mReadPermission;
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read and write data in the content
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read/write access.
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setWritePermission(String permission) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWritePermission = permission;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read/write access to
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getWritePermission() {
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWritePermission;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3352af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * Change the path-based permission required to read and/or write data in
3362af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * the content provider.  This is normally set for you from its manifest
3372af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * information when the provider is first created.
3382af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     *
3392af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * @param permissions Array of path permission descriptions.
3402af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     */
3412af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    protected final void setPathPermissions(PathPermission[] permissions) {
3422af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        mPathPermissions = permissions;
3432af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    }
3442af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3452af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    /**
3462af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * Return the path-based permissions required for read and/or write access to
3472af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * this content provider.  This method can be called from multiple
3482af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * threads, as described in
3492af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
3502af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     * Processes and Threads</a>.
3512af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn     */
3522af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    public final PathPermission[] getPathPermissions() {
3532af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn        return mPathPermissions;
3542af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    }
3552af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn
3562af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn    /**
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the provider is being started.
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the provider was successfully loaded, false otherwise
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract boolean onCreate();
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onLowMemory() {
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Receives a query request from a client in a local process, and
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns a Cursor. This is called internally by the {@link ContentResolver}.
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example client call:<p>
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// Request a specific record.
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Cursor managedCursor = managedQuery(
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Contacts.People.CONTENT_URI.addId(2),
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,    // Which columns to return.
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                null,          // WHERE clause.
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                People.NAME + " ASC");   // Sort order.</pre>
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example implementation:<p>
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// SQLiteQueryBuilder is a helper class that creates the
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // proper SQL syntax for us.
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the table we're querying.
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        qBuilder.setTables(DATABASE_TABLE_NAME);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the query ends in a specific record number, we're
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // being asked for a specific record, so set the
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // WHERE clause in our query.
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make the query.
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = qBuilder.query(mDb,
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selection,
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selectionArgs,
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                groupBy,
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                having,
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sortOrder);
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.setNotificationUri(getContext().getContentResolver(), uri);
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;</pre>
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This will be the full URI sent by the client;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the client is requesting a specific record, the URI will end in a record number
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that the implementation should parse and add to a WHERE or HAVING clause, specifying
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that _id value.
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param projection The list of columns to put into the cursor. If
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      null all columns are included.
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection A selection criteria to apply when filtering rows.
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      If null then all rows are included.
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sortOrder How the rows in the cursor should be sorted.
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        If null then the provider is free to define the sort order.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor or null.
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Cursor query(Uri uri, String[] projection,
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String selection, String[] selectionArgs, String sortOrder);
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the MIME type of the data at the given URI. This should start with
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>vnd.android.cursor.item</code> for a single record,
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or <code>vnd.android.cursor.dir/</code> for multiple items.
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri the URI to query.
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a MIME type string, or null if there is no type.
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract String getType(Uri uri);
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement this to insert a new row.
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A set of column_name/value pairs to add to the database.
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The URI for the newly inserted item.
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Uri insert(Uri uri, ContentValues values);
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement this to insert a set of new rows, or the default implementation will
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * iterate over the values and call {@link #insert} on each of them.
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values An array of sets of column_name/value pairs to add to the database.
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of values that were inserted.
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int bulkInsert(Uri uri, ContentValues[] values) {
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numValues = values.length;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < numValues; i++) {
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            insert(uri, values[i]);
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return numValues;
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A request to delete one or more rows. The selection clause is applied when performing
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the deletion, allowing the operation to affect multiple rows in a
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * directory.
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after deleting.
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The implementation is responsible for parsing out a row ID at the end
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the URI, if a specific row is being deleted. That is, the client would
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pass in <code>content://contacts/people/22</code> and the implementation is
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * responsible for parsing the record number (22) when creating a SQL statement.
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The full URI to query, including a row ID (if a specific record is requested).
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional restriction to apply to rows when deleting.
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of rows affected.
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SQLException
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int delete(Uri uri, String selection, String[] selectionArgs);
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Update a content URI. All rows matching the optionally provided selection
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will have their columns listed as the keys in the values map with the
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * values of those keys.
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after updating.
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This can potentially have a record ID if this
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is an update request for a specific record.
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A Bundle mapping from column names to new column values (NULL is a
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               valid value).
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional filter to match rows to update.
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the number of rows affected.
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int update(Uri uri, ContentValues values, String selection,
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] selectionArgs);
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Open a file blob associated with a content URI.
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns a
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ParcelFileDescriptor, from which you can obtain a
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link java.io.FileDescriptor} for use with
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link java.io.FileInputStream}, {@link java.io.FileOutputStream}, etc.
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This can be used to store large data (such as an image) associated with
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a particular piece of content.
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their responsibility to close it when done.  That is, the implementation
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of this method should create a new ParcelFileDescriptor for each call.
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access, or "rwt" for read and write access
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that truncates any existing file.
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor which you can use to access
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openAssetFile(Uri, String)
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ParcelFileDescriptor openFile(Uri uri, String mode)
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw new FileNotFoundException("No files supported by provider at "
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + uri);
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is like {@link #openFile}, but can be implemented by providers
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that need to be able to return sub-sections of files, often assets
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inside of their .apk.  Note that when implementing this your clients
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * must be able to deal with such files, either directly with
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ContentResolver#openAssetFileDescriptor
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentResolver.openAssetFileDescriptor}, or by using the higher-level
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * methods.
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><em>Note: if you are implementing this to return a full file, you
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should create the AssetFileDescriptor with
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applications that can not handle sub-sections of files.</em></p>
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new AssetFileDescriptor which you can use to access
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFile(Uri, String)
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AssetFileDescriptor openAssetFile(Uri uri, String mode)
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ParcelFileDescriptor fd = openFile(uri, mode);
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Convenience for subclasses that wish to implement {@link #openFile}
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by looking up a column named "_data" at the given URI.
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to be opened.
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode The file mode.  May be "r" for read-only access,
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor that can be used by the
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * client to access the file.
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final ParcelFileDescriptor openFileHelper(Uri uri,
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String mode) throws FileNotFoundException {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = query(uri, new String[]{"_data"}, null, null, null);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = (c != null) ? c.getCount() : 0;
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count != 1) {
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If there is not exactly one result, throw an appropriate
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // exception.
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != null) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c.close();
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (count == 0) {
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new FileNotFoundException("No entry for " + uri);
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Multiple items at " + uri);
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.moveToFirst();
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i = c.getColumnIndex("_data");
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String path = (i >= 0 ? c.getString(i) : null);
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.close();
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (path == null) {
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Column _data not found.");
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int modeBits = ContentResolver.modeToMode(uri, mode);
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ParcelFileDescriptor.open(new File(path), modeBits);
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Get the sync adapter that is to be used by this content provider.
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is intended for use by the sync system. If null then this
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * content provider is considered not syncable.
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the SyncAdapter that is to be used by this ContentProvider, or null
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *   if this ContentProvider is not syncable
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SyncAdapter getSyncAdapter() {
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this instance is a temporary content provider.
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if this instance is a temporary content provider
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean isTemporary() {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the Binder object for this provider.
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the Binder object for this provider
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IContentProvider getIContentProvider() {
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTransport;
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After being instantiated, this is called to tell the content provider
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * about itself.
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context this provider is running in
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Registered information about this content provider
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachInfo(Context context, ProviderInfo info) {
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Only allow it to be set once, so after the content service gives
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this to us clients can't change it.
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mContext == null) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
6912af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn            mMyUid = Process.myUid();
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (info != null) {
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setReadPermission(info.readPermission);
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setWritePermission(info.writePermission);
6952af632f87d487deaa5b2eb71341cfc4f0c0d1173Dianne Hackborn                setPathPermissions(info.pathPermissions);
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ContentProvider.this.onCreate();
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
701