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