use of android.database.MergeCursor in project android_frameworks_base by AOSPA.
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 Signal-Android by WhisperSystems.
the class ContactAccessor method getCursorForRecipientFilter.
/***
* If the code below looks shitty to you, that's because it was taken
* directly from the Android source, where shitty code is all you get.
*/
public Cursor getCursorForRecipientFilter(CharSequence constraint, ContentResolver mContentResolver) {
final String SORT_ORDER = Contacts.TIMES_CONTACTED + " DESC," + Contacts.DISPLAY_NAME + "," + Contacts.Data.IS_SUPER_PRIMARY + " DESC," + Phone.TYPE;
final String[] PROJECTION_PHONE = { // 0
Phone._ID, // 1
Phone.CONTACT_ID, // 2
Phone.TYPE, // 3
Phone.NUMBER, // 4
Phone.LABEL, // 5
Phone.DISPLAY_NAME };
String phone = "";
String cons = null;
if (constraint != null) {
cons = constraint.toString();
if (RecipientsAdapter.usefulAsDigits(cons)) {
phone = PhoneNumberUtils.convertKeypadLettersToDigits(cons);
if (phone.equals(cons) && !PhoneNumberUtils.isWellFormedSmsAddress(phone)) {
phone = "";
} else {
phone = phone.trim();
}
}
}
Uri uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(cons));
String selection = String.format("%s=%s OR %s=%s OR %s=%s", Phone.TYPE, Phone.TYPE_MOBILE, Phone.TYPE, Phone.TYPE_WORK_MOBILE, Phone.TYPE, Phone.TYPE_MMS);
Cursor phoneCursor = mContentResolver.query(uri, PROJECTION_PHONE, null, null, SORT_ORDER);
if (phone.length() > 0) {
ArrayList result = new ArrayList();
// ID
result.add(Integer.valueOf(-1));
// CONTACT_ID
result.add(Long.valueOf(-1));
// TYPE
result.add(Integer.valueOf(Phone.TYPE_CUSTOM));
// NUMBER
result.add(phone);
/*
* The " " keeps Phone.getDisplayLabel() from deciding
* to display the default label ("Home") next to the transformation
* of the letters into numbers.
*/
// LABEL
result.add(" ");
// NAME
result.add(cons);
ArrayList<ArrayList> wrap = new ArrayList<ArrayList>();
wrap.add(result);
ArrayListCursor translated = new ArrayListCursor(PROJECTION_PHONE, wrap);
return new MergeCursor(new Cursor[] { translated, phoneCursor });
} else {
return phoneCursor;
}
}
use of android.database.MergeCursor in project Signal-Android by WhisperSystems.
the class ConversationListLoader method getUnarchivedConversationList.
private Cursor getUnarchivedConversationList() {
List<Cursor> cursorList = new LinkedList<>();
cursorList.add(DatabaseFactory.getThreadDatabase(context).getConversationList());
int archivedCount = DatabaseFactory.getThreadDatabase(context).getArchivedConversationListCount();
if (archivedCount > 0) {
MatrixCursor switchToArchiveCursor = new MatrixCursor(new String[] { ThreadDatabase.ID, ThreadDatabase.DATE, ThreadDatabase.MESSAGE_COUNT, ThreadDatabase.RECIPIENT_IDS, ThreadDatabase.SNIPPET, ThreadDatabase.READ, ThreadDatabase.TYPE, ThreadDatabase.SNIPPET_TYPE, ThreadDatabase.SNIPPET_URI, ThreadDatabase.ARCHIVED, ThreadDatabase.STATUS, ThreadDatabase.RECEIPT_COUNT, ThreadDatabase.EXPIRES_IN, ThreadDatabase.LAST_SEEN }, 1);
switchToArchiveCursor.addRow(new Object[] { -1L, System.currentTimeMillis(), archivedCount, "-1", null, 1, ThreadDatabase.DistributionTypes.ARCHIVE, 0, null, 0, -1, 0, 0, 0 });
cursorList.add(switchToArchiveCursor);
}
return new MergeCursor(cursorList.toArray(new Cursor[0]));
}
use of android.database.MergeCursor in project Signal-Android by WhisperSystems.
the class ThreadDatabase method getFilteredConversationList.
public Cursor getFilteredConversationList(List<String> filter) {
if (filter == null || filter.size() == 0)
return null;
List<Long> rawRecipientIds = DatabaseFactory.getAddressDatabase(context).getCanonicalAddressIds(filter);
if (rawRecipientIds == null || rawRecipientIds.size() == 0)
return null;
SQLiteDatabase db = databaseHelper.getReadableDatabase();
List<List<Long>> partitionedRecipientIds = Util.partition(rawRecipientIds, 900);
List<Cursor> cursors = new LinkedList<>();
for (List<Long> recipientIds : partitionedRecipientIds) {
String selection = RECIPIENT_IDS + " = ?";
String[] selectionArgs = new String[recipientIds.size()];
for (int i = 0; i < recipientIds.size() - 1; i++) selection += (" OR " + RECIPIENT_IDS + " = ?");
int i = 0;
for (long id : recipientIds) {
selectionArgs[i++] = String.valueOf(id);
}
cursors.add(db.query(TABLE_NAME, null, selection, selectionArgs, null, null, DATE + " DESC"));
}
Cursor cursor = cursors.size() > 1 ? new MergeCursor(cursors.toArray(new Cursor[cursors.size()])) : cursors.get(0);
setNotifyConverationListListeners(cursor);
return cursor;
}
use of android.database.MergeCursor in project robolectric by robolectric.
the class ShadowMergeCursorTest method testGetDataMultipleCursor.
@Test
public void testGetDataMultipleCursor() throws Exception {
Cursor[] cursors = new Cursor[2];
cursors[0] = dbCursor1;
cursors[1] = dbCursor2;
cursor = new MergeCursor(cursors);
cursor.moveToFirst();
assertDataCursor1();
cursor.moveToNext();
assertDataCursor2();
}
Aggregations