OSDN Git Service

Sharing support for albums, bulk operations infrastructure
[android-x86/packages-apps-Gallery2.git] / src / com / android / photos / shims / MediaItemsLoader.java
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
17 package com.android.photos.shims;
18
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;
27
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;
38
39 import java.util.ArrayList;
40
41 /**
42  * Returns all MediaItems in a MediaSet, wrapping them in a cursor to appear
43  * like a PhotoSetLoader
44  */
45 public class MediaItemsLoader extends AsyncTaskLoader<Cursor> implements LoaderCompatShim<Cursor> {
46
47     private static final SyncListener sNullListener = new SyncListener() {
48         @Override
49         public void onSyncDone(MediaSet mediaSet, int resultCode) {
50         }
51     };
52
53     private final MediaSet mMediaSet;
54     private final DataManager mDataManager;
55     private Future<Integer> mSyncTask = null;
56     private ContentListener mObserver = new ContentListener() {
57         @Override
58         public void onContentDirty() {
59             onContentChanged();
60         }
61     };
62     private SparseArray<MediaItem> mMediaItems;
63
64     public MediaItemsLoader(Context context) {
65         super(context);
66         mDataManager = DataManager.from(context);
67         String path = mDataManager.getTopSetPath(DataManager.INCLUDE_ALL);
68         mMediaSet = mDataManager.getMediaSet(path);
69     }
70
71     public MediaItemsLoader(Context context, String parentPath) {
72         super(context);
73         mDataManager = DataManager.from(getContext());
74         mMediaSet = mDataManager.getMediaSet(parentPath);
75     }
76
77     @Override
78     protected void onStartLoading() {
79         super.onStartLoading();
80         mMediaSet.addContentListener(mObserver);
81         mSyncTask = mMediaSet.requestSync(sNullListener);
82         forceLoad();
83     }
84
85     @Override
86     protected boolean onCancelLoad() {
87         if (mSyncTask != null) {
88             mSyncTask.cancel();
89             mSyncTask = null;
90         }
91         return super.onCancelLoad();
92     }
93
94     @Override
95     protected void onStopLoading() {
96         super.onStopLoading();
97         cancelLoad();
98         mMediaSet.removeContentListener(mObserver);
99     }
100
101     @Override
102     protected void onReset() {
103         super.onReset();
104         onStopLoading();
105     }
106
107     @Override
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() {
114             @Override
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;
128                 }
129                 row[PhotoSetLoader.INDEX_MEDIA_TYPE] = mappedMediaType;
130                 row[PhotoSetLoader.INDEX_SUPPORTED_OPERATIONS] =
131                         item.getSupportedOperations();
132                 cursor.addRow(row);
133                 mediaItems.append(index, item);
134             }
135         });
136         synchronized (mMediaSet) {
137             mMediaItems = mediaItems;
138         }
139         return cursor;
140     }
141
142     @Override
143     public Drawable drawableForItem(Cursor item, Drawable recycle) {
144         BitmapJobDrawable drawable = null;
145         if (recycle == null || !(recycle instanceof BitmapJobDrawable)) {
146             drawable = new BitmapJobDrawable();
147         } else {
148             drawable = (BitmapJobDrawable) recycle;
149         }
150         int index = item.getInt(PhotoSetLoader.INDEX_ID);
151         drawable.setMediaItem(mMediaItems.get(index));
152         return drawable;
153     }
154
155     public static int getThumbnailSize() {
156         return MediaItem.getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL);
157     }
158
159     @Override
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();
164     }
165
166     @Override
167     public ArrayList<Uri> urisForSubItems(Cursor item) {
168         return null;
169     }
170
171     @Override
172     public void deleteItemWithPath(Object path) {
173         MediaObject o = mDataManager.getMediaObject((Path) path);
174         if (o != null) {
175             o.delete();
176         }
177     }
178
179     @Override
180     public Object getPathForItem(Cursor item) {
181         int index = item.getInt(PhotoSetLoader.INDEX_ID);
182         MediaItem mi = mMediaItems.get(index);
183         if (mi != null) {
184             return mi.getPath();
185         }
186         return null;
187     }
188
189 }