AlbumSetPage.java revision 90fe70f11b0961e1e5ae353cdf563236a55f502d
1/*
2 * Copyright (C) 2010 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.app;
18
19import android.app.Activity;
20import android.content.Context;
21import android.content.Intent;
22import android.graphics.Rect;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.Message;
26import android.os.Vibrator;
27import android.provider.MediaStore;
28import android.view.ActionMode;
29import android.view.Menu;
30import android.view.MenuInflater;
31import android.view.MenuItem;
32import android.widget.Toast;
33
34import com.android.gallery3d.R;
35import com.android.gallery3d.common.Utils;
36import com.android.gallery3d.data.DataManager;
37import com.android.gallery3d.data.MediaDetails;
38import com.android.gallery3d.data.MediaObject;
39import com.android.gallery3d.data.MediaSet;
40import com.android.gallery3d.data.Path;
41import com.android.gallery3d.picasasource.PicasaSource;
42import com.android.gallery3d.settings.GallerySettings;
43import com.android.gallery3d.ui.ActionModeHandler;
44import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
45import com.android.gallery3d.ui.AlbumSetSlotRenderer;
46import com.android.gallery3d.ui.DetailsHelper;
47import com.android.gallery3d.ui.DetailsHelper.CloseListener;
48import com.android.gallery3d.ui.FadeTexture;
49import com.android.gallery3d.ui.GLCanvas;
50import com.android.gallery3d.ui.GLRoot;
51import com.android.gallery3d.ui.GLView;
52import com.android.gallery3d.ui.SelectionManager;
53import com.android.gallery3d.ui.SlotView;
54import com.android.gallery3d.ui.SynchronizedHandler;
55import com.android.gallery3d.util.Future;
56import com.android.gallery3d.util.GalleryUtils;
57
58public class AlbumSetPage extends ActivityState implements
59        SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner,
60        EyePosition.EyePositionListener, MediaSet.SyncListener {
61    @SuppressWarnings("unused")
62    private static final String TAG = "AlbumSetPage";
63
64    private static final int MSG_PICK_ALBUM = 1;
65
66    public static final String KEY_MEDIA_PATH = "media-path";
67    public static final String KEY_SET_TITLE = "set-title";
68    public static final String KEY_SET_SUBTITLE = "set-subtitle";
69    public static final String KEY_SELECTED_CLUSTER_TYPE = "selected-cluster";
70
71    private static final int DATA_CACHE_SIZE = 256;
72    private static final int REQUEST_DO_ANIMATION = 1;
73
74    private static final int BIT_LOADING_RELOAD = 1;
75    private static final int BIT_LOADING_SYNC = 2;
76
77    private boolean mIsActive = false;
78    private SlotView mSlotView;
79    private AlbumSetSlotRenderer mAlbumSetView;
80
81    private MediaSet mMediaSet;
82    private String mTitle;
83    private String mSubtitle;
84    private boolean mShowClusterMenu;
85    private GalleryActionBar mActionBar;
86    private int mSelectedAction;
87    private Vibrator mVibrator;
88
89    protected SelectionManager mSelectionManager;
90    private AlbumSetDataLoader mAlbumSetDataAdapter;
91
92    private boolean mGetContent;
93    private boolean mGetAlbum;
94    private ActionMode mActionMode;
95    private ActionModeHandler mActionModeHandler;
96    private DetailsHelper mDetailsHelper;
97    private MyDetailsSource mDetailsSource;
98    private boolean mShowDetails;
99    private EyePosition mEyePosition;
100    private Handler mHandler;
101
102    // The eyes' position of the user, the origin is at the center of the
103    // device and the unit is in pixels.
104    private float mX;
105    private float mY;
106    private float mZ;
107
108    private Future<Integer> mSyncTask = null;
109
110    private int mLoadingBits = 0;
111    private boolean mInitialSynced = false;
112
113    private final GLView mRootPane = new GLView() {
114        private final float mMatrix[] = new float[16];
115
116        @Override
117        protected void renderBackground(GLCanvas view) {
118            view.clearBuffer();
119        }
120
121        @Override
122        protected void onLayout(
123                boolean changed, int left, int top, int right, int bottom) {
124            mEyePosition.resetPosition();
125
126            int slotViewTop = mActionBar.getHeight();
127            int slotViewBottom = bottom - top;
128            int slotViewRight = right - left;
129
130            if (mShowDetails) {
131                mDetailsHelper.layout(left, slotViewTop, right, bottom);
132            } else {
133                mAlbumSetView.setHighlightItemPath(null);
134            }
135
136            mSlotView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
137        }
138
139        @Override
140        protected void render(GLCanvas canvas) {
141            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
142            GalleryUtils.setViewPointMatrix(mMatrix,
143                    getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
144            canvas.multiplyMatrix(mMatrix, 0);
145            super.render(canvas);
146            canvas.restore();
147        }
148    };
149
150    @Override
151    public void onEyePositionChanged(float x, float y, float z) {
152        mRootPane.lockRendering();
153        mX = x;
154        mY = y;
155        mZ = z;
156        mRootPane.unlockRendering();
157        mRootPane.invalidate();
158    }
159
160    @Override
161    public void onBackPressed() {
162        if (mShowDetails) {
163            hideDetails();
164        } else if (mSelectionManager.inSelectionMode()) {
165            mSelectionManager.leaveSelectionMode();
166        } else {
167            super.onBackPressed();
168        }
169    }
170
171    private void getSlotCenter(int slotIndex, int center[]) {
172        Rect offset = new Rect();
173        mRootPane.getBoundsOf(mSlotView, offset);
174        Rect r = mSlotView.getSlotRect(slotIndex);
175        int scrollX = mSlotView.getScrollX();
176        int scrollY = mSlotView.getScrollY();
177        center[0] = offset.left + (r.left + r.right) / 2 - scrollX;
178        center[1] = offset.top + (r.top + r.bottom) / 2 - scrollY;
179    }
180
181    public void onSingleTapUp(int slotIndex) {
182        if (!mIsActive) return;
183
184        if (mSelectionManager.inSelectionMode()) {
185            MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
186            if (targetSet == null) return; // Content is dirty, we shall reload soon
187            mSelectionManager.toggle(targetSet.getPath());
188            mSlotView.invalidate();
189        } else {
190            // Show pressed-up animation for the single-tap.
191            mAlbumSetView.setPressedIndex(slotIndex);
192            mAlbumSetView.setPressedUp();
193            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0),
194                    FadeTexture.DURATION);
195        }
196    }
197
198    private void pickAlbum(int slotIndex) {
199        if (!mIsActive) return;
200
201        MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
202        if (targetSet == null) return; // Content is dirty, we shall reload soon
203        String mediaPath = targetSet.getPath().toString();
204
205        Bundle data = new Bundle(getData());
206        int[] center = new int[2];
207        getSlotCenter(slotIndex, center);
208        data.putIntArray(AlbumPage.KEY_SET_CENTER, center);
209        if (mGetAlbum && targetSet.isLeafAlbum()) {
210            Activity activity = (Activity) mActivity;
211            Intent result = new Intent()
212                    .putExtra(AlbumPicker.KEY_ALBUM_PATH, targetSet.getPath().toString());
213            activity.setResult(Activity.RESULT_OK, result);
214            activity.finish();
215        } else if (targetSet.getSubMediaSetCount() > 0) {
216            data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
217            mActivity.getStateManager().startStateForResult(
218                    AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
219        } else {
220            if (!mGetContent && (targetSet.getSupportedOperations()
221                    & MediaObject.SUPPORT_IMPORT) != 0) {
222                data.putBoolean(AlbumPage.KEY_AUTO_SELECT_ALL, true);
223            }
224            data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);
225            boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
226            // We only show cluster menu in the first AlbumPage in stack
227            data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
228            mActivity.getStateManager().startStateForResult(
229                    AlbumPage.class, REQUEST_DO_ANIMATION, data);
230        }
231    }
232
233    private void onDown(int index) {
234        mAlbumSetView.setPressedIndex(index);
235    }
236
237    private void onUp(boolean followedByLongPress) {
238        if (followedByLongPress) {
239            // Avoid showing press-up animations for long-press.
240            mAlbumSetView.setPressedIndex(-1);
241        } else {
242            mAlbumSetView.setPressedUp();
243        }
244    }
245
246    public void onLongTap(int slotIndex) {
247        if (mGetContent || mGetAlbum) return;
248        MediaSet set = mAlbumSetDataAdapter.getMediaSet(slotIndex);
249        if (set == null) return;
250        mSelectionManager.setAutoLeaveSelectionMode(true);
251        mSelectionManager.toggle(set.getPath());
252        mSlotView.invalidate();
253    }
254
255    @Override
256    public void doCluster(int clusterType) {
257        String basePath = mMediaSet.getPath().toString();
258        String newPath = FilterUtils.switchClusterPath(basePath, clusterType);
259        Bundle data = new Bundle(getData());
260        data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
261        data.putInt(KEY_SELECTED_CLUSTER_TYPE, clusterType);
262        mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
263    }
264
265    @Override
266    public void onCreate(Bundle data, Bundle restoreState) {
267        initializeViews();
268        initializeData(data);
269        Context context = mActivity.getAndroidContext();
270        mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
271        mGetAlbum = data.getBoolean(Gallery.KEY_GET_ALBUM, false);
272        mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE);
273        mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE);
274        mEyePosition = new EyePosition(context, this);
275        mDetailsSource = new MyDetailsSource();
276        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
277        mActionBar = mActivity.getGalleryActionBar();
278        mSelectedAction = data.getInt(AlbumSetPage.KEY_SELECTED_CLUSTER_TYPE,
279                FilterUtils.CLUSTER_BY_ALBUM);
280
281        mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
282            @Override
283            public void handleMessage(Message message) {
284                switch (message.what) {
285                    case MSG_PICK_ALBUM: {
286                        pickAlbum(message.arg1);
287                        break;
288                    }
289                    default: throw new AssertionError(message.what);
290                }
291            }
292        };
293    }
294
295    private void clearLoadingBit(int loadingBit) {
296        mLoadingBits &= ~loadingBit;
297        if (mLoadingBits == 0 && mIsActive) {
298            GalleryUtils.setSpinnerVisibility((Activity) mActivity, false);
299
300            // Only show toast when there's no album and we are going to finish
301            // the page. Toast is redundant if we are going to stay on this page.
302            if ((mAlbumSetDataAdapter.size() == 0)) {
303                Toast.makeText((Context) mActivity,
304                        R.string.empty_album, Toast.LENGTH_LONG).show();
305                if (mActivity.getStateManager().getStateCount() > 1) {
306                    mActivity.getStateManager().finishState(this);
307                }
308            }
309        }
310    }
311
312    private void setLoadingBit(int loadingBit) {
313        if (mLoadingBits == 0 && mIsActive) {
314            GalleryUtils.setSpinnerVisibility((Activity) mActivity, true);
315        }
316        mLoadingBits |= loadingBit;
317    }
318
319    @Override
320    public void onPause() {
321        super.onPause();
322        mIsActive = false;
323        mActionModeHandler.pause();
324        mAlbumSetDataAdapter.pause();
325        mAlbumSetView.pause();
326        mEyePosition.pause();
327        DetailsHelper.pause();
328        // Call disableClusterMenu to avoid receiving callback after paused.
329        // Don't hide menu here otherwise the list menu will disappear earlier than
330        // the action bar, which is janky and unwanted behavior.
331        mActionBar.disableClusterMenu(false);
332        if (mSyncTask != null) {
333            mSyncTask.cancel();
334            mSyncTask = null;
335            clearLoadingBit(BIT_LOADING_SYNC);
336        }
337        GalleryUtils.setSpinnerVisibility((Activity) mActivity, false);
338    }
339
340    @Override
341    public void onResume() {
342        super.onResume();
343        mIsActive = true;
344        setContentPane(mRootPane);
345
346        // Set the reload bit here to prevent it exit this page in clearLoadingBit().
347        setLoadingBit(BIT_LOADING_RELOAD);
348        mAlbumSetDataAdapter.resume();
349
350        mAlbumSetView.resume();
351        mEyePosition.resume();
352        mActionModeHandler.resume();
353        if (mShowClusterMenu) {
354            mActionBar.enableClusterMenu(mSelectedAction, this);
355        }
356        if (!mInitialSynced) {
357            setLoadingBit(BIT_LOADING_SYNC);
358            mSyncTask = mMediaSet.requestSync(AlbumSetPage.this);
359        }
360    }
361
362    private void initializeData(Bundle data) {
363        String mediaPath = data.getString(AlbumSetPage.KEY_MEDIA_PATH);
364        mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
365        mSelectionManager.setSourceMediaSet(mMediaSet);
366        mAlbumSetDataAdapter = new AlbumSetDataLoader(
367                mActivity, mMediaSet, DATA_CACHE_SIZE);
368        mAlbumSetDataAdapter.setLoadingListener(new MyLoadingListener());
369        mAlbumSetView.setModel(mAlbumSetDataAdapter);
370    }
371
372    private void initializeViews() {
373        mSelectionManager = new SelectionManager(mActivity, true);
374        mSelectionManager.setSelectionListener(this);
375
376        Config.AlbumSetPage config = Config.AlbumSetPage.get((Context) mActivity);
377        mSlotView = new SlotView(mActivity, config.slotViewSpec);
378        mAlbumSetView = new AlbumSetSlotRenderer(
379                mActivity, mSelectionManager, mSlotView, config.labelSpec);
380        mSlotView.setSlotRenderer(mAlbumSetView);
381        mSlotView.setListener(new SlotView.SimpleListener() {
382            @Override
383            public void onDown(int index) {
384                AlbumSetPage.this.onDown(index);
385            }
386
387            @Override
388            public void onUp(boolean followedByLongPress) {
389                AlbumSetPage.this.onUp(followedByLongPress);
390            }
391
392            @Override
393            public void onSingleTapUp(int slotIndex) {
394                AlbumSetPage.this.onSingleTapUp(slotIndex);
395            }
396
397            @Override
398            public void onLongTap(int slotIndex) {
399                AlbumSetPage.this.onLongTap(slotIndex);
400            }
401        });
402
403        mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
404        mActionModeHandler.setActionModeListener(new ActionModeListener() {
405            @Override
406            public boolean onActionItemClicked(MenuItem item) {
407                return onItemSelected(item);
408            }
409        });
410        mRootPane.addComponent(mSlotView);
411    }
412
413    @Override
414    protected boolean onCreateActionBar(Menu menu) {
415        Activity activity = (Activity) mActivity;
416        MenuInflater inflater = activity.getMenuInflater();
417
418        final boolean inAlbum = mActivity.getStateManager().hasStateClass(
419                AlbumPage.class);
420
421        if (mGetContent) {
422            inflater.inflate(R.menu.pickup, menu);
423            int typeBits = mData.getInt(
424                    Gallery.KEY_TYPE_BITS, DataManager.INCLUDE_IMAGE);
425            int id = R.string.select_image;
426            if ((typeBits & DataManager.INCLUDE_VIDEO) != 0) {
427                id = (typeBits & DataManager.INCLUDE_IMAGE) == 0
428                        ? R.string.select_video
429                        : R.string.select_item;
430            }
431            mActionBar.setTitle(id);
432        } else  if (mGetAlbum) {
433            inflater.inflate(R.menu.pickup, menu);
434            mActionBar.setTitle(R.string.select_album);
435        } else {
436            mShowClusterMenu = !inAlbum;
437            inflater.inflate(R.menu.albumset, menu);
438            MenuItem selectItem = menu.findItem(R.id.action_select);
439
440            if (selectItem != null) {
441                boolean selectAlbums = !inAlbum &&
442                        mActionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM;
443                if (selectAlbums) {
444                    selectItem.setTitle(R.string.select_album);
445                } else {
446                    selectItem.setTitle(R.string.select_group);
447                }
448            }
449
450            FilterUtils.setupMenuItems(mActionBar, mMediaSet.getPath(), false);
451            MenuItem switchCamera = menu.findItem(R.id.action_camera);
452            if (switchCamera != null) {
453                switchCamera.setVisible(GalleryUtils.isCameraAvailable(activity));
454            }
455
456            mActionBar.setTitle(mTitle);
457            mActionBar.setSubtitle(mSubtitle);
458        }
459        return true;
460    }
461
462    @Override
463    protected boolean onItemSelected(MenuItem item) {
464        Activity activity = (Activity) mActivity;
465        switch (item.getItemId()) {
466            case R.id.action_cancel:
467                activity.setResult(Activity.RESULT_CANCELED);
468                activity.finish();
469                return true;
470            case R.id.action_select:
471                mSelectionManager.setAutoLeaveSelectionMode(false);
472                mSelectionManager.enterSelectionMode();
473                return true;
474            case R.id.action_details:
475                if (mAlbumSetDataAdapter.size() != 0) {
476                    if (mShowDetails) {
477                        hideDetails();
478                    } else {
479                        showDetails();
480                    }
481                } else {
482                    Toast.makeText(activity,
483                            activity.getText(R.string.no_albums_alert),
484                            Toast.LENGTH_SHORT).show();
485                }
486                return true;
487            case R.id.action_camera: {
488                Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
489                        .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
490                        | Intent.FLAG_ACTIVITY_NEW_TASK);
491                activity.startActivity(intent);
492                return true;
493            }
494            case R.id.action_manage_offline: {
495                Bundle data = new Bundle();
496                String mediaPath = mActivity.getDataManager().getTopSetPath(
497                    DataManager.INCLUDE_ALL);
498                data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
499                mActivity.getStateManager().startState(ManageCachePage.class, data);
500                return true;
501            }
502            case R.id.action_sync_picasa_albums: {
503                PicasaSource.requestSync(activity);
504                return true;
505            }
506            case R.id.action_settings: {
507                activity.startActivity(new Intent(activity, GallerySettings.class));
508                return true;
509            }
510            case R.id.action_general_help: {
511                activity.startActivity(
512                        GalleryUtils.getHelpIntent(R.string.general_help_link, activity));
513                return true;
514            }
515            default:
516                return false;
517        }
518    }
519
520    @Override
521    protected void onStateResult(int requestCode, int resultCode, Intent data) {
522        switch (requestCode) {
523            case REQUEST_DO_ANIMATION: {
524                mSlotView.startRisingAnimation();
525            }
526        }
527    }
528
529    private String getSelectedString() {
530        int count = mSelectionManager.getSelectedCount();
531        int action = mActionBar.getClusterTypeAction();
532        int string = action == FilterUtils.CLUSTER_BY_ALBUM
533                ? R.plurals.number_of_albums_selected
534                : R.plurals.number_of_groups_selected;
535        String format = mActivity.getResources().getQuantityString(string, count);
536        return String.format(format, count);
537    }
538
539    @Override
540    public void onSelectionModeChange(int mode) {
541        switch (mode) {
542            case SelectionManager.ENTER_SELECTION_MODE: {
543                mActionBar.disableClusterMenu(true);
544                mActionMode = mActionModeHandler.startActionMode();
545                mVibrator.vibrate(100);
546                break;
547            }
548            case SelectionManager.LEAVE_SELECTION_MODE: {
549                mActionMode.finish();
550                if (mShowClusterMenu) {
551                    mActionBar.enableClusterMenu(mSelectedAction, this);
552                }
553                mRootPane.invalidate();
554                break;
555            }
556            case SelectionManager.SELECT_ALL_MODE: {
557                mActionModeHandler.setTitle(getSelectedString());
558                mRootPane.invalidate();
559                break;
560            }
561        }
562    }
563
564    @Override
565    public void onSelectionChange(Path path, boolean selected) {
566        Utils.assertTrue(mActionMode != null);
567        mActionModeHandler.setTitle(getSelectedString());
568        mActionModeHandler.updateSupportedOperation(path, selected);
569    }
570
571    private void hideDetails() {
572        mShowDetails = false;
573        mDetailsHelper.hide();
574        mAlbumSetView.setHighlightItemPath(null);
575        mSlotView.invalidate();
576    }
577
578    private void showDetails() {
579        mShowDetails = true;
580        if (mDetailsHelper == null) {
581            mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
582            mDetailsHelper.setCloseListener(new CloseListener() {
583                @Override
584                public void onClose() {
585                    hideDetails();
586                }
587            });
588        }
589        mDetailsHelper.show();
590    }
591
592    @Override
593    public void onSyncDone(final MediaSet mediaSet, final int resultCode) {
594        if (resultCode == MediaSet.SYNC_RESULT_ERROR) {
595            Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) + " result="
596                    + resultCode);
597        }
598        ((Activity) mActivity).runOnUiThread(new Runnable() {
599            @Override
600            public void run() {
601                GLRoot root = mActivity.getGLRoot();
602                root.lockRenderThread();
603                try {
604                    if (resultCode == MediaSet.SYNC_RESULT_SUCCESS) {
605                        mInitialSynced = true;
606                    }
607                    clearLoadingBit(BIT_LOADING_SYNC);
608                    if (resultCode == MediaSet.SYNC_RESULT_ERROR && mIsActive) {
609                        Toast.makeText((Context) mActivity, R.string.sync_album_set_error,
610                                Toast.LENGTH_LONG).show();
611                    }
612                } finally {
613                    root.unlockRenderThread();
614                }
615            }
616        });
617    }
618
619    private class MyLoadingListener implements LoadingListener {
620        @Override
621        public void onLoadingStarted() {
622            setLoadingBit(BIT_LOADING_RELOAD);
623        }
624
625        @Override
626        public void onLoadingFinished() {
627            clearLoadingBit(BIT_LOADING_RELOAD);
628        }
629    }
630
631    private class MyDetailsSource implements DetailsHelper.DetailsSource {
632        private int mIndex;
633
634        @Override
635        public int size() {
636            return mAlbumSetDataAdapter.size();
637        }
638
639        @Override
640        public int getIndex() {
641            return mIndex;
642        }
643
644        // If requested index is out of active window, suggest a valid index.
645        // If there is no valid index available, return -1.
646        @Override
647        public int findIndex(int indexHint) {
648            if (mAlbumSetDataAdapter.isActive(indexHint)) {
649                mIndex = indexHint;
650            } else {
651                mIndex = mAlbumSetDataAdapter.getActiveStart();
652                if (!mAlbumSetDataAdapter.isActive(mIndex)) {
653                    return -1;
654                }
655            }
656            return mIndex;
657        }
658
659        @Override
660        public MediaDetails getDetails() {
661            MediaObject item = mAlbumSetDataAdapter.getMediaSet(mIndex);
662            if (item != null) {
663                mAlbumSetView.setHighlightItemPath(item.getPath());
664                return item.getDetails();
665            } else {
666                return null;
667            }
668        }
669    }
670}
671