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

Commit eb3127eb authored by The Android Automerger's avatar The Android Automerger
Browse files

Revert "Fix ownership of CursorWindows across processes."

This reverts commit d2183654.
parent 3014ea3d
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.database.Cursor;
import android.database.CursorToBulkCursorAdaptor;
import android.database.CursorWindow;
import android.database.IBulkCursor;
import android.database.IContentObserver;
import android.database.SQLException;
import android.net.Uri;
import android.os.AsyncTask;
@@ -167,9 +171,22 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            return ContentProvider.this;
        }

        @Override
        public String getProviderName() {
            return getContentProvider().getClass().getName();
        /**
         * Remote version of a query, which returns an IBulkCursor. The bulk
         * cursor should be wrapped with BulkCursorToCursorAdaptor before use.
         */
        public IBulkCursor bulkQuery(Uri uri, String[] projection,
                String selection, String[] selectionArgs, String sortOrder,
                IContentObserver observer, CursorWindow window) {
            enforceReadPermission(uri);
            Cursor cursor = ContentProvider.this.query(uri, projection,
                    selection, selectionArgs, sortOrder);
            if (cursor == null) {
                return null;
            }
            return new CursorToBulkCursorAdaptor(cursor, observer,
                    ContentProvider.this.getClass().getName(),
                    hasWritePermission(uri), window);
        }

        public Cursor query(Uri uri, String[] projection,
+101 −77
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.content.res.AssetFileDescriptor;
import android.database.BulkCursorNative;
import android.database.BulkCursorToCursorAdaptor;
import android.database.Cursor;
import android.database.CursorToBulkCursorAdaptor;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.database.IBulkCursor;
@@ -66,13 +65,6 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
        return new ContentProviderProxy(obj);
    }

    /**
     * Gets the name of the content provider.
     * Should probably be part of the {@link IContentProvider} interface.
     * @return The content provider name.
     */
    public abstract String getProviderName();

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
@@ -106,23 +98,33 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
                    }

                    String sortOrder = data.readString();
                    IContentObserver observer = IContentObserver.Stub.asInterface(
                            data.readStrongBinder());
                    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);
                        final IBinder binder = adaptor.asBinder();
                        final int count = adaptor.count();
                    // Flag for whether caller wants 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.
                    boolean wantsCursorMetadata = data.readInt() != 0;

                    IBulkCursor bulkCursor = bulkQuery(url, projection, selection,
                            selectionArgs, sortOrder, observer, window);
                    if (bulkCursor != null) {
                        final IBinder binder = bulkCursor.asBinder();
                        if (wantsCursorMetadata) {
                            final int count = bulkCursor.count();
                            final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex(
                                adaptor.getColumnNames());
                                    bulkCursor.getColumnNames());

                            reply.writeNoException();
                            reply.writeStrongBinder(binder);
                            reply.writeInt(count);
                            reply.writeInt(index);
                        } else {
                            reply.writeNoException();
                            reply.writeStrongBinder(binder);
                        }
                    } else {
                        reply.writeNoException();
                        reply.writeStrongBinder(null);
@@ -322,11 +324,12 @@ final class ContentProviderProxy implements IContentProvider
        return mRemote;
    }

    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();
    // Like bulkQuery() but sets up provided 'adaptor' if not null.
    private IBulkCursor bulkQueryInternal(
        Uri url, String[] projection,
        String selection, String[] selectionArgs, String sortOrder,
        IContentObserver observer, CursorWindow window,
        BulkCursorToCursorAdaptor adaptor) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        try {
@@ -352,40 +355,61 @@ final class ContentProviderProxy implements IContentProvider
                data.writeString(selectionArgs[i]);
            }
            data.writeString(sortOrder);
                data.writeStrongBinder(adaptor.getObserver().asBinder());
            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);

            mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);

            DatabaseUtils.readExceptionFromParcel(reply);

                IBulkCursor bulkCursor = BulkCursorNative.asInterface(reply.readStrongBinder());
                if (bulkCursor != null) {
            IBulkCursor bulkCursor = null;
            IBinder bulkCursorBinder = reply.readStrongBinder();
            if (bulkCursorBinder != null) {
                bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder);

                if (wantsCursorMetadata) {
                    int rowCount = reply.readInt();
                    int idColumnPosition = reply.readInt();
                    adaptor.initialize(bulkCursor, rowCount, idColumnPosition);
                } else {
                    adaptor.close();
                    adaptor = null;
                    if (bulkCursor != null) {
                        adaptor.set(bulkCursor, rowCount, idColumnPosition);
                    }
                return adaptor;
            } catch (RemoteException ex) {
                adaptor.close();
                throw ex;
            } catch (RuntimeException ex) {
                adaptor.close();
                throw ex;
                }
            }
            return bulkCursor;
        } finally {
            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 IBulkCursor bulkQuery(Uri url, String[] projection,
            String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
            CursorWindow window) throws RemoteException {
        return bulkQueryInternal(
            url, projection, selection, selectionArgs, sortOrder,
            observer, window,
            null /* BulkCursorToCursorAdaptor */);
    }

    public Cursor query(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) throws RemoteException {
        //TODO make a pool of windows so we can reuse memory dealers
        CursorWindow window = new CursorWindow(false /* window will be used remotely */);
        BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
        IBulkCursor bulkCursor = bulkQueryInternal(
            url, projection, selection, selectionArgs, sortOrder,
            adaptor.getObserver(), window,
            adaptor);
        if (bulkCursor == null) {
            return null;
        }
        return adaptor;
    }

    public String getType(Uri url) throws RemoteException
+10 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package android.content;

import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.IBulkCursor;
import android.database.IContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -33,6 +36,13 @@ import java.util.ArrayList;
 * @hide
 */
public interface IContentProvider extends IInterface {
    /**
     * @hide - hide this because return type IBulkCursor and parameter
     * IContentObserver are system private classes.
     */
    public IBulkCursor bulkQuery(Uri url, String[] projection,
            String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
            CursorWindow window) throws RemoteException;
    public Cursor query(Uri url, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) throws RemoteException;
    public String getType(Uri url) throws RemoteException;
+6 −4
Original line number Diff line number Diff line
@@ -78,11 +78,13 @@ public abstract class AbstractCursor implements CrossProcessCursor {
    }

    public void deactivate() {
        onDeactivateOrClose();
        deactivateInternal();
    }

    /** @hide */
    protected void onDeactivateOrClose() {
    /**
     * @hide
     */
    public void deactivateInternal() {
        if (mSelfObserver != null) {
            mContentResolver.unregisterContentObserver(mSelfObserver);
            mSelfObserverRegistered = false;
@@ -106,7 +108,7 @@ public abstract class AbstractCursor implements CrossProcessCursor {
    public void close() {
        mClosed = true;
        mContentObservable.unregisterAll();
        onDeactivateOrClose();
        deactivateInternal();
    }

    /**
+0 −26
Original line number Diff line number Diff line
@@ -19,11 +19,6 @@ package android.database;
/**
 * A base class for Cursors that store their data in {@link CursorWindow}s.
 * <p>
 * The cursor owns the cursor window it uses.  When the cursor is closed,
 * its window is also closed.  Likewise, when the window used by the cursor is
 * changed, its old window is closed.  This policy of strict ownership ensures
 * that cursor windows are not leaked.
 * </p><p>
 * Subclasses are responsible for filling the cursor window with data during
 * {@link #onMove(int, int)}, allocating a new cursor window if necessary.
 * During {@link #requery()}, the existing cursor window should be cleared and
@@ -185,25 +180,4 @@ public abstract class AbstractWindowedCursor extends AbstractCursor {
            mWindow = null;
        }
    }

    /**
     * If there is a window, clear it.
     * Otherwise, creates a local window.
     * @hide
     */
    protected void clearOrCreateLocalWindow() {
        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 */);
        } else {
            mWindow.clear();
        }
    }

    /** @hide */
    @Override
    protected void onDeactivateOrClose() {
        super.onDeactivateOrClose();
        closeWindow();
    }
}
Loading