From df6611d8c0cd69c3dcb93462eb138e0bbf137b88 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Sun, 9 Oct 2011 12:28:54 -0700 Subject: [PATCH] Clean up handrolled Binder proxies. Bug: 5332296 We can't replace these with AIDL generated proxies just yet, but at least we can make them a little more conformant. Change-Id: I1814f76d0f9c5e44a7fd85a12b2e3c2b7e3c9daa --- .../content/ContentProviderNative.java | 376 +++++++++--------- .../android/database/BulkCursorNative.java | 231 +++++------ 2 files changed, 304 insertions(+), 303 deletions(-) diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index abeeb74069574..9a20951b8a992 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -332,60 +332,60 @@ final class ContentProviderProxy implements IContentProvider BulkCursorToCursorAdaptor adaptor) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + int length = 0; + if (projection != null) { + length = projection.length; + } + data.writeInt(length); + for (int i = 0; i < length; i++) { + data.writeString(projection[i]); + } + data.writeString(selection); + if (selectionArgs != null) { + length = selectionArgs.length; + } else { + length = 0; + } + data.writeInt(length); + for (int i = 0; i < length; i++) { + data.writeString(selectionArgs[i]); + } + data.writeString(sortOrder); + data.writeStrongBinder(observer.asBinder()); + window.writeToParcel(data, 0); - url.writeToParcel(data, 0); - int length = 0; - if (projection != null) { - length = projection.length; - } - data.writeInt(length); - for (int i = 0; i < length; i++) { - data.writeString(projection[i]); - } - data.writeString(selection); - if (selectionArgs != null) { - length = selectionArgs.length; - } else { - length = 0; - } - data.writeInt(length); - for (int i = 0; i < length; i++) { - data.writeString(selectionArgs[i]); - } - data.writeString(sortOrder); - data.writeStrongBinder(observer.asBinder()); - window.writeToParcel(data, 0); + // Flag for whether or not we want the number of rows in the + // cursor and the position of the "_id" column index (or -1 if + // non-existent). Only to be returned if binder != null. + final boolean wantsCursorMetadata = (adaptor != null); + data.writeInt(wantsCursorMetadata ? 1 : 0); - // Flag for whether or not we want the number of rows in the - // cursor and the position of the "_id" column index (or -1 if - // non-existent). Only to be returned if binder != null. - final boolean wantsCursorMetadata = (adaptor != null); - data.writeInt(wantsCursorMetadata ? 1 : 0); + mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - DatabaseUtils.readExceptionFromParcel(reply); + IBulkCursor bulkCursor = null; + IBinder bulkCursorBinder = reply.readStrongBinder(); + if (bulkCursorBinder != null) { + bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder); - IBulkCursor bulkCursor = null; - IBinder bulkCursorBinder = reply.readStrongBinder(); - if (bulkCursorBinder != null) { - bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder); - - if (wantsCursorMetadata) { - int rowCount = reply.readInt(); - int idColumnPosition = reply.readInt(); - if (bulkCursor != null) { - adaptor.set(bulkCursor, rowCount, idColumnPosition); + if (wantsCursorMetadata) { + int rowCount = reply.readInt(); + int idColumnPosition = reply.readInt(); + if (bulkCursor != null) { + adaptor.set(bulkCursor, rowCount, idColumnPosition); + } } } + return bulkCursor; + } finally { + data.recycle(); + reply.recycle(); } - - data.recycle(); - reply.recycle(); - - return bulkCursor; } public IBulkCursor bulkQuery(Uri url, String[] projection, @@ -416,240 +416,240 @@ final class ContentProviderProxy implements IContentProvider { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); - url.writeToParcel(data, 0); + mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - String out = reply.readString(); - - data.recycle(); - reply.recycle(); - - return out; + DatabaseUtils.readExceptionFromParcel(reply); + String out = reply.readString(); + return out; + } finally { + data.recycle(); + reply.recycle(); + } } public Uri insert(Uri url, ContentValues values) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + values.writeToParcel(data, 0); - url.writeToParcel(data, 0); - values.writeToParcel(data, 0); + mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - Uri out = Uri.CREATOR.createFromParcel(reply); - - data.recycle(); - reply.recycle(); - - return out; + DatabaseUtils.readExceptionFromParcel(reply); + Uri out = Uri.CREATOR.createFromParcel(reply); + return out; + } finally { + data.recycle(); + reply.recycle(); + } } public int bulkInsert(Uri url, ContentValues[] values) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + data.writeTypedArray(values, 0); - url.writeToParcel(data, 0); - data.writeTypedArray(values, 0); + mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - int count = reply.readInt(); - - data.recycle(); - reply.recycle(); - - return count; + DatabaseUtils.readExceptionFromParcel(reply); + int count = reply.readInt(); + return count; + } finally { + data.recycle(); + reply.recycle(); + } } public ContentProviderResult[] applyBatch(ArrayList operations) throws RemoteException, OperationApplicationException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); + data.writeInt(operations.size()); + for (ContentProviderOperation operation : operations) { + operation.writeToParcel(data, 0); + } + mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0); - data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInt(operations.size()); - for (ContentProviderOperation operation : operations) { - operation.writeToParcel(data, 0); + DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply); + final ContentProviderResult[] results = + reply.createTypedArray(ContentProviderResult.CREATOR); + return results; + } finally { + data.recycle(); + reply.recycle(); } - mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply); - final ContentProviderResult[] results = - reply.createTypedArray(ContentProviderResult.CREATOR); - - data.recycle(); - reply.recycle(); - - return results; } public int delete(Uri url, String selection, String[] selectionArgs) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + data.writeString(selection); + data.writeStringArray(selectionArgs); - url.writeToParcel(data, 0); - data.writeString(selection); - data.writeStringArray(selectionArgs); + mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - int count = reply.readInt(); - - data.recycle(); - reply.recycle(); - - return count; + DatabaseUtils.readExceptionFromParcel(reply); + int count = reply.readInt(); + return count; + } finally { + data.recycle(); + reply.recycle(); + } } public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + values.writeToParcel(data, 0); + data.writeString(selection); + data.writeStringArray(selectionArgs); - url.writeToParcel(data, 0); - values.writeToParcel(data, 0); - data.writeString(selection); - data.writeStringArray(selectionArgs); + mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - int count = reply.readInt(); - - data.recycle(); - reply.recycle(); - - return count; + DatabaseUtils.readExceptionFromParcel(reply); + int count = reply.readInt(); + return count; + } finally { + data.recycle(); + reply.recycle(); + } } public ParcelFileDescriptor openFile(Uri url, String mode) throws RemoteException, FileNotFoundException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + data.writeString(mode); - url.writeToParcel(data, 0); - data.writeString(mode); + mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply); - int has = reply.readInt(); - ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null; - - data.recycle(); - reply.recycle(); - - return fd; + DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply); + int has = reply.readInt(); + ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null; + return fd; + } finally { + data.recycle(); + reply.recycle(); + } } public AssetFileDescriptor openAssetFile(Uri url, String mode) throws RemoteException, FileNotFoundException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + data.writeString(mode); - url.writeToParcel(data, 0); - data.writeString(mode); + mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply); - int has = reply.readInt(); - AssetFileDescriptor fd = has != 0 - ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null; - - data.recycle(); - reply.recycle(); - - return fd; + DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply); + int has = reply.readInt(); + AssetFileDescriptor fd = has != 0 + ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null; + return fd; + } finally { + data.recycle(); + reply.recycle(); + } } public Bundle call(String method, String request, Bundle args) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + data.writeString(method); + data.writeString(request); + data.writeBundle(args); - data.writeString(method); - data.writeString(request); - data.writeBundle(args); + mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - Bundle bundle = reply.readBundle(); - - data.recycle(); - reply.recycle(); - - return bundle; + DatabaseUtils.readExceptionFromParcel(reply); + Bundle bundle = reply.readBundle(); + return bundle; + } finally { + data.recycle(); + reply.recycle(); + } } public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + data.writeString(mimeTypeFilter); - url.writeToParcel(data, 0); - data.writeString(mimeTypeFilter); + mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - String[] out = reply.createStringArray(); - - data.recycle(); - reply.recycle(); - - return out; + DatabaseUtils.readExceptionFromParcel(reply); + String[] out = reply.createStringArray(); + return out; + } finally { + data.recycle(); + reply.recycle(); + } } public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) throws RemoteException, FileNotFoundException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); - data.writeInterfaceToken(IContentProvider.descriptor); + url.writeToParcel(data, 0); + data.writeString(mimeType); + data.writeBundle(opts); - url.writeToParcel(data, 0); - data.writeString(mimeType); - data.writeBundle(opts); + mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0); - mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply); - int has = reply.readInt(); - AssetFileDescriptor fd = has != 0 - ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null; - - data.recycle(); - reply.recycle(); - - return fd; + DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply); + int has = reply.readInt(); + AssetFileDescriptor fd = has != 0 + ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null; + return fd; + } finally { + data.recycle(); + reply.recycle(); + } } private IBinder mRemote; diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java index fa62d69217783..9925a9ab7c0d9 100644 --- a/core/java/android/database/BulkCursorNative.java +++ b/core/java/android/database/BulkCursorNative.java @@ -20,12 +20,13 @@ import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; +import android.os.Parcelable; import android.os.RemoteException; /** * Native implementation of the bulk cursor. This is only for use in implementing * IPC, application code should use the Cursor interface. - * + * * {@hide} */ public abstract class BulkCursorNative extends Binder implements IBulkCursor @@ -67,7 +68,7 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor } reply.writeNoException(); reply.writeInt(1); - window.writeToParcel(reply, 0); + window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; } @@ -184,172 +185,172 @@ final class BulkCursorProxy implements IBulkCursor { { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); + data.writeInt(startPos); - data.writeInterfaceToken(IBulkCursor.descriptor); + mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - data.writeInt(startPos); - - mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - CursorWindow window = null; - if (reply.readInt() == 1) { - window = CursorWindow.newFromParcel(reply); + CursorWindow window = null; + if (reply.readInt() == 1) { + window = CursorWindow.newFromParcel(reply); + } + return window; + } finally { + data.recycle(); + reply.recycle(); } - - data.recycle(); - reply.recycle(); - - return window; } public void onMove(int position) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); + data.writeInt(position); - data.writeInterfaceToken(IBulkCursor.descriptor); - - data.writeInt(position); - - mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - data.recycle(); - reply.recycle(); + mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); + } finally { + data.recycle(); + reply.recycle(); + } } public int count() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); - data.writeInterfaceToken(IBulkCursor.descriptor); + boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - int count; - if (result == false) { - count = -1; - } else { - count = reply.readInt(); + int count; + if (result == false) { + count = -1; + } else { + count = reply.readInt(); + } + return count; + } finally { + data.recycle(); + reply.recycle(); } - data.recycle(); - reply.recycle(); - return count; } public String[] getColumnNames() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); - data.writeInterfaceToken(IBulkCursor.descriptor); + mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - String[] columnNames = null; - int numColumns = reply.readInt(); - columnNames = new String[numColumns]; - for (int i = 0; i < numColumns; i++) { - columnNames[i] = reply.readString(); + String[] columnNames = null; + int numColumns = reply.readInt(); + columnNames = new String[numColumns]; + for (int i = 0; i < numColumns; i++) { + columnNames[i] = reply.readString(); + } + return columnNames; + } finally { + data.recycle(); + reply.recycle(); } - - data.recycle(); - reply.recycle(); - return columnNames; } public void deactivate() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); - data.writeInterfaceToken(IBulkCursor.descriptor); - - mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0); - DatabaseUtils.readExceptionFromParcel(reply); - - data.recycle(); - reply.recycle(); + mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); + } finally { + data.recycle(); + reply.recycle(); + } } public void close() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); - data.writeInterfaceToken(IBulkCursor.descriptor); - - mRemote.transact(CLOSE_TRANSACTION, data, reply, 0); - DatabaseUtils.readExceptionFromParcel(reply); - - data.recycle(); - reply.recycle(); + mRemote.transact(CLOSE_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); + } finally { + data.recycle(); + reply.recycle(); + } } public int requery(IContentObserver observer, CursorWindow window) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); + data.writeStrongInterface(observer); + window.writeToParcel(data, 0); - data.writeInterfaceToken(IBulkCursor.descriptor); + boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - data.writeStrongInterface(observer); - window.writeToParcel(data, 0); - - boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - int count; - if (!result) { - count = -1; - } else { - count = reply.readInt(); - mExtras = reply.readBundle(); + int count; + if (!result) { + count = -1; + } else { + count = reply.readInt(); + mExtras = reply.readBundle(); + } + return count; + } finally { + data.recycle(); + reply.recycle(); } - - data.recycle(); - reply.recycle(); - - return count; } public boolean getWantsAllOnMoveCalls() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); - data.writeInterfaceToken(IBulkCursor.descriptor); + mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - int result = reply.readInt(); - data.recycle(); - reply.recycle(); - return result != 0; + int result = reply.readInt(); + return result != 0; + } finally { + data.recycle(); + reply.recycle(); + } } public Bundle getExtras() throws RemoteException { if (mExtras == null) { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); - data.writeInterfaceToken(IBulkCursor.descriptor); + mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - mExtras = reply.readBundle(); - data.recycle(); - reply.recycle(); + mExtras = reply.readBundle(); + } finally { + data.recycle(); + reply.recycle(); + } } return mExtras; } @@ -357,19 +358,19 @@ final class BulkCursorProxy implements IBulkCursor { public Bundle respond(Bundle extras) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IBulkCursor.descriptor); + data.writeBundle(extras); - data.writeInterfaceToken(IBulkCursor.descriptor); + mRemote.transact(RESPOND_TRANSACTION, data, reply, 0); + DatabaseUtils.readExceptionFromParcel(reply); - data.writeBundle(extras); - - mRemote.transact(RESPOND_TRANSACTION, data, reply, 0); - - DatabaseUtils.readExceptionFromParcel(reply); - - Bundle returnExtras = reply.readBundle(); - data.recycle(); - reply.recycle(); - return returnExtras; + Bundle returnExtras = reply.readBundle(); + return returnExtras; + } finally { + data.recycle(); + reply.recycle(); + } } }