summaryrefslogtreecommitdiffstats
path: root/packages/DocumentsUI/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'packages/DocumentsUI/src/com')
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java101
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java46
2 files changed, 141 insertions, 6 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index ac5629e..fbdb3a7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -16,17 +16,24 @@
package com.android.documentsui;
+import static com.android.documentsui.DocumentsActivity.TAG;
+
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Loader;
+import android.graphics.Bitmap;
+import android.graphics.Point;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.text.format.DateUtils;
import android.text.format.Formatter;
+import android.text.format.Time;
+import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
@@ -75,6 +82,8 @@ public class DirectoryFragment extends Fragment {
private int mType = TYPE_NORMAL;
+ private Point mThumbSize;
+
private DocumentsAdapter mAdapter;
private LoaderCallbacks<List<Document>> mCallbacks;
@@ -217,7 +226,9 @@ public class DirectoryFragment extends Fragment {
choiceMode = ListView.CHOICE_MODE_NONE;
}
+ final int thumbSize;
if (state.mode == DisplayState.MODE_GRID) {
+ thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width);
mListView.setAdapter(null);
mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
mGridView.setAdapter(mAdapter);
@@ -226,6 +237,7 @@ public class DirectoryFragment extends Fragment {
mGridView.setChoiceMode(choiceMode);
mCurrentView = mGridView;
} else if (state.mode == DisplayState.MODE_LIST) {
+ thumbSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
mGridView.setAdapter(null);
mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE);
mListView.setAdapter(mAdapter);
@@ -234,6 +246,8 @@ public class DirectoryFragment extends Fragment {
} else {
throw new IllegalStateException();
}
+
+ mThumbSize = new Point(thumbSize, thumbSize);
}
private OnItemClickListener mItemListener = new OnItemClickListener() {
@@ -349,9 +363,21 @@ public class DirectoryFragment extends Fragment {
final TextView date = (TextView) convertView.findViewById(R.id.date);
final TextView size = (TextView) convertView.findViewById(R.id.size);
+ final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) icon.getTag();
+ if (oldTask != null) {
+ oldTask.cancel(false);
+ }
+
if (doc.isThumbnailSupported()) {
- // TODO: load thumbnails async
- icon.setImageURI(doc.uri);
+ final Bitmap cachedResult = ThumbnailCache.get(context).get(doc.uri);
+ if (cachedResult != null) {
+ icon.setImageBitmap(cachedResult);
+ } else {
+ final ThumbnailAsyncTask task = new ThumbnailAsyncTask(icon, mThumbSize);
+ icon.setImageBitmap(null);
+ icon.setTag(task);
+ task.execute(doc.uri);
+ }
} else {
icon.setImageDrawable(RootsCache.resolveDocumentIcon(
context, doc.uri.getAuthority(), doc.mimeType));
@@ -380,10 +406,11 @@ public class DirectoryFragment extends Fragment {
(summary.getVisibility() == View.VISIBLE) ? View.VISIBLE : View.GONE);
}
- // TODO: omit year from format
- date.setText(DateUtils.formatSameDayTime(
- doc.lastModified, System.currentTimeMillis(), DateFormat.SHORT,
- DateFormat.SHORT));
+ if (doc.lastModified == -1) {
+ date.setText(null);
+ } else {
+ date.setText(formatTime(context, doc.lastModified));
+ }
if (state.showSize) {
size.setVisibility(View.VISIBLE);
@@ -414,4 +441,66 @@ public class DirectoryFragment extends Fragment {
return getItem(position).uri.hashCode();
}
}
+
+ private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> {
+ private final ImageView mTarget;
+ private final Point mSize;
+
+ public ThumbnailAsyncTask(ImageView target, Point size) {
+ mTarget = target;
+ mSize = size;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ mTarget.setTag(this);
+ }
+
+ @Override
+ protected Bitmap doInBackground(Uri... params) {
+ final Context context = mTarget.getContext();
+ final Uri uri = params[0];
+
+ Bitmap result = null;
+ try {
+ result = DocumentsContract.getThumbnail(
+ context.getContentResolver(), uri, mSize);
+ if (result != null) {
+ ThumbnailCache.get(context).put(uri, result);
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to load thumbnail: " + e);
+ }
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap result) {
+ if (mTarget.getTag() == this) {
+ mTarget.setImageBitmap(result);
+ mTarget.setTag(null);
+ }
+ }
+ }
+
+ private static String formatTime(Context context, long when) {
+ // TODO: DateUtils should make this easier
+ Time then = new Time();
+ then.set(when);
+ Time now = new Time();
+ now.setToNow();
+
+ int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT
+ | DateUtils.FORMAT_ABBREV_ALL;
+
+ if (then.year != now.year) {
+ flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
+ } else if (then.yearDay != now.yearDay) {
+ flags |= DateUtils.FORMAT_SHOW_DATE;
+ } else {
+ flags |= DateUtils.FORMAT_SHOW_TIME;
+ }
+
+ return DateUtils.formatDateTime(context, when, flags);
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java
new file mode 100644
index 0000000..bc7abeb
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.util.LruCache;
+
+public class ThumbnailCache extends LruCache<Uri, Bitmap> {
+ private static ThumbnailCache sCache;
+
+ public static ThumbnailCache get(Context context) {
+ if (sCache == null) {
+ final ActivityManager am = (ActivityManager) context.getSystemService(
+ Context.ACTIVITY_SERVICE);
+ final int memoryClassBytes = am.getMemoryClass() * 1024 * 1024;
+ sCache = new ThumbnailCache(memoryClassBytes / 4);
+ }
+ return sCache;
+ }
+
+ public ThumbnailCache(int maxSizeBytes) {
+ super(maxSizeBytes);
+ }
+
+ @Override
+ protected int sizeOf(Uri key, Bitmap value) {
+ return value.getByteCount();
+ }
+}