ContentProvider.java revision 38ed2a471a2291383821fb187bfa18450f0581c2
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.app.AppOpsManager;
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    private boolean mNoPerms;
104
105    private final ThreadLocal<String> mCallingPackage = new ThreadLocal<String>();
106
107    private Transport mTransport = new Transport();
108
109    /**
110     * Construct a ContentProvider instance.  Content providers must be
111     * <a href="{@docRoot}guide/topics/manifest/provider-element.html">declared
112     * in the manifest</a>, accessed with {@link ContentResolver}, and created
113     * automatically by the system, so applications usually do not create
114     * ContentProvider instances directly.
115     *
116     * <p>At construction time, the object is uninitialized, and most fields and
117     * methods are unavailable.  Subclasses should initialize themselves in
118     * {@link #onCreate}, not the constructor.
119     *
120     * <p>Content providers are created on the application main thread at
121     * application launch time.  The constructor must not perform lengthy
122     * operations, or application startup will be delayed.
123     */
124    public ContentProvider() {
125    }
126
127    /**
128     * Constructor just for mocking.
129     *
130     * @param context A Context object which should be some mock instance (like the
131     * instance of {@link android.test.mock.MockContext}).
132     * @param readPermission The read permision you want this instance should have in the
133     * test, which is available via {@link #getReadPermission()}.
134     * @param writePermission The write permission you want this instance should have
135     * in the test, which is available via {@link #getWritePermission()}.
136     * @param pathPermissions The PathPermissions you want this instance should have
137     * in the test, which is available via {@link #getPathPermissions()}.
138     * @hide
139     */
140    public ContentProvider(
141            Context context,
142            String readPermission,
143            String writePermission,
144            PathPermission[] pathPermissions) {
145        mContext = context;
146        mReadPermission = readPermission;
147        mWritePermission = writePermission;
148        mPathPermissions = pathPermissions;
149    }
150
151    /**
152     * Given an IContentProvider, try to coerce it back to the real
153     * ContentProvider object if it is running in the local process.  This can
154     * be used if you know you are running in the same process as a provider,
155     * and want to get direct access to its implementation details.  Most
156     * clients should not nor have a reason to use it.
157     *
158     * @param abstractInterface The ContentProvider interface that is to be
159     *              coerced.
160     * @return If the IContentProvider is non-{@code null} and local, returns its actual
161     * ContentProvider instance.  Otherwise returns {@code null}.
162     * @hide
163     */
164    public static ContentProvider coerceToLocalContentProvider(
165            IContentProvider abstractInterface) {
166        if (abstractInterface instanceof Transport) {
167            return ((Transport)abstractInterface).getContentProvider();
168        }
169        return null;
170    }
171
172    /**
173     * Binder object that deals with remoting.
174     *
175     * @hide
176     */
177    class Transport extends ContentProviderNative {
178        AppOpsManager mAppOpsManager = null;
179        int mReadOp = AppOpsManager.OP_NONE;
180        int mWriteOp = AppOpsManager.OP_NONE;
181
182        ContentProvider getContentProvider() {
183            return ContentProvider.this;
184        }
185
186        @Override
187        public String getProviderName() {
188            return getContentProvider().getClass().getName();
189        }
190
191        @Override
192        public Cursor query(String callingPkg, Uri uri, String[] projection,
193                String selection, String[] selectionArgs, String sortOrder,
194                ICancellationSignal cancellationSignal) {
195            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
196                return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
197                        CancellationSignal.fromTransport(cancellationSignal));
198            }
199            mCallingPackage.set(callingPkg);
200            try {
201                return ContentProvider.this.query(
202                        uri, projection, selection, selectionArgs, sortOrder,
203                        CancellationSignal.fromTransport(cancellationSignal));
204            } finally {
205                mCallingPackage.set(null);
206            }
207        }
208
209        @Override
210        public String getType(Uri uri) {
211            return ContentProvider.this.getType(uri);
212        }
213
214        @Override
215        public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
216            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
217                return rejectInsert(uri, initialValues);
218            }
219            mCallingPackage.set(callingPkg);
220            try {
221                return ContentProvider.this.insert(uri, initialValues);
222            } finally {
223                mCallingPackage.set(null);
224            }
225        }
226
227        @Override
228        public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
229            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
230                return 0;
231            }
232            mCallingPackage.set(callingPkg);
233            try {
234                return ContentProvider.this.bulkInsert(uri, initialValues);
235            } finally {
236                mCallingPackage.set(null);
237            }
238        }
239
240        @Override
241        public ContentProviderResult[] applyBatch(String callingPkg,
242                ArrayList<ContentProviderOperation> operations)
243                throws OperationApplicationException {
244            for (ContentProviderOperation operation : operations) {
245                if (operation.isReadOperation()) {
246                    if (enforceReadPermission(callingPkg, operation.getUri())
247                            != AppOpsManager.MODE_ALLOWED) {
248                        throw new OperationApplicationException("App op not allowed", 0);
249                    }
250                }
251
252                if (operation.isWriteOperation()) {
253                    if (enforceWritePermission(callingPkg, operation.getUri())
254                            != AppOpsManager.MODE_ALLOWED) {
255                        throw new OperationApplicationException("App op not allowed", 0);
256                    }
257                }
258            }
259            mCallingPackage.set(callingPkg);
260            try {
261                return ContentProvider.this.applyBatch(operations);
262            } finally {
263                mCallingPackage.set(null);
264            }
265        }
266
267        @Override
268        public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
269            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
270                return 0;
271            }
272            mCallingPackage.set(callingPkg);
273            try {
274                return ContentProvider.this.delete(uri, selection, selectionArgs);
275            } finally {
276                mCallingPackage.set(null);
277            }
278        }
279
280        @Override
281        public int update(String callingPkg, Uri uri, ContentValues values, String selection,
282                String[] selectionArgs) {
283            if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
284                return 0;
285            }
286            mCallingPackage.set(callingPkg);
287            try {
288                return ContentProvider.this.update(uri, values, selection, selectionArgs);
289            } finally {
290                mCallingPackage.set(null);
291            }
292        }
293
294        @Override
295        public ParcelFileDescriptor openFile(
296                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
297                throws FileNotFoundException {
298            enforceFilePermission(callingPkg, uri, mode);
299            mCallingPackage.set(callingPkg);
300            try {
301                return ContentProvider.this.openFile(
302                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
303            } finally {
304                mCallingPackage.set(null);
305            }
306        }
307
308        @Override
309        public AssetFileDescriptor openAssetFile(
310                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
311                throws FileNotFoundException {
312            enforceFilePermission(callingPkg, uri, mode);
313            mCallingPackage.set(callingPkg);
314            try {
315                return ContentProvider.this.openAssetFile(
316                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
317            } finally {
318                mCallingPackage.set(null);
319            }
320        }
321
322        @Override
323        public Bundle call(String callingPkg, String method, String arg, Bundle extras) {
324            mCallingPackage.set(callingPkg);
325            try {
326                return ContentProvider.this.call(method, arg, extras);
327            } finally {
328                mCallingPackage.set(null);
329            }
330        }
331
332        @Override
333        public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
334            return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
335        }
336
337        @Override
338        public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
339                Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
340            enforceFilePermission(callingPkg, uri, "r");
341            mCallingPackage.set(callingPkg);
342            try {
343                return ContentProvider.this.openTypedAssetFile(
344                        uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
345            } finally {
346                mCallingPackage.set(null);
347            }
348        }
349
350        @Override
351        public ICancellationSignal createCancellationSignal() {
352            return CancellationSignal.createTransport();
353        }
354
355        @Override
356        public Uri canonicalize(String callingPkg, Uri uri) {
357            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
358                return null;
359            }
360            mCallingPackage.set(callingPkg);
361            try {
362                return ContentProvider.this.canonicalize(uri);
363            } finally {
364                mCallingPackage.set(null);
365            }
366        }
367
368        @Override
369        public Uri uncanonicalize(String callingPkg, Uri uri) {
370            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
371                return null;
372            }
373            mCallingPackage.set(callingPkg);
374            try {
375                return ContentProvider.this.uncanonicalize(uri);
376            } finally {
377                mCallingPackage.set(null);
378            }
379        }
380
381        private void enforceFilePermission(String callingPkg, Uri uri, String mode)
382                throws FileNotFoundException, SecurityException {
383            if (mode != null && mode.indexOf('w') != -1) {
384                if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
385                    throw new FileNotFoundException("App op not allowed");
386                }
387            } else {
388                if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
389                    throw new FileNotFoundException("App op not allowed");
390                }
391            }
392        }
393
394        private int enforceReadPermission(String callingPkg, Uri uri) throws SecurityException {
395            enforceReadPermissionInner(uri);
396            if (mReadOp != AppOpsManager.OP_NONE) {
397                return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg);
398            }
399            return AppOpsManager.MODE_ALLOWED;
400        }
401
402        private void enforceReadPermissionInner(Uri uri) throws SecurityException {
403            final Context context = getContext();
404            final int pid = Binder.getCallingPid();
405            final int uid = Binder.getCallingUid();
406            String missingPerm = null;
407
408            if (UserHandle.isSameApp(uid, mMyUid)) {
409                return;
410            }
411
412            if (mExported) {
413                final String componentPerm = getReadPermission();
414                if (componentPerm != null) {
415                    if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
416                        return;
417                    } else {
418                        missingPerm = componentPerm;
419                    }
420                }
421
422                // track if unprotected read is allowed; any denied
423                // <path-permission> below removes this ability
424                boolean allowDefaultRead = (componentPerm == null);
425
426                final PathPermission[] pps = getPathPermissions();
427                if (pps != null) {
428                    final String path = uri.getPath();
429                    for (PathPermission pp : pps) {
430                        final String pathPerm = pp.getReadPermission();
431                        if (pathPerm != null && pp.match(path)) {
432                            if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
433                                return;
434                            } else {
435                                // any denied <path-permission> means we lose
436                                // default <provider> access.
437                                allowDefaultRead = false;
438                                missingPerm = pathPerm;
439                            }
440                        }
441                    }
442                }
443
444                // if we passed <path-permission> checks above, and no default
445                // <provider> permission, then allow access.
446                if (allowDefaultRead) return;
447            }
448
449            // last chance, check against any uri grants
450            if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
451                    == PERMISSION_GRANTED) {
452                return;
453            }
454
455            final String failReason = mExported
456                    ? " requires " + missingPerm + ", or grantUriPermission()"
457                    : " requires the provider be exported, or grantUriPermission()";
458            throw new SecurityException("Permission Denial: reading "
459                    + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
460                    + ", uid=" + uid + failReason);
461        }
462
463        private int enforceWritePermission(String callingPkg, Uri uri) throws SecurityException {
464            enforceWritePermissionInner(uri);
465            if (mWriteOp != AppOpsManager.OP_NONE) {
466                return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg);
467            }
468            return AppOpsManager.MODE_ALLOWED;
469        }
470
471        private void enforceWritePermissionInner(Uri uri) throws SecurityException {
472            final Context context = getContext();
473            final int pid = Binder.getCallingPid();
474            final int uid = Binder.getCallingUid();
475            String missingPerm = null;
476
477            if (UserHandle.isSameApp(uid, mMyUid)) {
478                return;
479            }
480
481            if (mExported) {
482                final String componentPerm = getWritePermission();
483                if (componentPerm != null) {
484                    if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
485                        return;
486                    } else {
487                        missingPerm = componentPerm;
488                    }
489                }
490
491                // track if unprotected write is allowed; any denied
492                // <path-permission> below removes this ability
493                boolean allowDefaultWrite = (componentPerm == null);
494
495                final PathPermission[] pps = getPathPermissions();
496                if (pps != null) {
497                    final String path = uri.getPath();
498                    for (PathPermission pp : pps) {
499                        final String pathPerm = pp.getWritePermission();
500                        if (pathPerm != null && pp.match(path)) {
501                            if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
502                                return;
503                            } else {
504                                // any denied <path-permission> means we lose
505                                // default <provider> access.
506                                allowDefaultWrite = false;
507                                missingPerm = pathPerm;
508                            }
509                        }
510                    }
511                }
512
513                // if we passed <path-permission> checks above, and no default
514                // <provider> permission, then allow access.
515                if (allowDefaultWrite) return;
516            }
517
518            // last chance, check against any uri grants
519            if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
520                    == PERMISSION_GRANTED) {
521                return;
522            }
523
524            final String failReason = mExported
525                    ? " requires " + missingPerm + ", or grantUriPermission()"
526                    : " requires the provider be exported, or grantUriPermission()";
527            throw new SecurityException("Permission Denial: writing "
528                    + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
529                    + ", uid=" + uid + failReason);
530        }
531    }
532
533    /**
534     * Retrieves the Context this provider is running in.  Only available once
535     * {@link #onCreate} has been called -- this will return {@code null} in the
536     * constructor.
537     */
538    public final Context getContext() {
539        return mContext;
540    }
541
542    /**
543     * Return the package name of the caller that initiated the request being
544     * processed on the current thread. The returned package will have been
545     * verified to belong to the calling UID. Returns {@code null} if not
546     * currently processing a request.
547     * <p>
548     * This will always return {@code null} when processing
549     * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
550     *
551     * @see Binder#getCallingUid()
552     * @see Context#grantUriPermission(String, Uri, int)
553     * @throws SecurityException if the calling package doesn't belong to the
554     *             calling UID.
555     */
556    public final String getCallingPackage() {
557        final String pkg = mCallingPackage.get();
558        if (pkg != null) {
559            mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg);
560        }
561        return pkg;
562    }
563
564    /**
565     * Change the permission required to read data from the content
566     * provider.  This is normally set for you from its manifest information
567     * when the provider is first created.
568     *
569     * @param permission Name of the permission required for read-only access.
570     */
571    protected final void setReadPermission(String permission) {
572        mReadPermission = permission;
573    }
574
575    /**
576     * Return the name of the permission required for read-only access to
577     * this content provider.  This method can be called from multiple
578     * threads, as described in
579     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
580     * and Threads</a>.
581     */
582    public final String getReadPermission() {
583        return mReadPermission;
584    }
585
586    /**
587     * Change the permission required to read and write data in the content
588     * provider.  This is normally set for you from its manifest information
589     * when the provider is first created.
590     *
591     * @param permission Name of the permission required for read/write access.
592     */
593    protected final void setWritePermission(String permission) {
594        mWritePermission = permission;
595    }
596
597    /**
598     * Return the name of the permission required for read/write access to
599     * this content provider.  This method can be called from multiple
600     * threads, as described in
601     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
602     * and Threads</a>.
603     */
604    public final String getWritePermission() {
605        return mWritePermission;
606    }
607
608    /**
609     * Change the path-based permission required to read and/or write data in
610     * the content provider.  This is normally set for you from its manifest
611     * information when the provider is first created.
612     *
613     * @param permissions Array of path permission descriptions.
614     */
615    protected final void setPathPermissions(PathPermission[] permissions) {
616        mPathPermissions = permissions;
617    }
618
619    /**
620     * Return the path-based permissions required for read and/or write access to
621     * this content provider.  This method can be called from multiple
622     * threads, as described in
623     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
624     * and Threads</a>.
625     */
626    public final PathPermission[] getPathPermissions() {
627        return mPathPermissions;
628    }
629
630    /** @hide */
631    public final void setAppOps(int readOp, int writeOp) {
632        if (!mNoPerms) {
633            mTransport.mReadOp = readOp;
634            mTransport.mWriteOp = writeOp;
635        }
636    }
637
638    /** @hide */
639    public AppOpsManager getAppOpsManager() {
640        return mTransport.mAppOpsManager;
641    }
642
643    /**
644     * Implement this to initialize your content provider on startup.
645     * This method is called for all registered content providers on the
646     * application main thread at application launch time.  It must not perform
647     * lengthy operations, or application startup will be delayed.
648     *
649     * <p>You should defer nontrivial initialization (such as opening,
650     * upgrading, and scanning databases) until the content provider is used
651     * (via {@link #query}, {@link #insert}, etc).  Deferred initialization
652     * keeps application startup fast, avoids unnecessary work if the provider
653     * turns out not to be needed, and stops database errors (such as a full
654     * disk) from halting application launch.
655     *
656     * <p>If you use SQLite, {@link android.database.sqlite.SQLiteOpenHelper}
657     * is a helpful utility class that makes it easy to manage databases,
658     * and will automatically defer opening until first use.  If you do use
659     * SQLiteOpenHelper, make sure to avoid calling
660     * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
661     * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
662     * from this method.  (Instead, override
663     * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
664     * database when it is first opened.)
665     *
666     * @return true if the provider was successfully loaded, false otherwise
667     */
668    public abstract boolean onCreate();
669
670    /**
671     * {@inheritDoc}
672     * This method is always called on the application main thread, and must
673     * not perform lengthy operations.
674     *
675     * <p>The default content provider implementation does nothing.
676     * Override this method to take appropriate action.
677     * (Content providers do not usually care about things like screen
678     * orientation, but may want to know about locale changes.)
679     */
680    public void onConfigurationChanged(Configuration newConfig) {
681    }
682
683    /**
684     * {@inheritDoc}
685     * This method is always called on the application main thread, and must
686     * not perform lengthy operations.
687     *
688     * <p>The default content provider implementation does nothing.
689     * Subclasses may override this method to take appropriate action.
690     */
691    public void onLowMemory() {
692    }
693
694    public void onTrimMemory(int level) {
695    }
696
697    /**
698     * @hide
699     * Implementation when a caller has performed a query on the content
700     * provider, but that call has been rejected for the operation given
701     * to {@link #setAppOps(int, int)}.  The default implementation
702     * rewrites the <var>selection</var> argument to include a condition
703     * that is never true (so will always result in an empty cursor)
704     * and calls through to {@link #query(android.net.Uri, String[], String, String[],
705     * String, android.os.CancellationSignal)} with that.
706     */
707    public Cursor rejectQuery(Uri uri, String[] projection,
708            String selection, String[] selectionArgs, String sortOrder,
709            CancellationSignal cancellationSignal) {
710        // The read is not allowed...  to fake it out, we replace the given
711        // selection statement with a dummy one that will always be false.
712        // This way we will get a cursor back that has the correct structure
713        // but contains no rows.
714        if (selection == null || selection.isEmpty()) {
715            selection = "'A' = 'B'";
716        } else {
717            selection = "'A' = 'B' AND (" + selection + ")";
718        }
719        return query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
720    }
721
722    /**
723     * Implement this to handle query requests from clients.
724     * This method can be called from multiple threads, as described in
725     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
726     * and Threads</a>.
727     * <p>
728     * Example client call:<p>
729     * <pre>// Request a specific record.
730     * Cursor managedCursor = managedQuery(
731                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
732                projection,    // Which columns to return.
733                null,          // WHERE clause.
734                null,          // WHERE clause value substitution
735                People.NAME + " ASC");   // Sort order.</pre>
736     * Example implementation:<p>
737     * <pre>// SQLiteQueryBuilder is a helper class that creates the
738        // proper SQL syntax for us.
739        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
740
741        // Set the table we're querying.
742        qBuilder.setTables(DATABASE_TABLE_NAME);
743
744        // If the query ends in a specific record number, we're
745        // being asked for a specific record, so set the
746        // WHERE clause in our query.
747        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
748            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
749        }
750
751        // Make the query.
752        Cursor c = qBuilder.query(mDb,
753                projection,
754                selection,
755                selectionArgs,
756                groupBy,
757                having,
758                sortOrder);
759        c.setNotificationUri(getContext().getContentResolver(), uri);
760        return c;</pre>
761     *
762     * @param uri The URI to query. This will be the full URI sent by the client;
763     *      if the client is requesting a specific record, the URI will end in a record number
764     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
765     *      that _id value.
766     * @param projection The list of columns to put into the cursor. If
767     *      {@code null} all columns are included.
768     * @param selection A selection criteria to apply when filtering rows.
769     *      If {@code null} then all rows are included.
770     * @param selectionArgs You may include ?s in selection, which will be replaced by
771     *      the values from selectionArgs, in order that they appear in the selection.
772     *      The values will be bound as Strings.
773     * @param sortOrder How the rows in the cursor should be sorted.
774     *      If {@code null} then the provider is free to define the sort order.
775     * @return a Cursor or {@code null}.
776     */
777    public abstract Cursor query(Uri uri, String[] projection,
778            String selection, String[] selectionArgs, String sortOrder);
779
780    /**
781     * Implement this to handle query requests from clients with support for cancellation.
782     * This method can be called from multiple threads, as described in
783     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
784     * and Threads</a>.
785     * <p>
786     * Example client call:<p>
787     * <pre>// Request a specific record.
788     * Cursor managedCursor = managedQuery(
789                ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
790                projection,    // Which columns to return.
791                null,          // WHERE clause.
792                null,          // WHERE clause value substitution
793                People.NAME + " ASC");   // Sort order.</pre>
794     * Example implementation:<p>
795     * <pre>// SQLiteQueryBuilder is a helper class that creates the
796        // proper SQL syntax for us.
797        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
798
799        // Set the table we're querying.
800        qBuilder.setTables(DATABASE_TABLE_NAME);
801
802        // If the query ends in a specific record number, we're
803        // being asked for a specific record, so set the
804        // WHERE clause in our query.
805        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
806            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
807        }
808
809        // Make the query.
810        Cursor c = qBuilder.query(mDb,
811                projection,
812                selection,
813                selectionArgs,
814                groupBy,
815                having,
816                sortOrder);
817        c.setNotificationUri(getContext().getContentResolver(), uri);
818        return c;</pre>
819     * <p>
820     * If you implement this method then you must also implement the version of
821     * {@link #query(Uri, String[], String, String[], String)} that does not take a cancellation
822     * signal to ensure correct operation on older versions of the Android Framework in
823     * which the cancellation signal overload was not available.
824     *
825     * @param uri The URI to query. This will be the full URI sent by the client;
826     *      if the client is requesting a specific record, the URI will end in a record number
827     *      that the implementation should parse and add to a WHERE or HAVING clause, specifying
828     *      that _id value.
829     * @param projection The list of columns to put into the cursor. If
830     *      {@code null} all columns are included.
831     * @param selection A selection criteria to apply when filtering rows.
832     *      If {@code null} then all rows are included.
833     * @param selectionArgs You may include ?s in selection, which will be replaced by
834     *      the values from selectionArgs, in order that they appear in the selection.
835     *      The values will be bound as Strings.
836     * @param sortOrder How the rows in the cursor should be sorted.
837     *      If {@code null} then the provider is free to define the sort order.
838     * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if none.
839     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
840     * when the query is executed.
841     * @return a Cursor or {@code null}.
842     */
843    public Cursor query(Uri uri, String[] projection,
844            String selection, String[] selectionArgs, String sortOrder,
845            CancellationSignal cancellationSignal) {
846        return query(uri, projection, selection, selectionArgs, sortOrder);
847    }
848
849    /**
850     * Implement this to handle requests for the MIME type of the data at the
851     * given URI.  The returned MIME type should start with
852     * <code>vnd.android.cursor.item</code> for a single record,
853     * or <code>vnd.android.cursor.dir/</code> for multiple items.
854     * This method can be called from multiple threads, as described in
855     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
856     * and Threads</a>.
857     *
858     * <p>Note that there are no permissions needed for an application to
859     * access this information; if your content provider requires read and/or
860     * write permissions, or is not exported, all applications can still call
861     * this method regardless of their access permissions.  This allows them
862     * to retrieve the MIME type for a URI when dispatching intents.
863     *
864     * @param uri the URI to query.
865     * @return a MIME type string, or {@code null} if there is no type.
866     */
867    public abstract String getType(Uri uri);
868
869    /**
870     * Implement this to support canonicalization of URIs that refer to your
871     * content provider.  A canonical URI is one that can be transported across
872     * devices, backup/restore, and other contexts, and still be able to refer
873     * to the same data item.  Typically this is implemented by adding query
874     * params to the URI allowing the content provider to verify that an incoming
875     * canonical URI references the same data as it was originally intended for and,
876     * if it doesn't, to find that data (if it exists) in the current environment.
877     *
878     * <p>For example, if the content provider holds people and a normal URI in it
879     * is created with a row index into that people database, the cananical representation
880     * may have an additional query param at the end which specifies the name of the
881     * person it is intended for.  Later calls into the provider with that URI will look
882     * up the row of that URI's base index and, if it doesn't match or its entry's
883     * name doesn't match the name in the query param, perform a query on its database
884     * to find the correct row to operate on.</p>
885     *
886     * <p>If you implement support for canonical URIs, <b>all</b> incoming calls with
887     * URIs (including this one) must perform this verification and recovery of any
888     * canonical URIs they receive.  In addition, you must also implement
889     * {@link #uncanonicalize} to strip the canonicalization of any of these URIs.</p>
890     *
891     * <p>The default implementation of this method returns null, indicating that
892     * canonical URIs are not supported.</p>
893     *
894     * @param url The Uri to canonicalize.
895     *
896     * @return Return the canonical representation of <var>url</var>, or null if
897     * canonicalization of that Uri is not supported.
898     */
899    public Uri canonicalize(Uri url) {
900        return null;
901    }
902
903    /**
904     * Remove canonicalization from canonical URIs previously returned by
905     * {@link #canonicalize}.  For example, if your implementation is to add
906     * a query param to canonicalize a URI, this method can simply trip any
907     * query params on the URI.  The default implementation always returns the
908     * same <var>url</var> that was passed in.
909     *
910     * @param url The Uri to remove any canonicalization from.
911     *
912     * @return Return the non-canonical representation of <var>url</var>, or return
913     * the <var>url</var> as-is if there is nothing to do.  Never return null.
914     */
915    public Uri uncanonicalize(Uri url) {
916        return url;
917    }
918
919    /**
920     * @hide
921     * Implementation when a caller has performed an insert on the content
922     * provider, but that call has been rejected for the operation given
923     * to {@link #setAppOps(int, int)}.  The default implementation simply
924     * returns a dummy URI that is the base URI with a 0 path element
925     * appended.
926     */
927    public Uri rejectInsert(Uri uri, ContentValues values) {
928        // If not allowed, we need to return some reasonable URI.  Maybe the
929        // content provider should be responsible for this, but for now we
930        // will just return the base URI with a dummy '0' tagged on to it.
931        // You shouldn't be able to read if you can't write, anyway, so it
932        // shouldn't matter much what is returned.
933        return uri.buildUpon().appendPath("0").build();
934    }
935
936    /**
937     * Implement this to handle requests to insert a new row.
938     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
939     * after inserting.
940     * This method can be called from multiple threads, as described in
941     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
942     * and Threads</a>.
943     * @param uri The content:// URI of the insertion request. This must not be {@code null}.
944     * @param values A set of column_name/value pairs to add to the database.
945     *     This must not be {@code null}.
946     * @return The URI for the newly inserted item.
947     */
948    public abstract Uri insert(Uri uri, ContentValues values);
949
950    /**
951     * Override this to handle requests to insert a set of new rows, or the
952     * default implementation will iterate over the values and call
953     * {@link #insert} on each of them.
954     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
955     * after inserting.
956     * This method can be called from multiple threads, as described in
957     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
958     * and Threads</a>.
959     *
960     * @param uri The content:// URI of the insertion request.
961     * @param values An array of sets of column_name/value pairs to add to the database.
962     *    This must not be {@code null}.
963     * @return The number of values that were inserted.
964     */
965    public int bulkInsert(Uri uri, ContentValues[] values) {
966        int numValues = values.length;
967        for (int i = 0; i < numValues; i++) {
968            insert(uri, values[i]);
969        }
970        return numValues;
971    }
972
973    /**
974     * Implement this to handle requests to delete one or more rows.
975     * The implementation should apply the selection clause when performing
976     * deletion, allowing the operation to affect multiple rows in a directory.
977     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
978     * after deleting.
979     * This method can be called from multiple threads, as described in
980     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
981     * and Threads</a>.
982     *
983     * <p>The implementation is responsible for parsing out a row ID at the end
984     * of the URI, if a specific row is being deleted. That is, the client would
985     * pass in <code>content://contacts/people/22</code> and the implementation is
986     * responsible for parsing the record number (22) when creating a SQL statement.
987     *
988     * @param uri The full URI to query, including a row ID (if a specific record is requested).
989     * @param selection An optional restriction to apply to rows when deleting.
990     * @return The number of rows affected.
991     * @throws SQLException
992     */
993    public abstract int delete(Uri uri, String selection, String[] selectionArgs);
994
995    /**
996     * Implement this to handle requests to update one or more rows.
997     * The implementation should update all rows matching the selection
998     * to set the columns according to the provided values map.
999     * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
1000     * after updating.
1001     * This method can be called from multiple threads, as described in
1002     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
1003     * and Threads</a>.
1004     *
1005     * @param uri The URI to query. This can potentially have a record ID if this
1006     * is an update request for a specific record.
1007     * @param values A set of column_name/value pairs to update in the database.
1008     *     This must not be {@code null}.
1009     * @param selection An optional filter to match rows to update.
1010     * @return the number of rows affected.
1011     */
1012    public abstract int update(Uri uri, ContentValues values, String selection,
1013            String[] selectionArgs);
1014
1015    /**
1016     * Override this to handle requests to open a file blob.
1017     * The default implementation always throws {@link FileNotFoundException}.
1018     * This method can be called from multiple threads, as described in
1019     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
1020     * and Threads</a>.
1021     *
1022     * <p>This method returns a ParcelFileDescriptor, which is returned directly
1023     * to the caller.  This way large data (such as images and documents) can be
1024     * returned without copying the content.
1025     *
1026     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
1027     * their responsibility to close it when done.  That is, the implementation
1028     * of this method should create a new ParcelFileDescriptor for each call.
1029     * <p>
1030     * If opened with the exclusive "r" or "w" modes, the returned
1031     * ParcelFileDescriptor can be a pipe or socket pair to enable streaming
1032     * of data. Opening with the "rw" or "rwt" modes implies a file on disk that
1033     * supports seeking.
1034     * <p>
1035     * If you need to detect when the returned ParcelFileDescriptor has been
1036     * closed, or if the remote process has crashed or encountered some other
1037     * error, you can use {@link ParcelFileDescriptor#open(File, int,
1038     * android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener)},
1039     * {@link ParcelFileDescriptor#createReliablePipe()}, or
1040     * {@link ParcelFileDescriptor#createReliableSocketPair()}.
1041     *
1042     * <p class="note">For use in Intents, you will want to implement {@link #getType}
1043     * to return the appropriate MIME type for the data returned here with
1044     * the same URI.  This will allow intent resolution to automatically determine the data MIME
1045     * type and select the appropriate matching targets as part of its operation.</p>
1046     *
1047     * <p class="note">For better interoperability with other applications, it is recommended
1048     * that for any URIs that can be opened, you also support queries on them
1049     * containing at least the columns specified by {@link android.provider.OpenableColumns}.
1050     * You may also want to support other common columns if you have additional meta-data
1051     * to supply, such as {@link android.provider.MediaStore.MediaColumns#DATE_ADDED}
1052     * in {@link android.provider.MediaStore.MediaColumns}.</p>
1053     *
1054     * @param uri The URI whose file is to be opened.
1055     * @param mode Access mode for the file.  May be "r" for read-only access,
1056     * "rw" for read and write access, or "rwt" for read and write access
1057     * that truncates any existing file.
1058     *
1059     * @return Returns a new ParcelFileDescriptor which you can use to access
1060     * the file.
1061     *
1062     * @throws FileNotFoundException Throws FileNotFoundException if there is
1063     * no file associated with the given URI or the mode is invalid.
1064     * @throws SecurityException Throws SecurityException if the caller does
1065     * not have permission to access the file.
1066     *
1067     * @see #openAssetFile(Uri, String)
1068     * @see #openFileHelper(Uri, String)
1069     * @see #getType(android.net.Uri)
1070     */
1071    public ParcelFileDescriptor openFile(Uri uri, String mode)
1072            throws FileNotFoundException {
1073        throw new FileNotFoundException("No files supported by provider at "
1074                + uri);
1075    }
1076
1077    /**
1078     * Override this to handle requests to open a file blob.
1079     * The default implementation always throws {@link FileNotFoundException}.
1080     * This method can be called from multiple threads, as described in
1081     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
1082     * and Threads</a>.
1083     *
1084     * <p>This method returns a ParcelFileDescriptor, which is returned directly
1085     * to the caller.  This way large data (such as images and documents) can be
1086     * returned without copying the content.
1087     *
1088     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
1089     * their responsibility to close it when done.  That is, the implementation
1090     * of this method should create a new ParcelFileDescriptor for each call.
1091     * <p>
1092     * If opened with the exclusive "r" or "w" modes, the returned
1093     * ParcelFileDescriptor can be a pipe or socket pair to enable streaming
1094     * of data. Opening with the "rw" or "rwt" modes implies a file on disk that
1095     * supports seeking.
1096     * <p>
1097     * If you need to detect when the returned ParcelFileDescriptor has been
1098     * closed, or if the remote process has crashed or encountered some other
1099     * error, you can use {@link ParcelFileDescriptor#open(File, int,
1100     * android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener)},
1101     * {@link ParcelFileDescriptor#createReliablePipe()}, or
1102     * {@link ParcelFileDescriptor#createReliableSocketPair()}.
1103     *
1104     * <p class="note">For use in Intents, you will want to implement {@link #getType}
1105     * to return the appropriate MIME type for the data returned here with
1106     * the same URI.  This will allow intent resolution to automatically determine the data MIME
1107     * type and select the appropriate matching targets as part of its operation.</p>
1108     *
1109     * <p class="note">For better interoperability with other applications, it is recommended
1110     * that for any URIs that can be opened, you also support queries on them
1111     * containing at least the columns specified by {@link android.provider.OpenableColumns}.
1112     * You may also want to support other common columns if you have additional meta-data
1113     * to supply, such as {@link android.provider.MediaStore.MediaColumns#DATE_ADDED}
1114     * in {@link android.provider.MediaStore.MediaColumns}.</p>
1115     *
1116     * @param uri The URI whose file is to be opened.
1117     * @param mode Access mode for the file. May be "r" for read-only access,
1118     *            "w" for write-only access, "rw" for read and write access, or
1119     *            "rwt" for read and write access that truncates any existing
1120     *            file.
1121     * @param signal A signal to cancel the operation in progress, or
1122     *            {@code null} if none. For example, if you are downloading a
1123     *            file from the network to service a "rw" mode request, you
1124     *            should periodically call
1125     *            {@link CancellationSignal#throwIfCanceled()} to check whether
1126     *            the client has canceled the request and abort the download.
1127     *
1128     * @return Returns a new ParcelFileDescriptor which you can use to access
1129     * the file.
1130     *
1131     * @throws FileNotFoundException Throws FileNotFoundException if there is
1132     * no file associated with the given URI or the mode is invalid.
1133     * @throws SecurityException Throws SecurityException if the caller does
1134     * not have permission to access the file.
1135     *
1136     * @see #openAssetFile(Uri, String)
1137     * @see #openFileHelper(Uri, String)
1138     * @see #getType(android.net.Uri)
1139     */
1140    public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
1141            throws FileNotFoundException {
1142        return openFile(uri, mode);
1143    }
1144
1145    /**
1146     * This is like {@link #openFile}, but can be implemented by providers
1147     * that need to be able to return sub-sections of files, often assets
1148     * inside of their .apk.
1149     * This method can be called from multiple threads, as described in
1150     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
1151     * and Threads</a>.
1152     *
1153     * <p>If you implement this, your clients must be able to deal with such
1154     * file slices, either directly with
1155     * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
1156     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
1157     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
1158     * methods.
1159     * <p>
1160     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
1161     * streaming of data.
1162     *
1163     * <p class="note">If you are implementing this to return a full file, you
1164     * should create the AssetFileDescriptor with
1165     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
1166     * applications that cannot handle sub-sections of files.</p>
1167     *
1168     * <p class="note">For use in Intents, you will want to implement {@link #getType}
1169     * to return the appropriate MIME type for the data returned here with
1170     * the same URI.  This will allow intent resolution to automatically determine the data MIME
1171     * type and select the appropriate matching targets as part of its operation.</p>
1172     *
1173     * <p class="note">For better interoperability with other applications, it is recommended
1174     * that for any URIs that can be opened, you also support queries on them
1175     * containing at least the columns specified by {@link android.provider.OpenableColumns}.</p>
1176     *
1177     * @param uri The URI whose file is to be opened.
1178     * @param mode Access mode for the file.  May be "r" for read-only access,
1179     * "w" for write-only access (erasing whatever data is currently in
1180     * the file), "wa" for write-only access to append to any existing data,
1181     * "rw" for read and write access on any existing data, and "rwt" for read
1182     * and write access that truncates any existing file.
1183     *
1184     * @return Returns a new AssetFileDescriptor which you can use to access
1185     * the file.
1186     *
1187     * @throws FileNotFoundException Throws FileNotFoundException if there is
1188     * no file associated with the given URI or the mode is invalid.
1189     * @throws SecurityException Throws SecurityException if the caller does
1190     * not have permission to access the file.
1191     *
1192     * @see #openFile(Uri, String)
1193     * @see #openFileHelper(Uri, String)
1194     * @see #getType(android.net.Uri)
1195     */
1196    public AssetFileDescriptor openAssetFile(Uri uri, String mode)
1197            throws FileNotFoundException {
1198        ParcelFileDescriptor fd = openFile(uri, mode);
1199        return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
1200    }
1201
1202    /**
1203     * This is like {@link #openFile}, but can be implemented by providers
1204     * that need to be able to return sub-sections of files, often assets
1205     * inside of their .apk.
1206     * This method can be called from multiple threads, as described in
1207     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
1208     * and Threads</a>.
1209     *
1210     * <p>If you implement this, your clients must be able to deal with such
1211     * file slices, either directly with
1212     * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
1213     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
1214     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
1215     * methods.
1216     * <p>
1217     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
1218     * streaming of data.
1219     *
1220     * <p class="note">If you are implementing this to return a full file, you
1221     * should create the AssetFileDescriptor with
1222     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
1223     * applications that cannot handle sub-sections of files.</p>
1224     *
1225     * <p class="note">For use in Intents, you will want to implement {@link #getType}
1226     * to return the appropriate MIME type for the data returned here with
1227     * the same URI.  This will allow intent resolution to automatically determine the data MIME
1228     * type and select the appropriate matching targets as part of its operation.</p>
1229     *
1230     * <p class="note">For better interoperability with other applications, it is recommended
1231     * that for any URIs that can be opened, you also support queries on them
1232     * containing at least the columns specified by {@link android.provider.OpenableColumns}.</p>
1233     *
1234     * @param uri The URI whose file is to be opened.
1235     * @param mode Access mode for the file.  May be "r" for read-only access,
1236     * "w" for write-only access (erasing whatever data is currently in
1237     * the file), "wa" for write-only access to append to any existing data,
1238     * "rw" for read and write access on any existing data, and "rwt" for read
1239     * and write access that truncates any existing file.
1240     * @param signal A signal to cancel the operation in progress, or
1241     *            {@code null} if none. For example, if you are downloading a
1242     *            file from the network to service a "rw" mode request, you
1243     *            should periodically call
1244     *            {@link CancellationSignal#throwIfCanceled()} to check whether
1245     *            the client has canceled the request and abort the download.
1246     *
1247     * @return Returns a new AssetFileDescriptor which you can use to access
1248     * the file.
1249     *
1250     * @throws FileNotFoundException Throws FileNotFoundException if there is
1251     * no file associated with the given URI or the mode is invalid.
1252     * @throws SecurityException Throws SecurityException if the caller does
1253     * not have permission to access the file.
1254     *
1255     * @see #openFile(Uri, String)
1256     * @see #openFileHelper(Uri, String)
1257     * @see #getType(android.net.Uri)
1258     */
1259    public AssetFileDescriptor openAssetFile(Uri uri, String mode, CancellationSignal signal)
1260            throws FileNotFoundException {
1261        return openAssetFile(uri, mode);
1262    }
1263
1264    /**
1265     * Convenience for subclasses that wish to implement {@link #openFile}
1266     * by looking up a column named "_data" at the given URI.
1267     *
1268     * @param uri The URI to be opened.
1269     * @param mode The file mode.  May be "r" for read-only access,
1270     * "w" for write-only access (erasing whatever data is currently in
1271     * the file), "wa" for write-only access to append to any existing data,
1272     * "rw" for read and write access on any existing data, and "rwt" for read
1273     * and write access that truncates any existing file.
1274     *
1275     * @return Returns a new ParcelFileDescriptor that can be used by the
1276     * client to access the file.
1277     */
1278    protected final ParcelFileDescriptor openFileHelper(Uri uri,
1279            String mode) throws FileNotFoundException {
1280        Cursor c = query(uri, new String[]{"_data"}, null, null, null);
1281        int count = (c != null) ? c.getCount() : 0;
1282        if (count != 1) {
1283            // If there is not exactly one result, throw an appropriate
1284            // exception.
1285            if (c != null) {
1286                c.close();
1287            }
1288            if (count == 0) {
1289                throw new FileNotFoundException("No entry for " + uri);
1290            }
1291            throw new FileNotFoundException("Multiple items at " + uri);
1292        }
1293
1294        c.moveToFirst();
1295        int i = c.getColumnIndex("_data");
1296        String path = (i >= 0 ? c.getString(i) : null);
1297        c.close();
1298        if (path == null) {
1299            throw new FileNotFoundException("Column _data not found.");
1300        }
1301
1302        int modeBits = ContentResolver.modeToMode(uri, mode);
1303        return ParcelFileDescriptor.open(new File(path), modeBits);
1304    }
1305
1306    /**
1307     * Called by a client to determine the types of data streams that this
1308     * content provider supports for the given URI.  The default implementation
1309     * returns {@code null}, meaning no types.  If your content provider stores data
1310     * of a particular type, return that MIME type if it matches the given
1311     * mimeTypeFilter.  If it can perform type conversions, return an array
1312     * of all supported MIME types that match mimeTypeFilter.
1313     *
1314     * @param uri The data in the content provider being queried.
1315     * @param mimeTypeFilter The type of data the client desires.  May be
1316     * a pattern, such as *\/* to retrieve all possible data types.
1317     * @return Returns {@code null} if there are no possible data streams for the
1318     * given mimeTypeFilter.  Otherwise returns an array of all available
1319     * concrete MIME types.
1320     *
1321     * @see #getType(Uri)
1322     * @see #openTypedAssetFile(Uri, String, Bundle)
1323     * @see ClipDescription#compareMimeTypes(String, String)
1324     */
1325    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
1326        return null;
1327    }
1328
1329    /**
1330     * Called by a client to open a read-only stream containing data of a
1331     * particular MIME type.  This is like {@link #openAssetFile(Uri, String)},
1332     * except the file can only be read-only and the content provider may
1333     * perform data conversions to generate data of the desired type.
1334     *
1335     * <p>The default implementation compares the given mimeType against the
1336     * result of {@link #getType(Uri)} and, if they match, simply calls
1337     * {@link #openAssetFile(Uri, String)}.
1338     *
1339     * <p>See {@link ClipData} for examples of the use and implementation
1340     * of this method.
1341     * <p>
1342     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
1343     * streaming of data.
1344     *
1345     * <p class="note">For better interoperability with other applications, it is recommended
1346     * that for any URIs that can be opened, you also support queries on them
1347     * containing at least the columns specified by {@link android.provider.OpenableColumns}.
1348     * You may also want to support other common columns if you have additional meta-data
1349     * to supply, such as {@link android.provider.MediaStore.MediaColumns#DATE_ADDED}
1350     * in {@link android.provider.MediaStore.MediaColumns}.</p>
1351     *
1352     * @param uri The data in the content provider being queried.
1353     * @param mimeTypeFilter The type of data the client desires.  May be
1354     * a pattern, such as *\/*, if the caller does not have specific type
1355     * requirements; in this case the content provider will pick its best
1356     * type matching the pattern.
1357     * @param opts Additional options from the client.  The definitions of
1358     * these are specific to the content provider being called.
1359     *
1360     * @return Returns a new AssetFileDescriptor from which the client can
1361     * read data of the desired type.
1362     *
1363     * @throws FileNotFoundException Throws FileNotFoundException if there is
1364     * no file associated with the given URI or the mode is invalid.
1365     * @throws SecurityException Throws SecurityException if the caller does
1366     * not have permission to access the data.
1367     * @throws IllegalArgumentException Throws IllegalArgumentException if the
1368     * content provider does not support the requested MIME type.
1369     *
1370     * @see #getStreamTypes(Uri, String)
1371     * @see #openAssetFile(Uri, String)
1372     * @see ClipDescription#compareMimeTypes(String, String)
1373     */
1374    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
1375            throws FileNotFoundException {
1376        if ("*/*".equals(mimeTypeFilter)) {
1377            // If they can take anything, the untyped open call is good enough.
1378            return openAssetFile(uri, "r");
1379        }
1380        String baseType = getType(uri);
1381        if (baseType != null && ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) {
1382            // Use old untyped open call if this provider has a type for this
1383            // URI and it matches the request.
1384            return openAssetFile(uri, "r");
1385        }
1386        throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
1387    }
1388
1389
1390    /**
1391     * Called by a client to open a read-only stream containing data of a
1392     * particular MIME type.  This is like {@link #openAssetFile(Uri, String)},
1393     * except the file can only be read-only and the content provider may
1394     * perform data conversions to generate data of the desired type.
1395     *
1396     * <p>The default implementation compares the given mimeType against the
1397     * result of {@link #getType(Uri)} and, if they match, simply calls
1398     * {@link #openAssetFile(Uri, String)}.
1399     *
1400     * <p>See {@link ClipData} for examples of the use and implementation
1401     * of this method.
1402     * <p>
1403     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
1404     * streaming of data.
1405     *
1406     * <p class="note">For better interoperability with other applications, it is recommended
1407     * that for any URIs that can be opened, you also support queries on them
1408     * containing at least the columns specified by {@link android.provider.OpenableColumns}.
1409     * You may also want to support other common columns if you have additional meta-data
1410     * to supply, such as {@link android.provider.MediaStore.MediaColumns#DATE_ADDED}
1411     * in {@link android.provider.MediaStore.MediaColumns}.</p>
1412     *
1413     * @param uri The data in the content provider being queried.
1414     * @param mimeTypeFilter The type of data the client desires.  May be
1415     * a pattern, such as *\/*, if the caller does not have specific type
1416     * requirements; in this case the content provider will pick its best
1417     * type matching the pattern.
1418     * @param opts Additional options from the client.  The definitions of
1419     * these are specific to the content provider being called.
1420     * @param signal A signal to cancel the operation in progress, or
1421     *            {@code null} if none. For example, if you are downloading a
1422     *            file from the network to service a "rw" mode request, you
1423     *            should periodically call
1424     *            {@link CancellationSignal#throwIfCanceled()} to check whether
1425     *            the client has canceled the request and abort the download.
1426     *
1427     * @return Returns a new AssetFileDescriptor from which the client can
1428     * read data of the desired type.
1429     *
1430     * @throws FileNotFoundException Throws FileNotFoundException if there is
1431     * no file associated with the given URI or the mode is invalid.
1432     * @throws SecurityException Throws SecurityException if the caller does
1433     * not have permission to access the data.
1434     * @throws IllegalArgumentException Throws IllegalArgumentException if the
1435     * content provider does not support the requested MIME type.
1436     *
1437     * @see #getStreamTypes(Uri, String)
1438     * @see #openAssetFile(Uri, String)
1439     * @see ClipDescription#compareMimeTypes(String, String)
1440     */
1441    public AssetFileDescriptor openTypedAssetFile(
1442            Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
1443            throws FileNotFoundException {
1444        return openTypedAssetFile(uri, mimeTypeFilter, opts);
1445    }
1446
1447    /**
1448     * Interface to write a stream of data to a pipe.  Use with
1449     * {@link ContentProvider#openPipeHelper}.
1450     */
1451    public interface PipeDataWriter<T> {
1452        /**
1453         * Called from a background thread to stream data out to a pipe.
1454         * Note that the pipe is blocking, so this thread can block on
1455         * writes for an arbitrary amount of time if the client is slow
1456         * at reading.
1457         *
1458         * @param output The pipe where data should be written.  This will be
1459         * closed for you upon returning from this function.
1460         * @param uri The URI whose data is to be written.
1461         * @param mimeType The desired type of data to be written.
1462         * @param opts Options supplied by caller.
1463         * @param args Your own custom arguments.
1464         */
1465        public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
1466                Bundle opts, T args);
1467    }
1468
1469    /**
1470     * A helper function for implementing {@link #openTypedAssetFile}, for
1471     * creating a data pipe and background thread allowing you to stream
1472     * generated data back to the client.  This function returns a new
1473     * ParcelFileDescriptor that should be returned to the caller (the caller
1474     * is responsible for closing it).
1475     *
1476     * @param uri The URI whose data is to be written.
1477     * @param mimeType The desired type of data to be written.
1478     * @param opts Options supplied by caller.
1479     * @param args Your own custom arguments.
1480     * @param func Interface implementing the function that will actually
1481     * stream the data.
1482     * @return Returns a new ParcelFileDescriptor holding the read side of
1483     * the pipe.  This should be returned to the caller for reading; the caller
1484     * is responsible for closing it when done.
1485     */
1486    public <T> ParcelFileDescriptor openPipeHelper(final Uri uri, final String mimeType,
1487            final Bundle opts, final T args, final PipeDataWriter<T> func)
1488            throws FileNotFoundException {
1489        try {
1490            final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
1491
1492            AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
1493                @Override
1494                protected Object doInBackground(Object... params) {
1495                    func.writeDataToPipe(fds[1], uri, mimeType, opts, args);
1496                    try {
1497                        fds[1].close();
1498                    } catch (IOException e) {
1499                        Log.w(TAG, "Failure closing pipe", e);
1500                    }
1501                    return null;
1502                }
1503            };
1504            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null);
1505
1506            return fds[0];
1507        } catch (IOException e) {
1508            throw new FileNotFoundException("failure making pipe");
1509        }
1510    }
1511
1512    /**
1513     * Returns true if this instance is a temporary content provider.
1514     * @return true if this instance is a temporary content provider
1515     */
1516    protected boolean isTemporary() {
1517        return false;
1518    }
1519
1520    /**
1521     * Returns the Binder object for this provider.
1522     *
1523     * @return the Binder object for this provider
1524     * @hide
1525     */
1526    public IContentProvider getIContentProvider() {
1527        return mTransport;
1528    }
1529
1530    /**
1531     * Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use
1532     * when directly instantiating the provider for testing.
1533     * @hide
1534     */
1535    public void attachInfoForTesting(Context context, ProviderInfo info) {
1536        attachInfo(context, info, true);
1537    }
1538
1539    /**
1540     * After being instantiated, this is called to tell the content provider
1541     * about itself.
1542     *
1543     * @param context The context this provider is running in
1544     * @param info Registered information about this content provider
1545     */
1546    public void attachInfo(Context context, ProviderInfo info) {
1547        attachInfo(context, info, false);
1548    }
1549
1550    private void attachInfo(Context context, ProviderInfo info, boolean testing) {
1551        /*
1552         * We may be using AsyncTask from binder threads.  Make it init here
1553         * so its static handler is on the main thread.
1554         */
1555        AsyncTask.init();
1556
1557        mNoPerms = testing;
1558
1559        /*
1560         * Only allow it to be set once, so after the content service gives
1561         * this to us clients can't change it.
1562         */
1563        if (mContext == null) {
1564            mContext = context;
1565            mTransport.mAppOpsManager = (AppOpsManager) mContext.getSystemService(
1566                    Context.APP_OPS_SERVICE);
1567            mMyUid = Process.myUid();
1568            if (info != null) {
1569                setReadPermission(info.readPermission);
1570                setWritePermission(info.writePermission);
1571                setPathPermissions(info.pathPermissions);
1572                mExported = info.exported;
1573            }
1574            ContentProvider.this.onCreate();
1575        }
1576    }
1577
1578    /**
1579     * Override this to handle requests to perform a batch of operations, or the
1580     * default implementation will iterate over the operations and call
1581     * {@link ContentProviderOperation#apply} on each of them.
1582     * If all calls to {@link ContentProviderOperation#apply} succeed
1583     * then a {@link ContentProviderResult} array with as many
1584     * elements as there were operations will be returned.  If any of the calls
1585     * fail, it is up to the implementation how many of the others take effect.
1586     * This method can be called from multiple threads, as described in
1587     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
1588     * and Threads</a>.
1589     *
1590     * @param operations the operations to apply
1591     * @return the results of the applications
1592     * @throws OperationApplicationException thrown if any operation fails.
1593     * @see ContentProviderOperation#apply
1594     */
1595    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
1596            throws OperationApplicationException {
1597        final int numOperations = operations.size();
1598        final ContentProviderResult[] results = new ContentProviderResult[numOperations];
1599        for (int i = 0; i < numOperations; i++) {
1600            results[i] = operations.get(i).apply(this, results, i);
1601        }
1602        return results;
1603    }
1604
1605    /**
1606     * Call a provider-defined method.  This can be used to implement
1607     * interfaces that are cheaper and/or unnatural for a table-like
1608     * model.
1609     *
1610     * <p class="note"><strong>WARNING:</strong> The framework does no permission checking
1611     * on this entry into the content provider besides the basic ability for the application
1612     * to get access to the provider at all.  For example, it has no idea whether the call
1613     * being executed may read or write data in the provider, so can't enforce those
1614     * individual permissions.  Any implementation of this method <strong>must</strong>
1615     * do its own permission checks on incoming calls to make sure they are allowed.</p>
1616     *
1617     * @param method method name to call.  Opaque to framework, but should not be {@code null}.
1618     * @param arg provider-defined String argument.  May be {@code null}.
1619     * @param extras provider-defined Bundle argument.  May be {@code null}.
1620     * @return provider-defined return value.  May be {@code null}, which is also
1621     *   the default for providers which don't implement any call methods.
1622     */
1623    public Bundle call(String method, String arg, Bundle extras) {
1624        return null;
1625    }
1626
1627    /**
1628     * Implement this to shut down the ContentProvider instance. You can then
1629     * invoke this method in unit tests.
1630     *
1631     * <p>
1632     * Android normally handles ContentProvider startup and shutdown
1633     * automatically. You do not need to start up or shut down a
1634     * ContentProvider. When you invoke a test method on a ContentProvider,
1635     * however, a ContentProvider instance is started and keeps running after
1636     * the test finishes, even if a succeeding test instantiates another
1637     * ContentProvider. A conflict develops because the two instances are
1638     * usually running against the same underlying data source (for example, an
1639     * sqlite database).
1640     * </p>
1641     * <p>
1642     * Implementing shutDown() avoids this conflict by providing a way to
1643     * terminate the ContentProvider. This method can also prevent memory leaks
1644     * from multiple instantiations of the ContentProvider, and it can ensure
1645     * unit test isolation by allowing you to completely clean up the test
1646     * fixture before moving on to the next test.
1647     * </p>
1648     */
1649    public void shutdown() {
1650        Log.w(TAG, "implement ContentProvider shutdown() to make sure all database " +
1651                "connections are gracefully shutdown");
1652    }
1653
1654    /**
1655     * Print the Provider's state into the given stream.  This gets invoked if
1656     * you run "adb shell dumpsys activity provider &lt;provider_component_name&gt;".
1657     *
1658     * @param fd The raw file descriptor that the dump is being sent to.
1659     * @param writer The PrintWriter to which you should dump your state.  This will be
1660     * closed for you after you return.
1661     * @param args additional arguments to the dump request.
1662     */
1663    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
1664        writer.println("nothing to dump");
1665    }
1666}
1667