OSDN Git Service

Sharing support for albums, bulk operations infrastructure
[android-x86/packages-apps-Gallery2.git] / src / com / android / photos / shims / MediaSetLoader.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
26 import com.android.gallery3d.data.ContentListener;
27 import com.android.gallery3d.data.DataManager;
28 import com.android.gallery3d.data.MediaItem;
29 import com.android.gallery3d.data.MediaObject;
30 import com.android.gallery3d.data.MediaSet;
31 import com.android.gallery3d.data.Path;
32 import com.android.gallery3d.data.MediaSet.SyncListener;
33 import com.android.gallery3d.util.Future;
34 import com.android.photos.data.AlbumSetLoader;
35
36 import java.util.ArrayList;
37
38 /**
39  * Returns all MediaSets in a MediaSet, wrapping them in a cursor to appear
40  * like a AlbumSetLoader.
41  */
42 public class MediaSetLoader extends AsyncTaskLoader<Cursor> implements LoaderCompatShim<Cursor>{
43
44     private static final SyncListener sNullListener = new SyncListener() {
45         @Override
46         public void onSyncDone(MediaSet mediaSet, int resultCode) {
47         }
48     };
49
50     private final MediaSet mMediaSet;
51     private final DataManager mDataManager;
52     private Future<Integer> mSyncTask = null;
53     private ContentListener mObserver = new ContentListener() {
54         @Override
55         public void onContentDirty() {
56             onContentChanged();
57         }
58     };
59
60     private ArrayList<MediaItem> mCoverItems;
61
62     public MediaSetLoader(Context context) {
63         super(context);
64         mDataManager = DataManager.from(context);
65         String path = mDataManager.getTopSetPath(DataManager.INCLUDE_ALL);
66         mMediaSet = mDataManager.getMediaSet(path);
67     }
68
69     public MediaSetLoader(Context context, String path) {
70         super(context);
71         mDataManager = DataManager.from(getContext());
72         mMediaSet = mDataManager.getMediaSet(path);
73     }
74
75     @Override
76     protected void onStartLoading() {
77         super.onStartLoading();
78         mMediaSet.addContentListener(mObserver);
79         mSyncTask = mMediaSet.requestSync(sNullListener);
80         forceLoad();
81     }
82
83     @Override
84     protected boolean onCancelLoad() {
85         if (mSyncTask != null) {
86             mSyncTask.cancel();
87             mSyncTask = null;
88         }
89         return super.onCancelLoad();
90     }
91
92     @Override
93     protected void onStopLoading() {
94         super.onStopLoading();
95         cancelLoad();
96         mMediaSet.removeContentListener(mObserver);
97     }
98
99     @Override
100     protected void onReset() {
101         super.onReset();
102         onStopLoading();
103     }
104
105     @Override
106     public Cursor loadInBackground() {
107         mMediaSet.loadIfDirty();
108         final MatrixCursor cursor = new MatrixCursor(AlbumSetLoader.PROJECTION);
109         final Object[] row = new Object[AlbumSetLoader.PROJECTION.length];
110         int count = mMediaSet.getSubMediaSetCount();
111         ArrayList<MediaItem> coverItems = new ArrayList<MediaItem>(count);
112         for (int i = 0; i < count; i++) {
113             MediaSet m = mMediaSet.getSubMediaSet(i);
114             m.loadIfDirty();
115             row[AlbumSetLoader.INDEX_ID] = i;
116             row[AlbumSetLoader.INDEX_TITLE] = m.getName();
117             row[AlbumSetLoader.INDEX_COUNT] = m.getMediaItemCount();
118             row[AlbumSetLoader.INDEX_SUPPORTED_OPERATIONS] = m.getSupportedOperations();
119             MediaItem coverItem = m.getCoverMediaItem();
120             if (coverItem != null) {
121                 row[AlbumSetLoader.INDEX_TIMESTAMP] = coverItem.getDateInMs();
122             }
123             coverItems.add(coverItem);
124             cursor.addRow(row);
125         }
126         synchronized (mMediaSet) {
127             mCoverItems = coverItems;
128         }
129         return cursor;
130     }
131
132     @Override
133     public Drawable drawableForItem(Cursor item, Drawable recycle) {
134         BitmapJobDrawable drawable = null;
135         if (recycle == null || !(recycle instanceof BitmapJobDrawable)) {
136             drawable = new BitmapJobDrawable();
137         } else {
138             drawable = (BitmapJobDrawable) recycle;
139         }
140         int index = item.getInt(AlbumSetLoader.INDEX_ID);
141         drawable.setMediaItem(mCoverItems.get(index));
142         return drawable;
143     }
144
145     public static int getThumbnailSize() {
146         return MediaItem.getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL);
147     }
148
149     @Override
150     public Uri uriForItem(Cursor item) {
151         int index = item.getInt(AlbumSetLoader.INDEX_ID);
152         MediaSet ms = mMediaSet.getSubMediaSet(index);
153         return ms == null ? null : ms.getContentUri();
154     }
155
156     @Override
157     public ArrayList<Uri> urisForSubItems(Cursor item) {
158         int index = item.getInt(AlbumSetLoader.INDEX_ID);
159         MediaSet ms = mMediaSet.getSubMediaSet(index);
160         if (ms == null) return null;
161         final ArrayList<Uri> result = new ArrayList<Uri>();
162         ms.enumerateMediaItems(new MediaSet.ItemConsumer() {
163             @Override
164             public void consume(int index, MediaItem item) {
165                 if (item != null) {
166                     result.add(item.getContentUri());
167                 }
168             }
169         });
170         return result;
171     }
172
173     @Override
174     public void deleteItemWithPath(Object path) {
175         MediaObject o = mDataManager.getMediaObject((Path) path);
176         if (o != null) {
177             o.delete();
178         }
179     }
180
181     @Override
182     public Object getPathForItem(Cursor item) {
183         int index = item.getInt(AlbumSetLoader.INDEX_ID);
184         MediaSet ms = mMediaSet.getSubMediaSet(index);
185         if (ms != null) {
186             return ms.getPath();
187         }
188         return null;
189     }
190 }