use of android.database.MergeCursor in project platform_frameworks_base by android.
the class RecentsLoader method loadInBackgroundLocked.
private DirectoryResult loadInBackgroundLocked() {
if (mFirstPassLatch == null) {
// First time through we kick off all the recent tasks, and wait
// around to see if everyone finishes quickly.
final Collection<RootInfo> roots = mRoots.getMatchingRootsBlocking(mState);
for (RootInfo root : roots) {
if (root.supportsRecents()) {
mTasks.put(root, new RecentsTask(root.authority, root.rootId));
}
}
mFirstPassLatch = new CountDownLatch(mTasks.size());
for (RecentsTask task : mTasks.values()) {
ProviderExecutor.forAuthority(task.authority).execute(task);
}
try {
mFirstPassLatch.await(MAX_FIRST_PASS_WAIT_MILLIS, TimeUnit.MILLISECONDS);
mFirstPassDone = true;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
final long rejectBefore = System.currentTimeMillis() - REJECT_OLDER_THAN;
// Collect all finished tasks
boolean allDone = true;
List<Cursor> cursors = new ArrayList<>();
for (RecentsTask task : mTasks.values()) {
if (task.isDone()) {
try {
final Cursor cursor = task.get();
if (cursor == null)
continue;
final FilteringCursorWrapper filtered = new FilteringCursorWrapper(cursor, mState.acceptMimes, RECENT_REJECT_MIMES, rejectBefore) {
@Override
public void close() {
// Ignored, since we manage cursor lifecycle internally
}
};
cursors.add(filtered);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
// We already logged on other side
} catch (Exception e) {
Log.e(TAG, "Failed to query Recents for authority: " + task.authority + ". Skip this authority in Recents.", e);
}
} else {
allDone = false;
}
}
if (DEBUG) {
Log.d(TAG, "Found " + cursors.size() + " of " + mTasks.size() + " recent queries done");
}
final DirectoryResult result = new DirectoryResult();
result.sortOrder = SORT_ORDER_LAST_MODIFIED;
final Cursor merged;
if (cursors.size() > 0) {
merged = new MergeCursor(cursors.toArray(new Cursor[cursors.size()]));
} else {
// Return something when nobody is ready
merged = new MatrixCursor(new String[0]);
}
// Tell the UI if this is an in-progress result. When loading is complete, another update is
// sent with EXTRA_LOADING set to false.
Bundle extras = new Bundle();
extras.putBoolean(DocumentsContract.EXTRA_LOADING, !allDone);
merged.setExtras(extras);
result.cursor = merged;
return result;
}
use of android.database.MergeCursor in project android_frameworks_base by DirtyUnicorns.
the class ModelTest method testModelIdIsUnique.
// Tests multiple authorities with clashing document IDs.
public void testModelIdIsUnique() {
MatrixCursor cIn1 = new MatrixCursor(COLUMNS);
MatrixCursor cIn2 = new MatrixCursor(COLUMNS);
// Make two sets of items with the same IDs, under different authorities.
final String AUTHORITY0 = "auth0";
final String AUTHORITY1 = "auth1";
for (int i = 0; i < ITEM_COUNT; ++i) {
MatrixCursor.RowBuilder row0 = cIn1.newRow();
row0.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY0);
row0.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
MatrixCursor.RowBuilder row1 = cIn2.newRow();
row1.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY1);
row1.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
}
Cursor cIn = new MergeCursor(new Cursor[] { cIn1, cIn2 });
// Update the model, then make sure it contains all the expected items.
DirectoryResult r = new DirectoryResult();
r.cursor = cIn;
model.update(r);
assertEquals(ITEM_COUNT * 2, model.getItemCount());
BitSet b0 = new BitSet(ITEM_COUNT);
BitSet b1 = new BitSet(ITEM_COUNT);
for (String id : model.getModelIds()) {
Cursor cOut = model.getItem(id);
String authority = DocumentInfo.getCursorString(cOut, RootCursorWrapper.COLUMN_AUTHORITY);
String docId = DocumentInfo.getCursorString(cOut, Document.COLUMN_DOCUMENT_ID);
switch(authority) {
case AUTHORITY0:
b0.set(Integer.parseInt(docId));
break;
case AUTHORITY1:
b1.set(Integer.parseInt(docId));
break;
default:
fail("Unrecognized authority string");
}
}
assertEquals(ITEM_COUNT, b0.cardinality());
assertEquals(ITEM_COUNT, b1.cardinality());
}
use of android.database.MergeCursor in project android_frameworks_base by AOSPA.
the class Model method updateModelData.
/**
* Scan over the incoming cursor data, generate Model IDs for each row, and sort the IDs
* according to the current sort order.
*/
private void updateModelData() {
int[] positions = new int[mCursorCount];
mIds = new String[mCursorCount];
boolean[] isDirs = new boolean[mCursorCount];
String[] displayNames = null;
long[] longValues = null;
switch(mSortOrder) {
case SORT_ORDER_DISPLAY_NAME:
displayNames = new String[mCursorCount];
break;
case SORT_ORDER_LAST_MODIFIED:
case SORT_ORDER_SIZE:
longValues = new long[mCursorCount];
break;
}
String mimeType;
mCursor.moveToPosition(-1);
for (int pos = 0; pos < mCursorCount; ++pos) {
if (!mCursor.moveToNext()) {
Log.e(TAG, "Fail to move cursor to next pos: " + pos);
return;
}
positions[pos] = pos;
// with the authority to avoid collisions.
if (mCursor instanceof MergeCursor) {
mIds[pos] = getCursorString(mCursor, RootCursorWrapper.COLUMN_AUTHORITY) + "|" + getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
} else {
mIds[pos] = getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
}
mimeType = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
isDirs[pos] = Document.MIME_TYPE_DIR.equals(mimeType);
switch(mSortOrder) {
case SORT_ORDER_DISPLAY_NAME:
final String displayName = getCursorString(mCursor, Document.COLUMN_DISPLAY_NAME);
displayNames[pos] = displayName;
break;
case SORT_ORDER_LAST_MODIFIED:
longValues[pos] = getLastModified(mCursor);
break;
case SORT_ORDER_SIZE:
longValues[pos] = getCursorLong(mCursor, Document.COLUMN_SIZE);
break;
}
}
switch(mSortOrder) {
case SORT_ORDER_DISPLAY_NAME:
binarySort(displayNames, isDirs, positions, mIds);
break;
case SORT_ORDER_LAST_MODIFIED:
case SORT_ORDER_SIZE:
binarySort(longValues, isDirs, positions, mIds);
break;
}
// Populate the positions.
mPositions.clear();
for (int i = 0; i < mCursorCount; ++i) {
mPositions.put(mIds[i], positions[i]);
}
}
use of android.database.MergeCursor in project android_frameworks_base by AOSPA.
the class ModelTest method testModelIdIsUnique.
// Tests multiple authorities with clashing document IDs.
public void testModelIdIsUnique() {
MatrixCursor cIn1 = new MatrixCursor(COLUMNS);
MatrixCursor cIn2 = new MatrixCursor(COLUMNS);
// Make two sets of items with the same IDs, under different authorities.
final String AUTHORITY0 = "auth0";
final String AUTHORITY1 = "auth1";
for (int i = 0; i < ITEM_COUNT; ++i) {
MatrixCursor.RowBuilder row0 = cIn1.newRow();
row0.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY0);
row0.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
MatrixCursor.RowBuilder row1 = cIn2.newRow();
row1.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY1);
row1.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
}
Cursor cIn = new MergeCursor(new Cursor[] { cIn1, cIn2 });
// Update the model, then make sure it contains all the expected items.
DirectoryResult r = new DirectoryResult();
r.cursor = cIn;
model.update(r);
assertEquals(ITEM_COUNT * 2, model.getItemCount());
BitSet b0 = new BitSet(ITEM_COUNT);
BitSet b1 = new BitSet(ITEM_COUNT);
for (String id : model.getModelIds()) {
Cursor cOut = model.getItem(id);
String authority = DocumentInfo.getCursorString(cOut, RootCursorWrapper.COLUMN_AUTHORITY);
String docId = DocumentInfo.getCursorString(cOut, Document.COLUMN_DOCUMENT_ID);
switch(authority) {
case AUTHORITY0:
b0.set(Integer.parseInt(docId));
break;
case AUTHORITY1:
b1.set(Integer.parseInt(docId));
break;
default:
fail("Unrecognized authority string");
}
}
assertEquals(ITEM_COUNT, b0.cardinality());
assertEquals(ITEM_COUNT, b1.cardinality());
}
use of android.database.MergeCursor in project JamsMusicPlayer by psaravan.
the class Common method queueSongsToPin.
/**
* Download Manager implementation for pinning songs.
*/
public void queueSongsToPin(boolean getAllPinnedSongs, boolean pinPlaylist, String selection) {
//If the current cursor is empty or null, retrieve the cursor using the selection parameter.
if (mPinnedSongsCursor == null || mPinnedSongsCursor.getCount() <= 0) {
if (getAllPinnedSongs == true) {
mPinnedSongsCursor = null;
mIsFetchingPinnedSongs = true;
Toast.makeText(mContext, R.string.getting_pinned_songs, Toast.LENGTH_LONG).show();
} else if (pinPlaylist == true) {
//Pinning from a playlist, so we'll need to use a db call that utilizes a JOIN.
mPinnedSongsCursor = mDBAccessHelper.getAllSongsInPlaylistSearchable(selection);
} else {
//Check if we're pinning a smart playlist.
if (selection.equals("TOP_25_PLAYED_SONGS")) {
mPinnedSongsCursor = mDBAccessHelper.getTop25PlayedTracks(selection);
} else if (selection.equals("RECENTLY_ADDED")) {
mPinnedSongsCursor = mDBAccessHelper.getRecentlyAddedSongs(selection);
} else if (selection.equals("TOP_RATED")) {
mPinnedSongsCursor = mDBAccessHelper.getTopRatedSongs(selection);
} else if (selection.equals("RECENTLY_PLAYED")) {
mPinnedSongsCursor = mDBAccessHelper.getRecentlyPlayedSongs(selection);
} else {
//Not playing from a smart playlist. Just use a regular db query that searches songs.
mPinnedSongsCursor = mDBAccessHelper.getAllSongsSearchable(selection);
}
}
Intent intent = new Intent(this, PinGMusicSongsService.class);
startService(intent);
} else {
//mPinnedSongsCursor already has songs queued, so append a new intermCursor;
Cursor intermCursor = null;
if (getAllPinnedSongs == true) {
Toast.makeText(mContext, R.string.wait_until_pinning_complete, Toast.LENGTH_SHORT).show();
return;
} else if (pinPlaylist == true) {
//Pinning from a playlist, so we'll need to use a db call that utilizes a JOIN.
intermCursor = mDBAccessHelper.getAllSongsInPlaylistSearchable(selection);
} else {
//Check if we're pinning a smart playlist.
if (selection.equals("TOP_25_PLAYED_SONGS")) {
intermCursor = mDBAccessHelper.getTop25PlayedTracks(selection);
} else if (selection.equals("RECENTLY_ADDED")) {
intermCursor = mDBAccessHelper.getRecentlyAddedSongs(selection);
} else if (selection.equals("TOP_RATED")) {
intermCursor = mDBAccessHelper.getTopRatedSongs(selection);
} else if (selection.equals("RECENTLY_PLAYED")) {
intermCursor = mDBAccessHelper.getRecentlyPlayedSongs(selection);
} else {
//Not playing from a smart playlist. Just use a regular db query that searches songs.
intermCursor = mDBAccessHelper.getAllSongsSearchable(selection);
}
}
Cursor[] cursorArray = { mPinnedSongsCursor, intermCursor };
MergeCursor mergeCursor = new MergeCursor(cursorArray);
mPinnedSongsCursor = (Cursor) mergeCursor;
}
}
Aggregations