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.os.Bundle;
24 import android.os.Handler;
25 import android.os.Message;
26 import android.view.HapticFeedbackConstants;
27 import android.view.Menu;
28 import android.view.MenuInflater;
29 import android.view.MenuItem;
30 import android.view.View;
31 import android.view.View.OnClickListener;
32 import android.widget.Button;
33 import android.widget.RelativeLayout;
34 import android.widget.Toast;
36 import com.android.gallery3d.R;
37 import com.android.gallery3d.common.Utils;
38 import com.android.gallery3d.data.DataManager;
39 import com.android.gallery3d.data.MediaDetails;
40 import com.android.gallery3d.data.MediaItem;
41 import com.android.gallery3d.data.MediaObject;
42 import com.android.gallery3d.data.MediaSet;
43 import com.android.gallery3d.data.Path;
44 import com.android.gallery3d.glrenderer.FadeTexture;
45 import com.android.gallery3d.glrenderer.GLCanvas;
46 import com.android.gallery3d.picasasource.PicasaSource;
47 import com.android.gallery3d.settings.GallerySettings;
48 import com.android.gallery3d.ui.ActionModeHandler;
49 import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
50 import com.android.gallery3d.ui.AlbumSetSlotRenderer;
51 import com.android.gallery3d.ui.DetailsHelper;
52 import com.android.gallery3d.ui.DetailsHelper.CloseListener;
53 import com.android.gallery3d.ui.GLRoot;
54 import com.android.gallery3d.ui.GLView;
55 import com.android.gallery3d.ui.SelectionManager;
56 import com.android.gallery3d.ui.SlotView;
57 import com.android.gallery3d.ui.SynchronizedHandler;
58 import com.android.gallery3d.util.Future;
59 import com.android.gallery3d.util.GalleryUtils;
60 import com.android.gallery3d.util.HelpUtils;
62 import java.lang.ref.WeakReference;
63 import java.util.ArrayList;
65 public class AlbumSetPage extends ActivityState implements
66 SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner,
67 EyePosition.EyePositionListener, MediaSet.SyncListener {
68 @SuppressWarnings("unused")
69 private static final String TAG = "AlbumSetPage";
71 private static final int MSG_PICK_ALBUM = 1;
73 public static final String KEY_MEDIA_PATH = "media-path";
74 public static final String KEY_SET_TITLE = "set-title";
75 public static final String KEY_SET_SUBTITLE = "set-subtitle";
76 public static final String KEY_SELECTED_CLUSTER_TYPE = "selected-cluster";
78 private static final int DATA_CACHE_SIZE = 256;
79 private static final int REQUEST_DO_ANIMATION = 1;
81 private static final int BIT_LOADING_RELOAD = 1;
82 private static final int BIT_LOADING_SYNC = 2;
84 private boolean mIsActive = false;
85 private SlotView mSlotView;
86 private AlbumSetSlotRenderer mAlbumSetView;
87 private Config.AlbumSetPage mConfig;
89 private MediaSet mMediaSet;
90 private String mTitle;
91 private String mSubtitle;
92 private boolean mShowClusterMenu;
93 private GalleryActionBar mActionBar;
94 private int mSelectedAction;
96 protected SelectionManager mSelectionManager;
97 private AlbumSetDataLoader mAlbumSetDataAdapter;
99 private boolean mGetContent;
100 private boolean mGetAlbum;
101 private ActionModeHandler mActionModeHandler;
102 private DetailsHelper mDetailsHelper;
103 private MyDetailsSource mDetailsSource;
104 private boolean mShowDetails;
105 private EyePosition mEyePosition;
106 private Handler mHandler;
108 // The eyes' position of the user, the origin is at the center of the
109 // device and the unit is in pixels.
114 private Future<Integer> mSyncTask = null;
116 private int mLoadingBits = 0;
117 private boolean mInitialSynced = false;
119 private Button mCameraButton;
120 private boolean mShowedEmptyToastForSelf = false;
123 protected int getBackgroundColorId() {
124 return R.color.albumset_background;
127 private final GLView mRootPane = new GLView() {
128 private final float mMatrix[] = new float[16];
131 protected void onLayout(
132 boolean changed, int left, int top, int right, int bottom) {
133 mEyePosition.resetPosition();
135 int slotViewTop = mActionBar.getHeight() + mConfig.paddingTop;
136 int slotViewBottom = bottom - top - mConfig.paddingBottom;
137 int slotViewRight = right - left;
140 mDetailsHelper.layout(left, slotViewTop, right, bottom);
142 mAlbumSetView.setHighlightItemPath(null);
145 mSlotView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
149 protected void render(GLCanvas canvas) {
150 canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
151 GalleryUtils.setViewPointMatrix(mMatrix,
152 getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
153 canvas.multiplyMatrix(mMatrix, 0);
154 super.render(canvas);
160 public void onEyePositionChanged(float x, float y, float z) {
161 mRootPane.lockRendering();
165 mRootPane.unlockRendering();
166 mRootPane.invalidate();
170 public void onBackPressed() {
173 } else if (mSelectionManager.inSelectionMode()) {
174 mSelectionManager.leaveSelectionMode();
176 super.onBackPressed();
180 private void getSlotCenter(int slotIndex, int center[]) {
181 Rect offset = new Rect();
182 mRootPane.getBoundsOf(mSlotView, offset);
183 Rect r = mSlotView.getSlotRect(slotIndex);
184 int scrollX = mSlotView.getScrollX();
185 int scrollY = mSlotView.getScrollY();
186 center[0] = offset.left + (r.left + r.right) / 2 - scrollX;
187 center[1] = offset.top + (r.top + r.bottom) / 2 - scrollY;
190 public void onSingleTapUp(int slotIndex) {
191 if (!mIsActive) return;
193 if (mSelectionManager.inSelectionMode()) {
194 MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
195 if (targetSet == null) return; // Content is dirty, we shall reload soon
196 mSelectionManager.toggle(targetSet.getPath());
197 mSlotView.invalidate();
199 // Show pressed-up animation for the single-tap.
200 mAlbumSetView.setPressedIndex(slotIndex);
201 mAlbumSetView.setPressedUp();
202 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0),
203 FadeTexture.DURATION);
207 private static boolean albumShouldOpenInFilmstrip(MediaSet album) {
208 int itemCount = album.getMediaItemCount();
209 ArrayList<MediaItem> list = (itemCount == 1) ? album.getMediaItem(0, 1) : null;
210 // open in film strip only if there's one item in the album and the item exists
211 return (list != null && !list.isEmpty());
214 WeakReference<Toast> mEmptyAlbumToast = null;
216 private void showEmptyAlbumToast(int toastLength) {
218 if (mEmptyAlbumToast != null) {
219 toast = mEmptyAlbumToast.get();
225 toast = Toast.makeText(mActivity, R.string.empty_album, toastLength);
226 mEmptyAlbumToast = new WeakReference<Toast>(toast);
230 private void hideEmptyAlbumToast() {
231 if (mEmptyAlbumToast != null) {
232 Toast toast = mEmptyAlbumToast.get();
233 if (toast != null) toast.cancel();
237 private void pickAlbum(int slotIndex) {
238 if (!mIsActive) return;
240 MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
241 if (targetSet == null) return; // Content is dirty, we shall reload soon
242 if (targetSet.getTotalMediaItemCount() == 0) {
243 showEmptyAlbumToast(Toast.LENGTH_SHORT);
246 hideEmptyAlbumToast();
248 String mediaPath = targetSet.getPath().toString();
250 Bundle data = new Bundle(getData());
251 int[] center = new int[2];
252 getSlotCenter(slotIndex, center);
253 data.putIntArray(AlbumPage.KEY_SET_CENTER, center);
254 if (mGetAlbum && targetSet.isLeafAlbum()) {
255 Activity activity = mActivity;
256 Intent result = new Intent()
257 .putExtra(AlbumPicker.KEY_ALBUM_PATH, targetSet.getPath().toString());
258 activity.setResult(Activity.RESULT_OK, result);
260 } else if (targetSet.getSubMediaSetCount() > 0) {
261 data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
262 mActivity.getStateManager().startStateForResult(
263 AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
265 if (!mGetContent && albumShouldOpenInFilmstrip(targetSet)) {
266 data.putParcelable(PhotoPage.KEY_OPEN_ANIMATION_RECT,
267 mSlotView.getSlotRect(slotIndex, mRootPane));
268 data.putInt(PhotoPage.KEY_INDEX_HINT, 0);
269 data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
271 data.putBoolean(PhotoPage.KEY_START_IN_FILMSTRIP, true);
272 data.putBoolean(PhotoPage.KEY_IN_CAMERA_ROLL, targetSet.isCameraRoll());
273 mActivity.getStateManager().startStateForResult(
274 FilmstripPage.class, AlbumPage.REQUEST_PHOTO, data);
277 data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);
279 // We only show cluster menu in the first AlbumPage in stack
280 boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
281 data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
282 mActivity.getStateManager().startStateForResult(
283 AlbumPage.class, REQUEST_DO_ANIMATION, data);
287 private void onDown(int index) {
288 mAlbumSetView.setPressedIndex(index);
291 private void onUp(boolean followedByLongPress) {
292 if (followedByLongPress) {
293 // Avoid showing press-up animations for long-press.
294 mAlbumSetView.setPressedIndex(-1);
296 mAlbumSetView.setPressedUp();
300 public void onLongTap(int slotIndex) {
301 if (mGetContent || mGetAlbum) return;
302 MediaSet set = mAlbumSetDataAdapter.getMediaSet(slotIndex);
303 if (set == null) return;
304 mSelectionManager.setAutoLeaveSelectionMode(true);
305 mSelectionManager.toggle(set.getPath());
306 mSlotView.invalidate();
310 public void doCluster(int clusterType) {
311 String basePath = mMediaSet.getPath().toString();
312 String newPath = FilterUtils.switchClusterPath(basePath, clusterType);
313 Bundle data = new Bundle(getData());
314 data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
315 data.putInt(KEY_SELECTED_CLUSTER_TYPE, clusterType);
316 mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
320 public void onCreate(Bundle data, Bundle restoreState) {
321 super.onCreate(data, restoreState);
323 initializeData(data);
324 Context context = mActivity.getAndroidContext();
325 mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
326 mGetAlbum = data.getBoolean(Gallery.KEY_GET_ALBUM, false);
327 mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE);
328 mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE);
329 mEyePosition = new EyePosition(context, this);
330 mDetailsSource = new MyDetailsSource();
331 mActionBar = mActivity.getGalleryActionBar();
332 mSelectedAction = data.getInt(AlbumSetPage.KEY_SELECTED_CLUSTER_TYPE,
333 FilterUtils.CLUSTER_BY_ALBUM);
335 mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
337 public void handleMessage(Message message) {
338 switch (message.what) {
339 case MSG_PICK_ALBUM: {
340 pickAlbum(message.arg1);
343 default: throw new AssertionError(message.what);
350 public void onDestroy() {
352 cleanupCameraButton();
353 mActionModeHandler.destroy();
356 private boolean setupCameraButton() {
357 if (!GalleryUtils.isCameraAvailable(mActivity)) return false;
358 RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity)
359 .findViewById(R.id.gallery_root);
360 if (galleryRoot == null) return false;
362 mCameraButton = new Button(mActivity);
363 mCameraButton.setText(R.string.camera_label);
364 mCameraButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.frame_overlay_gallery_camera, 0, 0);
365 mCameraButton.setOnClickListener(new OnClickListener() {
367 public void onClick(View arg0) {
368 GalleryUtils.startCameraActivity(mActivity);
371 RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
372 RelativeLayout.LayoutParams.WRAP_CONTENT,
373 RelativeLayout.LayoutParams.WRAP_CONTENT);
374 lp.addRule(RelativeLayout.CENTER_IN_PARENT);
375 galleryRoot.addView(mCameraButton, lp);
379 private void cleanupCameraButton() {
380 if (mCameraButton == null) return;
381 RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity)
382 .findViewById(R.id.gallery_root);
383 if (galleryRoot == null) return;
384 galleryRoot.removeView(mCameraButton);
385 mCameraButton = null;
388 private void showCameraButton() {
389 if (mCameraButton == null && !setupCameraButton()) return;
390 mCameraButton.setVisibility(View.VISIBLE);
393 private void hideCameraButton() {
394 if (mCameraButton == null) return;
395 mCameraButton.setVisibility(View.GONE);
398 private void clearLoadingBit(int loadingBit) {
399 mLoadingBits &= ~loadingBit;
400 if (mLoadingBits == 0 && mIsActive) {
401 if (mAlbumSetDataAdapter.size() == 0) {
402 // If this is not the top of the gallery folder hierarchy,
403 // tell the parent AlbumSetPage instance to handle displaying
404 // the empty album toast, otherwise show it within this
406 if (mActivity.getStateManager().getStateCount() > 1) {
407 Intent result = new Intent();
408 result.putExtra(AlbumPage.KEY_EMPTY_ALBUM, true);
409 setStateResult(Activity.RESULT_OK, result);
410 mActivity.getStateManager().finishState(this);
412 mShowedEmptyToastForSelf = true;
413 showEmptyAlbumToast(Toast.LENGTH_LONG);
414 mSlotView.invalidate();
420 // Hide the empty album toast if we are in the root instance of
421 // AlbumSetPage and the album is no longer empty (for instance,
422 // after a sync is completed and web albums have been synced)
423 if (mShowedEmptyToastForSelf) {
424 mShowedEmptyToastForSelf = false;
425 hideEmptyAlbumToast();
430 private void setLoadingBit(int loadingBit) {
431 mLoadingBits |= loadingBit;
435 public void onPause() {
438 mAlbumSetDataAdapter.pause();
439 mAlbumSetView.pause();
440 mActionModeHandler.pause();
441 mEyePosition.pause();
442 DetailsHelper.pause();
443 // Call disableClusterMenu to avoid receiving callback after paused.
444 // Don't hide menu here otherwise the list menu will disappear earlier than
445 // the action bar, which is janky and unwanted behavior.
446 mActionBar.disableClusterMenu(false);
447 if (mSyncTask != null) {
450 clearLoadingBit(BIT_LOADING_SYNC);
455 public void onResume() {
458 setContentPane(mRootPane);
460 // Set the reload bit here to prevent it exit this page in clearLoadingBit().
461 setLoadingBit(BIT_LOADING_RELOAD);
462 mAlbumSetDataAdapter.resume();
464 mAlbumSetView.resume();
465 mEyePosition.resume();
466 mActionModeHandler.resume();
467 if (mShowClusterMenu) {
468 mActionBar.enableClusterMenu(mSelectedAction, this);
470 if (!mInitialSynced) {
471 setLoadingBit(BIT_LOADING_SYNC);
472 mSyncTask = mMediaSet.requestSync(AlbumSetPage.this);
476 private void initializeData(Bundle data) {
477 String mediaPath = data.getString(AlbumSetPage.KEY_MEDIA_PATH);
478 mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
479 mSelectionManager.setSourceMediaSet(mMediaSet);
480 mAlbumSetDataAdapter = new AlbumSetDataLoader(
481 mActivity, mMediaSet, DATA_CACHE_SIZE);
482 mAlbumSetDataAdapter.setLoadingListener(new MyLoadingListener());
483 mAlbumSetView.setModel(mAlbumSetDataAdapter);
486 private void initializeViews() {
487 mSelectionManager = new SelectionManager(mActivity, true);
488 mSelectionManager.setSelectionListener(this);
490 mConfig = Config.AlbumSetPage.get(mActivity);
491 mSlotView = new SlotView(mActivity, mConfig.slotViewSpec);
492 mAlbumSetView = new AlbumSetSlotRenderer(
493 mActivity, mSelectionManager, mSlotView, mConfig.labelSpec,
494 mConfig.placeholderColor);
495 mSlotView.setSlotRenderer(mAlbumSetView);
496 mSlotView.setListener(new SlotView.SimpleListener() {
498 public void onDown(int index) {
499 AlbumSetPage.this.onDown(index);
503 public void onUp(boolean followedByLongPress) {
504 AlbumSetPage.this.onUp(followedByLongPress);
508 public void onSingleTapUp(int slotIndex) {
509 AlbumSetPage.this.onSingleTapUp(slotIndex);
513 public void onLongTap(int slotIndex) {
514 AlbumSetPage.this.onLongTap(slotIndex);
518 mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
519 mActionModeHandler.setActionModeListener(new ActionModeListener() {
521 public boolean onActionItemClicked(MenuItem item) {
522 return onItemSelected(item);
525 mRootPane.addComponent(mSlotView);
529 protected boolean onCreateActionBar(Menu menu) {
530 Activity activity = mActivity;
531 final boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
532 MenuInflater inflater = getSupportMenuInflater();
535 inflater.inflate(R.menu.pickup, menu);
536 int typeBits = mData.getInt(
537 Gallery.KEY_TYPE_BITS, DataManager.INCLUDE_IMAGE);
538 mActionBar.setTitle(GalleryUtils.getSelectionModePrompt(typeBits));
539 } else if (mGetAlbum) {
540 inflater.inflate(R.menu.pickup, menu);
541 mActionBar.setTitle(R.string.select_album);
543 inflater.inflate(R.menu.albumset, menu);
544 boolean wasShowingClusterMenu = mShowClusterMenu;
545 mShowClusterMenu = !inAlbum;
546 boolean selectAlbums = !inAlbum &&
547 mActionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM;
548 MenuItem selectItem = menu.findItem(R.id.action_select);
549 selectItem.setTitle(activity.getString(
550 selectAlbums ? R.string.select_album : R.string.select_group));
552 MenuItem cameraItem = menu.findItem(R.id.action_camera);
553 cameraItem.setVisible(GalleryUtils.isCameraAvailable(activity));
555 FilterUtils.setupMenuItems(mActionBar, mMediaSet.getPath(), false);
557 Intent helpIntent = HelpUtils.getHelpIntent(activity);
559 MenuItem helpItem = menu.findItem(R.id.action_general_help);
560 helpItem.setVisible(helpIntent != null);
561 if (helpIntent != null) helpItem.setIntent(helpIntent);
563 mActionBar.setTitle(mTitle);
564 mActionBar.setSubtitle(mSubtitle);
565 if (mShowClusterMenu != wasShowingClusterMenu) {
566 if (mShowClusterMenu) {
567 mActionBar.enableClusterMenu(mSelectedAction, this);
569 mActionBar.disableClusterMenu(true);
577 protected boolean onItemSelected(MenuItem item) {
578 Activity activity = mActivity;
579 switch (item.getItemId()) {
580 case R.id.action_cancel:
581 activity.setResult(Activity.RESULT_CANCELED);
584 case R.id.action_select:
585 mSelectionManager.setAutoLeaveSelectionMode(false);
586 mSelectionManager.enterSelectionMode();
588 case R.id.action_details:
589 if (mAlbumSetDataAdapter.size() != 0) {
596 Toast.makeText(activity,
597 activity.getText(R.string.no_albums_alert),
598 Toast.LENGTH_SHORT).show();
601 case R.id.action_camera: {
602 GalleryUtils.startCameraActivity(activity);
605 case R.id.action_manage_offline: {
606 Bundle data = new Bundle();
607 String mediaPath = mActivity.getDataManager().getTopSetPath(
608 DataManager.INCLUDE_ALL);
609 data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
610 mActivity.getStateManager().startState(ManageCachePage.class, data);
613 case R.id.action_sync_picasa_albums: {
614 PicasaSource.requestSync(activity);
617 case R.id.action_settings: {
618 activity.startActivity(new Intent(activity, GallerySettings.class));
627 protected void onStateResult(int requestCode, int resultCode, Intent data) {
628 if (data != null && data.getBooleanExtra(AlbumPage.KEY_EMPTY_ALBUM, false)) {
629 showEmptyAlbumToast(Toast.LENGTH_SHORT);
631 switch (requestCode) {
632 case REQUEST_DO_ANIMATION: {
633 mSlotView.startRisingAnimation();
638 private String getSelectedString() {
639 int count = mSelectionManager.getSelectedCount();
640 int action = mActionBar.getClusterTypeAction();
641 int string = action == FilterUtils.CLUSTER_BY_ALBUM
642 ? R.plurals.number_of_albums_selected
643 : R.plurals.number_of_groups_selected;
644 String format = mActivity.getResources().getQuantityString(string, count);
645 return String.format(format, count);
649 public void onSelectionModeChange(int mode) {
651 case SelectionManager.ENTER_SELECTION_MODE: {
652 mActionBar.disableClusterMenu(true);
653 mActionModeHandler.startActionMode();
654 performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
657 case SelectionManager.LEAVE_SELECTION_MODE: {
658 mActionModeHandler.finishActionMode();
659 if (mShowClusterMenu) {
660 mActionBar.enableClusterMenu(mSelectedAction, this);
662 mRootPane.invalidate();
665 case SelectionManager.SELECT_ALL_MODE: {
666 mActionModeHandler.updateSupportedOperation();
667 mRootPane.invalidate();
674 public void onSelectionChange(Path path, boolean selected) {
675 mActionModeHandler.setTitle(getSelectedString());
676 mActionModeHandler.updateSupportedOperation(path, selected);
679 private void hideDetails() {
680 mShowDetails = false;
681 mDetailsHelper.hide();
682 mAlbumSetView.setHighlightItemPath(null);
683 mSlotView.invalidate();
686 private void showDetails() {
688 if (mDetailsHelper == null) {
689 mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
690 mDetailsHelper.setCloseListener(new CloseListener() {
692 public void onClose() {
697 mDetailsHelper.show();
701 public void onSyncDone(final MediaSet mediaSet, final int resultCode) {
702 if (resultCode == MediaSet.SYNC_RESULT_ERROR) {
703 Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) + " result="
706 ((Activity) mActivity).runOnUiThread(new Runnable() {
709 GLRoot root = mActivity.getGLRoot();
710 root.lockRenderThread();
712 if (resultCode == MediaSet.SYNC_RESULT_SUCCESS) {
713 mInitialSynced = true;
715 clearLoadingBit(BIT_LOADING_SYNC);
716 if (resultCode == MediaSet.SYNC_RESULT_ERROR && mIsActive) {
717 Log.w(TAG, "failed to load album set");
720 root.unlockRenderThread();
726 private class MyLoadingListener implements LoadingListener {
728 public void onLoadingStarted() {
729 setLoadingBit(BIT_LOADING_RELOAD);
733 public void onLoadingFinished(boolean loadingFailed) {
734 clearLoadingBit(BIT_LOADING_RELOAD);
738 private class MyDetailsSource implements DetailsHelper.DetailsSource {
743 return mAlbumSetDataAdapter.size();
747 public int setIndex() {
748 Path id = mSelectionManager.getSelected(false).get(0);
749 mIndex = mAlbumSetDataAdapter.findSet(id);
754 public MediaDetails getDetails() {
755 MediaObject item = mAlbumSetDataAdapter.getMediaSet(mIndex);
757 mAlbumSetView.setHighlightItemPath(item.getPath());
758 return item.getDetails();