ContentProvider.java revision 6a8d5332f00bdfade6674b312e7166940aa28348
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;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ProviderInfo;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Configuration;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.CursorToBulkCursorAdaptor;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.CursorWindow;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IBulkCursor;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.SQLException;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Content providers are one of the primary building blocks of Android applications, providing
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * content to applications. They encapsulate data and provide it to applications through the single
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ContentResolver} interface. A content provider is only required if you need to share
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data between multiple applications. For example, the contacts data is used by multiple
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * applications and must be stored in a content provider. If you don't need to share data amongst
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * multiple applications you can use a database directly via
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.database.sqlite.SQLiteDatabase}.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>For more information, read <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Providers</a>.</p>
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When a request is made via
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * request to the content provider registered with the authority. The content provider can interpret
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * URIs.</p>
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The primary methods that need to be implemented are:
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #query} which returns data to the caller</li>
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #insert} which inserts new data into the content provider</li>
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #update} which updates existing data in the content provider</li>
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #delete} which deletes data from the content provider</li>
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *   <li>{@link #getType} which returns the MIME type of data in the content provider</li>
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul></p>
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This class takes care of cross process calls so subclasses don't have to worry about which
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * process a request is coming from.</p>
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentProvider implements ComponentCallbacks {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext = null;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mReadPermission;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mWritePermission;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Transport mTransport = new Transport();
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Given an IContentProvider, try to coerce it back to the real
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider object if it is running in the local process.  This can
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be used if you know you are running in the same process as a provider,
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and want to get direct access to its implementation details.  Most
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clients should not nor have a reason to use it.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param abstractInterface The ContentProvider interface that is to be
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              coerced.
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return If the IContentProvider is non-null and local, returns its actual
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentProvider instance.  Otherwise returns null.
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static ContentProvider coerceToLocalContentProvider(
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IContentProvider abstractInterface) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (abstractInterface instanceof Transport) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ((Transport)abstractInterface).getContentProvider();
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Binder object that deals with remoting.
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class Transport extends ContentProviderNative {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ContentProvider getContentProvider() {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Remote version of a query, which returns an IBulkCursor. The bulk
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * cursor should be wrapped with BulkCursorToCursorAdaptor before use.
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public IBulkCursor bulkQuery(Uri uri, String[] projection,
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String selection, String[] selectionArgs, String sortOrder,
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IContentObserver observer, CursorWindow window) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkReadPermission(uri);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Cursor cursor = ContentProvider.this.query(uri, projection,
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    selection, selectionArgs, sortOrder);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cursor == null) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String wperm = getWritePermission();
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new CursorToBulkCursorAdaptor(cursor, observer,
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ContentProvider.this.getClass().getName(),
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    wperm == null ||
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    getContext().checkCallingOrSelfPermission(getWritePermission())
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            == PackageManager.PERMISSION_GRANTED,
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    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) {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkReadPermission(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
1336a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
1346a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana                String sortOrder) {
1356a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            checkReadPermission(uri);
1366a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            return ContentProvider.this.queryEntities(uri, selection, selectionArgs, sortOrder);
1376a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        }
1386a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getType(Uri uri) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.getType(uri);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Uri insert(Uri uri, ContentValues initialValues) {
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkWritePermission(uri);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.insert(uri, initialValues);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int bulkInsert(Uri uri, ContentValues[] initialValues) {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkWritePermission(uri);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.bulkInsert(uri, initialValues);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1546a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        public Uri[] bulkInsertEntities(Uri uri, Entity[] entities) {
1556a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            checkWritePermission(uri);
1566a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            return ContentProvider.this.bulkInsertEntities(uri, entities);
1576a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        }
1586a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int delete(Uri uri, String selection, String[] selectionArgs) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkWritePermission(uri);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.delete(uri, selection, selectionArgs);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int update(Uri uri, ContentValues values, String selection,
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] selectionArgs) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            checkWritePermission(uri);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.update(uri, values, selection, selectionArgs);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1706a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        public int[] bulkUpdateEntities(Uri uri, Entity[] entities) {
1716a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            checkWritePermission(uri);
1726a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            return ContentProvider.this.bulkUpdateEntities(uri, entities);
1736a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        }
1746a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ParcelFileDescriptor openFile(Uri uri, String mode)
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mode != null && mode.startsWith("rw")) checkWritePermission(uri);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else checkReadPermission(uri);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openFile(uri, mode);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AssetFileDescriptor openAssetFile(Uri uri, String mode)
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws FileNotFoundException {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mode != null && mode.startsWith("rw")) checkWritePermission(uri);
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else checkReadPermission(uri);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ContentProvider.this.openAssetFile(uri, mode);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void checkReadPermission(Uri uri) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final String rperm = getReadPermission();
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int uid = Binder.getCallingUid();
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (getContext().checkUriPermission(uri, rperm, null, pid, uid,
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Intent.FLAG_GRANT_READ_URI_PERMISSION)
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    == PackageManager.PERMISSION_GRANTED) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String msg = "Permission Denial: reading "
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ContentProvider.this.getClass().getName()
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " uri " + uri + " from pid=" + Binder.getCallingPid()
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid()
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " requires " + rperm;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException(msg);
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void checkWritePermission(Uri uri) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final String wperm = getWritePermission();
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int pid = Binder.getCallingPid();
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int uid = Binder.getCallingUid();
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (getContext().checkUriPermission(uri, null, wperm, pid, uid,
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    == PackageManager.PERMISSION_GRANTED) {
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String msg = "Permission Denial: writing "
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ContentProvider.this.getClass().getName()
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " uri " + uri + " from pid=" + Binder.getCallingPid()
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid()
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " requires " + wperm;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException(msg);
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Retrieve the Context this provider is running in.  Only available once
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * onCreate(Map icicle) has been called -- this will be null in the
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * constructor.
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Context getContext() {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContext;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read data from the content
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read-only access.
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setReadPermission(String permission) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mReadPermission = permission;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read-only access to
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getReadPermission() {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mReadPermission;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the permission required to read and write data in the content
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider.  This is normally set for you from its manifest information
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the provider is first created.
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param permission Name of the permission required for read/write access.
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final void setWritePermission(String permission) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWritePermission = permission;
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the name of the permission required for read/write access to
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this content provider.  This method can be called from multiple
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final String getWritePermission() {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWritePermission;
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the provider is being started.
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the provider was successfully loaded, false otherwise
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract boolean onCreate();
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onLowMemory() {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Receives a query request from a client in a local process, and
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns a Cursor. This is called internally by the {@link ContentResolver}.
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example client call:<p>
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// Request a specific record.
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Cursor managedCursor = managedQuery(
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Contacts.People.CONTENT_URI.addId(2),
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,    // Which columns to return.
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                null,          // WHERE clause.
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                People.NAME + " ASC");   // Sort order.</pre>
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Example implementation:<p>
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <pre>// SQLiteQueryBuilder is a helper class that creates the
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // proper SQL syntax for us.
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the table we're querying.
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        qBuilder.setTables(DATABASE_TABLE_NAME);
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the query ends in a specific record number, we're
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // being asked for a specific record, so set the
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // WHERE clause in our query.
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Make the query.
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = qBuilder.query(mDb,
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                projection,
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selection,
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selectionArgs,
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                groupBy,
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                having,
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sortOrder);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.setNotificationUri(getContext().getContentResolver(), uri);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;</pre>
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This will be the full URI sent by the client;
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the client is requesting a specific record, the URI will end in a record number
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that the implementation should parse and add to a WHERE or HAVING clause, specifying
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that _id value.
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param projection The list of columns to put into the cursor. If
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      null all columns are included.
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection A selection criteria to apply when filtering rows.
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      If null then all rows are included.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sortOrder How the rows in the cursor should be sorted.
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        If null then the provider is free to define the sort order.
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor or null.
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Cursor query(Uri uri, String[] projection,
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String selection, String[] selectionArgs, String sortOrder);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3476a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
3486a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            String sortOrder) {
3496a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        throw new UnsupportedOperationException();
3506a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    }
3516a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the MIME type of the data at the given URI. This should start with
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>vnd.android.cursor.item</code> for a single record,
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or <code>vnd.android.cursor.dir/</code> for multiple items.
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri the URI to query.
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a MIME type string, or null if there is no type.
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract String getType(Uri uri);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement this to insert a new row.
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A set of column_name/value pairs to add to the database.
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The URI for the newly inserted item.
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Uri insert(Uri uri, ContentValues values);
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement this to insert a set of new rows, or the default implementation will
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * iterate over the values and call {@link #insert} on each of them.
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after inserting.
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The content:// URI of the insertion request.
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values An array of sets of column_name/value pairs to add to the database.
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of values that were inserted.
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int bulkInsert(Uri uri, ContentValues[] values) {
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numValues = values.length;
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < numValues; i++) {
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            insert(uri, values[i]);
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return numValues;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4026a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    public Uri insertEntity(Uri uri, Entity entity) {
4036a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        throw new UnsupportedOperationException();
4046a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    }
4056a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
4066a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    public Uri[] bulkInsertEntities(Uri uri, Entity[] entities) {
4076a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        Uri[] result = new Uri[entities.length];
4086a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        for (int i = 0; i < entities.length; i++) {
4096a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            result[i] = insertEntity(uri, entities[i]);
4106a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        }
4116a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        return result;
4126a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    }
4136a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A request to delete one or more rows. The selection clause is applied when performing
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the deletion, allowing the operation to affect multiple rows in a
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * directory.
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after deleting.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The implementation is responsible for parsing out a row ID at the end
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the URI, if a specific row is being deleted. That is, the client would
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pass in <code>content://contacts/people/22</code> and the implementation is
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * responsible for parsing the record number (22) when creating a SQL statement.
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The full URI to query, including a row ID (if a specific record is requested).
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional restriction to apply to rows when deleting.
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of rows affected.
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SQLException
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int delete(Uri uri, String selection, String[] selectionArgs);
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Update a content URI. All rows matching the optionally provided selection
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will have their columns listed as the keys in the values map with the
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * values of those keys.
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 updating.
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     *
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to query. This can potentially have a record ID if this
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is an update request for a specific record.
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param values A Bundle mapping from column names to new column values (NULL is a
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               valid value).
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selection An optional filter to match rows to update.
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the number of rows affected.
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int update(Uri uri, ContentValues values, String selection,
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String[] selectionArgs);
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4586a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    public int updateEntity(Uri uri, Entity entity) {
4596a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        throw new UnsupportedOperationException();
4606a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    }
4616a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
4626a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    public int[] bulkUpdateEntities(Uri uri, Entity[] entities) {
4636a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        int[] result = new int[entities.length];
4646a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        for (int i = 0; i < entities.length; i++) {
4656a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana            result[i] = updateEntity(uri, entities[i]);
4666a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        }
4676a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana        return result;
4686a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    }
4696a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Open a file blob associated with a content URI.
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method can be called from multiple
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * threads, as described in
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Processes and Threads</a>.
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns a
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ParcelFileDescriptor, from which you can obtain a
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link java.io.FileDescriptor} for use with
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link java.io.FileInputStream}, {@link java.io.FileOutputStream}, etc.
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This can be used to store large data (such as an image) associated with
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a particular piece of content.
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their responsibility to close it when done.  That is, the implementation
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of this method should create a new ParcelFileDescriptor for each call.
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access, or "rwt" for read and write access
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that truncates any existing file.
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor which you can use to access
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openAssetFile(Uri, String)
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ParcelFileDescriptor openFile(Uri uri, String mode)
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        throw new FileNotFoundException("No files supported by provider at "
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + uri);
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is like {@link #openFile}, but can be implemented by providers
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that need to be able to return sub-sections of files, often assets
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inside of their .apk.  Note that when implementing this your clients
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * must be able to deal with such files, either directly with
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ContentResolver#openAssetFileDescriptor
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ContentResolver.openAssetFileDescriptor}, or by using the higher-level
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * methods.
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><em>Note: if you are implementing this to return a full file, you
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * should create the AssetFileDescriptor with
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applications that can not handle sub-sections of files.</em></p>
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI whose file is to be opened.
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Access mode for the file.  May be "r" for read-only access,
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new AssetFileDescriptor which you can use to access
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file.
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if there is
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no file associated with the given URI or the mode is invalid.
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws SecurityException Throws SecurityException if the caller does
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not have permission to access the file.
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFile(Uri, String)
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #openFileHelper(Uri, String)
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AssetFileDescriptor openAssetFile(Uri uri, String mode)
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ParcelFileDescriptor fd = openFile(uri, mode);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Convenience for subclasses that wish to implement {@link #openFile}
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by looking up a column named "_data" at the given URI.
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to be opened.
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode The file mode.  May be "r" for read-only access,
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "w" for write-only access (erasing whatever data is currently in
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the file), "wa" for write-only access to append to any existing data,
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "rw" for read and write access on any existing data, and "rwt" for read
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and write access that truncates any existing file.
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor that can be used by the
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * client to access the file.
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected final ParcelFileDescriptor openFileHelper(Uri uri,
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String mode) throws FileNotFoundException {
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor c = query(uri, new String[]{"_data"}, null, null, null);
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int count = (c != null) ? c.getCount() : 0;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (count != 1) {
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If there is not exactly one result, throw an appropriate
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // exception.
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != null) {
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c.close();
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (count == 0) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new FileNotFoundException("No entry for " + uri);
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Multiple items at " + uri);
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.moveToFirst();
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i = c.getColumnIndex("_data");
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String path = (i >= 0 ? c.getString(i) : null);
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.close();
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (path == null) {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new FileNotFoundException("Column _data not found.");
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int modeBits = ContentResolver.modeToMode(uri, mode);
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ParcelFileDescriptor.open(new File(path), modeBits);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this instance is a temporary content provider.
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if this instance is a temporary content provider
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean isTemporary() {
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the Binder object for this provider.
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the Binder object for this provider
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IContentProvider getIContentProvider() {
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTransport;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After being instantiated, this is called to tell the content provider
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * about itself.
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context this provider is running in
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Registered information about this content provider
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachInfo(Context context, ProviderInfo info) {
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Only allow it to be set once, so after the content service gives
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * this to us clients can't change it.
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mContext == null) {
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (info != null) {
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setReadPermission(info.readPermission);
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setWritePermission(info.writePermission);
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ContentProvider.this.onCreate();
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
633