2 * Copyright (C) 2013 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.photos.shims;
19 import android.content.AsyncTaskLoader;
20 import android.content.Context;
21 import android.database.Cursor;
22 import android.database.MatrixCursor;
23 import android.graphics.drawable.Drawable;
24 import android.net.Uri;
25 import android.provider.MediaStore.Files.FileColumns;
26 import android.util.SparseArray;
28 import com.android.gallery3d.data.ContentListener;
29 import com.android.gallery3d.data.DataManager;
30 import com.android.gallery3d.data.MediaItem;
31 import com.android.gallery3d.data.MediaObject;
32 import com.android.gallery3d.data.MediaSet;
33 import com.android.gallery3d.data.MediaSet.ItemConsumer;
34 import com.android.gallery3d.data.MediaSet.SyncListener;
35 import com.android.gallery3d.data.Path;
36 import com.android.gallery3d.util.Future;
37 import com.android.photos.data.PhotoSetLoader;
39 import java.util.ArrayList;
42 * Returns all MediaItems in a MediaSet, wrapping them in a cursor to appear
43 * like a PhotoSetLoader
45 public class MediaItemsLoader extends AsyncTaskLoader<Cursor> implements LoaderCompatShim<Cursor> {
47 private static final SyncListener sNullListener = new SyncListener() {
49 public void onSyncDone(MediaSet mediaSet, int resultCode) {
53 private final MediaSet mMediaSet;
54 private final DataManager mDataManager;
55 private Future<Integer> mSyncTask = null;
56 private ContentListener mObserver = new ContentListener() {
58 public void onContentDirty() {
62 private SparseArray<MediaItem> mMediaItems;
64 public MediaItemsLoader(Context context) {
66 mDataManager = DataManager.from(context);
67 String path = mDataManager.getTopSetPath(DataManager.INCLUDE_ALL);
68 mMediaSet = mDataManager.getMediaSet(path);
71 public MediaItemsLoader(Context context, String parentPath) {
73 mDataManager = DataManager.from(getContext());
74 mMediaSet = mDataManager.getMediaSet(parentPath);
78 protected void onStartLoading() {
79 super.onStartLoading();
80 mMediaSet.addContentListener(mObserver);
81 mSyncTask = mMediaSet.requestSync(sNullListener);
86 protected boolean onCancelLoad() {
87 if (mSyncTask != null) {
91 return super.onCancelLoad();
95 protected void onStopLoading() {
96 super.onStopLoading();
98 mMediaSet.removeContentListener(mObserver);
102 protected void onReset() {
108 public Cursor loadInBackground() {
109 mMediaSet.loadIfDirty();
110 final MatrixCursor cursor = new MatrixCursor(PhotoSetLoader.PROJECTION);
111 final Object[] row = new Object[PhotoSetLoader.PROJECTION.length];
112 final SparseArray<MediaItem> mediaItems = new SparseArray<MediaItem>();
113 mMediaSet.enumerateTotalMediaItems(new ItemConsumer() {
115 public void consume(int index, MediaItem item) {
116 row[PhotoSetLoader.INDEX_ID] = index;
117 row[PhotoSetLoader.INDEX_DATA] = item.getContentUri().toString();
118 row[PhotoSetLoader.INDEX_DATE_ADDED] = item.getDateInMs();
119 row[PhotoSetLoader.INDEX_HEIGHT] = item.getHeight();
120 row[PhotoSetLoader.INDEX_WIDTH] = item.getWidth();
121 row[PhotoSetLoader.INDEX_WIDTH] = item.getWidth();
122 int rawMediaType = item.getMediaType();
123 int mappedMediaType = FileColumns.MEDIA_TYPE_NONE;
124 if (rawMediaType == MediaItem.MEDIA_TYPE_IMAGE) {
125 mappedMediaType = FileColumns.MEDIA_TYPE_IMAGE;
126 } else if (rawMediaType == MediaItem.MEDIA_TYPE_VIDEO) {
127 mappedMediaType = FileColumns.MEDIA_TYPE_VIDEO;
129 row[PhotoSetLoader.INDEX_MEDIA_TYPE] = mappedMediaType;
130 row[PhotoSetLoader.INDEX_SUPPORTED_OPERATIONS] =
131 item.getSupportedOperations();
133 mediaItems.append(index, item);
136 synchronized (mMediaSet) {
137 mMediaItems = mediaItems;
143 public Drawable drawableForItem(Cursor item, Drawable recycle) {
144 BitmapJobDrawable drawable = null;
145 if (recycle == null || !(recycle instanceof BitmapJobDrawable)) {
146 drawable = new BitmapJobDrawable();
148 drawable = (BitmapJobDrawable) recycle;
150 int index = item.getInt(PhotoSetLoader.INDEX_ID);
151 drawable.setMediaItem(mMediaItems.get(index));
155 public static int getThumbnailSize() {
156 return MediaItem.getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL);
160 public Uri uriForItem(Cursor item) {
161 int index = item.getInt(PhotoSetLoader.INDEX_ID);
162 MediaItem mi = mMediaItems.get(index);
163 return mi == null ? null : mi.getContentUri();
167 public ArrayList<Uri> urisForSubItems(Cursor item) {
172 public void deleteItemWithPath(Object path) {
173 MediaObject o = mDataManager.getMediaObject((Path) path);
180 public Object getPathForItem(Cursor item) {
181 int index = item.getInt(PhotoSetLoader.INDEX_ID);
182 MediaItem mi = mMediaItems.get(index);