Merge "Add a CrossProcessCursorWrapper. Bug: 5220669"
This commit is contained in:
@@ -6782,6 +6782,13 @@ package android.database {
|
||||
method public abstract boolean onMove(int, int);
|
||||
}
|
||||
|
||||
public class CrossProcessCursorWrapper extends android.database.CursorWrapper implements android.database.CrossProcessCursor {
|
||||
ctor public CrossProcessCursorWrapper(android.database.Cursor);
|
||||
method public void fillWindow(int, android.database.CursorWindow);
|
||||
method public android.database.CursorWindow getWindow();
|
||||
method public boolean onMove(int, int);
|
||||
}
|
||||
|
||||
public abstract interface Cursor {
|
||||
method public abstract void close();
|
||||
method public abstract void copyStringToBuffer(int, android.database.CharArrayBuffer);
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.CrossProcessCursorWrapper;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.database.IContentObserver;
|
||||
@@ -1568,7 +1569,7 @@ public abstract class ContentResolver {
|
||||
samplePercent);
|
||||
}
|
||||
|
||||
private final class CursorWrapperInner extends CursorWrapper {
|
||||
private final class CursorWrapperInner extends CrossProcessCursorWrapper {
|
||||
private final IContentProvider mContentProvider;
|
||||
public static final String TAG="CursorWrapperInner";
|
||||
|
||||
|
||||
@@ -16,27 +16,63 @@
|
||||
|
||||
package android.database;
|
||||
|
||||
/**
|
||||
* A cross process cursor is an extension of a {@link Cursor} that also supports
|
||||
* usage from remote processes.
|
||||
* <p>
|
||||
* The contents of a cross process cursor are marshalled to the remote process by
|
||||
* filling {@link CursorWindow} objects using {@link #fillWindow}. As an optimization,
|
||||
* the cursor can provide a pre-filled window to use via {@link #getWindow} thereby
|
||||
* obviating the need to copy the data to yet another cursor window.
|
||||
*/
|
||||
public interface CrossProcessCursor extends Cursor {
|
||||
/**
|
||||
* returns a pre-filled window, return NULL if no such window
|
||||
* Returns a pre-filled window that contains the data within this cursor.
|
||||
* <p>
|
||||
* In particular, the window contains the row indicated by {@link Cursor#getPosition}.
|
||||
* The window's contents are automatically scrolled whenever the current
|
||||
* row moved outside the range covered by the window.
|
||||
* </p>
|
||||
*
|
||||
* @return The pre-filled window, or null if none.
|
||||
*/
|
||||
CursorWindow getWindow();
|
||||
|
||||
/**
|
||||
* copies cursor data into the window start at pos
|
||||
* Copies cursor data into the window.
|
||||
* <p>
|
||||
* Clears the window and fills it with data beginning at the requested
|
||||
* row position until all of the data in the cursor is exhausted
|
||||
* or the window runs out of space.
|
||||
* </p><p>
|
||||
* The filled window uses the same row indices as the original cursor.
|
||||
* For example, if you fill a window starting from row 5 from the cursor,
|
||||
* you can query the contents of row 5 from the window just by asking it
|
||||
* for row 5 because there is a direct correspondence between the row indices
|
||||
* used by the cursor and the window.
|
||||
* </p><p>
|
||||
* The current position of the cursor, as returned by {@link #getPosition},
|
||||
* is not changed by this method.
|
||||
* </p>
|
||||
*
|
||||
* @param position The zero-based index of the first row to copy into the window.
|
||||
* @param window The window to fill.
|
||||
*/
|
||||
void fillWindow(int pos, CursorWindow winow);
|
||||
void fillWindow(int position, CursorWindow window);
|
||||
|
||||
/**
|
||||
* This function is called every time the cursor is successfully scrolled
|
||||
* to a new position, giving the subclass a chance to update any state it
|
||||
* may have. If it returns false the move function will also do so and the
|
||||
* may have. If it returns false the move function will also do so and the
|
||||
* cursor will scroll to the beforeFirst position.
|
||||
* <p>
|
||||
* This function should be called by methods such as {@link #moveToPosition(int)},
|
||||
* so it will typically not be called from outside of the cursor class itself.
|
||||
* </p>
|
||||
*
|
||||
* @param oldPosition the position that we're moving from
|
||||
* @param newPosition the position that we're moving to
|
||||
* @return true if the move is successful, false otherwise
|
||||
* @param oldPosition The position that we're moving from.
|
||||
* @param newPosition The position that we're moving to.
|
||||
* @return True if the move is successful, false otherwise.
|
||||
*/
|
||||
boolean onMove(int oldPosition, int newPosition);
|
||||
|
||||
}
|
||||
|
||||
75
core/java/android/database/CrossProcessCursorWrapper.java
Normal file
75
core/java/android/database/CrossProcessCursorWrapper.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.database.CrossProcessCursor;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWindow;
|
||||
import android.database.CursorWrapper;
|
||||
|
||||
/**
|
||||
* Cursor wrapper that implements {@link CrossProcessCursor}.
|
||||
* <p>
|
||||
* If the wrapper cursor implemented {@link CrossProcessCursor}, then delegates
|
||||
* {@link #fillWindow}, {@link #getWindow()} and {@link #onMove} to it. Otherwise,
|
||||
* provides default implementations of these methods that traverse the contents
|
||||
* of the cursor similar to {@link AbstractCursor#fillWindow}.
|
||||
* </p><p>
|
||||
* This wrapper can be used to adapt an ordinary {@link Cursor} into a
|
||||
* {@link CrossProcessCursor}.
|
||||
* </p>
|
||||
*/
|
||||
public class CrossProcessCursorWrapper extends CursorWrapper implements CrossProcessCursor {
|
||||
/**
|
||||
* Creates a cross process cursor wrapper.
|
||||
* @param cursor The underlying cursor to wrap.
|
||||
*/
|
||||
public CrossProcessCursorWrapper(Cursor cursor) {
|
||||
super(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillWindow(int position, CursorWindow window) {
|
||||
if (mCursor instanceof CrossProcessCursor) {
|
||||
final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
|
||||
crossProcessCursor.fillWindow(position, window);
|
||||
return;
|
||||
}
|
||||
|
||||
DatabaseUtils.cursorFillWindow(mCursor, position, window);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CursorWindow getWindow() {
|
||||
if (mCursor instanceof CrossProcessCursor) {
|
||||
final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
|
||||
return crossProcessCursor.getWindow();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(int oldPosition, int newPosition) {
|
||||
if (mCursor instanceof CrossProcessCursor) {
|
||||
final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
|
||||
return crossProcessCursor.onMove(oldPosition, newPosition);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -89,11 +89,10 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
|
||||
|
||||
public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer,
|
||||
String providerName) {
|
||||
try {
|
||||
mCursor = (CrossProcessCursor) cursor;
|
||||
} catch (ClassCastException e) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Only CrossProcessCursor cursors are supported across process for now", e);
|
||||
if (cursor instanceof CrossProcessCursor) {
|
||||
mCursor = (CrossProcessCursor)cursor;
|
||||
} else {
|
||||
mCursor = new CrossProcessCursorWrapper(cursor);
|
||||
}
|
||||
mProviderName = providerName;
|
||||
|
||||
|
||||
@@ -25,9 +25,13 @@ import android.os.Bundle;
|
||||
* use for this class is to extend a cursor while overriding only a subset of its methods.
|
||||
*/
|
||||
public class CursorWrapper implements Cursor {
|
||||
/** @hide */
|
||||
protected final Cursor mCursor;
|
||||
|
||||
private final Cursor mCursor;
|
||||
|
||||
/**
|
||||
* Creates a cursor wrapper.
|
||||
* @param cursor The underlying cursor to wrap.
|
||||
*/
|
||||
public CursorWrapper(Cursor cursor) {
|
||||
mCursor = cursor;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user