16a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana/*
26a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * Copyright (C) 2009 The Android Open Source Project
36a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *
46a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * Licensed under the Apache License, Version 2.0 (the "License");
56a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * you may not use this file except in compliance with the License.
66a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * You may obtain a copy of the License at
76a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *
86a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *      http://www.apache.org/licenses/LICENSE-2.0
96a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana *
106a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * Unless required by applicable law or agreed to in writing, software
116a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * distributed under the License is distributed on an "AS IS" BASIS,
126a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * See the License for the specific language governing permissions and
146a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana * limitations under the License.
156a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana */
166a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
17718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanapackage android.content;
18718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
19718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.database.Cursor;
20718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.net.Uri;
2123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport android.os.Bundle;
22a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal;
236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackbornimport android.os.DeadObjectException;
24a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.ICancellationSignal;
25718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.os.RemoteException;
26718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.os.ParcelFileDescriptor;
27718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport android.content.res.AssetFileDescriptor;
28718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
29718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanaimport java.io.FileNotFoundException;
3003d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanaimport java.util.ArrayList;
31718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
32718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana/**
33718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * The public interface object used to interact with a {@link ContentProvider}. This is obtained by
34718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * calling {@link ContentResolver#acquireContentProviderClient}. This object must be released
35718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * using {@link #release} in order to indicate to the system that the {@link ContentProvider} is
36718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * no longer needed and can be killed to free up resources.
376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn *
386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * <p>Note that you should generally create a new ContentProviderClient instance
396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * for each thread that will be performing operations.  Unlike
406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link ContentResolver}, the methods here such as {@link #query} and
416ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link #openFile} are not thread safe -- you must not call
426ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * {@link #release()} on the ContentProviderClient those calls are made from
436ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn * until you are finished with the data they have returned.
44718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */
45718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintanapublic class ContentProviderClient {
46718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    private final IContentProvider mContentProvider;
47718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    private final ContentResolver mContentResolver;
48652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn    private final boolean mStable;
496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn    private boolean mReleased;
50718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
51718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    /**
52718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * @hide
53718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     */
54652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn    ContentProviderClient(ContentResolver contentResolver,
55652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn            IContentProvider contentProvider, boolean stable) {
56718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana        mContentProvider = contentProvider;
57718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana        mContentResolver = contentResolver;
58652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn        mStable = stable;
59718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
60718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
6123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#query ContentProvider.query} */
62718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public Cursor query(Uri url, String[] projection, String selection,
63718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            String[] selectionArgs, String sortOrder) throws RemoteException {
646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return query(url, projection, selection,  selectionArgs, sortOrder, null);
666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
676ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
686ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
696ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
706ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
716ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
7275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    }
7375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown
7475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    /** See {@link ContentProvider#query ContentProvider.query} */
7575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown    public Cursor query(Uri url, String[] projection, String selection,
764c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown            String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
7775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                    throws RemoteException {
784c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown        ICancellationSignal remoteCancellationSignal = null;
794c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown        if (cancellationSignal != null) {
804c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown            remoteCancellationSignal = mContentProvider.createCancellationSignal();
814c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown            cancellationSignal.setRemote(remoteCancellationSignal);
8275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        }
836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.query(url, projection, selection,  selectionArgs, sortOrder,
856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                    remoteCancellationSignal);
866ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
876ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
886ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
896ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
906ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
916ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
92718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
93718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
9423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#getType ContentProvider.getType} */
95718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public String getType(Uri url) throws RemoteException {
966ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.getType(url);
986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
104718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
105718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
10623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#getStreamTypes ContentProvider.getStreamTypes} */
10723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
1086ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1096ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.getStreamTypes(url, mimeTypeFilter);
1106ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
11623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
11723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
11823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#insert ContentProvider.insert} */
119718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public Uri insert(Uri url, ContentValues initialValues)
120718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            throws RemoteException {
1216ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1226ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.insert(url, initialValues);
1236ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1256ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1286ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
129718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
130718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
13123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#bulkInsert ContentProvider.bulkInsert} */
132718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
1336ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1346ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.bulkInsert(url, initialValues);
1356ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1366ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1376ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1386ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1396ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1406ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
141718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
142718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
14323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#delete ContentProvider.delete} */
144718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public int delete(Uri url, String selection, String[] selectionArgs)
145718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            throws RemoteException {
1466ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1476ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.delete(url, selection, selectionArgs);
1486ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1496ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1506ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1516ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1526ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
154718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
155718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
15623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#update ContentProvider.update} */
157718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public int update(Uri url, ContentValues values, String selection,
158718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            String[] selectionArgs) throws RemoteException {
1596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.update(url, values, selection, selectionArgs);
1616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1636ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1646ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1656ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1666ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
167718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
168718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
16923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
17023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * See {@link ContentProvider#openFile ContentProvider.openFile}.  Note that
17123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * this <em>does not</em>
17223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * take care of non-content: URIs such as file:.  It is strongly recommended
17323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * you use the {@link ContentResolver#openFileDescriptor
17423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * ContentResolver.openFileDescriptor} API instead.
17523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
176718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public ParcelFileDescriptor openFile(Uri url, String mode)
177718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            throws RemoteException, FileNotFoundException {
1786ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1796ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.openFile(url, mode);
1806ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
1816ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
1826ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
1836ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
1846ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
1856ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
186718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
187718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
18823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /**
18923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * See {@link ContentProvider#openAssetFile ContentProvider.openAssetFile}.
19023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * Note that this <em>does not</em>
19123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * take care of non-content: URIs such as file:.  It is strongly recommended
19223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * you use the {@link ContentResolver#openAssetFileDescriptor
19323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     * ContentResolver.openAssetFileDescriptor} API instead.
19423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn     */
195718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public AssetFileDescriptor openAssetFile(Uri url, String mode)
196718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana            throws RemoteException, FileNotFoundException {
1976ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
1986ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.openAssetFile(url, mode);
1996ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2006ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2016ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2026ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2036ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2046ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
205718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
206718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
20723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
20823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
20923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            String mimeType, Bundle opts)
21023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn            throws RemoteException, FileNotFoundException {
2116ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
2126ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.openTypedAssetFile(uri, mimeType, opts);
2136ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2146ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2156ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2166ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2176ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2186ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
21923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    }
22023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn
22123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn    /** See {@link ContentProvider#applyBatch ContentProvider.applyBatch} */
22203d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
2238943737692169f564cd34a9c8d471f3a5d438712Fred Quintana            throws RemoteException, OperationApplicationException {
2246ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        try {
2256ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            return mContentProvider.applyBatch(operations);
2266ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        } catch (DeadObjectException e) {
2276ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (!mStable) {
2286ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2296ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2306ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            throw e;
2316ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        }
2326a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana    }
2336a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana
2347d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn    /** See {@link ContentProvider#call(String, String, Bundle)} */
2357d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn    public Bundle call(String method, String arg, Bundle extras)
2367d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            throws RemoteException {
2377d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        try {
2387d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            return mContentProvider.call(method, arg, extras);
2397d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        } catch (DeadObjectException e) {
2407d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            if (!mStable) {
2417d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn                mContentResolver.unstableProviderDied(mContentProvider);
2427d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            }
2437d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn            throw e;
2447d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn        }
2457d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn    }
2467d19e0242faac8017033dabb872cdf1542fa184cDianne Hackborn
247718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    /**
248718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * Call this to indicate to the system that the associated {@link ContentProvider} is no
249718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * longer needed by this {@link ContentProviderClient}.
250718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * @return true if this was release, false if it was already released
251718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     */
252718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public boolean release() {
2536ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn        synchronized (this) {
2546ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (mReleased) {
2556ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                throw new IllegalStateException("Already released");
2566ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
2576ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            mReleased = true;
2586ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            if (mStable) {
2596ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                return mContentResolver.releaseProvider(mContentProvider);
2606ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            } else {
2616ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn                return mContentResolver.releaseUnstableProvider(mContentProvider);
2626ae8d1821822296df0606c9cd1c46708cc21cb58Dianne Hackborn            }
263652b6d1e591f6684cda4b93d4712920f287991b4Dianne Hackborn        }
264718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
265718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana
266718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    /**
267718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * Get a reference to the {@link ContentProvider} that is associated with this
268718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * client. If the {@link ContentProvider} is running in a different process then
269718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * null will be returned. This can be used if you know you are running in the same
270718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * process as a provider, and want to get direct access to its implementation details.
271718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     *
272718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * @return If the associated {@link ContentProvider} is local, returns it.
273718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     * Otherwise returns null.
274718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana     */
275718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    public ContentProvider getLocalContentProvider() {
276718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana        return ContentProvider.coerceToLocalContentProvider(mContentProvider);
277718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana    }
278718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana}
279