1/* 2 * Copyright (C) 2011 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.gallery3d.gadget; 18 19import android.graphics.Bitmap; 20import android.net.Uri; 21import android.os.Binder; 22 23import com.android.gallery3d.common.Utils; 24import com.android.gallery3d.data.ContentListener; 25import com.android.gallery3d.data.MediaItem; 26import com.android.gallery3d.data.MediaObject; 27import com.android.gallery3d.data.MediaSet; 28 29import java.util.ArrayList; 30import java.util.Arrays; 31 32public class MediaSetSource implements WidgetSource, ContentListener { 33 private static final int CACHE_SIZE = 32; 34 35 @SuppressWarnings("unused") 36 private static final String TAG = "MediaSetSource"; 37 38 private MediaSet mSource; 39 private MediaItem mCache[] = new MediaItem[CACHE_SIZE]; 40 private int mCacheStart; 41 private int mCacheEnd; 42 private long mSourceVersion = MediaObject.INVALID_DATA_VERSION; 43 44 private ContentListener mContentListener; 45 46 public MediaSetSource(MediaSet source) { 47 mSource = Utils.checkNotNull(source); 48 mSource.addContentListener(this); 49 } 50 51 @Override 52 public void close() { 53 mSource.removeContentListener(this); 54 } 55 56 private void ensureCacheRange(int index) { 57 if (index >= mCacheStart && index < mCacheEnd) return; 58 59 long token = Binder.clearCallingIdentity(); 60 try { 61 mCacheStart = index; 62 ArrayList<MediaItem> items = mSource.getMediaItem(mCacheStart, CACHE_SIZE); 63 mCacheEnd = mCacheStart + items.size(); 64 items.toArray(mCache); 65 } finally { 66 Binder.restoreCallingIdentity(token); 67 } 68 } 69 70 @Override 71 public synchronized Uri getContentUri(int index) { 72 ensureCacheRange(index); 73 if (index < mCacheStart || index >= mCacheEnd) return null; 74 return mCache[index - mCacheStart].getContentUri(); 75 } 76 77 @Override 78 public synchronized Bitmap getImage(int index) { 79 ensureCacheRange(index); 80 if (index < mCacheStart || index >= mCacheEnd) return null; 81 return WidgetUtils.createWidgetBitmap(mCache[index - mCacheStart]); 82 } 83 84 @Override 85 public void reload() { 86 long version = mSource.reload(); 87 if (mSourceVersion != version) { 88 mSourceVersion = version; 89 mCacheStart = 0; 90 mCacheEnd = 0; 91 Arrays.fill(mCache, null); 92 } 93 } 94 95 @Override 96 public void setContentListener(ContentListener listener) { 97 mContentListener = listener; 98 } 99 100 @Override 101 public int size() { 102 long token = Binder.clearCallingIdentity(); 103 try { 104 return mSource.getMediaItemCount(); 105 } finally { 106 Binder.restoreCallingIdentity(token); 107 } 108 } 109 110 @Override 111 public void onContentDirty() { 112 if (mContentListener != null) mContentListener.onContentDirty(); 113 } 114} 115