• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.gallery3d.data;
18 
19 import com.android.gallery3d.app.GalleryApp;
20 
21 import android.content.Context;
22 import android.net.Uri;
23 
24 import java.util.ArrayList;
25 import java.util.HashSet;
26 
27 public class ClusterAlbumSet extends MediaSet implements ContentListener {
28     private static final String TAG = "ClusterAlbumSet";
29     private GalleryApp mApplication;
30     private MediaSet mBaseSet;
31     private int mKind;
32     private ArrayList<ClusterAlbum> mAlbums = new ArrayList<ClusterAlbum>();
33     private boolean mFirstReloadDone;
34 
ClusterAlbumSet(Path path, GalleryApp application, MediaSet baseSet, int kind)35     public ClusterAlbumSet(Path path, GalleryApp application,
36             MediaSet baseSet, int kind) {
37         super(path, INVALID_DATA_VERSION);
38         mApplication = application;
39         mBaseSet = baseSet;
40         mKind = kind;
41         baseSet.addContentListener(this);
42     }
43 
44     @Override
getSubMediaSet(int index)45     public MediaSet getSubMediaSet(int index) {
46         return mAlbums.get(index);
47     }
48 
49     @Override
getSubMediaSetCount()50     public int getSubMediaSetCount() {
51         return mAlbums.size();
52     }
53 
54     @Override
getName()55     public String getName() {
56         return mBaseSet.getName();
57     }
58 
59     @Override
reload()60     public long reload() {
61         if (mBaseSet.reload() > mDataVersion) {
62             if (mFirstReloadDone) {
63                 updateClustersContents();
64             } else {
65                 updateClusters();
66                 mFirstReloadDone = true;
67             }
68             mDataVersion = nextVersionNumber();
69         }
70         return mDataVersion;
71     }
72 
onContentDirty()73     public void onContentDirty() {
74         notifyContentChanged();
75     }
76 
updateClusters()77     private void updateClusters() {
78         mAlbums.clear();
79         Clustering clustering;
80         Context context = mApplication.getAndroidContext();
81         switch (mKind) {
82             case ClusterSource.CLUSTER_ALBUMSET_TIME:
83                 clustering = new TimeClustering(context);
84                 break;
85             case ClusterSource.CLUSTER_ALBUMSET_LOCATION:
86                 clustering = new LocationClustering(context);
87                 break;
88             case ClusterSource.CLUSTER_ALBUMSET_TAG:
89                 clustering = new TagClustering(context);
90                 break;
91             case ClusterSource.CLUSTER_ALBUMSET_FACE:
92                 clustering = new FaceClustering(context);
93                 break;
94             default: /* CLUSTER_ALBUMSET_SIZE */
95                 clustering = new SizeClustering(context);
96                 break;
97         }
98 
99         clustering.run(mBaseSet);
100         int n = clustering.getNumberOfClusters();
101         DataManager dataManager = mApplication.getDataManager();
102         for (int i = 0; i < n; i++) {
103             Path childPath;
104             String childName = clustering.getClusterName(i);
105             if (mKind == ClusterSource.CLUSTER_ALBUMSET_TAG) {
106                 childPath = mPath.getChild(Uri.encode(childName));
107             } else if (mKind == ClusterSource.CLUSTER_ALBUMSET_SIZE) {
108                 long minSize = ((SizeClustering) clustering).getMinSize(i);
109                 childPath = mPath.getChild(minSize);
110             } else {
111                 childPath = mPath.getChild(i);
112             }
113             ClusterAlbum album = (ClusterAlbum) dataManager.peekMediaObject(
114                         childPath);
115             if (album == null) {
116                 album = new ClusterAlbum(childPath, dataManager, this);
117             }
118             album.setMediaItems(clustering.getCluster(i));
119             album.setName(childName);
120             mAlbums.add(album);
121         }
122     }
123 
updateClustersContents()124     private void updateClustersContents() {
125         final HashSet<Path> existing = new HashSet<Path>();
126         mBaseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
127             public void consume(int index, MediaItem item) {
128                 existing.add(item.getPath());
129             }
130         });
131 
132         int n = mAlbums.size();
133 
134         // The loop goes backwards because we may remove empty albums from
135         // mAlbums.
136         for (int i = n - 1; i >= 0; i--) {
137             ArrayList<Path> oldPaths = mAlbums.get(i).getMediaItems();
138             ArrayList<Path> newPaths = new ArrayList<Path>();
139             int m = oldPaths.size();
140             for (int j = 0; j < m; j++) {
141                 Path p = oldPaths.get(j);
142                 if (existing.contains(p)) {
143                     newPaths.add(p);
144                 }
145             }
146             mAlbums.get(i).setMediaItems(newPaths);
147             if (newPaths.isEmpty()) {
148                 mAlbums.remove(i);
149             }
150         }
151     }
152 }
153