1/*
2 * Copyright (C) 2009 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
17package com.android.camera.gallery;
18
19import android.content.ContentResolver;
20import android.database.Cursor;
21import android.net.Uri;
22import android.provider.MediaStore.Images.Media;
23
24import java.util.HashMap;
25
26/**
27 * Represents an ordered collection of Image objects. Provides an API to add
28 * and remove an image.
29 */
30public class ImageList extends BaseImageList implements IImageList {
31
32    @SuppressWarnings("unused")
33    private static final String TAG = "ImageList";
34
35    private static final String[] ACCEPTABLE_IMAGE_TYPES =
36            new String[] { "image/jpeg", "image/png", "image/gif" };
37
38    public HashMap<String, String> getBucketIds() {
39        Uri uri = mBaseUri.buildUpon()
40                .appendQueryParameter("distinct", "true").build();
41        Cursor cursor = Media.query(
42                mContentResolver, uri,
43                new String[] {
44                    Media.BUCKET_DISPLAY_NAME,
45                    Media.BUCKET_ID},
46                whereClause(), whereClauseArgs(), null);
47        try {
48            HashMap<String, String> hash = new HashMap<String, String>();
49            while (cursor.moveToNext()) {
50                hash.put(cursor.getString(1), cursor.getString(0));
51            }
52            return hash;
53        } finally {
54            cursor.close();
55        }
56    }
57
58    /**
59     * ImageList constructor.
60     */
61    public ImageList(ContentResolver resolver, Uri imageUri,
62            int sort, String bucketId) {
63        super(resolver, imageUri, sort, bucketId);
64    }
65
66    private static final String WHERE_CLAUSE =
67            "(" + Media.MIME_TYPE + " in (?, ?, ?))";
68    private static final String WHERE_CLAUSE_WITH_BUCKET_ID =
69            WHERE_CLAUSE + " AND " + Media.BUCKET_ID + " = ?";
70
71    protected String whereClause() {
72        return mBucketId == null ? WHERE_CLAUSE : WHERE_CLAUSE_WITH_BUCKET_ID;
73    }
74
75    protected String[] whereClauseArgs() {
76        // TODO: Since mBucketId won't change, we should keep the array.
77        if (mBucketId != null) {
78            int count = ACCEPTABLE_IMAGE_TYPES.length;
79            String[] result = new String[count + 1];
80            System.arraycopy(ACCEPTABLE_IMAGE_TYPES, 0, result, 0, count);
81            result[count] = mBucketId;
82            return result;
83        }
84        return ACCEPTABLE_IMAGE_TYPES;
85    }
86
87    @Override
88    protected Cursor createCursor() {
89        Cursor c = Media.query(
90                mContentResolver, mBaseUri, IMAGE_PROJECTION,
91                whereClause(), whereClauseArgs(), sortOrder());
92        return c;
93    }
94
95    static final String[] IMAGE_PROJECTION = new String[] {
96            Media._ID,
97            Media.DATA,
98            Media.DATE_TAKEN,
99            Media.MINI_THUMB_MAGIC,
100            Media.ORIENTATION,
101            Media.TITLE,
102            Media.MIME_TYPE,
103            Media.DATE_MODIFIED};
104
105    private static final int INDEX_ID = 0;
106    private static final int INDEX_DATA_PATH = 1;
107    private static final int INDEX_DATE_TAKEN = 2;
108    private static final int INDEX_MINI_THUMB_MAGIC = 3;
109    private static final int INDEX_ORIENTATION = 4;
110    private static final int INDEX_TITLE = 5;
111    private static final int INDEX_MIME_TYPE = 6;
112    private static final int INDEX_DATE_MODIFIED = 7;
113
114    @Override
115    protected long getImageId(Cursor cursor) {
116        return cursor.getLong(INDEX_ID);
117    }
118
119    @Override
120    protected BaseImage loadImageFromCursor(Cursor cursor) {
121        long id = cursor.getLong(INDEX_ID);
122        String dataPath = cursor.getString(INDEX_DATA_PATH);
123        long dateTaken = cursor.getLong(INDEX_DATE_TAKEN);
124        if (dateTaken == 0) {
125            dateTaken = cursor.getLong(INDEX_DATE_MODIFIED) * 1000;
126        }
127        long miniThumbMagic = cursor.getLong(INDEX_MINI_THUMB_MAGIC);
128        int orientation = cursor.getInt(INDEX_ORIENTATION);
129        String title = cursor.getString(INDEX_TITLE);
130        String mimeType = cursor.getString(INDEX_MIME_TYPE);
131        if (title == null || title.length() == 0) {
132            title = dataPath;
133        }
134        return new Image(this, mContentResolver, id, cursor.getPosition(),
135                contentUri(id), dataPath, mimeType, dateTaken, title,
136                orientation);
137    }
138}
139