summaryrefslogtreecommitdiffstats
path: root/core/java/android/content/ContentProviderClient.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/content/ContentProviderClient.java')
-rw-r--r--core/java/android/content/ContentProviderClient.java133
1 files changed, 116 insertions, 17 deletions
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 423f1f6..5c315ce 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -20,6 +20,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.DeadObjectException;
import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.os.ParcelFileDescriptor;
@@ -33,11 +34,19 @@ import java.util.ArrayList;
* calling {@link ContentResolver#acquireContentProviderClient}. This object must be released
* using {@link #release} in order to indicate to the system that the {@link ContentProvider} is
* no longer needed and can be killed to free up resources.
+ *
+ * <p>Note that you should generally create a new ContentProviderClient instance
+ * for each thread that will be performing operations. Unlike
+ * {@link ContentResolver}, the methods here such as {@link #query} and
+ * {@link #openFile} are not thread safe -- you must not call
+ * {@link #release()} on the ContentProviderClient those calls are made from
+ * until you are finished with the data they have returned.
*/
public class ContentProviderClient {
private final IContentProvider mContentProvider;
private final ContentResolver mContentResolver;
private final boolean mStable;
+ private boolean mReleased;
/**
* @hide
@@ -52,7 +61,14 @@ public class ContentProviderClient {
/** See {@link ContentProvider#query ContentProvider.query} */
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sortOrder) throws RemoteException {
- return query(url, projection, selection, selectionArgs, sortOrder, null);
+ try {
+ return query(url, projection, selection, selectionArgs, sortOrder, null);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#query ContentProvider.query} */
@@ -64,41 +80,90 @@ public class ContentProviderClient {
remoteCancellationSignal = mContentProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
- return mContentProvider.query(url, projection, selection, selectionArgs, sortOrder,
- remoteCancellationSignal);
+ try {
+ return mContentProvider.query(url, projection, selection, selectionArgs, sortOrder,
+ remoteCancellationSignal);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#getType ContentProvider.getType} */
public String getType(Uri url) throws RemoteException {
- return mContentProvider.getType(url);
+ try {
+ return mContentProvider.getType(url);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#getStreamTypes ContentProvider.getStreamTypes} */
public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
- return mContentProvider.getStreamTypes(url, mimeTypeFilter);
+ try {
+ return mContentProvider.getStreamTypes(url, mimeTypeFilter);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#insert ContentProvider.insert} */
public Uri insert(Uri url, ContentValues initialValues)
throws RemoteException {
- return mContentProvider.insert(url, initialValues);
+ try {
+ return mContentProvider.insert(url, initialValues);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#bulkInsert ContentProvider.bulkInsert} */
public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
- return mContentProvider.bulkInsert(url, initialValues);
+ try {
+ return mContentProvider.bulkInsert(url, initialValues);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#delete ContentProvider.delete} */
public int delete(Uri url, String selection, String[] selectionArgs)
throws RemoteException {
- return mContentProvider.delete(url, selection, selectionArgs);
+ try {
+ return mContentProvider.delete(url, selection, selectionArgs);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#update ContentProvider.update} */
public int update(Uri url, ContentValues values, String selection,
String[] selectionArgs) throws RemoteException {
- return mContentProvider.update(url, values, selection, selectionArgs);
+ try {
+ return mContentProvider.update(url, values, selection, selectionArgs);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/**
@@ -110,7 +175,14 @@ public class ContentProviderClient {
*/
public ParcelFileDescriptor openFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
- return mContentProvider.openFile(url, mode);
+ try {
+ return mContentProvider.openFile(url, mode);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/**
@@ -122,20 +194,41 @@ public class ContentProviderClient {
*/
public AssetFileDescriptor openAssetFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
- return mContentProvider.openAssetFile(url, mode);
+ try {
+ return mContentProvider.openAssetFile(url, mode);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
String mimeType, Bundle opts)
throws RemoteException, FileNotFoundException {
- return mContentProvider.openTypedAssetFile(uri, mimeType, opts);
+ try {
+ return mContentProvider.openTypedAssetFile(uri, mimeType, opts);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#applyBatch ContentProvider.applyBatch} */
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
- return mContentProvider.applyBatch(operations);
+ try {
+ return mContentProvider.applyBatch(operations);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/**
@@ -144,10 +237,16 @@ public class ContentProviderClient {
* @return true if this was release, false if it was already released
*/
public boolean release() {
- if (mStable) {
- return mContentResolver.releaseProvider(mContentProvider);
- } else {
- return mContentResolver.releaseUnstableProvider(mContentProvider);
+ synchronized (this) {
+ if (mReleased) {
+ throw new IllegalStateException("Already released");
+ }
+ mReleased = true;
+ if (mStable) {
+ return mContentResolver.releaseProvider(mContentProvider);
+ } else {
+ return mContentResolver.releaseUnstableProvider(mContentProvider);
+ }
}
}