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.app; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport android.app.Activity; 20604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport android.content.Intent; 21604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport android.graphics.Bitmap; 22604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport android.os.Bundle; 23604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport android.os.Handler; 24604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport android.os.Message; 25604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport android.view.MotionEvent; 26604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen 27915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescuimport com.android.gallery3d.R; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.Utils; 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.ContentListener; 30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaItem; 31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaObject; 32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaSet; 33604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chenimport com.android.gallery3d.data.Path; 34a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.GLCanvas; 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.GLView; 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.SlideshowView; 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.SynchronizedHandler; 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.Future; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.FutureListener; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList; 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.Random; 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class SlideshowPage extends ActivityState { 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "SlideshowPage"; 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static final String KEY_SET_PATH = "media-set-path"; 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static final String KEY_ITEM_PATH = "media-item-path"; 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static final String KEY_PHOTO_INDEX = "photo-index"; 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static final String KEY_RANDOM_ORDER = "random-order"; 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static final String KEY_REPEAT = "repeat"; 52afb3d1d8f341620f6b69d47d52b515f53817aa91Yuli Huang public static final String KEY_DREAM = "dream"; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final long SLIDESHOW_DELAY = 3000; // 3 seconds 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int MSG_LOAD_NEXT_BITMAP = 1; 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int MSG_SHOW_PENDING_BITMAP = 2; 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static interface Model { 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void pause(); 61604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void resume(); 63604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Future<Slide> nextSlide(FutureListener<Slide> listener); 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static class Slide { 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Bitmap bitmap; 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public MediaItem item; 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int index; 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Slide(MediaItem item, int index, Bitmap bitmap) { 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin this.bitmap = bitmap; 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin this.item = item; 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin this.index = index; 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Handler mHandler; 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Model mModel; 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private SlideshowView mSlideshowView; 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Slide mPendingSlide = null; 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mIsActive = false; 85604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen private final Intent mResultIntent = new Intent(); 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 87915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu @Override 88915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu protected int getBackgroundColorId() { 89915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu return R.color.slideshow_background; 90915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu } 91915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu 92604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen private final GLView mRootPane = new GLView() { 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 94604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSlideshowView.layout(0, 0, right - left, bottom - top); 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected boolean onTouch(MotionEvent event) { 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (event.getAction() == MotionEvent.ACTION_UP) { 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin onBackPressed(); 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void renderBackground(GLCanvas canvas) { 108915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu canvas.clearBuffer(getBackgroundColor()); 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }; 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onCreate(Bundle data, Bundle restoreState) { 11445c56f2d34c71d0bc9b84ebeef6d1314738d0fc0Bobby Georgescu super.onCreate(data, restoreState); 115ef132358deba6acbbeaf0a63014c77c98bca1d9aBobby Georgescu mFlags |= (FLAG_HIDE_ACTION_BAR | FLAG_HIDE_STATUS_BAR); 116afb3d1d8f341620f6b69d47d52b515f53817aa91Yuli Huang if (data.getBoolean(KEY_DREAM)) { 117afb3d1d8f341620f6b69d47d52b515f53817aa91Yuli Huang // Dream screensaver only keeps screen on for plugged devices. 1184a10c9782bc397ab3b77e5d7a439a90169484b1aDoris Liu mFlags |= FLAG_SCREEN_ON_WHEN_PLUGGED | FLAG_SHOW_WHEN_LOCKED; 119afb3d1d8f341620f6b69d47d52b515f53817aa91Yuli Huang } else { 120afb3d1d8f341620f6b69d47d52b515f53817aa91Yuli Huang // User-initiated slideshow would always keep screen on. 121afb3d1d8f341620f6b69d47d52b515f53817aa91Yuli Huang mFlags |= FLAG_SCREEN_ON_ALWAYS; 122afb3d1d8f341620f6b69d47d52b515f53817aa91Yuli Huang } 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHandler = new SynchronizedHandler(mActivity.getGLRoot()) { 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void handleMessage(Message message) { 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin switch (message.what) { 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case MSG_SHOW_PENDING_BITMAP: 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin showPendingBitmap(); 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin break; 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin case MSG_LOAD_NEXT_BITMAP: 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin loadNextBitmap(); 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin break; 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin default: throw new AssertionError(); 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }; 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin initializeViews(); 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin initializeData(data); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void loadNextBitmap() { 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mModel.nextSlide(new FutureListener<Slide>() { 1447817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onFutureDone(Future<Slide> future) { 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mPendingSlide = future.get(); 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHandler.sendEmptyMessage(MSG_SHOW_PENDING_BITMAP); 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }); 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void showPendingBitmap() { 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // mPendingBitmap could be null, if 154604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen // 1.) there is no more items 155604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen // 2.) mModel is paused 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Slide slide = mPendingSlide; 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (slide == null) { 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mIsActive) { 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActivity.getStateManager().finishState(SlideshowPage.this); 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return; 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSlideshowView.next(slide.bitmap, slide.item.getRotation()); 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setStateResult(Activity.RESULT_OK, mResultIntent 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .putExtra(KEY_ITEM_PATH, slide.item.getPath().toString()) 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .putExtra(KEY_PHOTO_INDEX, slide.index)); 169604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen mHandler.sendEmptyMessageDelayed(MSG_LOAD_NEXT_BITMAP, SLIDESHOW_DELAY); 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onPause() { 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super.onPause(); 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIsActive = false; 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mModel.pause(); 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSlideshowView.release(); 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHandler.removeMessages(MSG_LOAD_NEXT_BITMAP); 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHandler.removeMessages(MSG_SHOW_PENDING_BITMAP); 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onResume() { 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super.onResume(); 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIsActive = true; 187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mModel.resume(); 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mPendingSlide != null) { 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin showPendingBitmap(); 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin loadNextBitmap(); 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void initializeData(Bundle data) { 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean random = data.getBoolean(KEY_RANDOM_ORDER, false); 19878979fc21d1e1111a504cc07ae6b0e0bc4d61447Chih-Chung Chang 19978979fc21d1e1111a504cc07ae6b0e0bc4d61447Chih-Chung Chang // We only want to show slideshow for images only, not videos. 20078979fc21d1e1111a504cc07ae6b0e0bc4d61447Chih-Chung Chang String mediaPath = data.getString(KEY_SET_PATH); 201604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen mediaPath = FilterUtils.newFilterPath(mediaPath, FilterUtils.FILTER_IMAGE_ONLY); 202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaSet mediaSet = mActivity.getDataManager().getMediaSet(mediaPath); 203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (random) { 205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean repeat = data.getBoolean(KEY_REPEAT); 206604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen mModel = new SlideshowDataAdapter(mActivity, 207604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen new ShuffleSource(mediaSet, repeat), 0, null); 208604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen setStateResult(Activity.RESULT_OK, mResultIntent.putExtra(KEY_PHOTO_INDEX, 0)); 209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int index = data.getInt(KEY_PHOTO_INDEX); 211506200619672fa8221b98d50efbe77c777fae3e9Ray Chen String itemPath = data.getString(KEY_ITEM_PATH); 212506200619672fa8221b98d50efbe77c777fae3e9Ray Chen Path path = itemPath != null ? Path.fromString(itemPath) : null; 213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean repeat = data.getBoolean(KEY_REPEAT); 214604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen mModel = new SlideshowDataAdapter(mActivity, new SequentialSource(mediaSet, repeat), 215604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen index, path); 216604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen setStateResult(Activity.RESULT_OK, mResultIntent.putExtra(KEY_PHOTO_INDEX, index)); 217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void initializeViews() { 221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSlideshowView = new SlideshowView(); 222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRootPane.addComponent(mSlideshowView); 223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setContentPane(mRootPane); 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static MediaItem findMediaItem(MediaSet mediaSet, int index) { 227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0, n = mediaSet.getSubMediaSetCount(); i < n; ++i) { 228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaSet subset = mediaSet.getSubMediaSet(i); 229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int count = subset.getTotalMediaItemCount(); 230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (index < count) { 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return findMediaItem(subset, index); 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin index -= count; 234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ArrayList<MediaItem> list = mediaSet.getMediaItem(index, 1); 236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return list.isEmpty() ? null : list.get(0); 237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class ShuffleSource implements SlideshowDataAdapter.SlideshowSource { 240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int RETRY_COUNT = 5; 241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final MediaSet mMediaSet; 242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final Random mRandom = new Random(); 243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mOrder[] = new int[0]; 244604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen private final boolean mRepeat; 245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long mSourceVersion = MediaSet.INVALID_DATA_VERSION; 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mLastIndex = -1; 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public ShuffleSource(MediaSet mediaSet, boolean repeat) { 249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMediaSet = Utils.checkNotNull(mediaSet); 250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRepeat = repeat; 251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2537817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 254604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen public int findItemIndex(Path path, int hint) { 255604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen return hint; 256604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen } 257604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen 2587817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public MediaItem getMediaItem(int index) { 260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!mRepeat && index >= mOrder.length) return null; 26178979fc21d1e1111a504cc07ae6b0e0bc4d61447Chih-Chung Chang if (mOrder.length == 0) return null; 262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mLastIndex = mOrder[index % mOrder.length]; 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaItem item = findMediaItem(mMediaSet, mLastIndex); 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < RETRY_COUNT && item == null; ++i) { 265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "fail to find image: " + mLastIndex); 266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mLastIndex = mRandom.nextInt(mOrder.length); 267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item = findMediaItem(mMediaSet, mLastIndex); 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return item; 270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2727817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public long reload() { 274705dc819661cb8c8e839a04577b0641bd6caad53John Reck long version = mMediaSet.reload(); 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (version != mSourceVersion) { 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSourceVersion = version; 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int count = mMediaSet.getTotalMediaItemCount(); 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (count != mOrder.length) generateOrderArray(count); 279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 280f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return version; 281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 282f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void generateOrderArray(int totalCount) { 284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mOrder.length != totalCount) { 285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mOrder = new int[totalCount]; 286f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < totalCount; ++i) { 287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mOrder[i] = i; 288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = totalCount - 1; i > 0; --i) { 291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.swap(mOrder, i, mRandom.nextInt(i + 1)); 292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mOrder[0] == mLastIndex && totalCount > 1) { 294f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.swap(mOrder, 0, mRandom.nextInt(totalCount - 1) + 1); 295f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2987817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void addContentListener(ContentListener listener) { 300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMediaSet.addContentListener(listener); 301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3037817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 304f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void removeContentListener(ContentListener listener) { 305f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMediaSet.removeContentListener(listener); 306f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 307f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class SequentialSource implements SlideshowDataAdapter.SlideshowSource { 310f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int DATA_SIZE = 32; 311f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 312f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private ArrayList<MediaItem> mData = new ArrayList<MediaItem>(); 313f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mDataStart = 0; 314f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long mDataVersion = MediaObject.INVALID_DATA_VERSION; 315f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final MediaSet mMediaSet; 316f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final boolean mRepeat; 317f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 318f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public SequentialSource(MediaSet mediaSet, boolean repeat) { 319f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMediaSet = mediaSet; 320f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRepeat = repeat; 321f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 322f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3237817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 324604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen public int findItemIndex(Path path, int hint) { 325604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen return mMediaSet.getIndexOfItem(path, hint); 326604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen } 327604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen 3287817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 329f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public MediaItem getMediaItem(int index) { 330f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int dataEnd = mDataStart + mData.size(); 331f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 332f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mRepeat) { 33378979fc21d1e1111a504cc07ae6b0e0bc4d61447Chih-Chung Chang int count = mMediaSet.getMediaItemCount(); 33478979fc21d1e1111a504cc07ae6b0e0bc4d61447Chih-Chung Chang if (count == 0) return null; 33578979fc21d1e1111a504cc07ae6b0e0bc4d61447Chih-Chung Chang index = index % count; 336f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 337f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (index < mDataStart || index >= dataEnd) { 338f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mData = mMediaSet.getMediaItem(index, DATA_SIZE); 339f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDataStart = index; 340f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin dataEnd = index + mData.size(); 341f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 342f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 343604f053d040782159b61d3b74ee533bc2c0ccdd0Ray Chen return (index < mDataStart || index >= dataEnd) ? null : mData.get(index - mDataStart); 344f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 345f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3467817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 347f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public long reload() { 348705dc819661cb8c8e839a04577b0641bd6caad53John Reck long version = mMediaSet.reload(); 349f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (version != mDataVersion) { 350f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDataVersion = version; 351f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mData.clear(); 352f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 353f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mDataVersion; 354f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3567817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void addContentListener(ContentListener listener) { 358f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMediaSet.addContentListener(listener); 359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 360f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3617817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 362f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void removeContentListener(ContentListener listener) { 363f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMediaSet.removeContentListener(listener); 364f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 365f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 366f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 367