Search in sources :

Example 21 with MergeCursor

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;
}
Also used : Bundle(android.os.Bundle) ArrayList(java.util.ArrayList) MergeCursor(android.database.MergeCursor) CountDownLatch(java.util.concurrent.CountDownLatch) Cursor(android.database.Cursor) MergeCursor(android.database.MergeCursor) MatrixCursor(android.database.MatrixCursor) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) MatrixCursor(android.database.MatrixCursor) RootInfo(com.android.documentsui.model.RootInfo) ExecutionException(java.util.concurrent.ExecutionException)

Example 22 with MergeCursor

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());
}
Also used : DirectoryResult(com.android.documentsui.DirectoryResult) MergeCursor(android.database.MergeCursor) BitSet(java.util.BitSet) MergeCursor(android.database.MergeCursor) MatrixCursor(android.database.MatrixCursor) Cursor(android.database.Cursor) MatrixCursor(android.database.MatrixCursor)

Example 23 with MergeCursor

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]);
    }
}
Also used : MergeCursor(android.database.MergeCursor) DocumentInfo.getCursorString(com.android.documentsui.model.DocumentInfo.getCursorString)

Example 24 with MergeCursor

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());
}
Also used : DirectoryResult(com.android.documentsui.DirectoryResult) MergeCursor(android.database.MergeCursor) BitSet(java.util.BitSet) MergeCursor(android.database.MergeCursor) MatrixCursor(android.database.MatrixCursor) Cursor(android.database.Cursor) MatrixCursor(android.database.MatrixCursor)

Example 25 with MergeCursor

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;
    }
}
Also used : MergeCursor(android.database.MergeCursor) Intent(android.content.Intent) Cursor(android.database.Cursor) MergeCursor(android.database.MergeCursor)

Aggregations

MergeCursor (android.database.MergeCursor)31 Cursor (android.database.Cursor)25 MatrixCursor (android.database.MatrixCursor)13 SQLiteCursor (android.database.sqlite.SQLiteCursor)7 ArrayList (java.util.ArrayList)7 Test (org.junit.Test)7 Bundle (android.os.Bundle)5 DirectoryResult (com.android.documentsui.DirectoryResult)5 DocumentInfo.getCursorString (com.android.documentsui.model.DocumentInfo.getCursorString)5 RootInfo (com.android.documentsui.model.RootInfo)5 IOException (java.io.IOException)5 BitSet (java.util.BitSet)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 ExecutionException (java.util.concurrent.ExecutionException)5 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)2 LinkedList (java.util.LinkedList)2 Intent (android.content.Intent)1 SQLiteQueryBuilder (android.database.sqlite.SQLiteQueryBuilder)1 Uri (android.net.Uri)1 List (java.util.List)1