blob: b2be11b9ced98c87b52d6256e31b405a6fa47025 [file] [log] [blame]
Jeff Sharkeya5defe32013-08-05 17:56:48 -07001/*
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
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070019import android.content.AsyncTaskLoader;
20import android.content.ContentProviderClient;
Jeff Sharkeya5defe32013-08-05 17:56:48 -070021import android.content.Context;
22import android.database.Cursor;
23import android.net.Uri;
24import android.os.CancellationSignal;
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070025import android.os.OperationCanceledException;
26import android.provider.DocumentsContract.Document;
Jeff Sharkeya5defe32013-08-05 17:56:48 -070027
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070028import com.android.documentsui.DocumentsActivity.DisplayState;
Jeff Sharkeya5defe32013-08-05 17:56:48 -070029
30import libcore.io.IoUtils;
31
Jeff Sharkey46899c82013-08-18 22:26:48 -070032class DirectoryResult implements AutoCloseable {
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070033 ContentProviderClient client;
Jeff Sharkey46899c82013-08-18 22:26:48 -070034 Cursor cursor;
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070035 Exception exception;
Jeff Sharkey46899c82013-08-18 22:26:48 -070036
37 @Override
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070038 public void close() {
Jeff Sharkey46899c82013-08-18 22:26:48 -070039 IoUtils.closeQuietly(cursor);
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070040 ContentProviderClient.closeQuietly(client);
41 cursor = null;
42 client = null;
Jeff Sharkey46899c82013-08-18 22:26:48 -070043 }
44}
45
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070046public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
47 private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
Jeff Sharkeya5defe32013-08-05 17:56:48 -070048
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070049 private final Uri mUri;
50 private final int mSortOrder;
Jeff Sharkeya5defe32013-08-05 17:56:48 -070051
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070052 private CancellationSignal mSignal;
53 private DirectoryResult mResult;
54
55 public DirectoryLoader(Context context, Uri uri, int sortOrder) {
56 super(context);
57 mUri = uri;
Jeff Sharkeya5defe32013-08-05 17:56:48 -070058 mSortOrder = sortOrder;
59 }
60
61 @Override
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070062 public final DirectoryResult loadInBackground() {
63 synchronized (this) {
64 if (isLoadInBackgroundCanceled()) {
65 throw new OperationCanceledException();
66 }
67 mSignal = new CancellationSignal();
68 }
Jeff Sharkey46899c82013-08-18 22:26:48 -070069 final DirectoryResult result = new DirectoryResult();
Jeff Sharkey1d890e02013-08-15 11:24:03 -070070 try {
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070071 result.client = getContext()
72 .getContentResolver().acquireUnstableContentProviderClient(mUri.getAuthority());
73 final Cursor cursor = result.client.query(
74 mUri, null, null, null, getQuerySortOrder(), mSignal);
75 result.cursor = new SortingCursorWrapper(cursor, mSortOrder);
76 result.cursor.registerContentObserver(mObserver);
Jeff Sharkey1d890e02013-08-15 11:24:03 -070077 } catch (Exception e) {
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070078 result.exception = e;
79 ContentProviderClient.closeQuietly(result.client);
80 } finally {
81 synchronized (this) {
82 mSignal = null;
83 }
Jeff Sharkey1d890e02013-08-15 11:24:03 -070084 }
Jeff Sharkey46899c82013-08-18 22:26:48 -070085 return result;
Jeff Sharkey1d890e02013-08-15 11:24:03 -070086 }
87
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070088 @Override
89 public void cancelLoadInBackground() {
90 super.cancelLoadInBackground();
Jeff Sharkeya5defe32013-08-05 17:56:48 -070091
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070092 synchronized (this) {
93 if (mSignal != null) {
94 mSignal.cancel();
Jeff Sharkey46899c82013-08-18 22:26:48 -070095 }
Jeff Sharkeya5defe32013-08-05 17:56:48 -070096 }
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070097 }
Jeff Sharkeya5defe32013-08-05 17:56:48 -070098
Jeff Sharkeyac9e6272013-08-31 21:27:44 -070099 @Override
100 public void deliverResult(DirectoryResult result) {
101 if (isReset()) {
102 IoUtils.closeQuietly(result);
103 return;
104 }
105 DirectoryResult oldResult = mResult;
106 mResult = result;
107
108 if (isStarted()) {
109 super.deliverResult(result);
110 }
111
112 if (oldResult != null && oldResult != result) {
113 IoUtils.closeQuietly(oldResult);
114 }
115 }
116
117 @Override
118 protected void onStartLoading() {
119 if (mResult != null) {
120 deliverResult(mResult);
121 }
122 if (takeContentChanged() || mResult == null) {
123 forceLoad();
124 }
125 }
126
127 @Override
128 protected void onStopLoading() {
129 cancelLoad();
130 }
131
132 @Override
133 public void onCanceled(DirectoryResult result) {
134 IoUtils.closeQuietly(result);
135 }
136
137 @Override
138 protected void onReset() {
139 super.onReset();
140
141 // Ensure the loader is stopped
142 onStopLoading();
143
144 IoUtils.closeQuietly(mResult);
145 mResult = null;
146
147 getContext().getContentResolver().unregisterContentObserver(mObserver);
148 }
149
150 private String getQuerySortOrder() {
151 switch (mSortOrder) {
152 case DisplayState.SORT_ORDER_DISPLAY_NAME:
153 return Document.COLUMN_DISPLAY_NAME + " ASC";
154 case DisplayState.SORT_ORDER_LAST_MODIFIED:
155 return Document.COLUMN_LAST_MODIFIED + " DESC";
156 case DisplayState.SORT_ORDER_SIZE:
157 return Document.COLUMN_SIZE + " DESC";
158 default:
159 return null;
Jeff Sharkeya5defe32013-08-05 17:56:48 -0700160 }
Jeff Sharkeya5defe32013-08-05 17:56:48 -0700161 }
Jeff Sharkeya5defe32013-08-05 17:56:48 -0700162}