Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58bf986c authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Use ashmem for CursorWindows. Bug: 5332296" into ics-mr0

parents a72a8063 0cde89f5
Loading
Loading
Loading
Loading
+51 −59
Original line number Diff line number Diff line
@@ -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);
@@ -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();
@@ -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);

@@ -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;
@@ -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
+4 −2
Original line number Diff line number Diff line
@@ -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();
        }
+3 −5
Original line number Diff line number Diff line
@@ -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());
@@ -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);
+21 −28
Original line number Diff line number Diff line
@@ -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;
    }

    /**
@@ -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");
@@ -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();
@@ -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();
+39 −46
Original line number Diff line number Diff line
@@ -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;
@@ -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);
        }
@@ -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() {
@@ -139,7 +130,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
    @Override
    public void binderDied() {
        synchronized (mLock) {
            closeCursorAndWindowLocked();
            disposeLocked();
        }
    }

@@ -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;
                }
            }

@@ -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()) {
@@ -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