1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.ContentProviderClient;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.ContentUris;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.UriMatcher;
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri;
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.provider.MediaStore;
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
2506c027675948259368a902fd6f8c2ecac5db5167Mangesh Ghiwareimport com.android.gallery3d.app.GalleryActivity;
269819424cbf0c21b50f4fefdd3472f543eec48d18Owen Linimport com.android.gallery3d.app.GalleryApp;
279819424cbf0c21b50f4fefdd3472f543eec48d18Owen Linimport com.android.gallery3d.data.MediaSet.ItemConsumer;
289819424cbf0c21b50f4fefdd3472f543eec48d18Owen Lin
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList;
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.Collections;
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.Comparator;
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linclass LocalSource extends MediaSource {
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final String KEY_BUCKET_ID = "bucketId";
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private GalleryApp mApplication;
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private PathMatcher mMatcher;
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int NO_MATCH = -1;
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private final UriMatcher mUriMatcher = new UriMatcher(NO_MATCH);
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final Comparator<PathId> sIdComparator = new IdComparator();
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_IMAGE_ALBUMSET = 0;
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_VIDEO_ALBUMSET = 1;
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_IMAGE_ALBUM = 2;
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_VIDEO_ALBUM = 3;
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_IMAGE_ITEM = 4;
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_VIDEO_ITEM = 5;
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_ALL_ALBUMSET = 6;
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int LOCAL_ALL_ALBUM = 7;
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "LocalSource";
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private ContentProviderClient mClient;
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public LocalSource(GalleryApp context) {
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super("local");
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mApplication = context;
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher = new PathMatcher();
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/image", LOCAL_IMAGE_ALBUMSET);
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/video", LOCAL_VIDEO_ALBUMSET);
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/all", LOCAL_ALL_ALBUMSET);
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/image/*", LOCAL_IMAGE_ALBUM);
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/video/*", LOCAL_VIDEO_ALBUM);
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/all/*", LOCAL_ALL_ALBUM);
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/image/item/*", LOCAL_IMAGE_ITEM);
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMatcher.add("/local/video/item/*", LOCAL_VIDEO_ITEM);
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mUriMatcher.addURI(MediaStore.AUTHORITY,
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "external/images/media/#", LOCAL_IMAGE_ITEM);
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mUriMatcher.addURI(MediaStore.AUTHORITY,
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "external/video/media/#", LOCAL_VIDEO_ITEM);
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mUriMatcher.addURI(MediaStore.AUTHORITY,
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "external/images/media", LOCAL_IMAGE_ALBUM);
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mUriMatcher.addURI(MediaStore.AUTHORITY,
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "external/video/media", LOCAL_VIDEO_ALBUM);
7884c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen        mUriMatcher.addURI(MediaStore.AUTHORITY,
7984c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen                "external/file", LOCAL_ALL_ALBUM);
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public MediaObject createMediaObject(Path path) {
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        GalleryApp app = mApplication;
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        switch (mMatcher.match(path)) {
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_ALL_ALBUMSET:
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_IMAGE_ALBUMSET:
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_VIDEO_ALBUMSET:
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return new LocalAlbumSet(path, mApplication);
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_IMAGE_ALBUM:
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return new LocalAlbum(path, app, mMatcher.getIntVar(0), true);
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_VIDEO_ALBUM:
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return new LocalAlbum(path, app, mMatcher.getIntVar(0), false);
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_ALL_ALBUM: {
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                int bucketId = mMatcher.getIntVar(0);
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                DataManager dataManager = app.getDataManager();
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                MediaSet imageSet = (MediaSet) dataManager.getMediaObject(
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        LocalAlbumSet.PATH_IMAGE.getChild(bucketId));
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                MediaSet videoSet = (MediaSet) dataManager.getMediaObject(
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        LocalAlbumSet.PATH_VIDEO.getChild(bucketId));
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Comparator<MediaItem> comp = DataManager.sDateTakenComparator;
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return new LocalMergeAlbum(
10384c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen                        path, comp, new MediaSet[] {imageSet, videoSet}, bucketId);
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_IMAGE_ITEM:
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return new LocalImage(path, mApplication, mMatcher.getIntVar(0));
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case LOCAL_VIDEO_ITEM:
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return new LocalVideo(path, mApplication, mMatcher.getIntVar(0));
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            default:
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                throw new RuntimeException("bad path: " + path);
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static int getMediaType(String type, int defaultType) {
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (type == null) return defaultType;
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int value = Integer.parseInt(type);
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if ((value & (MEDIA_TYPE_IMAGE
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    | MEDIA_TYPE_VIDEO)) != 0) return value;
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } catch (NumberFormatException e) {
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.w(TAG, "invalid type: " + type, e);
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return defaultType;
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // The media type bit passed by the intent
12784c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen    private static final int MEDIA_TYPE_ALL = 0;
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int MEDIA_TYPE_IMAGE = 1;
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int MEDIA_TYPE_VIDEO = 4;
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private Path getAlbumPath(Uri uri, int defaultType) {
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int mediaType = getMediaType(
13306c027675948259368a902fd6f8c2ecac5db5167Mangesh Ghiware                uri.getQueryParameter(GalleryActivity.KEY_MEDIA_TYPES),
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                defaultType);
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String bucketId = uri.getQueryParameter(KEY_BUCKET_ID);
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int id = 0;
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            id = Integer.parseInt(bucketId);
139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } catch (NumberFormatException e) {
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.w(TAG, "invalid bucket id: " + bucketId, e);
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return null;
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        switch (mediaType) {
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case MEDIA_TYPE_IMAGE:
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return Path.fromString("/local/image").getChild(id);
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case MEDIA_TYPE_VIDEO:
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return Path.fromString("/local/video").getChild(id);
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            default:
1499819424cbf0c21b50f4fefdd3472f543eec48d18Owen Lin                return Path.fromString("/local/all").getChild(id);
150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
15421a412c93c9b0401b039f4eb86d4950752e5bb84Owen Lin    public Path findPathByUri(Uri uri, String type) {
155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        try {
156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            switch (mUriMatcher.match(uri)) {
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                case LOCAL_IMAGE_ITEM: {
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    long id = ContentUris.parseId(uri);
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return id >= 0 ? LocalImage.ITEM_PATH.getChild(id) : null;
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                case LOCAL_VIDEO_ITEM: {
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    long id = ContentUris.parseId(uri);
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return id >= 0 ? LocalVideo.ITEM_PATH.getChild(id) : null;
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                case LOCAL_IMAGE_ALBUM: {
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return getAlbumPath(uri, MEDIA_TYPE_IMAGE);
167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                case LOCAL_VIDEO_ALBUM: {
169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return getAlbumPath(uri, MEDIA_TYPE_VIDEO);
170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
17184c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen                case LOCAL_ALL_ALBUM: {
17284c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen                    return getAlbumPath(uri, MEDIA_TYPE_ALL);
17384c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen                }
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } catch (NumberFormatException e) {
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Log.w(TAG, "uri: " + uri.toString(), e);
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return null;
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Path getDefaultSetOf(Path item) {
183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MediaObject object = mApplication.getDataManager().getMediaObject(item);
1849819424cbf0c21b50f4fefdd3472f543eec48d18Owen Lin        if (object instanceof LocalMediaItem) {
1859819424cbf0c21b50f4fefdd3472f543eec48d18Owen Lin            return Path.fromString("/local/all").getChild(
1869819424cbf0c21b50f4fefdd3472f543eec48d18Owen Lin                    String.valueOf(((LocalMediaItem) object).getBucketId()));
187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return null;
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void mapMediaItems(ArrayList<PathId> list, ItemConsumer consumer) {
193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        ArrayList<PathId> imageList = new ArrayList<PathId>();
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        ArrayList<PathId> videoList = new ArrayList<PathId>();
195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int n = list.size();
196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        for (int i = 0; i < n; i++) {
197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            PathId pid = list.get(i);
198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // We assume the form is: "/local/{image,video}/item/#"
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // We don't use mMatcher for efficiency's reason.
200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Path parent = pid.path.getParent();
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (parent == LocalImage.ITEM_PATH) {
202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                imageList.add(pid);
203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else if (parent == LocalVideo.ITEM_PATH) {
204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                videoList.add(pid);
205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // TODO: use "files" table so we can merge the two cases.
208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        processMapMediaItems(imageList, consumer, true);
209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        processMapMediaItems(videoList, consumer, false);
210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void processMapMediaItems(ArrayList<PathId> list,
213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            ItemConsumer consumer, boolean isImage) {
214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // Sort path by path id
215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Collections.sort(list, sIdComparator);
216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int n = list.size();
217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        for (int i = 0; i < n; ) {
218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            PathId pid = list.get(i);
219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // Find a range of items.
221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            ArrayList<Integer> ids = new ArrayList<Integer>();
222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int startId = Integer.parseInt(pid.path.getSuffix());
223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            ids.add(startId);
224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int j;
226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            for (j = i + 1; j < n; j++) {
227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                PathId pid2 = list.get(j);
228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                int curId = Integer.parseInt(pid2.path.getSuffix());
229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (curId - startId >= MediaSet.MEDIAITEM_BATCH_FETCH_COUNT) {
230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    break;
231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                ids.add(curId);
233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaItem[] items = LocalAlbum.getMediaItemById(
236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mApplication, isImage, ids);
237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            for(int k = i ; k < j; k++) {
238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                PathId pid2 = list.get(k);
239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                consumer.consume(pid2.id, items[k - i]);
240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            i = j;
243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // This is a comparator which compares the suffix number in two Paths.
247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static class IdComparator implements Comparator<PathId> {
2487817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        @Override
249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public int compare(PathId p1, PathId p2) {
250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            String s1 = p1.path.getSuffix();
251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            String s2 = p2.path.getSuffix();
252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int len1 = s1.length();
253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int len2 = s2.length();
254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (len1 < len2) {
255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return -1;
256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else if (len1 > len2) {
257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return 1;
258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return s1.compareTo(s2);
260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void resume() {
266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mClient = mApplication.getContentResolver()
267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                .acquireContentProviderClient(MediaStore.AUTHORITY);
268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void pause() {
272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mClient.release();
273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mClient = null;
274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
276