ContentProvider.java revision e5d4933692343d082912856198fc3d207865d1cc
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import android.content.pm.PackageManager;
22import android.content.pm.PathPermission;
23import android.content.pm.ProviderInfo;
24import android.content.res.AssetFileDescriptor;
25import android.content.res.Configuration;
26import android.database.Cursor;
27import android.database.SQLException;
28import android.net.Uri;
29import android.os.AsyncTask;
30import android.os.Binder;
31import android.os.Bundle;
32import android.os.ParcelFileDescriptor;
33import android.os.Process;
34import android.os.RemoteException;
35import android.os.UserId;
36import android.util.Log;
37
38import java.io.File;
39import java.io.FileDescriptor;
40import java.io.FileNotFoundException;
41import java.io.IOException;
42import java.io.PrintWriter;
43import java.util.ArrayList;
44
45/**
46 * Content providers are one of the primary building blocks of Android applications, providing
47 * content to applications. They encapsulate data and provide it to applications through the single
48 * {@link ContentResolver} interface. A content provider is only required if you need to share
49 * data between multiple applications. For example, the contacts data is used by multiple
50 * applications and must be stored in a content provider. If you don't need to share data amongst
51 * multiple applications you can use a database directly via
52 * {@link android.database.sqlite.SQLiteDatabase}.
53 *
54 * <p>When a request is made via
55 * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
56 * request to the content provider registered with the authority. The content provider can interpret
57 * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
58 * URIs.</p>
59 *
60 * <p>The primary methods that need to be implemented are:
61 * <ul>
62 *   <li>{@link #onCreate} which is called to initialize the provider</li>
63 *   <li>{@link #query} which returns data to the caller</li>
64 *   <li>{@link #insert} which inserts new data into the content provider</li>
65 *   <li>{@link #update} which updates existing data in the content provider</li>
66 *   <li>{@link #delete} which deletes data from the content provider</li>
67 *   <li>{@link #getType} which returns the MIME type of data in the content provider</li>
68 * </ul></p>
69 *
70 * <p class="caution">Data access methods (such as {@link #insert} and
71 * {@link #update}) may be called from many threads at once, and must be thread-safe.
72 * Other methods (such as {@link #onCreate}) are only called from the application
73 * main thread, and must avoid performing lengthy operations.  See the method
74 * descriptions for their expected thread behavior.</p>
75 *
76 * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
77 * ContentProvider instance, so subclasses don't have to worry about the details of
78 * cross-process calls.</p>
79 *
80 * <div class="special reference">
81 * <h3>Developer Guides</h3>
82 * <p>For more information about using content providers, read the
83 * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
84 * developer guide.</p>
85 */
86public abstract class ContentProvider implements ComponentCallbacks2 {
87    private static final String TAG = "ContentProvider";
88
89    /*
90     * Note: if you add methods to ContentProvider, you must add similar methods to
91     *       MockContentProvider.
92     */
93
94    private Context mContext = null;
95    private int mMyUid;
96    private String mReadPermission;
97    private String mWritePermission;
98    private PathPermission[] mPathPermissions;
99    private boolean mExported;
100
101    private Transport mTransport = new Transport();
102
103    /**
104     * Construct a ContentProvider instance.  Content providers must be
105     * <a href="{@docRoot}guide/topics/manifest/provider-element.html">declared
106     * in the manifest</a>, accessed with {@link ContentResolver}, and created
107     * automatically by the system, so applications usually do not create
108     * ContentProvider instances directly.
109     *
110     * <p>At construction time, the object is uninitialized, and most fields and
111     * methods are unavailable.  Subclasses should initialize themselves in
112     * {@link #onCreate}, not the constructor.
113     *
114     * <p>Content providers are created on the application main thread at
115     * application launch time.  The constructor must not perform lengthy
116     * operations, or application startup will be delayed.
117     */
118    public ContentProvider() {
119    }
120
121    /**
122     * Constructor just for mocking.
123     *
124     * @param context A Context object which should be some mock instance (like the
125     * instance of {@link android.test.mock.MockContext}).
126     * @param readPermission The read permision you want this instance should have in the
127     * test, which is available via {@link #getReadPermission()}.
128     * @param writePermission The write permission you want this instance should have
129     * in the test, which is available via {@link #getWritePermission()}.
130     * @param pathPermissions The PathPermissions you want this instance should have
131     * in the test, which is available via {@link #getPathPermissions()}.
132     * @hide
133     */
134    public ContentProvider(
135            Context context,
136            String readPermission,
137            String writePermission,
138            PathPermission[] pathPermissions) {
139        mContext = context;
140        mReadPermission = readPermission;
141        mWritePermission = writePermission;
142        mPathPermissions = pathPermissions;
143    }
144
145    /**
146     * Given an IContentProvider, try to coerce it back to the real
147     * ContentProvider object if it is running in the local process.  This can
148     * be used if you know you are running in the same process as a provider,
149     * and want to get direct access to its implementation details.  Most
150     * clients should not nor have a reason to use it.
151     *
152     * @param abstractInterface The ContentProvider interface that is to be
153     *              coerced.
154     * @return If the IContentProvider is non-null and local, returns its actual
155     * ContentProvider instance.  Otherwise returns null.
156     * @hide
157     */
158    public static ContentProvider coerceToLocalContentProvider(
159            IContentProvider abstractInterface) {
160        if (abstractInterface instanceof Transport) {
161            return ((Transport)abstractInterface).getContentProvider();
162        }
163        return null;
164    }
165
166    /**
167     * Binder object that deals with remoting.
168     *
169     * @hide
170     */
171    class Transport extends ContentProviderNative {
172        ContentProvider getContentProvider() {
173            return ContentProvider.this;
174        }
175
176        @Override
177        public String getProviderName() {
178            return getContentProvider().getClass().getName();
179        }
180
181        @Override
182        public Cursor query(Uri uri, String[] projection,
183                String selection, String[] selectionArgs, String sortOrder,
184                ICancellationSignal cancellationSignal) {
185            enforceReadPermission(uri);
186            return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
187                    CancellationSignal.fromTransport(cancellationSignal));
188        }
189
190        @Override
191        public String getType(Uri uri) {
192            return ContentProvider.this.getType(uri);
193        }
194
195        @Override
196        public Uri insert(Uri uri, ContentValues initialValues) {
197            enforceWritePermission(uri);
198            return ContentProvider.this.insert(uri, initialValues);
199        }
200
201        @Override
202        public int bulkInsert(Uri uri, ContentValues[] initialValues) {
203            enforceWritePermission(uri);
204            return ContentProvider.this.bulkInsert(uri, initialValues);
205        }
206
207        @Override
208        public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
209                throws OperationApplicationException {
210            for (ContentProviderOperation operation : operations) {
211                if (operation.isReadOperation()) {
212                    enforceReadPermission(operation.getUri());
213                }
214
215                if (operation.isWriteOperation()) {
216                    enforceWritePermission(operation.getUri());
217                }
218            }
219            return ContentProvider.this.applyBatch(operations);
220        }
221
222        @Override
223        public int delete(Uri uri, String selection, String[] selectionArgs) {
224            enforceWritePermission(uri);
225            return ContentProvider.this.delete(uri, selection, selectionArgs);
226        }
227
228        @Override
229        public int update(Uri uri, ContentValues values, String selection,
230                String[] selectionArgs) {
231            enforceWritePermission(uri);
232            return ContentProvider.this.update(uri, values, selection, selectionArgs);
233        }
234
235        @Override
236        public ParcelFileDescriptor openFile(Uri uri, String mode)
237                throws FileNotFoundException {
238            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
239            else enforceReadPermission(uri);
240            return ContentProvider.this.openFile(uri, mode);
241        }
242
243        @Override
244        public AssetFileDescriptor openAssetFile(Uri uri, String mode)
245                throws FileNotFoundException {
246            if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
247            else enforceReadPermission(uri);
248            return ContentProvider.this.openAssetFile(uri, mode);
249        }
250
251        @Override
252        public Bundle call(String method, String arg, Bundle extras) {
253            return ContentProvider.this.call(method, arg, extras);
254        }
255
256        @Override
257        public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
258            return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
259        }
260
261        @Override
262        public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeType, Bundle opts)
263                throws FileNotFoundException {
264            enforceReadPermission(uri);
265            return ContentProvider.this.openTypedAssetFile(uri, mimeType, opts);
266        }
267
268        @Override
269        public ICancellationSignal createCancellationSignal() throws RemoteException {
270            return CancellationSignal.createTransport();
271        }
272
273        private void enforceReadPermission(Uri uri) throws SecurityException {
274            final Context context = getContext();
275            final int pid = Binder.getCallingPid();
276            final int uid = Binder.getCallingUid();
277            String missingPerm = null;
278
279            if (uid == mMyUid) {
280                return;
281            }
282
283            if (mExported) {
284                final String componentPerm = getReadPermission();
285                if (componentPerm != null) {
286                    if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
287                        return;
288                    } else {
289                        missingPerm = componentPerm;
290                    }
291                }
292
293                // track if unprotected read is allowed; any denied
294                // <path-permission> below removes this ability
295                boolean allowDefaultRead = (componentPerm == null);
296
297                final PathPermission[] pps = getPathPermissions();
298                if (pps != null) {
299                    final String path = uri.getPath();
300                    for (PathPermission pp : pps) {
301                        final String pathPerm = pp.getReadPermission();
302                        if (pathPerm != null && pp.match(path)) {
303                            if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
304                                return;
305                            } else {
306                                // any denied <path-permission> means we lose
307                                // default <provider> access.
308                                allowDefaultRead = false;
309                                missingPerm = pathPerm;
310                            }
311                        }
312                    }
313                }
314
315                // if we passed <path-permission> checks above, and no default
316                // <provider> permission, then allow access.
317                if (allowDefaultRead) return;
318            }
319
320            // last chance, check against any uri grants
321            if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
322                    == PERMISSION_GRANTED) {
323                return;
324            }
325
326            final String failReason = mExported
327                    ? " requires " + missingPerm + ", or grantUriPermission()"
328                    : " requires the provider be exported, or grantUriPermission()";
329            throw new SecurityException("Permission Denial: reading "
330                    + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
331                    + ", uid=" + uid + failReason);
332        }
333
334        private void enforceWritePermission(Uri uri) throws SecurityException {
335            final Context context = getContext();
336            final int pid = Binder.getCallingPid();
337            final int uid = Binder.getCallingUid();
338            String missingPerm = null;
339
340            if (uid == mMyUid) {
341                return;
342            }
343
344            if (mExported) {
345                final String componentPerm = getWritePermission();
346                if (componentPerm != null) {
347                    if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
348                        return;
349                    } else {
350                        missingPerm = componentPerm;
351                    }
352                }
353
354                // track if unprotected write is allowed; any denied
355                // <path-permission> below removes this ability
356                boolean allowDefaultWrite = (componentPerm == null);
357
358                final PathPermission[] pps = getPathPermissions();
359                if (pps != null) {
360                    final String path = uri.getPath();
361                    for (PathPermission pp : pps) {
362                        final String pathPerm = pp.getWritePermission();
363                        if (pathPerm != null && pp.match(path)) {
364                            if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
365                                return;
366                            } else {
367                                // any denied <path-permission> means we lose
368                                // default <provider> access.
369                                allowDefaultWrite = false;
370                                missingPerm = pathPerm;
371                            }
372                        }
373                    }
374                }
375
376                // if we passed <path-permission> checks above, and no default
377                // <provider> permission, then allow access.
378                if (allowDefaultWrite) return;
379            }
380
381            // last chance, check against any uri grants
382            if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
383                    == PERMISSION_GRANTED) {
384                return;
385            }
386
387            final String failReason = mExported
388                    ? " requires " + missingPerm + ", or grantUriPermission()"
389                    : " requires the provider be exported, or grantUriPermission()";
390            throw new SecurityException("Permission Denial: writing "
391                    + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
392                    + ", uid=" + uid + failReason);
393        }
394    }
395
396    /**
397     * Retrieves the Context this provider is running in.  Only available once
398     * {@link #onCreate} has been called -- this will return null in the
399     * constructor.
400     */
401    public final Context getContext() {
402        return mContext;
403    }
404
405    /**
406     * Change the permission required to read data from the content
407     * provider.  This is normally set for you from its manifest information
408     * when the provider is first created.
409     *
410     * @param permission Name of the permission required for read-only access.
411     */
412    protected final void setReadPermission(String permission) {
413        mReadPermission = permission;
414    }
415
416    /**
417     * Return the name of the permission required for read-only access to
418     * this content provider.  This method can be called from multiple
419     * threads, as described in
420     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
421     * and Threads</a>.
422     */
423    public final String getReadPermission() {
424        return mReadPermission;
425    }
426
427    /**
428     * Change the permission required to read and write data in the content
429     * provider.  This is normally set for you from its manifest information
430     * when the provider is first created.
431     *
432     * @param permission Name of the permission required for read/write access.
433     */
434    protected final void setWritePermission(String permission) {
435        mWritePermission = permission;
436    }
437
438    /**
439     * Return the name of the permission required for read/write access to
440     * this content provider.  This method can be called from multiple
441     * threads, as described in
442     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
443     * and Threads</a>.
444     */
445    public final String getWritePermission() {
446        return mWritePermission;
447    }
448
449    /**
450     * Change the path-based permission required to read and/or write data in
451     * the content provider.  This is normally set for you from its manifest
452     * information when the provider is first created.
453     *
454     * @param permissions Array of path permission descriptions.
455     */
456    protected final void setPathPermissions(PathPermission[] permissions) {
457        mPathPermissions = permissions;
458    }
459
460    /**
461     * Return the path-based permissions required for read and/or write access to
462     * this content provider.  This method can be called from multiple
463     * threads, as described in
464     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
465     * and Threads</a>.
466     */
467    public final PathPermission[] getPathPermissions() {
468        return mPathPermissions;
469    }
470
471    /**
472     * Implement this to initialize your content provider on startup.
473     * This method is called for all registered content providers on the
474     * application main thread at application launch time.  It must not perform
475     * lengthy operations, or application startup will be delayed.
476     *
477     * <p>You should defer nontrivial initialization (such as opening,
478     * upgrading, and scanning databases) until the content provider is used
479     * (via {@link #query}, {@link #insert}, etc).  Deferred initialization
480     * keeps application startup fast, avoids unnecessary work if the provider
481     * turns out not to be needed, and stops database errors (such as a full
482     * disk) from halting application launch.
483     *
484     * <p>If you use SQLite, {@link android.database.sqlite.SQLiteOpenHelper}
485     * is a helpful utility class that makes it easy to manage databases,
486     * and will automatically defer opening until first use.  If you do use
487     * SQLiteOpenHelper, make sure to avoid calling
488     * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
489     * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
490     * from this method.  (Instead, override
491     * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
492     * database when it is first opened.)
493     *
494     * @return true if the provider was successfully loaded, false otherwise
495     */
496    public abstract boolean onCreate();
497
498    /**
499     * {@inheritDoc}
500     * This method is always called on the application main thread, and must
501     * not perform lengthy operations.
502     *
503     * <p>The default content provider implementation does nothing.
504     * Override this method to take appropriate action.
505     * (Content providers do not usually care about things like screen
506     * orientation, but may want to know about locale changes.)
507     */
508    public void onConfigurationChanged(Configuration newConfig) {
509    }
510
511    /**
512     * {@inheritDoc}
513     * This method is always called on the application main thread, and must
514     * not perform lengthy operations.
515     *
516     * <p>The default content provider implementation does nothing.
517     * Subclasses may override this method to take appropriate action.
518     */
519    public void onLowMemory() {
520    }
521
522    public void onTrimMemory(int level) {
523    }
524
525    /**
526     * Implement this to handle query requests from clients.
527     * This method can be called from multiple threads, as described in
528     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
529     * and Threads</a>.
530     * <p>
531     * Example client call:<p>
532     * <pre>// Request a specific record.
533     * Cursor managedCursor = managedQuery(
534                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
535                projection,    // Which columns to return.
536                null,          // WHERE clause.
537                null,          // WHERE clause value substitution
538                People.NAME + " ASC");   // Sort order.</pre>
539     * Example implementation:<p>
540     * <pre>// SQLiteQueryBuilder is a helper class that creates the
541        // proper SQL syntax for us.
542        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
543
544        // Set the table we're querying.
545        qBuilder.setTables(DATABASE_TABLE_NAME);
546
547        // If the query ends in a specific record number, we're
548        // being asked for a specific record, so set the
549        // WHERE clause in our query.
550        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
551            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
552        }
553
554        // Make the query.
555        Cursor c = qBuilder.query(mDb,
556                projection,
557                selection,
558                selectionArgs,
559                groupBy,
560                having,
561                sortOrder);
562        c.setNotificationUri(getContext().getContentResolver(), uri);
563        return c;</pre>
564     *
565     * @param uri The URI to query. This will be the full URI sent by the client;
566     *      if the client is requesting a specific record, the URI will end in a record number
567     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
568     *      that _id value.
569     * @param projection The list of columns to put into the cursor. If
570     *      null all columns are included.
571     * @param selection A selection criteria to apply when filtering rows.
572     *      If null then all rows are included.
573     * @param selectionArgs You may include ?s in selection, which will be replaced by
574     *      the values from selectionArgs, in order that they appear in the selection.
575     *      The values will be bound as Strings.
576     * @param sortOrder How the rows in the cursor should be sorted.
577     *      If null then the provider is free to define the sort order.
578     * @return a Cursor or null.
579     */
580    public abstract Cursor query(Uri uri, String[] projection,
581            String selection, String[] selectionArgs, String sortOrder);
582
583    /**
584     * Implement this to handle query requests from clients with support for cancellation.
585     * This method can be called from multiple threads, as described in
586     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
587     * and Threads</a>.
588     * <p>
589     * Example client call:<p>
590     * <pre>// Request a specific record.
591     * Cursor managedCursor = managedQuery(
592                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
593                projection,    // Which columns to return.
594                null,          // WHERE clause.
595                null,          // WHERE clause value substitution
596                People.NAME + " ASC");   // Sort order.</pre>
597     * Example implementation:<p>
598     * <pre>// SQLiteQueryBuilder is a helper class that creates the
599        // proper SQL syntax for us.
600        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
601
602        // Set the table we're querying.
603        qBuilder.setTables(DATABASE_TABLE_NAME);
604
605        // If the query ends in a specific record number, we're
606        // being asked for a specific record, so set the
607        // WHERE clause in our query.
608        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
609            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
610        }
611
612        // Make the query.
613        Cursor c = qBuilder.query(mDb,
614                projection,
615                selection,
616                selectionArgs,
617                groupBy,
618                having,
619                sortOrder);
620        c.setNotificationUri(getContext().getContentResolver(), uri);
621        return c;</pre>
622     * <p>
623     * If you implement this method then you must also implement the version of
624     * {@link #query(Uri, String[], String, String[], String)} that does not take a cancellation
625     * signal to ensure correct operation on older versions of the Android Framework in
626     * which the cancellation signal overload was not available.
627     *
628     * @param uri The URI to query. This will be the full URI sent by the client;
629     *      if the client is requesting a specific record, the URI will end in a record number
630     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
631     *      that _id value.
632     * @param projection The list of columns to put into the cursor. If
633     *      null all columns are included.
634     * @param selection A selection criteria to apply when filtering rows.
635     *      If null then all rows are included.
636     * @param selectionArgs You may include ?s in selection, which will be replaced by
637     *      the values from selectionArgs, in order that they appear in the selection.
638     *      The values will be bound as Strings.
639     * @param sortOrder How the rows in the cursor should be sorted.
640     *      If null then the provider is free to define the sort order.
641     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
642     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
643     * when the query is executed.
644     * @return a Cursor or null.
645     */
646    public Cursor query(Uri uri, String[] projection,
647            String selection, String[] selectionArgs, String sortOrder,
648            CancellationSignal cancellationSignal) {
649        return query(uri, projection, selection, selectionArgs, sortOrder);
650    }
651
652    /**
653     * Implement this to handle requests for the MIME type of the data at the
654     * given URI.  The returned MIME type should start with
655     * <code>vnd.android.cursor.item</code> for a single record,
656     * or <code>vnd.android.cursor.dir/</code> for multiple items.
657     * This method can be called from multiple threads, as described in
658     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
659     * and Threads</a>.
660     *
661     * <p>Note that there are no permissions needed for an application to
662     * access this information; if your content provider requires read and/or
663     * write permissions, or is not exported, all applications can still call
664     * this method regardless of their access permissions.  This allows them
665     * to retrieve the MIME type for a URI when dispatching intents.
666     *
667     * @param uri the URI to query.
668     * @return a MIME type string, or null if there is no type.
669     */
670    public abstract String getType(Uri uri);
671
672    /**
673     * Implement this to handle requests to insert a new row.
674     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
675     * after inserting.
676     * This method can be called from multiple threads, as described in
677     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
678     * and Threads</a>.
679     * @param uri The content:// URI of the insertion request.
680     * @param values A set of column_name/value pairs to add to the database.
681     * @return The URI for the newly inserted item.
682     */
683    public abstract Uri insert(Uri uri, ContentValues values);
684
685    /**
686     * Override this to handle requests to insert a set of new rows, or the
687     * default implementation will iterate over the values and call
688     * {@link #insert} on each of them.
689     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
690     * after inserting.
691     * This method can be called from multiple threads, as described in
692     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
693     * and Threads</a>.
694     *
695     * @param uri The content:// URI of the insertion request.
696     * @param values An array of sets of column_name/value pairs to add to the database.
697     * @return The number of values that were inserted.
698     */
699    public int bulkInsert(Uri uri, ContentValues[] values) {
700        int numValues = values.length;
701        for (int i = 0; i < numValues; i++) {
702            insert(uri, values[i]);
703        }
704        return numValues;
705    }
706
707    /**
708     * Implement this to handle requests to delete one or more rows.
709     * The implementation should apply the selection clause when performing
710     * deletion, allowing the operation to affect multiple rows in a directory.
711     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
712     * after deleting.
713     * This method can be called from multiple threads, as described in
714     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
715     * and Threads</a>.
716     *
717     * <p>The implementation is responsible for parsing out a row ID at the end
718     * of the URI, if a specific row is being deleted. That is, the client would
719     * pass in <code>content://contacts/people/22</code> and the implementation is
720     * responsible for parsing the record number (22) when creating a SQL statement.
721     *
722     * @param uri The full URI to query, including a row ID (if a specific record is requested).
723     * @param selection An optional restriction to apply to rows when deleting.
724     * @return The number of rows affected.
725     * @throws SQLException
726     */
727    public abstract int delete(Uri uri, String selection, String[] selectionArgs);
728
729    /**
730     * Implement this to handle requests to update one or more rows.
731     * The implementation should update all rows matching the selection
732     * to set the columns according to the provided values map.
733     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
734     * after updating.
735     * This method can be called from multiple threads, as described in
736     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
737     * and Threads</a>.
738     *
739     * @param uri The URI to query. This can potentially have a record ID if this
740     * is an update request for a specific record.
741     * @param values A Bundle mapping from column names to new column values (NULL is a
742     *               valid value).
743     * @param selection An optional filter to match rows to update.
744     * @return the number of rows affected.
745     */
746    public abstract int update(Uri uri, ContentValues values, String selection,
747            String[] selectionArgs);
748
749    /**
750     * Override this to handle requests to open a file blob.
751     * The default implementation always throws {@link FileNotFoundException}.
752     * This method can be called from multiple threads, as described in
753     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
754     * and Threads</a>.
755     *
756     * <p>This method returns a ParcelFileDescriptor, which is returned directly
757     * to the caller.  This way large data (such as images and documents) can be
758     * returned without copying the content.
759     *
760     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
761     * their responsibility to close it when done.  That is, the implementation
762     * of this method should create a new ParcelFileDescriptor for each call.
763     *
764     * @param uri The URI whose file is to be opened.
765     * @param mode Access mode for the file.  May be "r" for read-only access,
766     * "rw" for read and write access, or "rwt" for read and write access
767     * that truncates any existing file.
768     *
769     * @return Returns a new ParcelFileDescriptor which you can use to access
770     * the file.
771     *
772     * @throws FileNotFoundException Throws FileNotFoundException if there is
773     * no file associated with the given URI or the mode is invalid.
774     * @throws SecurityException Throws SecurityException if the caller does
775     * not have permission to access the file.
776     *
777     * @see #openAssetFile(Uri, String)
778     * @see #openFileHelper(Uri, String)
779     */
780    public ParcelFileDescriptor openFile(Uri uri, String mode)
781            throws FileNotFoundException {
782        throw new FileNotFoundException("No files supported by provider at "
783                + uri);
784    }
785
786    /**
787     * This is like {@link #openFile}, but can be implemented by providers
788     * that need to be able to return sub-sections of files, often assets
789     * inside of their .apk.
790     * This method can be called from multiple threads, as described in
791     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
792     * and Threads</a>.
793     *
794     * <p>If you implement this, your clients must be able to deal with such
795     * file slices, either directly with
796     * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
797     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
798     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
799     * methods.
800     *
801     * <p class="note">If you are implementing this to return a full file, you
802     * should create the AssetFileDescriptor with
803     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
804     * applications that can not handle sub-sections of files.</p>
805     *
806     * @param uri The URI whose file is to be opened.
807     * @param mode Access mode for the file.  May be "r" for read-only access,
808     * "w" for write-only access (erasing whatever data is currently in
809     * the file), "wa" for write-only access to append to any existing data,
810     * "rw" for read and write access on any existing data, and "rwt" for read
811     * and write access that truncates any existing file.
812     *
813     * @return Returns a new AssetFileDescriptor which you can use to access
814     * the file.
815     *
816     * @throws FileNotFoundException Throws FileNotFoundException if there is
817     * no file associated with the given URI or the mode is invalid.
818     * @throws SecurityException Throws SecurityException if the caller does
819     * not have permission to access the file.
820     *
821     * @see #openFile(Uri, String)
822     * @see #openFileHelper(Uri, String)
823     */
824    public AssetFileDescriptor openAssetFile(Uri uri, String mode)
825            throws FileNotFoundException {
826        ParcelFileDescriptor fd = openFile(uri, mode);
827        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
828    }
829
830    /**
831     * Convenience for subclasses that wish to implement {@link #openFile}
832     * by looking up a column named "_data" at the given URI.
833     *
834     * @param uri The URI to be opened.
835     * @param mode The file mode.  May be "r" for read-only access,
836     * "w" for write-only access (erasing whatever data is currently in
837     * the file), "wa" for write-only access to append to any existing data,
838     * "rw" for read and write access on any existing data, and "rwt" for read
839     * and write access that truncates any existing file.
840     *
841     * @return Returns a new ParcelFileDescriptor that can be used by the
842     * client to access the file.
843     */
844    protected final ParcelFileDescriptor openFileHelper(Uri uri,
845            String mode) throws FileNotFoundException {
846        Cursor c = query(uri, new String[]{"_data"}, null, null, null);
847        int count = (c != null) ? c.getCount() : 0;
848        if (count != 1) {
849            // If there is not exactly one result, throw an appropriate
850            // exception.
851            if (c != null) {
852                c.close();
853            }
854            if (count == 0) {
855                throw new FileNotFoundException("No entry for " + uri);
856            }
857            throw new FileNotFoundException("Multiple items at " + uri);
858        }
859
860        c.moveToFirst();
861        int i = c.getColumnIndex("_data");
862        String path = (i >= 0 ? c.getString(i) : null);
863        c.close();
864        if (path == null) {
865            throw new FileNotFoundException("Column _data not found.");
866        }
867
868        int modeBits = ContentResolver.modeToMode(uri, mode);
869        return ParcelFileDescriptor.open(new File(path), modeBits);
870    }
871
872    /**
873     * Called by a client to determine the types of data streams that this
874     * content provider supports for the given URI.  The default implementation
875     * returns null, meaning no types.  If your content provider stores data
876     * of a particular type, return that MIME type if it matches the given
877     * mimeTypeFilter.  If it can perform type conversions, return an array
878     * of all supported MIME types that match mimeTypeFilter.
879     *
880     * @param uri The data in the content provider being queried.
881     * @param mimeTypeFilter The type of data the client desires.  May be
882     * a pattern, such as *\/* to retrieve all possible data types.
883     * @return Returns null if there are no possible data streams for the
884     * given mimeTypeFilter.  Otherwise returns an array of all available
885     * concrete MIME types.
886     *
887     * @see #getType(Uri)
888     * @see #openTypedAssetFile(Uri, String, Bundle)
889     * @see ClipDescription#compareMimeTypes(String, String)
890     */
891    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
892        return null;
893    }
894
895    /**
896     * Called by a client to open a read-only stream containing data of a
897     * particular MIME type.  This is like {@link #openAssetFile(Uri, String)},
898     * except the file can only be read-only and the content provider may
899     * perform data conversions to generate data of the desired type.
900     *
901     * <p>The default implementation compares the given mimeType against the
902     * result of {@link #getType(Uri)} and, if the match, simple calls
903     * {@link #openAssetFile(Uri, String)}.
904     *
905     * <p>See {@link ClipData} for examples of the use and implementation
906     * of this method.
907     *
908     * @param uri The data in the content provider being queried.
909     * @param mimeTypeFilter The type of data the client desires.  May be
910     * a pattern, such as *\/*, if the caller does not have specific type
911     * requirements; in this case the content provider will pick its best
912     * type matching the pattern.
913     * @param opts Additional options from the client.  The definitions of
914     * these are specific to the content provider being called.
915     *
916     * @return Returns a new AssetFileDescriptor from which the client can
917     * read data of the desired type.
918     *
919     * @throws FileNotFoundException Throws FileNotFoundException if there is
920     * no file associated with the given URI or the mode is invalid.
921     * @throws SecurityException Throws SecurityException if the caller does
922     * not have permission to access the data.
923     * @throws IllegalArgumentException Throws IllegalArgumentException if the
924     * content provider does not support the requested MIME type.
925     *
926     * @see #getStreamTypes(Uri, String)
927     * @see #openAssetFile(Uri, String)
928     * @see ClipDescription#compareMimeTypes(String, String)
929     */
930    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
931            throws FileNotFoundException {
932        if ("*/*".equals(mimeTypeFilter)) {
933            // If they can take anything, the untyped open call is good enough.
934            return openAssetFile(uri, "r");
935        }
936        String baseType = getType(uri);
937        if (baseType != null && ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) {
938            // Use old untyped open call if this provider has a type for this
939            // URI and it matches the request.
940            return openAssetFile(uri, "r");
941        }
942        throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
943    }
944
945    /**
946     * Interface to write a stream of data to a pipe.  Use with
947     * {@link ContentProvider#openPipeHelper}.
948     */
949    public interface PipeDataWriter<T> {
950        /**
951         * Called from a background thread to stream data out to a pipe.
952         * Note that the pipe is blocking, so this thread can block on
953         * writes for an arbitrary amount of time if the client is slow
954         * at reading.
955         *
956         * @param output The pipe where data should be written.  This will be
957         * closed for you upon returning from this function.
958         * @param uri The URI whose data is to be written.
959         * @param mimeType The desired type of data to be written.
960         * @param opts Options supplied by caller.
961         * @param args Your own custom arguments.
962         */
963        public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
964                Bundle opts, T args);
965    }
966
967    /**
968     * A helper function for implementing {@link #openTypedAssetFile}, for
969     * creating a data pipe and background thread allowing you to stream
970     * generated data back to the client.  This function returns a new
971     * ParcelFileDescriptor that should be returned to the caller (the caller
972     * is responsible for closing it).
973     *
974     * @param uri The URI whose data is to be written.
975     * @param mimeType The desired type of data to be written.
976     * @param opts Options supplied by caller.
977     * @param args Your own custom arguments.
978     * @param func Interface implementing the function that will actually
979     * stream the data.
980     * @return Returns a new ParcelFileDescriptor holding the read side of
981     * the pipe.  This should be returned to the caller for reading; the caller
982     * is responsible for closing it when done.
983     */
984    public <T> ParcelFileDescriptor openPipeHelper(final Uri uri, final String mimeType,
985            final Bundle opts, final T args, final PipeDataWriter<T> func)
986            throws FileNotFoundException {
987        try {
988            final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
989
990            AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
991                @Override
992                protected Object doInBackground(Object... params) {
993                    func.writeDataToPipe(fds[1], uri, mimeType, opts, args);
994                    try {
995                        fds[1].close();
996                    } catch (IOException e) {
997                        Log.w(TAG, "Failure closing pipe", e);
998                    }
999                    return null;
1000                }
1001            };
1002            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null);
1003
1004            return fds[0];
1005        } catch (IOException e) {
1006            throw new FileNotFoundException("failure making pipe");
1007        }
1008    }
1009
1010    /**
1011     * Returns true if this instance is a temporary content provider.
1012     * @return true if this instance is a temporary content provider
1013     */
1014    protected boolean isTemporary() {
1015        return false;
1016    }
1017
1018    /**
1019     * Returns the Binder object for this provider.
1020     *
1021     * @return the Binder object for this provider
1022     * @hide
1023     */
1024    public IContentProvider getIContentProvider() {
1025        return mTransport;
1026    }
1027
1028    /**
1029     * After being instantiated, this is called to tell the content provider
1030     * about itself.
1031     *
1032     * @param context The context this provider is running in
1033     * @param info Registered information about this content provider
1034     */
1035    public void attachInfo(Context context, ProviderInfo info) {
1036        /*
1037         * We may be using AsyncTask from binder threads.  Make it init here
1038         * so its static handler is on the main thread.
1039         */
1040        AsyncTask.init();
1041
1042        /*
1043         * Only allow it to be set once, so after the content service gives
1044         * this to us clients can't change it.
1045         */
1046        if (mContext == null) {
1047            mContext = context;
1048            mMyUid = Process.myUid();
1049            if (info != null) {
1050                setReadPermission(info.readPermission);
1051                setWritePermission(info.writePermission);
1052                setPathPermissions(info.pathPermissions);
1053                mExported = info.exported;
1054            }
1055            ContentProvider.this.onCreate();
1056        }
1057    }
1058
1059    /**
1060     * Override this to handle requests to perform a batch of operations, or the
1061     * default implementation will iterate over the operations and call
1062     * {@link ContentProviderOperation#apply} on each of them.
1063     * If all calls to {@link ContentProviderOperation#apply} succeed
1064     * then a {@link ContentProviderResult} array with as many
1065     * elements as there were operations will be returned.  If any of the calls
1066     * fail, it is up to the implementation how many of the others take effect.
1067     * This method can be called from multiple threads, as described in
1068     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
1069     * and Threads</a>.
1070     *
1071     * @param operations the operations to apply
1072     * @return the results of the applications
1073     * @throws OperationApplicationException thrown if any operation fails.
1074     * @see ContentProviderOperation#apply
1075     */
1076    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
1077            throws OperationApplicationException {
1078        final int numOperations = operations.size();
1079        final ContentProviderResult[] results = new ContentProviderResult[numOperations];
1080        for (int i = 0; i < numOperations; i++) {
1081            results[i] = operations.get(i).apply(this, results, i);
1082        }
1083        return results;
1084    }
1085
1086    /**
1087     * Call a provider-defined method.  This can be used to implement
1088     * interfaces that are cheaper and/or unnatural for a table-like
1089     * model.
1090     *
1091     * @param method method name to call.  Opaque to framework, but should not be null.
1092     * @param arg provider-defined String argument.  May be null.
1093     * @param extras provider-defined Bundle argument.  May be null.
1094     * @return provider-defined return value.  May be null.  Null is also
1095     *   the default for providers which don't implement any call methods.
1096     */
1097    public Bundle call(String method, String arg, Bundle extras) {
1098        return null;
1099    }
1100
1101    /**
1102     * Implement this to shut down the ContentProvider instance. You can then
1103     * invoke this method in unit tests.
1104     *
1105     * <p>
1106     * Android normally handles ContentProvider startup and shutdown
1107     * automatically. You do not need to start up or shut down a
1108     * ContentProvider. When you invoke a test method on a ContentProvider,
1109     * however, a ContentProvider instance is started and keeps running after
1110     * the test finishes, even if a succeeding test instantiates another
1111     * ContentProvider. A conflict develops because the two instances are
1112     * usually running against the same underlying data source (for example, an
1113     * sqlite database).
1114     * </p>
1115     * <p>
1116     * Implementing shutDown() avoids this conflict by providing a way to
1117     * terminate the ContentProvider. This method can also prevent memory leaks
1118     * from multiple instantiations of the ContentProvider, and it can ensure
1119     * unit test isolation by allowing you to completely clean up the test
1120     * fixture before moving on to the next test.
1121     * </p>
1122     */
1123    public void shutdown() {
1124        Log.w(TAG, "implement ContentProvider shutdown() to make sure all database " +
1125                "connections are gracefully shutdown");
1126    }
1127
1128    /**
1129     * Print the Provider's state into the given stream.  This gets invoked if
1130     * you run "adb shell dumpsys activity provider <provider_component_name>".
1131     *
1132     * @param prefix Desired prefix to prepend at each line of output.
1133     * @param fd The raw file descriptor that the dump is being sent to.
1134     * @param writer The PrintWriter to which you should dump your state.  This will be
1135     * closed for you after you return.
1136     * @param args additional arguments to the dump request.
1137     * @hide
1138     */
1139    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
1140        writer.println("nothing to dump");
1141    }
1142}
1143