DirectoryLoader.java revision 4eb407a832b7d6a2d62a535e5cab70b00a0bc8ed
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.documentsui; 18 19import static com.android.documentsui.DirectoryFragment.TYPE_NORMAL; 20import static com.android.documentsui.DirectoryFragment.TYPE_RECENT_OPEN; 21import static com.android.documentsui.DirectoryFragment.TYPE_SEARCH; 22import static com.android.documentsui.DocumentsActivity.TAG; 23 24import android.content.ContentResolver; 25import android.content.Context; 26import android.database.Cursor; 27import android.net.Uri; 28import android.os.CancellationSignal; 29import android.provider.DocumentsContract.DocumentColumns; 30import android.util.Log; 31 32import com.android.documentsui.model.Document; 33import com.android.internal.util.Predicate; 34import com.google.android.collect.Lists; 35 36import libcore.io.IoUtils; 37 38import java.io.FileNotFoundException; 39import java.util.ArrayList; 40import java.util.Collections; 41import java.util.Comparator; 42import java.util.LinkedList; 43import java.util.List; 44 45public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { 46 47 private final int mType; 48 private Predicate<Document> mFilter; 49 private Comparator<Document> mSortOrder; 50 51 /** 52 * Stub result that represents an internal error. 53 */ 54 public static class ExceptionResult extends LinkedList<Document> { 55 public final Exception e; 56 57 public ExceptionResult(Exception e) { 58 this.e = e; 59 } 60 } 61 62 public DirectoryLoader(Context context, Uri uri, int type, Predicate<Document> filter, 63 Comparator<Document> sortOrder) { 64 super(context, uri); 65 mType = type; 66 mFilter = filter; 67 mSortOrder = sortOrder; 68 } 69 70 @Override 71 public List<Document> loadInBackground(Uri uri, CancellationSignal signal) { 72 try { 73 return loadInBackgroundInternal(uri, signal); 74 } catch (Exception e) { 75 return new ExceptionResult(e); 76 } 77 } 78 79 private List<Document> loadInBackgroundInternal(Uri uri, CancellationSignal signal) { 80 final ArrayList<Document> result = Lists.newArrayList(); 81 82 // TODO: subscribe to the notify uri from query 83 84 final ContentResolver resolver = getContext().getContentResolver(); 85 final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal); 86 try { 87 while (cursor != null && cursor.moveToNext()) { 88 Document doc = null; 89 switch (mType) { 90 case TYPE_NORMAL: 91 case TYPE_SEARCH: 92 doc = Document.fromDirectoryCursor(uri, cursor); 93 break; 94 case TYPE_RECENT_OPEN: 95 try { 96 doc = Document.fromRecentOpenCursor(resolver, cursor); 97 } catch (FileNotFoundException e) { 98 Log.w(TAG, "Failed to find recent: " + e); 99 } 100 break; 101 default: 102 throw new IllegalArgumentException("Unknown type"); 103 } 104 105 if (doc != null && (mFilter == null || mFilter.apply(doc))) { 106 result.add(doc); 107 } 108 } 109 } finally { 110 IoUtils.closeQuietly(cursor); 111 } 112 113 if (mSortOrder != null) { 114 Collections.sort(result, mSortOrder); 115 } 116 117 return result; 118 } 119 120 private String getQuerySortOrder() { 121 if (mSortOrder instanceof Document.DateComparator) { 122 return DocumentColumns.LAST_MODIFIED + " DESC"; 123 } else if (mSortOrder instanceof Document.NameComparator) { 124 return DocumentColumns.DISPLAY_NAME + " ASC"; 125 } else if (mSortOrder instanceof Document.SizeComparator) { 126 return DocumentColumns.SIZE + " DESC"; 127 } else { 128 return null; 129 } 130 } 131} 132