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