2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.gallery3d.app;
19 import android.app.Activity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.graphics.Rect;
23 import android.net.Uri;
24 import android.os.Bundle;
25 import android.os.Handler;
26 import android.os.Message;
27 import android.os.Vibrator;
28 import android.provider.MediaStore;
29 import android.view.Menu;
30 import android.view.MenuInflater;
31 import android.view.MenuItem;
32 import android.widget.Toast;
34 import com.android.gallery3d.R;
35 import com.android.gallery3d.common.Utils;
36 import com.android.gallery3d.data.DataManager;
37 import com.android.gallery3d.data.MediaDetails;
38 import com.android.gallery3d.data.MediaItem;
39 import com.android.gallery3d.data.MediaObject;
40 import com.android.gallery3d.data.MediaSet;
41 import com.android.gallery3d.data.MtpDevice;
42 import com.android.gallery3d.data.Path;
43 import com.android.gallery3d.ui.ActionModeHandler;
44 import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
45 import com.android.gallery3d.ui.AlbumSlotRenderer;
46 import com.android.gallery3d.ui.DetailsHelper;
47 import com.android.gallery3d.ui.DetailsHelper.CloseListener;
48 import com.android.gallery3d.ui.FadeTexture;
49 import com.android.gallery3d.ui.GLCanvas;
50 import com.android.gallery3d.ui.GLRoot;
51 import com.android.gallery3d.ui.GLView;
52 import com.android.gallery3d.ui.PhotoFallbackEffect;
53 import com.android.gallery3d.ui.RelativePosition;
54 import com.android.gallery3d.ui.SelectionManager;
55 import com.android.gallery3d.ui.SlotView;
56 import com.android.gallery3d.ui.SynchronizedHandler;
57 import com.android.gallery3d.util.Future;
58 import com.android.gallery3d.util.GalleryUtils;
59 import com.android.gallery3d.util.MediaSetUtils;
61 public class AlbumPage extends ActivityState implements GalleryActionBar.ClusterRunner,
62 SelectionManager.SelectionListener, MediaSet.SyncListener, GalleryActionBar.OnAlbumModeSelectedListener {
63 @SuppressWarnings("unused")
64 private static final String TAG = "AlbumPage";
66 public static final String KEY_MEDIA_PATH = "media-path";
67 public static final String KEY_PARENT_MEDIA_PATH = "parent-media-path";
68 public static final String KEY_SET_CENTER = "set-center";
69 public static final String KEY_AUTO_SELECT_ALL = "auto-select-all";
70 public static final String KEY_SHOW_CLUSTER_MENU = "cluster-menu";
71 public static final String KEY_EMPTY_ALBUM = "empty-album";
72 public static final String KEY_RESUME_ANIMATION = "resume_animation";
74 private static final int REQUEST_SLIDESHOW = 1;
75 public static final int REQUEST_PHOTO = 2;
76 private static final int REQUEST_DO_ANIMATION = 3;
78 private static final int BIT_LOADING_RELOAD = 1;
79 private static final int BIT_LOADING_SYNC = 2;
81 private static final float USER_DISTANCE_METER = 0.3f;
83 private boolean mIsActive = false;
84 private AlbumSlotRenderer mAlbumView;
85 private Path mMediaSetPath;
86 private String mParentMediaSetString;
87 private SlotView mSlotView;
89 private AlbumDataLoader mAlbumDataAdapter;
91 protected SelectionManager mSelectionManager;
92 private Vibrator mVibrator;
94 private boolean mGetContent;
95 private boolean mShowClusterMenu;
97 private ActionModeHandler mActionModeHandler;
98 private int mFocusIndex = 0;
99 private DetailsHelper mDetailsHelper;
100 private MyDetailsSource mDetailsSource;
101 private MediaSet mMediaSet;
102 private boolean mShowDetails;
103 private float mUserDistance; // in pixel
104 private Future<Integer> mSyncTask = null;
105 private boolean mLaunchedFromPhotoPage;
106 private boolean mInCameraApp;
107 private boolean mInCameraAndWantQuitOnPause;
109 private int mLoadingBits = 0;
110 private boolean mInitialSynced = false;
111 private RelativePosition mOpenCenter = new RelativePosition();
113 private Handler mHandler;
114 private static final int MSG_PICK_PHOTO = 0;
116 private PhotoFallbackEffect mResumeEffect;
117 private PhotoFallbackEffect.PositionProvider mPositionProvider =
118 new PhotoFallbackEffect.PositionProvider() {
120 public Rect getPosition(int index) {
121 Rect rect = mSlotView.getSlotRect(index);
122 Rect bounds = mSlotView.bounds();
123 rect.offset(bounds.left - mSlotView.getScrollX(),
124 bounds.top - mSlotView.getScrollY());
129 public int getItemIndex(Path path) {
130 int start = mSlotView.getVisibleStart();
131 int end = mSlotView.getVisibleEnd();
132 for (int i = start; i < end; ++i) {
133 MediaItem item = mAlbumDataAdapter.get(i);
134 if (item != null && item.getPath() == path) return i;
141 protected int getBackgroundColorId() {
142 return R.color.album_background;
145 private final GLView mRootPane = new GLView() {
146 private final float mMatrix[] = new float[16];
149 protected void onLayout(
150 boolean changed, int left, int top, int right, int bottom) {
152 int slotViewTop = mActivity.getGalleryActionBar().getHeight();
153 int slotViewBottom = bottom - top;
154 int slotViewRight = right - left;
157 mDetailsHelper.layout(left, slotViewTop, right, bottom);
159 mAlbumView.setHighlightItemPath(null);
162 // Set the mSlotView as a reference point to the open animation
163 mOpenCenter.setReferencePosition(0, slotViewTop);
164 mSlotView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
165 GalleryUtils.setViewPointMatrix(mMatrix,
166 (right - left) / 2, (bottom - top) / 2, -mUserDistance);
170 protected void render(GLCanvas canvas) {
171 canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
172 canvas.multiplyMatrix(mMatrix, 0);
173 super.render(canvas);
175 if (mResumeEffect != null) {
176 boolean more = mResumeEffect.draw(canvas);
178 mResumeEffect = null;
179 mAlbumView.setSlotFilter(null);
181 // We want to render one more time even when no more effect
182 // required. So that the animated thumbnails could be draw
183 // with declarations in super.render().
190 // This are the transitions we want:
192 // +--------+ +------------+ +-------+ +----------+
193 // | Camera |---------->| Fullscreen |--->| Album |--->| AlbumSet |
194 // | View | thumbnail | Photo | up | Page | up | Page |
195 // +--------+ +------------+ +-------+ +----------+
198 // +----------back--------+ +----back----+ +--back-> app
201 protected void onBackPressed() {
204 } else if (mSelectionManager.inSelectionMode()) {
205 mSelectionManager.leaveSelectionMode();
207 if(mLaunchedFromPhotoPage) {
208 mActivity.getTransitionStore().putIfNotPresent(
209 PhotoPage.KEY_ALBUMPAGE_TRANSITION,
210 PhotoPage.MSG_ALBUMPAGE_RESUMED);
212 // TODO: fix this regression
213 // mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
215 super.onBackPressed();
222 private void onUpPressed() {
224 GalleryUtils.startGalleryActivity(mActivity);
225 } else if (mActivity.getStateManager().getStateCount() > 1) {
226 super.onBackPressed();
227 } else if (mParentMediaSetString != null) {
228 Bundle data = new Bundle(getData());
229 data.putString(AlbumSetPage.KEY_MEDIA_PATH, mParentMediaSetString);
230 mActivity.getStateManager().switchState(
231 this, AlbumSetPage.class, data);
235 private void onDown(int index) {
236 mAlbumView.setPressedIndex(index);
239 private void onUp(boolean followedByLongPress) {
240 if (followedByLongPress) {
241 // Avoid showing press-up animations for long-press.
242 mAlbumView.setPressedIndex(-1);
244 mAlbumView.setPressedUp();
248 private void onSingleTapUp(int slotIndex) {
249 if (!mIsActive) return;
251 if (mSelectionManager.inSelectionMode()) {
252 MediaItem item = mAlbumDataAdapter.get(slotIndex);
253 if (item == null) return; // Item not ready yet, ignore the click
254 mSelectionManager.toggle(item.getPath());
255 mSlotView.invalidate();
257 // Render transition in pressed state
258 mAlbumView.setPressedIndex(slotIndex);
259 mAlbumView.setPressedUp();
260 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_PHOTO, slotIndex, 0),
261 FadeTexture.DURATION);
265 private void pickPhoto(int slotIndex) {
266 pickPhoto(slotIndex, false);
269 private void pickPhoto(int slotIndex, boolean startInFilmstrip) {
270 if (!mIsActive) return;
272 if (!startInFilmstrip) {
273 // Launch photos in lights out mode
274 mActivity.getGLRoot().setLightsOutMode(true);
277 MediaItem item = mAlbumDataAdapter.get(slotIndex);
278 if (item == null) return; // Item not ready yet, ignore the click
281 } else if (mLaunchedFromPhotoPage) {
282 TransitionStore transitions = mActivity.getTransitionStore();
284 PhotoPage.KEY_ALBUMPAGE_TRANSITION,
285 PhotoPage.MSG_ALBUMPAGE_PICKED);
286 transitions.put(PhotoPage.KEY_INDEX_HINT, slotIndex);
289 // Get into the PhotoPage.
290 // mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
291 Bundle data = new Bundle();
292 data.putInt(PhotoPage.KEY_INDEX_HINT, slotIndex);
293 data.putParcelable(PhotoPage.KEY_OPEN_ANIMATION_RECT,
294 mSlotView.getSlotRect(slotIndex, mRootPane));
295 data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
296 mMediaSetPath.toString());
297 data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH,
298 item.getPath().toString());
299 data.putInt(PhotoPage.KEY_ALBUMPAGE_TRANSITION,
300 PhotoPage.MSG_ALBUMPAGE_STARTED);
301 data.putBoolean(PhotoPage.KEY_START_IN_FILMSTRIP,
303 data.putBoolean(PhotoPage.KEY_IN_CAMERA_ROLL, mMediaSet.isCameraRoll());
304 if (startInFilmstrip) {
305 mActivity.getStateManager().switchState(this, PhotoPage.class, data);
307 mActivity.getStateManager().startStateForResult(
308 PhotoPage.class, REQUEST_PHOTO, data);
313 private void onGetContent(final MediaItem item) {
314 DataManager dm = mActivity.getDataManager();
315 Activity activity = mActivity;
316 if (mData.getString(Gallery.EXTRA_CROP) != null) {
317 // TODO: Handle MtpImagew
318 Uri uri = dm.getContentUri(item.getPath());
319 Intent intent = new Intent(CropImage.ACTION_CROP, uri)
320 .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
321 .putExtras(getData());
322 if (mData.getParcelable(MediaStore.EXTRA_OUTPUT) == null) {
323 intent.putExtra(CropImage.KEY_RETURN_DATA, true);
325 activity.startActivity(intent);
328 Intent intent = new Intent(null, item.getContentUri())
329 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
330 activity.setResult(Activity.RESULT_OK, intent);
335 public void onLongTap(int slotIndex) {
336 if (mGetContent) return;
337 MediaItem item = mAlbumDataAdapter.get(slotIndex);
338 if (item == null) return;
339 mSelectionManager.setAutoLeaveSelectionMode(true);
340 mSelectionManager.toggle(item.getPath());
341 mSlotView.invalidate();
345 public void doCluster(int clusterType) {
346 String basePath = mMediaSet.getPath().toString();
347 String newPath = FilterUtils.newClusterPath(basePath, clusterType);
348 Bundle data = new Bundle(getData());
349 data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
350 if (mShowClusterMenu) {
351 Context context = mActivity.getAndroidContext();
352 data.putString(AlbumSetPage.KEY_SET_TITLE, mMediaSet.getName());
353 data.putString(AlbumSetPage.KEY_SET_SUBTITLE,
354 GalleryActionBar.getClusterByTypeString(context, clusterType));
357 // mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
358 mActivity.getStateManager().startStateForResult(
359 AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
363 protected void onCreate(Bundle data, Bundle restoreState) {
364 super.onCreate(data, restoreState);
365 mUserDistance = GalleryUtils.meterToPixel(USER_DISTANCE_METER);
367 initializeData(data);
368 mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
369 mShowClusterMenu = data.getBoolean(KEY_SHOW_CLUSTER_MENU, false);
370 mDetailsSource = new MyDetailsSource();
371 Context context = mActivity.getAndroidContext();
372 mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
374 // Enable auto-select-all for mtp album
375 if (data.getBoolean(KEY_AUTO_SELECT_ALL)) {
376 mSelectionManager.selectAll();
379 mLaunchedFromPhotoPage =
380 mActivity.getStateManager().hasStateClass(PhotoPage.class);
381 mInCameraApp = data.getBoolean(PhotoPage.KEY_APP_BRIDGE, false);
383 mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
385 public void handleMessage(Message message) {
386 switch (message.what) {
387 case MSG_PICK_PHOTO: {
388 pickPhoto(message.arg1);
392 throw new AssertionError(message.what);
399 protected void onResume() {
403 mResumeEffect = mActivity.getTransitionStore().get(KEY_RESUME_ANIMATION);
404 if (mResumeEffect != null) {
405 mAlbumView.setSlotFilter(mResumeEffect);
406 mResumeEffect.setPositionProvider(mPositionProvider);
407 mResumeEffect.start();
410 setContentPane(mRootPane);
412 boolean enableHomeButton = (mActivity.getStateManager().getStateCount() > 1) |
413 mParentMediaSetString != null;
414 GalleryActionBar actionBar = mActivity.getGalleryActionBar();
415 actionBar.setDisplayOptions(enableHomeButton, false);
417 actionBar.enableAlbumModeMenu(GalleryActionBar.ALBUM_GRID_MODE_SELECTED, this);
420 // Set the reload bit here to prevent it exit this page in clearLoadingBit().
421 setLoadingBit(BIT_LOADING_RELOAD);
422 mAlbumDataAdapter.resume();
425 mAlbumView.setPressedIndex(-1);
426 mActionModeHandler.resume();
427 if (!mInitialSynced) {
428 setLoadingBit(BIT_LOADING_SYNC);
429 mSyncTask = mMediaSet.requestSync(this);
431 mInCameraAndWantQuitOnPause = mInCameraApp;
435 protected void onPause() {
439 if (mSelectionManager.inSelectionMode()) {
440 mSelectionManager.leaveSelectionMode();
442 mAlbumView.setSlotFilter(null);
444 mAlbumDataAdapter.pause();
446 DetailsHelper.pause();
448 mActivity.getGalleryActionBar().disableAlbumModeMenu(true);
451 if (mSyncTask != null) {
454 clearLoadingBit(BIT_LOADING_SYNC);
456 mActionModeHandler.pause();
460 protected void onDestroy() {
462 if (mAlbumDataAdapter != null) {
463 mAlbumDataAdapter.setLoadingListener(null);
467 private void initializeViews() {
468 mSelectionManager = new SelectionManager(mActivity, false);
469 mSelectionManager.setSelectionListener(this);
470 Config.AlbumPage config = Config.AlbumPage.get(mActivity);
471 mSlotView = new SlotView(mActivity, config.slotViewSpec);
472 mAlbumView = new AlbumSlotRenderer(mActivity, mSlotView,
473 mSelectionManager, config.placeholderColor);
474 mSlotView.setSlotRenderer(mAlbumView);
475 mRootPane.addComponent(mSlotView);
476 mSlotView.setListener(new SlotView.SimpleListener() {
478 public void onDown(int index) {
479 AlbumPage.this.onDown(index);
483 public void onUp(boolean followedByLongPress) {
484 AlbumPage.this.onUp(followedByLongPress);
488 public void onSingleTapUp(int slotIndex) {
489 AlbumPage.this.onSingleTapUp(slotIndex);
493 public void onLongTap(int slotIndex) {
494 AlbumPage.this.onLongTap(slotIndex);
497 mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
498 mActionModeHandler.setActionModeListener(new ActionModeListener() {
500 public boolean onActionItemClicked(MenuItem item) {
501 return onItemSelected(item);
506 private void initializeData(Bundle data) {
507 mMediaSetPath = Path.fromString(data.getString(KEY_MEDIA_PATH));
508 mParentMediaSetString = data.getString(KEY_PARENT_MEDIA_PATH);
509 mMediaSet = mActivity.getDataManager().getMediaSet(mMediaSetPath);
510 if (mMediaSet == null) {
511 Utils.fail("MediaSet is null. Path = %s", mMediaSetPath);
513 mSelectionManager.setSourceMediaSet(mMediaSet);
514 mAlbumDataAdapter = new AlbumDataLoader(mActivity, mMediaSet);
515 mAlbumDataAdapter.setLoadingListener(new MyLoadingListener());
516 mAlbumView.setModel(mAlbumDataAdapter);
519 private void showDetails() {
521 if (mDetailsHelper == null) {
522 mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
523 mDetailsHelper.setCloseListener(new CloseListener() {
525 public void onClose() {
530 mDetailsHelper.show();
533 private void hideDetails() {
534 mShowDetails = false;
535 mDetailsHelper.hide();
536 mAlbumView.setHighlightItemPath(null);
537 mSlotView.invalidate();
541 protected boolean onCreateActionBar(Menu menu) {
542 GalleryActionBar actionBar = mActivity.getGalleryActionBar();
543 MenuInflater inflator = getSupportMenuInflater();
545 inflator.inflate(R.menu.pickup, menu);
546 int typeBits = mData.getInt(Gallery.KEY_TYPE_BITS,
547 DataManager.INCLUDE_IMAGE);
548 actionBar.setTitle(GalleryUtils.getSelectionModePrompt(typeBits));
550 inflator.inflate(R.menu.album, menu);
551 actionBar.setTitle(mMediaSet.getName());
553 menu.findItem(R.id.action_slideshow)
554 .setVisible(!(mMediaSet instanceof MtpDevice));
556 FilterUtils.setupMenuItems(actionBar, mMediaSetPath, true);
558 menu.findItem(R.id.action_group_by).setVisible(mShowClusterMenu);
559 menu.findItem(R.id.action_camera).setVisible(
560 MediaSetUtils.isCameraSource(mMediaSetPath)
561 && GalleryUtils.isCameraAvailable(mActivity));
564 actionBar.setSubtitle(null);
568 private void prepareAnimationBackToFilmstrip(int slotIndex) {
569 if (mAlbumDataAdapter == null || !mAlbumDataAdapter.isActive(slotIndex)) return;
570 MediaItem item = mAlbumDataAdapter.get(slotIndex);
571 if (item == null) return;
572 TransitionStore transitions = mActivity.getTransitionStore();
573 transitions.put(PhotoPage.KEY_INDEX_HINT, slotIndex);
574 transitions.put(PhotoPage.KEY_OPEN_ANIMATION_RECT,
575 mSlotView.getSlotRect(slotIndex, mRootPane));
578 private void switchToFilmstrip() {
579 if (mAlbumDataAdapter.size() < 1) return;
580 int targetPhoto = mSlotView.getVisibleStart();
581 prepareAnimationBackToFilmstrip(targetPhoto);
582 if(mLaunchedFromPhotoPage) {
585 pickPhoto(targetPhoto, true);
590 protected boolean onItemSelected(MenuItem item) {
591 switch (item.getItemId()) {
592 case android.R.id.home: {
596 case R.id.action_cancel:
597 mActivity.getStateManager().finishState(this);
599 case R.id.action_select:
600 mSelectionManager.setAutoLeaveSelectionMode(false);
601 mSelectionManager.enterSelectionMode();
603 case R.id.action_group_by: {
604 mActivity.getGalleryActionBar().showClusterDialog(this);
607 case R.id.action_slideshow: {
608 mInCameraAndWantQuitOnPause = false;
609 Bundle data = new Bundle();
610 data.putString(SlideshowPage.KEY_SET_PATH,
611 mMediaSetPath.toString());
612 data.putBoolean(SlideshowPage.KEY_REPEAT, true);
613 mActivity.getStateManager().startStateForResult(
614 SlideshowPage.class, REQUEST_SLIDESHOW, data);
617 case R.id.action_details: {
625 case R.id.action_camera: {
626 GalleryUtils.startCameraActivity(mActivity);
635 protected void onStateResult(int request, int result, Intent data) {
637 case REQUEST_SLIDESHOW: {
638 // data could be null, if there is no images in the album
639 if (data == null) return;
640 mFocusIndex = data.getIntExtra(SlideshowPage.KEY_PHOTO_INDEX, 0);
641 mSlotView.setCenterIndex(mFocusIndex);
644 case REQUEST_PHOTO: {
645 if (data == null) return;
646 mFocusIndex = data.getIntExtra(PhotoPage.KEY_RETURN_INDEX_HINT, 0);
647 mSlotView.makeSlotVisible(mFocusIndex);
650 case REQUEST_DO_ANIMATION: {
651 mSlotView.startRisingAnimation();
658 public void onSelectionModeChange(int mode) {
660 case SelectionManager.ENTER_SELECTION_MODE: {
661 mActionModeHandler.startActionMode();
662 if (mHapticsEnabled) mVibrator.vibrate(100);
665 case SelectionManager.LEAVE_SELECTION_MODE: {
666 mActionModeHandler.finishActionMode();
667 mRootPane.invalidate();
670 case SelectionManager.SELECT_ALL_MODE: {
671 mActionModeHandler.updateSupportedOperation();
672 mRootPane.invalidate();
679 public void onSelectionChange(Path path, boolean selected) {
680 int count = mSelectionManager.getSelectedCount();
681 String format = mActivity.getResources().getQuantityString(
682 R.plurals.number_of_items_selected, count);
683 mActionModeHandler.setTitle(String.format(format, count));
684 mActionModeHandler.updateSupportedOperation(path, selected);
688 public void onSyncDone(final MediaSet mediaSet, final int resultCode) {
689 Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) + " result="
691 ((Activity) mActivity).runOnUiThread(new Runnable() {
694 GLRoot root = mActivity.getGLRoot();
695 root.lockRenderThread();
697 if (resultCode == MediaSet.SYNC_RESULT_SUCCESS) {
698 mInitialSynced = true;
700 clearLoadingBit(BIT_LOADING_SYNC);
701 if (resultCode == MediaSet.SYNC_RESULT_ERROR && mIsActive
702 && (mAlbumDataAdapter.size() == 0)) {
703 // show error toast only if the album is empty
704 Toast.makeText(mActivity, R.string.sync_album_error,
705 Toast.LENGTH_LONG).show();
708 root.unlockRenderThread();
714 private void setLoadingBit(int loadTaskBit) {
715 mLoadingBits |= loadTaskBit;
718 private void clearLoadingBit(int loadTaskBit) {
719 mLoadingBits &= ~loadTaskBit;
720 if (mLoadingBits == 0 && mIsActive) {
721 if (mAlbumDataAdapter.size() == 0) {
722 Intent result = new Intent();
723 result.putExtra(KEY_EMPTY_ALBUM, true);
724 setStateResult(Activity.RESULT_OK, result);
725 mActivity.getStateManager().finishState(this);
730 private class MyLoadingListener implements LoadingListener {
732 public void onLoadingStarted() {
733 setLoadingBit(BIT_LOADING_RELOAD);
737 public void onLoadingFinished() {
738 clearLoadingBit(BIT_LOADING_RELOAD);
742 private class MyDetailsSource implements DetailsHelper.DetailsSource {
747 return mAlbumDataAdapter.size();
751 public int setIndex() {
752 Path id = mSelectionManager.getSelected(false).get(0);
753 mIndex = mAlbumDataAdapter.findItem(id);
758 public MediaDetails getDetails() {
759 // this relies on setIndex() being called beforehand
760 MediaObject item = mAlbumDataAdapter.get(mIndex);
762 mAlbumView.setHighlightItemPath(item.getPath());
763 return item.getDetails();
771 public void onAlbumModeSelected(int mode) {
772 if (mode == GalleryActionBar.ALBUM_FILMSTRIP_MODE_SELECTED) {