/* * Copyright (C) 2010 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.gallery3d.data; import android.content.Context; import android.net.Uri; import com.android.gallery3d.app.GalleryApp; import java.util.ArrayList; import java.util.HashSet; public class ClusterAlbumSet extends MediaSet implements ContentListener { @SuppressWarnings("unused") private static final String TAG = "ClusterAlbumSet"; private GalleryApp mApplication; private MediaSet mBaseSet; private int mKind; private ArrayList mAlbums = new ArrayList(); private boolean mFirstReloadDone; public ClusterAlbumSet(Path path, GalleryApp application, MediaSet baseSet, int kind) { super(path, INVALID_DATA_VERSION); mApplication = application; mBaseSet = baseSet; mKind = kind; baseSet.addContentListener(this); } @Override public MediaSet getSubMediaSet(int index) { return mAlbums.get(index); } @Override public int getSubMediaSetCount() { return mAlbums.size(); } @Override public String getName() { return mBaseSet.getName(); } @Override public long reload() { if (mBaseSet.reload() > mDataVersion) { if (mFirstReloadDone) { updateClustersContents(); } else { updateClusters(); mFirstReloadDone = true; } mDataVersion = nextVersionNumber(); } return mDataVersion; } @Override public void onContentDirty() { notifyContentChanged(); } private void updateClusters() { mAlbums.clear(); Clustering clustering; Context context = mApplication.getAndroidContext(); switch (mKind) { case ClusterSource.CLUSTER_ALBUMSET_TIME: clustering = new TimeClustering(context); break; case ClusterSource.CLUSTER_ALBUMSET_LOCATION: clustering = new LocationClustering(context); break; case ClusterSource.CLUSTER_ALBUMSET_TAG: clustering = new TagClustering(context); break; case ClusterSource.CLUSTER_ALBUMSET_FACE: clustering = new FaceClustering(context); break; default: /* CLUSTER_ALBUMSET_SIZE */ clustering = new SizeClustering(context); break; } clustering.run(mBaseSet); int n = clustering.getNumberOfClusters(); DataManager dataManager = mApplication.getDataManager(); for (int i = 0; i < n; i++) { Path childPath; String childName = clustering.getClusterName(i); if (mKind == ClusterSource.CLUSTER_ALBUMSET_TAG) { childPath = mPath.getChild(Uri.encode(childName)); } else if (mKind == ClusterSource.CLUSTER_ALBUMSET_SIZE) { long minSize = ((SizeClustering) clustering).getMinSize(i); childPath = mPath.getChild(minSize); } else { childPath = mPath.getChild(i); } ClusterAlbum album = (ClusterAlbum) dataManager.peekMediaObject( childPath); if (album == null) { album = new ClusterAlbum(childPath, dataManager, this); } album.setMediaItems(clustering.getCluster(i)); album.setName(childName); album.setCoverMediaItem(clustering.getClusterCover(i)); mAlbums.add(album); } } private void updateClustersContents() { final HashSet existing = new HashSet(); mBaseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() { @Override public void consume(int index, MediaItem item) { existing.add(item.getPath()); } }); int n = mAlbums.size(); // The loop goes backwards because we may remove empty albums from // mAlbums. for (int i = n - 1; i >= 0; i--) { ArrayList oldPaths = mAlbums.get(i).getMediaItems(); ArrayList newPaths = new ArrayList(); int m = oldPaths.size(); for (int j = 0; j < m; j++) { Path p = oldPaths.get(j); if (existing.contains(p)) { newPaths.add(p); } } mAlbums.get(i).setMediaItems(newPaths); if (newPaths.isEmpty()) { mAlbums.remove(i); } } } }