use of com.android.documentsui.model.RootInfo in project android_frameworks_base by crdroidandroid.
the class RootsCache method getMatchingRoots.
@VisibleForTesting
static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) {
final List<RootInfo> matching = new ArrayList<>();
for (RootInfo root : roots) {
if (DEBUG)
Log.d(TAG, "Evaluating " + root);
if (state.action == State.ACTION_CREATE && !root.supportsCreate()) {
if (DEBUG)
Log.d(TAG, "Excluding read-only root because: ACTION_CREATE.");
continue;
}
if (state.action == State.ACTION_PICK_COPY_DESTINATION && !root.supportsCreate()) {
if (DEBUG)
Log.d(TAG, "Excluding read-only root because: ACTION_PICK_COPY_DESTINATION.");
continue;
}
if (state.action == State.ACTION_OPEN_TREE && !root.supportsChildren()) {
if (DEBUG)
Log.d(TAG, "Excluding root !supportsChildren because: ACTION_OPEN_TREE.");
continue;
}
if (!state.showAdvanced && root.isAdvanced()) {
if (DEBUG)
Log.d(TAG, "Excluding root because: unwanted advanced device.");
continue;
}
if (state.localOnly && !root.isLocalOnly()) {
if (DEBUG)
Log.d(TAG, "Excluding root because: unwanted non-local device.");
continue;
}
if (state.directoryCopy && root.isDownloads()) {
if (DEBUG)
Log.d(TAG, "Excluding downloads root because: unsupported directory copy.");
continue;
}
if (state.action == State.ACTION_OPEN && root.isEmpty()) {
if (DEBUG)
Log.d(TAG, "Excluding empty root because: ACTION_OPEN.");
continue;
}
if (state.action == State.ACTION_GET_CONTENT && root.isEmpty()) {
if (DEBUG)
Log.d(TAG, "Excluding empty root because: ACTION_GET_CONTENT.");
continue;
}
final boolean overlap = MimePredicate.mimeMatches(root.derivedMimeTypes, state.acceptMimes) || MimePredicate.mimeMatches(state.acceptMimes, root.derivedMimeTypes);
if (!overlap) {
if (DEBUG)
Log.d(TAG, "Excluding root because: unsupported content types > " + state.acceptMimes);
continue;
}
if (state.excludedAuthorities.contains(root.authority)) {
if (DEBUG)
Log.d(TAG, "Excluding root because: owned by calling package.");
continue;
}
if (DEBUG)
Log.d(TAG, "Including " + root);
matching.add(root);
}
return matching;
}
use of com.android.documentsui.model.RootInfo in project android_frameworks_base by crdroidandroid.
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 com.android.documentsui.model.RootInfo in project android_frameworks_base by crdroidandroid.
the class DocumentsActivity method refreshDirectory.
@Override
void refreshDirectory(int anim) {
final FragmentManager fm = getFragmentManager();
final RootInfo root = getCurrentRoot();
final DocumentInfo cwd = getCurrentDirectory();
if (cwd == null) {
// No directory means recents
if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE || mState.action == ACTION_PICK_COPY_DESTINATION) {
RecentsCreateFragment.show(fm);
} else {
DirectoryFragment.showRecentsOpen(fm, anim);
// In recents we pick layout mode based on the mimetype,
// picking GRID for visual types. We intentionally don't
// consult a user's saved preferences here since they are
// set per root (not per root and per mimetype).
boolean visualMimes = MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes);
mState.derivedMode = visualMimes ? State.MODE_GRID : State.MODE_LIST;
}
} else {
// Normal boring directory
DirectoryFragment.showDirectory(fm, root, cwd, anim);
}
// Forget any replacement target
if (mState.action == ACTION_CREATE) {
final SaveFragment save = SaveFragment.get(fm);
if (save != null) {
save.setReplaceTarget(null);
}
}
if (mState.action == ACTION_OPEN_TREE || mState.action == ACTION_PICK_COPY_DESTINATION) {
final PickFragment pick = PickFragment.get(fm);
if (pick != null) {
pick.setPickTarget(mState.action, mState.copyOperationSubType, cwd);
}
}
}
use of com.android.documentsui.model.RootInfo in project android_frameworks_base by crdroidandroid.
the class RootsFragment method onCurrentRootChanged.
public void onCurrentRootChanged() {
if (mAdapter == null) {
return;
}
final RootInfo root = ((BaseActivity) getActivity()).getCurrentRoot();
for (int i = 0; i < mAdapter.getCount(); i++) {
final Object item = mAdapter.getItem(i);
if (item instanceof RootItem) {
final RootInfo testRoot = ((RootItem) item).root;
if (Objects.equals(testRoot, root)) {
mList.setItemChecked(i, true);
mList.setSelection(i);
return;
}
}
}
}
use of com.android.documentsui.model.RootInfo in project android_frameworks_base by crdroidandroid.
the class RootsCacheTest method testExcludedAuthorities.
public void testExcludedAuthorities() throws Exception {
final List<RootInfo> roots = newArrayList();
// Set up some roots
for (int i = 0; i < 5; ++i) {
RootInfo root = new RootInfo();
root.authority = "authority" + i;
roots.add(root);
}
// Make some allowed authorities
List<RootInfo> allowedRoots = newArrayList(roots.get(0), roots.get(2), roots.get(4));
// Set up the excluded authority list
for (RootInfo root : roots) {
if (!allowedRoots.contains(root)) {
mState.excludedAuthorities.add(root.authority);
}
}
mState.acceptMimes = new String[] { "*/*" };
assertContainsExactly(allowedRoots, getMatchingRoots(roots, mState));
}
Aggregations