Loading core/java/android/content/ContentProviderNative.java +51 −59 Original line number Diff line number Diff line Loading @@ -108,21 +108,22 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String sortOrder = data.readString(); IContentObserver observer = IContentObserver.Stub.asInterface( data.readStrongBinder()); CursorWindow window = CursorWindow.CREATOR.createFromParcel(data); Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder); if (cursor != null) { CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor( cursor, observer, getProviderName(), window); 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(); reply.writeNoException(); reply.writeStrongBinder(binder); reply.writeInt(count); reply.writeInt(index); reply.writeInt(wantsAllOnMoveCalls ? 1 : 0); } else { reply.writeNoException(); reply.writeStrongBinder(null); Loading Loading @@ -324,8 +325,6 @@ final class ContentProviderProxy implements IContentProvider public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder) throws RemoteException { CursorWindow window = new CursorWindow(false /* window will be used remotely */); try { BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor(); Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); Loading Loading @@ -353,7 +352,6 @@ final class ContentProviderProxy implements IContentProvider } data.writeString(sortOrder); data.writeStrongBinder(adaptor.getObserver().asBinder()); window.writeToParcel(data, 0); mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0); Loading @@ -363,7 +361,8 @@ final class ContentProviderProxy implements IContentProvider if (bulkCursor != null) { int rowCount = reply.readInt(); int idColumnPosition = reply.readInt(); adaptor.initialize(bulkCursor, rowCount, idColumnPosition); boolean wantsAllOnMoveCalls = reply.readInt() != 0; adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls); } else { adaptor.close(); adaptor = null; Loading @@ -379,13 +378,6 @@ final class ContentProviderProxy implements IContentProvider data.recycle(); reply.recycle(); } } finally { // We close the window now because the cursor adaptor does not // take ownership of the window until the first call to onMove. // The adaptor will obtain a fresh reference to the window when // it is filled. window.close(); } } public String getType(Uri url) throws RemoteException Loading core/java/android/database/AbstractWindowedCursor.java +4 −2 Original line number Diff line number Diff line Loading @@ -189,12 +189,14 @@ public abstract class AbstractWindowedCursor extends AbstractCursor { /** * If there is a window, clear it. * Otherwise, creates a local window. * * @param name The window name. * @hide */ protected void clearOrCreateLocalWindow() { protected void clearOrCreateLocalWindow(String name) { if (mWindow == null) { // If there isn't a window set already it will only be accessed locally mWindow = new CursorWindow(true /* the window is local only */); mWindow = new CursorWindow(name, true /* the window is local only */); } else { mWindow.clear(); } Loading core/java/android/database/BulkCursorNative.java +3 −5 Original line number Diff line number Diff line Loading @@ -110,8 +110,7 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor data.enforceInterface(IBulkCursor.descriptor); IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder()); CursorWindow window = CursorWindow.CREATOR.createFromParcel(data); int count = requery(observer, window); int count = requery(observer); reply.writeNoException(); reply.writeInt(count); reply.writeBundle(getExtras()); Loading Loading @@ -294,13 +293,12 @@ final class BulkCursorProxy implements IBulkCursor { } } public int requery(IContentObserver observer, CursorWindow window) throws RemoteException { public int requery(IContentObserver observer) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IBulkCursor.descriptor); data.writeStrongInterface(observer); window.writeToParcel(data, 0); boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0); DatabaseUtils.readExceptionFromParcel(reply); Loading core/java/android/database/BulkCursorToCursorAdaptor.java +21 −28 Original line number Diff line number Diff line Loading @@ -38,11 +38,13 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { * Initializes the adaptor. * Must be called before first use. */ public void initialize(IBulkCursor bulkCursor, int count, int idIndex) { public void initialize(IBulkCursor bulkCursor, int count, int idIndex, boolean wantsAllOnMoveCalls) { mBulkCursor = bulkCursor; mColumns = null; // lazily retrieved mCount = count; mRowIdColumnIndex = idIndex; mWantsAllOnMoveCalls = wantsAllOnMoveCalls; } /** Loading Loading @@ -86,16 +88,13 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { try { // Make sure we have the proper window if (mWindow != null) { if (newPosition < mWindow.getStartPosition() || newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) { if (mWindow == null || newPosition < mWindow.getStartPosition() || newPosition >= mWindow.getStartPosition() + mWindow.getNumRows()) { setWindow(mBulkCursor.getWindow(newPosition)); } else if (mWantsAllOnMoveCalls) { mBulkCursor.onMove(newPosition); } } else { setWindow(mBulkCursor.getWindow(newPosition)); } } catch (RemoteException ex) { // We tried to get a window and failed Log.e(TAG, "Unable to get window because the remote process is dead"); Loading Loading @@ -145,9 +144,7 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { throwIfCursorIsClosed(); try { CursorWindow newWindow = new CursorWindow(false /* create a remote window */); try { mCount = mBulkCursor.requery(getObserver(), newWindow); mCount = mBulkCursor.requery(getObserver()); if (mCount != -1) { mPos = -1; closeWindow(); Loading @@ -161,10 +158,6 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { deactivate(); return false; } } finally { // Don't take ownership of the window until the next call to onMove. newWindow.close(); } } catch (Exception ex) { Log.e(TAG, "Unable to requery because the remote process exception " + ex.getMessage()); deactivate(); Loading core/java/android/database/CursorToBulkCursorAdaptor.java +39 −46 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative * for managing the lifetime of their window. */ private CursorWindow mWindowForNonWindowedCursor; private boolean mWindowForNonWindowedCursorWasFilled; private static final class ContentObserverProxy extends ContentObserver { protected IContentObserver mRemote; Loading Loading @@ -87,26 +88,11 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName, CursorWindow window) { public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName) { try { mCursor = (CrossProcessCursor) cursor; if (mCursor instanceof AbstractWindowedCursor) { AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor) cursor; if (windowedCursor.hasWindow()) { if (Log.isLoggable(TAG, Log.VERBOSE) || false) { Log.v(TAG, "Cross process cursor has a local window before setWindow in " + providerName, new RuntimeException()); } } windowedCursor.setWindow(window); // cursor takes ownership of window } else { mWindowForNonWindowedCursor = window; // we own the window mCursor.fillWindow(0, window); } } catch (ClassCastException e) { // TODO Implement this case. window.close(); throw new UnsupportedOperationException( "Only CrossProcessCursor cursors are supported across process for now", e); } Loading @@ -117,17 +103,22 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } private void closeCursorAndWindowLocked() { private void closeWindowForNonWindowedCursorLocked() { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; mWindowForNonWindowedCursorWasFilled = false; } } private void disposeLocked() { if (mCursor != null) { unregisterObserverProxyLocked(); mCursor.close(); mCursor = null; } if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; } closeWindowForNonWindowedCursorLocked(); } private void throwIfCursorIsClosed() { Loading @@ -139,7 +130,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative @Override public void binderDied() { synchronized (mLock) { closeCursorAndWindowLocked(); disposeLocked(); } } Loading @@ -148,17 +139,30 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative synchronized (mLock) { throwIfCursorIsClosed(); mCursor.moveToPosition(startPos); final CursorWindow window; CursorWindow window; if (mCursor instanceof AbstractWindowedCursor) { window = ((AbstractWindowedCursor)mCursor).getWindow(); AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor)mCursor; window = windowedCursor.getWindow(); if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); windowedCursor.setWindow(window); } mCursor.moveToPosition(startPos); } else { window = mWindowForNonWindowedCursor; if (window != null && (startPos < window.getStartPosition() || startPos >= (window.getStartPosition() + window.getNumRows()))) { if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); mWindowForNonWindowedCursor = window; } mCursor.moveToPosition(startPos); if (!mWindowForNonWindowedCursorWasFilled || startPos < window.getStartPosition() || startPos >= window.getStartPosition() + window.getNumRows()) { mCursor.fillWindow(startPos, window); mWindowForNonWindowedCursorWasFilled = true; } } Loading Loading @@ -206,29 +210,24 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative unregisterObserverProxyLocked(); mCursor.deactivate(); } closeWindowForNonWindowedCursorLocked(); } } @Override public void close() { synchronized (mLock) { closeCursorAndWindowLocked(); disposeLocked(); } } @Override public int requery(IContentObserver observer, CursorWindow window) { public int requery(IContentObserver observer) { synchronized (mLock) { throwIfCursorIsClosed(); if (mCursor instanceof AbstractWindowedCursor) { ((AbstractWindowedCursor) mCursor).setWindow(window); } else { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); } mWindowForNonWindowedCursor = window; } closeWindowForNonWindowedCursorLocked(); try { if (!mCursor.requery()) { Loading @@ -241,12 +240,6 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative throw leakProgram; } if (!(mCursor instanceof AbstractWindowedCursor)) { if (window != null) { mCursor.fillWindow(0, window); } } unregisterObserverProxyLocked(); createAndRegisterObserverProxyLocked(observer); return mCursor.getCount(); Loading Loading
core/java/android/content/ContentProviderNative.java +51 −59 Original line number Diff line number Diff line Loading @@ -108,21 +108,22 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String sortOrder = data.readString(); IContentObserver observer = IContentObserver.Stub.asInterface( data.readStrongBinder()); CursorWindow window = CursorWindow.CREATOR.createFromParcel(data); Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder); if (cursor != null) { CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor( cursor, observer, getProviderName(), window); 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(); reply.writeNoException(); reply.writeStrongBinder(binder); reply.writeInt(count); reply.writeInt(index); reply.writeInt(wantsAllOnMoveCalls ? 1 : 0); } else { reply.writeNoException(); reply.writeStrongBinder(null); Loading Loading @@ -324,8 +325,6 @@ final class ContentProviderProxy implements IContentProvider public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder) throws RemoteException { CursorWindow window = new CursorWindow(false /* window will be used remotely */); try { BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor(); Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); Loading Loading @@ -353,7 +352,6 @@ final class ContentProviderProxy implements IContentProvider } data.writeString(sortOrder); data.writeStrongBinder(adaptor.getObserver().asBinder()); window.writeToParcel(data, 0); mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0); Loading @@ -363,7 +361,8 @@ final class ContentProviderProxy implements IContentProvider if (bulkCursor != null) { int rowCount = reply.readInt(); int idColumnPosition = reply.readInt(); adaptor.initialize(bulkCursor, rowCount, idColumnPosition); boolean wantsAllOnMoveCalls = reply.readInt() != 0; adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls); } else { adaptor.close(); adaptor = null; Loading @@ -379,13 +378,6 @@ final class ContentProviderProxy implements IContentProvider data.recycle(); reply.recycle(); } } finally { // We close the window now because the cursor adaptor does not // take ownership of the window until the first call to onMove. // The adaptor will obtain a fresh reference to the window when // it is filled. window.close(); } } public String getType(Uri url) throws RemoteException Loading
core/java/android/database/AbstractWindowedCursor.java +4 −2 Original line number Diff line number Diff line Loading @@ -189,12 +189,14 @@ public abstract class AbstractWindowedCursor extends AbstractCursor { /** * If there is a window, clear it. * Otherwise, creates a local window. * * @param name The window name. * @hide */ protected void clearOrCreateLocalWindow() { protected void clearOrCreateLocalWindow(String name) { if (mWindow == null) { // If there isn't a window set already it will only be accessed locally mWindow = new CursorWindow(true /* the window is local only */); mWindow = new CursorWindow(name, true /* the window is local only */); } else { mWindow.clear(); } Loading
core/java/android/database/BulkCursorNative.java +3 −5 Original line number Diff line number Diff line Loading @@ -110,8 +110,7 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor data.enforceInterface(IBulkCursor.descriptor); IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder()); CursorWindow window = CursorWindow.CREATOR.createFromParcel(data); int count = requery(observer, window); int count = requery(observer); reply.writeNoException(); reply.writeInt(count); reply.writeBundle(getExtras()); Loading Loading @@ -294,13 +293,12 @@ final class BulkCursorProxy implements IBulkCursor { } } public int requery(IContentObserver observer, CursorWindow window) throws RemoteException { public int requery(IContentObserver observer) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { data.writeInterfaceToken(IBulkCursor.descriptor); data.writeStrongInterface(observer); window.writeToParcel(data, 0); boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0); DatabaseUtils.readExceptionFromParcel(reply); Loading
core/java/android/database/BulkCursorToCursorAdaptor.java +21 −28 Original line number Diff line number Diff line Loading @@ -38,11 +38,13 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { * Initializes the adaptor. * Must be called before first use. */ public void initialize(IBulkCursor bulkCursor, int count, int idIndex) { public void initialize(IBulkCursor bulkCursor, int count, int idIndex, boolean wantsAllOnMoveCalls) { mBulkCursor = bulkCursor; mColumns = null; // lazily retrieved mCount = count; mRowIdColumnIndex = idIndex; mWantsAllOnMoveCalls = wantsAllOnMoveCalls; } /** Loading Loading @@ -86,16 +88,13 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { try { // Make sure we have the proper window if (mWindow != null) { if (newPosition < mWindow.getStartPosition() || newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) { if (mWindow == null || newPosition < mWindow.getStartPosition() || newPosition >= mWindow.getStartPosition() + mWindow.getNumRows()) { setWindow(mBulkCursor.getWindow(newPosition)); } else if (mWantsAllOnMoveCalls) { mBulkCursor.onMove(newPosition); } } else { setWindow(mBulkCursor.getWindow(newPosition)); } } catch (RemoteException ex) { // We tried to get a window and failed Log.e(TAG, "Unable to get window because the remote process is dead"); Loading Loading @@ -145,9 +144,7 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { throwIfCursorIsClosed(); try { CursorWindow newWindow = new CursorWindow(false /* create a remote window */); try { mCount = mBulkCursor.requery(getObserver(), newWindow); mCount = mBulkCursor.requery(getObserver()); if (mCount != -1) { mPos = -1; closeWindow(); Loading @@ -161,10 +158,6 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { deactivate(); return false; } } finally { // Don't take ownership of the window until the next call to onMove. newWindow.close(); } } catch (Exception ex) { Log.e(TAG, "Unable to requery because the remote process exception " + ex.getMessage()); deactivate(); Loading
core/java/android/database/CursorToBulkCursorAdaptor.java +39 −46 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative * for managing the lifetime of their window. */ private CursorWindow mWindowForNonWindowedCursor; private boolean mWindowForNonWindowedCursorWasFilled; private static final class ContentObserverProxy extends ContentObserver { protected IContentObserver mRemote; Loading Loading @@ -87,26 +88,11 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName, CursorWindow window) { public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName) { try { mCursor = (CrossProcessCursor) cursor; if (mCursor instanceof AbstractWindowedCursor) { AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor) cursor; if (windowedCursor.hasWindow()) { if (Log.isLoggable(TAG, Log.VERBOSE) || false) { Log.v(TAG, "Cross process cursor has a local window before setWindow in " + providerName, new RuntimeException()); } } windowedCursor.setWindow(window); // cursor takes ownership of window } else { mWindowForNonWindowedCursor = window; // we own the window mCursor.fillWindow(0, window); } } catch (ClassCastException e) { // TODO Implement this case. window.close(); throw new UnsupportedOperationException( "Only CrossProcessCursor cursors are supported across process for now", e); } Loading @@ -117,17 +103,22 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } private void closeCursorAndWindowLocked() { private void closeWindowForNonWindowedCursorLocked() { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; mWindowForNonWindowedCursorWasFilled = false; } } private void disposeLocked() { if (mCursor != null) { unregisterObserverProxyLocked(); mCursor.close(); mCursor = null; } if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; } closeWindowForNonWindowedCursorLocked(); } private void throwIfCursorIsClosed() { Loading @@ -139,7 +130,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative @Override public void binderDied() { synchronized (mLock) { closeCursorAndWindowLocked(); disposeLocked(); } } Loading @@ -148,17 +139,30 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative synchronized (mLock) { throwIfCursorIsClosed(); mCursor.moveToPosition(startPos); final CursorWindow window; CursorWindow window; if (mCursor instanceof AbstractWindowedCursor) { window = ((AbstractWindowedCursor)mCursor).getWindow(); AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor)mCursor; window = windowedCursor.getWindow(); if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); windowedCursor.setWindow(window); } mCursor.moveToPosition(startPos); } else { window = mWindowForNonWindowedCursor; if (window != null && (startPos < window.getStartPosition() || startPos >= (window.getStartPosition() + window.getNumRows()))) { if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); mWindowForNonWindowedCursor = window; } mCursor.moveToPosition(startPos); if (!mWindowForNonWindowedCursorWasFilled || startPos < window.getStartPosition() || startPos >= window.getStartPosition() + window.getNumRows()) { mCursor.fillWindow(startPos, window); mWindowForNonWindowedCursorWasFilled = true; } } Loading Loading @@ -206,29 +210,24 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative unregisterObserverProxyLocked(); mCursor.deactivate(); } closeWindowForNonWindowedCursorLocked(); } } @Override public void close() { synchronized (mLock) { closeCursorAndWindowLocked(); disposeLocked(); } } @Override public int requery(IContentObserver observer, CursorWindow window) { public int requery(IContentObserver observer) { synchronized (mLock) { throwIfCursorIsClosed(); if (mCursor instanceof AbstractWindowedCursor) { ((AbstractWindowedCursor) mCursor).setWindow(window); } else { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); } mWindowForNonWindowedCursor = window; } closeWindowForNonWindowedCursorLocked(); try { if (!mCursor.requery()) { Loading @@ -241,12 +240,6 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative throw leakProgram; } if (!(mCursor instanceof AbstractWindowedCursor)) { if (window != null) { mCursor.fillWindow(0, window); } } unregisterObserverProxyLocked(); createAndRegisterObserverProxyLocked(observer); return mCursor.getCount(); Loading