Loading core/java/android/content/ContentProviderNative.java +59 −51 Original line number Diff line number Diff line Loading @@ -108,22 +108,21 @@ 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()); cursor, observer, getProviderName(), window); 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 @@ -325,6 +324,8 @@ 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 @@ -352,6 +353,7 @@ 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 @@ -361,8 +363,7 @@ final class ContentProviderProxy implements IContentProvider if (bulkCursor != null) { int rowCount = reply.readInt(); int idColumnPosition = reply.readInt(); boolean wantsAllOnMoveCalls = reply.readInt() != 0; adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls); adaptor.initialize(bulkCursor, rowCount, idColumnPosition); } else { adaptor.close(); adaptor = null; Loading @@ -378,6 +379,13 @@ 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 +2 −4 Original line number Diff line number Diff line Loading @@ -189,14 +189,12 @@ 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(String name) { protected void clearOrCreateLocalWindow() { if (mWindow == null) { // If there isn't a window set already it will only be accessed locally mWindow = new CursorWindow(name, true /* the window is local only */); mWindow = new CursorWindow(true /* the window is local only */); } else { mWindow.clear(); } Loading core/java/android/database/BulkCursorNative.java +5 −3 Original line number Diff line number Diff line Loading @@ -110,7 +110,8 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor data.enforceInterface(IBulkCursor.descriptor); IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder()); int count = requery(observer); CursorWindow window = CursorWindow.CREATOR.createFromParcel(data); int count = requery(observer, window); reply.writeNoException(); reply.writeInt(count); reply.writeBundle(getExtras()); Loading Loading @@ -293,12 +294,13 @@ final class BulkCursorProxy implements IBulkCursor { } } public int requery(IContentObserver observer) throws RemoteException { 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); boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0); DatabaseUtils.readExceptionFromParcel(reply); Loading core/java/android/database/BulkCursorToCursorAdaptor.java +28 −21 Original line number Diff line number Diff line Loading @@ -38,13 +38,11 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { * Initializes the adaptor. * Must be called before first use. */ public void initialize(IBulkCursor bulkCursor, int count, int idIndex, boolean wantsAllOnMoveCalls) { public void initialize(IBulkCursor bulkCursor, int count, int idIndex) { mBulkCursor = bulkCursor; mColumns = null; // lazily retrieved mCount = count; mRowIdColumnIndex = idIndex; mWantsAllOnMoveCalls = wantsAllOnMoveCalls; } /** Loading Loading @@ -88,13 +86,16 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { try { // Make sure we have the proper window if (mWindow == null || newPosition < mWindow.getStartPosition() || newPosition >= mWindow.getStartPosition() + mWindow.getNumRows()) { if (mWindow != null) { if (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 @@ -144,7 +145,9 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { throwIfCursorIsClosed(); try { mCount = mBulkCursor.requery(getObserver()); CursorWindow newWindow = new CursorWindow(false /* create a remote window */); try { mCount = mBulkCursor.requery(getObserver(), newWindow); if (mCount != -1) { mPos = -1; closeWindow(); Loading @@ -158,6 +161,10 @@ 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 +46 −39 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ 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 @@ -88,11 +87,26 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName) { public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName, CursorWindow window) { 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 @@ -103,22 +117,17 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } private void closeWindowForNonWindowedCursorLocked() { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; mWindowForNonWindowedCursorWasFilled = false; } } private void disposeLocked() { private void closeCursorAndWindowLocked() { if (mCursor != null) { unregisterObserverProxyLocked(); mCursor.close(); mCursor = null; } closeWindowForNonWindowedCursorLocked(); if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; } } private void throwIfCursorIsClosed() { Loading @@ -130,7 +139,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative @Override public void binderDied() { synchronized (mLock) { disposeLocked(); closeCursorAndWindowLocked(); } } Loading @@ -139,30 +148,17 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative synchronized (mLock) { throwIfCursorIsClosed(); CursorWindow window; if (mCursor instanceof AbstractWindowedCursor) { AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor)mCursor; window = windowedCursor.getWindow(); if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); windowedCursor.setWindow(window); } mCursor.moveToPosition(startPos); final CursorWindow window; if (mCursor instanceof AbstractWindowedCursor) { window = ((AbstractWindowedCursor)mCursor).getWindow(); } else { window = mWindowForNonWindowedCursor; if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); mWindowForNonWindowedCursor = window; } mCursor.moveToPosition(startPos); if (!mWindowForNonWindowedCursorWasFilled || startPos < window.getStartPosition() || startPos >= window.getStartPosition() + window.getNumRows()) { if (window != null && (startPos < window.getStartPosition() || startPos >= (window.getStartPosition() + window.getNumRows()))) { mCursor.fillWindow(startPos, window); mWindowForNonWindowedCursorWasFilled = true; } } Loading Loading @@ -210,24 +206,29 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative unregisterObserverProxyLocked(); mCursor.deactivate(); } closeWindowForNonWindowedCursorLocked(); } } @Override public void close() { synchronized (mLock) { disposeLocked(); closeCursorAndWindowLocked(); } } @Override public int requery(IContentObserver observer) { public int requery(IContentObserver observer, CursorWindow window) { synchronized (mLock) { throwIfCursorIsClosed(); closeWindowForNonWindowedCursorLocked(); if (mCursor instanceof AbstractWindowedCursor) { ((AbstractWindowedCursor) mCursor).setWindow(window); } else { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); } mWindowForNonWindowedCursor = window; } try { if (!mCursor.requery()) { Loading @@ -240,6 +241,12 @@ 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 +59 −51 Original line number Diff line number Diff line Loading @@ -108,22 +108,21 @@ 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()); cursor, observer, getProviderName(), window); 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 @@ -325,6 +324,8 @@ 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 @@ -352,6 +353,7 @@ 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 @@ -361,8 +363,7 @@ final class ContentProviderProxy implements IContentProvider if (bulkCursor != null) { int rowCount = reply.readInt(); int idColumnPosition = reply.readInt(); boolean wantsAllOnMoveCalls = reply.readInt() != 0; adaptor.initialize(bulkCursor, rowCount, idColumnPosition, wantsAllOnMoveCalls); adaptor.initialize(bulkCursor, rowCount, idColumnPosition); } else { adaptor.close(); adaptor = null; Loading @@ -378,6 +379,13 @@ 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 +2 −4 Original line number Diff line number Diff line Loading @@ -189,14 +189,12 @@ 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(String name) { protected void clearOrCreateLocalWindow() { if (mWindow == null) { // If there isn't a window set already it will only be accessed locally mWindow = new CursorWindow(name, true /* the window is local only */); mWindow = new CursorWindow(true /* the window is local only */); } else { mWindow.clear(); } Loading
core/java/android/database/BulkCursorNative.java +5 −3 Original line number Diff line number Diff line Loading @@ -110,7 +110,8 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor data.enforceInterface(IBulkCursor.descriptor); IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder()); int count = requery(observer); CursorWindow window = CursorWindow.CREATOR.createFromParcel(data); int count = requery(observer, window); reply.writeNoException(); reply.writeInt(count); reply.writeBundle(getExtras()); Loading Loading @@ -293,12 +294,13 @@ final class BulkCursorProxy implements IBulkCursor { } } public int requery(IContentObserver observer) throws RemoteException { 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); boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0); DatabaseUtils.readExceptionFromParcel(reply); Loading
core/java/android/database/BulkCursorToCursorAdaptor.java +28 −21 Original line number Diff line number Diff line Loading @@ -38,13 +38,11 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { * Initializes the adaptor. * Must be called before first use. */ public void initialize(IBulkCursor bulkCursor, int count, int idIndex, boolean wantsAllOnMoveCalls) { public void initialize(IBulkCursor bulkCursor, int count, int idIndex) { mBulkCursor = bulkCursor; mColumns = null; // lazily retrieved mCount = count; mRowIdColumnIndex = idIndex; mWantsAllOnMoveCalls = wantsAllOnMoveCalls; } /** Loading Loading @@ -88,13 +86,16 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { try { // Make sure we have the proper window if (mWindow == null || newPosition < mWindow.getStartPosition() || newPosition >= mWindow.getStartPosition() + mWindow.getNumRows()) { if (mWindow != null) { if (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 @@ -144,7 +145,9 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { throwIfCursorIsClosed(); try { mCount = mBulkCursor.requery(getObserver()); CursorWindow newWindow = new CursorWindow(false /* create a remote window */); try { mCount = mBulkCursor.requery(getObserver(), newWindow); if (mCount != -1) { mPos = -1; closeWindow(); Loading @@ -158,6 +161,10 @@ 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 +46 −39 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ 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 @@ -88,11 +87,26 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName) { public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName, CursorWindow window) { 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 @@ -103,22 +117,17 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } private void closeWindowForNonWindowedCursorLocked() { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; mWindowForNonWindowedCursorWasFilled = false; } } private void disposeLocked() { private void closeCursorAndWindowLocked() { if (mCursor != null) { unregisterObserverProxyLocked(); mCursor.close(); mCursor = null; } closeWindowForNonWindowedCursorLocked(); if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); mWindowForNonWindowedCursor = null; } } private void throwIfCursorIsClosed() { Loading @@ -130,7 +139,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative @Override public void binderDied() { synchronized (mLock) { disposeLocked(); closeCursorAndWindowLocked(); } } Loading @@ -139,30 +148,17 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative synchronized (mLock) { throwIfCursorIsClosed(); CursorWindow window; if (mCursor instanceof AbstractWindowedCursor) { AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor)mCursor; window = windowedCursor.getWindow(); if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); windowedCursor.setWindow(window); } mCursor.moveToPosition(startPos); final CursorWindow window; if (mCursor instanceof AbstractWindowedCursor) { window = ((AbstractWindowedCursor)mCursor).getWindow(); } else { window = mWindowForNonWindowedCursor; if (window == null) { window = new CursorWindow(mProviderName, false /*localOnly*/); mWindowForNonWindowedCursor = window; } mCursor.moveToPosition(startPos); if (!mWindowForNonWindowedCursorWasFilled || startPos < window.getStartPosition() || startPos >= window.getStartPosition() + window.getNumRows()) { if (window != null && (startPos < window.getStartPosition() || startPos >= (window.getStartPosition() + window.getNumRows()))) { mCursor.fillWindow(startPos, window); mWindowForNonWindowedCursorWasFilled = true; } } Loading Loading @@ -210,24 +206,29 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative unregisterObserverProxyLocked(); mCursor.deactivate(); } closeWindowForNonWindowedCursorLocked(); } } @Override public void close() { synchronized (mLock) { disposeLocked(); closeCursorAndWindowLocked(); } } @Override public int requery(IContentObserver observer) { public int requery(IContentObserver observer, CursorWindow window) { synchronized (mLock) { throwIfCursorIsClosed(); closeWindowForNonWindowedCursorLocked(); if (mCursor instanceof AbstractWindowedCursor) { ((AbstractWindowedCursor) mCursor).setWindow(window); } else { if (mWindowForNonWindowedCursor != null) { mWindowForNonWindowedCursor.close(); } mWindowForNonWindowedCursor = window; } try { if (!mCursor.requery()) { Loading @@ -240,6 +241,12 @@ 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