Home | History | Annotate | Download | only in data
      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 
     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
     45     public MediaSet getSubMediaSet(int index) {
     46         return mAlbums.get(index);
     47     }
     48 
     49     @Override
     50     public int getSubMediaSetCount() {
     51         return mAlbums.size();
     52     }
     53 
     54     @Override
     55     public String getName() {
     56         return mBaseSet.getName();
     57     }
     58 
     59     @Override
     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 
     73     public void onContentDirty() {
     74         notifyContentChanged();
     75     }
     76 
     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             album.setCoverMediaItem(clustering.getClusterCover(i));
    121             mAlbums.add(album);
    122         }
    123     }
    124 
    125     private void updateClustersContents() {
    126         final HashSet<Path> existing = new HashSet<Path>();
    127         mBaseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
    128             public void consume(int index, MediaItem item) {
    129                 existing.add(item.getPath());
    130             }
    131         });
    132 
    133         int n = mAlbums.size();
    134 
    135         // The loop goes backwards because we may remove empty albums from
    136         // mAlbums.
    137         for (int i = n - 1; i >= 0; i--) {
    138             ArrayList<Path> oldPaths = mAlbums.get(i).getMediaItems();
    139             ArrayList<Path> newPaths = new ArrayList<Path>();
    140             int m = oldPaths.size();
    141             for (int j = 0; j < m; j++) {
    142                 Path p = oldPaths.get(j);
    143                 if (existing.contains(p)) {
    144                     newPaths.add(p);
    145                 }
    146             }
    147             mAlbums.get(i).setMediaItems(newPaths);
    148             if (newPaths.isEmpty()) {
    149                 mAlbums.remove(i);
    150             }
    151         }
    152     }
    153 }
    154