diff options
-rw-r--r-- | core/java/android/content/ContentProviderNative.java | 24 | ||||
-rw-r--r-- | core/java/android/database/AbstractCursor.java | 61 | ||||
-rw-r--r-- | core/java/android/database/BulkCursorDescriptor.java | 78 | ||||
-rw-r--r-- | core/java/android/database/BulkCursorNative.java | 91 | ||||
-rw-r--r-- | core/java/android/database/BulkCursorToCursorAdaptor.java | 37 | ||||
-rw-r--r-- | core/java/android/database/CursorToBulkCursorAdaptor.java | 51 | ||||
-rw-r--r-- | core/java/android/database/DatabaseUtils.java | 14 | ||||
-rw-r--r-- | core/java/android/database/IBulkCursor.java | 32 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteCursor.java | 7 |
9 files changed, 169 insertions, 226 deletions
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index eb83dbc..4b31552 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -17,6 +17,7 @@ package android.content; import android.content.res.AssetFileDescriptor; +import android.database.BulkCursorDescriptor; import android.database.BulkCursorNative; import android.database.BulkCursorToCursorAdaptor; import android.database.Cursor; @@ -113,20 +114,14 @@ abstract public class ContentProviderNative extends Binder implements IContentPr if (cursor != null) { CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor( cursor, observer, getProviderName()); - final IBinder binder = adaptor.asBinder(); - final int count = adaptor.count(); - final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex( - adaptor.getColumnNames()); - final boolean wantsAllOnMoveCalls = adaptor.getWantsAllOnMoveCalls(); + BulkCursorDescriptor d = adaptor.getBulkCursorDescriptor(); reply.writeNoException(); - reply.writeStrongBinder(binder); - reply.writeInt(count); - reply.writeInt(index); - reply.writeInt(wantsAllOnMoveCalls ? 1 : 0); + reply.writeInt(1); + d.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeNoException(); - reply.writeStrongBinder(null); + reply.writeInt(0); } return true; @@ -369,12 +364,9 @@ final class ContentProviderProxy implements IContentProvider DatabaseUtils.readExceptionFromParcel(reply); - IBulkCursor bulkCursor = BulkCursorNative.asInterface(reply.readStrongBinder()); - if (bulkCursor != null) { - int rowCount = reply.readInt(); - int idColumnPosition = reply.readInt(); - boolean wantsAllOnMoveCalls = reply.readInt() != 0; - adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls); + if (reply.readInt() != 0) { + BulkCursorDescriptor d = BulkCursorDescriptor.CREATOR.createFromParcel(reply); + adaptor.initialize(d); } else { adaptor.close(); adaptor = null; diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java index b28ed8d..dd6692c 100644 --- a/core/java/android/database/AbstractCursor.java +++ b/core/java/android/database/AbstractCursor.java @@ -33,10 +33,39 @@ import java.util.Map; public abstract class AbstractCursor implements CrossProcessCursor { private static final String TAG = "Cursor"; - DataSetObservable mDataSetObservable = new DataSetObservable(); - ContentObservable mContentObservable = new ContentObservable(); + /** + * @deprecated This is never updated by this class and should not be used + */ + @Deprecated + protected HashMap<Long, Map<String, Object>> mUpdatedRows; + + protected int mPos; + + /** + * This must be set to the index of the row ID column by any + * subclass that wishes to support updates. + */ + protected int mRowIdColumnIndex; + + /** + * If {@link #mRowIdColumnIndex} is not -1 this contains contains the value of + * the column at {@link #mRowIdColumnIndex} for the current row this cursor is + * pointing at. + */ + protected Long mCurrentRowID; + + protected boolean mClosed; + protected ContentResolver mContentResolver; + private Uri mNotifyUri; + + private final Object mSelfObserverLock = new Object(); + private ContentObserver mSelfObserver; + private boolean mSelfObserverRegistered; - Bundle mExtras = Bundle.EMPTY; + private DataSetObservable mDataSetObservable = new DataSetObservable(); + private ContentObservable mContentObservable = new ContentObservable(); + + private Bundle mExtras = Bundle.EMPTY; /* -------------------------------------------------------- */ /* These need to be implemented by subclasses */ @@ -415,30 +444,4 @@ public abstract class AbstractCursor implements CrossProcessCursor { } } } - - /** - * @deprecated This is never updated by this class and should not be used - */ - @Deprecated - protected HashMap<Long, Map<String, Object>> mUpdatedRows; - - /** - * This must be set to the index of the row ID column by any - * subclass that wishes to support updates. - */ - protected int mRowIdColumnIndex; - - protected int mPos; - /** - * If {@link #mRowIdColumnIndex} is not -1 this contains contains the value of - * the column at {@link #mRowIdColumnIndex} for the current row this cursor is - * pointing at. - */ - protected Long mCurrentRowID; - protected ContentResolver mContentResolver; - protected boolean mClosed = false; - private Uri mNotifyUri; - private ContentObserver mSelfObserver; - final private Object mSelfObserverLock = new Object(); - private boolean mSelfObserverRegistered; } diff --git a/core/java/android/database/BulkCursorDescriptor.java b/core/java/android/database/BulkCursorDescriptor.java new file mode 100644 index 0000000..c1e5e63 --- /dev/null +++ b/core/java/android/database/BulkCursorDescriptor.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.database; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Describes the properties of a {@link CursorToBulkCursorAdaptor} that are + * needed to initialize its {@link BulkCursorToCursorAdaptor} counterpart on the client's end. + * + * {@hide} + */ +public final class BulkCursorDescriptor implements Parcelable { + public static final Parcelable.Creator<BulkCursorDescriptor> CREATOR = + new Parcelable.Creator<BulkCursorDescriptor>() { + @Override + public BulkCursorDescriptor createFromParcel(Parcel in) { + BulkCursorDescriptor d = new BulkCursorDescriptor(); + d.readFromParcel(in); + return d; + } + + @Override + public BulkCursorDescriptor[] newArray(int size) { + return new BulkCursorDescriptor[size]; + } + }; + + public IBulkCursor cursor; + public String[] columnNames; + public boolean wantsAllOnMoveCalls; + public int count; + public CursorWindow window; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeStrongBinder(cursor.asBinder()); + out.writeStringArray(columnNames); + out.writeInt(wantsAllOnMoveCalls ? 1 : 0); + out.writeInt(count); + if (window != null) { + out.writeInt(1); + window.writeToParcel(out, flags); + } else { + out.writeInt(0); + } + } + + public void readFromParcel(Parcel in) { + cursor = BulkCursorNative.asInterface(in.readStrongBinder()); + columnNames = in.readStringArray(); + wantsAllOnMoveCalls = in.readInt() != 0; + count = in.readInt(); + if (in.readInt() != 0) { + window = CursorWindow.CREATOR.createFromParcel(in); + } + } +} diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java index 67cf0f8..d3c11e7 100644 --- a/core/java/android/database/BulkCursorNative.java +++ b/core/java/android/database/BulkCursorNative.java @@ -72,26 +72,6 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor return true; } - case COUNT_TRANSACTION: { - data.enforceInterface(IBulkCursor.descriptor); - int count = count(); - reply.writeNoException(); - reply.writeInt(count); - return true; - } - - case GET_COLUMN_NAMES_TRANSACTION: { - data.enforceInterface(IBulkCursor.descriptor); - String[] columnNames = getColumnNames(); - reply.writeNoException(); - reply.writeInt(columnNames.length); - int length = columnNames.length; - for (int i = 0; i < length; i++) { - reply.writeString(columnNames[i]); - } - return true; - } - case DEACTIVATE_TRANSACTION: { data.enforceInterface(IBulkCursor.descriptor); deactivate(); @@ -125,14 +105,6 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor return true; } - case WANTS_ON_MOVE_TRANSACTION: { - data.enforceInterface(IBulkCursor.descriptor); - boolean result = getWantsAllOnMoveCalls(); - reply.writeNoException(); - reply.writeInt(result ? 1 : 0); - return true; - } - case GET_EXTRAS_TRANSACTION: { data.enforceInterface(IBulkCursor.descriptor); Bundle extras = getExtras(); @@ -217,52 +189,6 @@ final class BulkCursorProxy implements IBulkCursor { } } - public int count() throws RemoteException - { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - try { - data.writeInterfaceToken(IBulkCursor.descriptor); - - boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0); - DatabaseUtils.readExceptionFromParcel(reply); - - int count; - if (result == false) { - count = -1; - } else { - count = reply.readInt(); - } - return count; - } finally { - data.recycle(); - reply.recycle(); - } - } - - public String[] getColumnNames() throws RemoteException - { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - try { - data.writeInterfaceToken(IBulkCursor.descriptor); - - 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(); - } - return columnNames; - } finally { - data.recycle(); - reply.recycle(); - } - } - public void deactivate() throws RemoteException { Parcel data = Parcel.obtain(); @@ -317,23 +243,6 @@ final class BulkCursorProxy implements IBulkCursor { } } - public boolean getWantsAllOnMoveCalls() throws RemoteException { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - try { - data.writeInterfaceToken(IBulkCursor.descriptor); - - mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0); - DatabaseUtils.readExceptionFromParcel(reply); - - int result = reply.readInt(); - return result != 0; - } finally { - data.recycle(); - reply.recycle(); - } - } - public Bundle getExtras() throws RemoteException { if (mExtras == null) { Parcel data = Parcel.obtain(); diff --git a/core/java/android/database/BulkCursorToCursorAdaptor.java b/core/java/android/database/BulkCursorToCursorAdaptor.java index 885046b..98c7043 100644 --- a/core/java/android/database/BulkCursorToCursorAdaptor.java +++ b/core/java/android/database/BulkCursorToCursorAdaptor.java @@ -30,34 +30,23 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { private SelfContentObserver mObserverBridge = new SelfContentObserver(this); private IBulkCursor mBulkCursor; - private int mCount; private String[] mColumns; private boolean mWantsAllOnMoveCalls; + private int mCount; /** * Initializes the adaptor. * Must be called before first use. */ - public void initialize(IBulkCursor bulkCursor, int count, int idIndex, - boolean wantsAllOnMoveCalls) { - mBulkCursor = bulkCursor; - mColumns = null; // lazily retrieved - mCount = count; - mRowIdColumnIndex = idIndex; - mWantsAllOnMoveCalls = wantsAllOnMoveCalls; - } - - /** - * Returns column index of "_id" column, or -1 if not found. - */ - public static int findRowIdColumnIndex(String[] columnNames) { - int length = columnNames.length; - for (int i = 0; i < length; i++) { - if (columnNames[i].equals("_id")) { - return i; - } + public void initialize(BulkCursorDescriptor d) { + mBulkCursor = d.cursor; + mColumns = d.columnNames; + mRowIdColumnIndex = DatabaseUtils.findRowIdColumnIndex(mColumns); + mWantsAllOnMoveCalls = d.wantsAllOnMoveCalls; + mCount = d.count; + if (d.window != null) { + setWindow(d.window); } - return -1; } /** @@ -169,14 +158,6 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { public String[] getColumnNames() { throwIfCursorIsClosed(); - if (mColumns == null) { - try { - mColumns = mBulkCursor.getColumnNames(); - } catch (RemoteException ex) { - Log.e(TAG, "Unable to fetch column names because the remote process is dead"); - return null; - } - } return mColumns; } diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java index 167278a..525be96 100644 --- a/core/java/android/database/CursorToBulkCursorAdaptor.java +++ b/core/java/android/database/CursorToBulkCursorAdaptor.java @@ -132,6 +132,25 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } + public BulkCursorDescriptor getBulkCursorDescriptor() { + synchronized (mLock) { + throwIfCursorIsClosed(); + + BulkCursorDescriptor d = new BulkCursorDescriptor(); + d.cursor = this; + d.columnNames = mCursor.getColumnNames(); + d.wantsAllOnMoveCalls = mCursor.getWantsAllOnMoveCalls(); + d.count = mCursor.getCount(); + d.window = mCursor.getWindow(); + if (d.window != null) { + // Acquire a reference to the window because its reference count will be + // decremented when it is returned as part of the binder call reply parcel. + d.window.acquireReference(); + } + return d; + } + } + @Override public CursorWindow getWindow(int position) { synchronized (mLock) { @@ -157,10 +176,9 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative mCursor.fillWindow(position, window); } - // Acquire a reference before returning from this RPC. - // The Binder proxy will decrement the reference count again as part of writing - // the CursorWindow to the reply parcel as a return value. if (window != null) { + // Acquire a reference to the window because its reference count will be + // decremented when it is returned as part of the binder call reply parcel. window.acquireReference(); } return window; @@ -177,24 +195,6 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } @Override - public int count() { - synchronized (mLock) { - throwIfCursorIsClosed(); - - return mCursor.getCount(); - } - } - - @Override - public String[] getColumnNames() { - synchronized (mLock) { - throwIfCursorIsClosed(); - - return mCursor.getColumnNames(); - } - } - - @Override public void deactivate() { synchronized (mLock) { if (mCursor != null) { @@ -237,15 +237,6 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } - @Override - public boolean getWantsAllOnMoveCalls() { - synchronized (mLock) { - throwIfCursorIsClosed(); - - return mCursor.getWantsAllOnMoveCalls(); - } - } - /** * Create a ContentObserver from the observer and register it as an observer on the * underlying cursor. diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java index 99d260e..40a54cf 100644 --- a/core/java/android/database/DatabaseUtils.java +++ b/core/java/android/database/DatabaseUtils.java @@ -1386,4 +1386,18 @@ public class DatabaseUtils { System.arraycopy(newValues, 0, result, originalValues.length, newValues.length); return result; } + + /** + * Returns column index of "_id" column, or -1 if not found. + * @hide + */ + public static int findRowIdColumnIndex(String[] columnNames) { + int length = columnNames.length; + for (int i = 0; i < length; i++) { + if (columnNames[i].equals("_id")) { + return i; + } + } + return -1; + } } diff --git a/core/java/android/database/IBulkCursor.java b/core/java/android/database/IBulkCursor.java index 0f4500a..b551116 100644 --- a/core/java/android/database/IBulkCursor.java +++ b/core/java/android/database/IBulkCursor.java @@ -43,29 +43,12 @@ public interface IBulkCursor extends IInterface { */ public void onMove(int position) throws RemoteException; - /** - * Returns the number of rows in the cursor. - * - * @return the number of rows in the cursor. - */ - public int count() throws RemoteException; - - /** - * Returns a string array holding the names of all of the columns in the - * cursor in the order in which they were listed in the result. - * - * @return the names of the columns returned in this query. - */ - public String[] getColumnNames() throws RemoteException; - public void deactivate() throws RemoteException; public void close() throws RemoteException; public int requery(IContentObserver observer) throws RemoteException; - boolean getWantsAllOnMoveCalls() throws RemoteException; - Bundle getExtras() throws RemoteException; Bundle respond(Bundle extras) throws RemoteException; @@ -74,13 +57,10 @@ public interface IBulkCursor extends IInterface { static final String descriptor = "android.content.IBulkCursor"; static final int GET_CURSOR_WINDOW_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; - static final int COUNT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1; - static final int GET_COLUMN_NAMES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2; - static final int DEACTIVATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 5; - static final int REQUERY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 6; - static final int ON_MOVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 7; - static final int WANTS_ON_MOVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 8; - static final int GET_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 9; - static final int RESPOND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 10; - static final int CLOSE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 11; + static final int DEACTIVATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1; + static final int REQUERY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2; + static final int ON_MOVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 3; + static final int GET_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 4; + static final int RESPOND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 5; + static final int CLOSE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 6; } diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java index 82bb23e..b29897e 100644 --- a/core/java/android/database/sqlite/SQLiteCursor.java +++ b/core/java/android/database/sqlite/SQLiteCursor.java @@ -105,12 +105,7 @@ public class SQLiteCursor extends AbstractWindowedCursor { mQuery = query; mColumns = query.getColumnNames(); - for (int i = 0; i < mColumns.length; i++) { - // Make note of the row ID column index for quick access to it - if ("_id".equals(mColumns[i])) { - mRowIdColumnIndex = i; - } - } + mRowIdColumnIndex = DatabaseUtils.findRowIdColumnIndex(mColumns); } /** |