diff --git a/src/com/android/gallery3d/anim/AlphaAnimation.java b/src/com/android/gallery3d/anim/AlphaAnimation.java
new file mode 100644
index 0000000..cb17527
--- /dev/null
+++ b/src/com/android/gallery3d/anim/AlphaAnimation.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.anim;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.ui.GLCanvas;
+
+public class AlphaAnimation extends CanvasAnimation {
+    private final float mStartAlpha;
+    private final float mEndAlpha;
+    private float mCurrentAlpha;
+
+    public AlphaAnimation(float from, float to) {
+        mStartAlpha = from;
+        mEndAlpha = to;
+        mCurrentAlpha = from;
+    }
+
+    @Override
+    public void apply(GLCanvas canvas) {
+        canvas.multiplyAlpha(mCurrentAlpha);
+    }
+
+    @Override
+    public int getCanvasSaveFlags() {
+        return GLCanvas.SAVE_FLAG_ALPHA;
+    }
+
+    @Override
+    protected void onCalculate(float progress) {
+        mCurrentAlpha = Utils.clamp(mStartAlpha
+                + (mEndAlpha - mStartAlpha) * progress, 0f, 1f);
+    }
+}
diff --git a/src/com/android/gallery3d/anim/Animation.java b/src/com/android/gallery3d/anim/Animation.java
new file mode 100644
index 0000000..bd5a6cd
--- /dev/null
+++ b/src/com/android/gallery3d/anim/Animation.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.anim;
+
+import com.android.gallery3d.common.Utils;
+
+import android.view.animation.Interpolator;
+
+// Animation calculates a value according to the current input time.
+//
+// 1. First we need to use setDuration(int) to set the duration of the
+//    animation. The duration is in milliseconds.
+// 2. Then we should call start(). The actual start time is the first value
+//    passed to calculate(long).
+// 3. Each time we want to get an animation value, we call
+//    calculate(long currentTimeMillis) to ask the Animation to calculate it.
+//    The parameter passed to calculate(long) should be nonnegative.
+// 4. Use get() to get that value.
+//
+// In step 3, onCalculate(float progress) is called so subclasses can calculate
+// the value according to progress (progress is a value in [0,1]).
+//
+// Before onCalculate(float) is called, There is an optional interpolator which
+// can change the progress value. The interpolator can be set by
+// setInterpolator(Interpolator). If the interpolator is used, the value passed
+// to onCalculate may be (for example, the overshoot effect).
+//
+// The isActive() method returns true after the animation start() is called and
+// before calculate is passed a value which reaches the duration of the
+// animation.
+//
+// The start() method can be called again to restart the Animation.
+//
+abstract public class Animation {
+    private static final long ANIMATION_START = -1;
+    private static final long NO_ANIMATION = -2;
+
+    private long mStartTime = NO_ANIMATION;
+    private int mDuration;
+    private Interpolator mInterpolator;
+
+    public void setInterpolator(Interpolator interpolator) {
+        mInterpolator = interpolator;
+    }
+
+    public void setDuration(int duration) {
+        mDuration = duration;
+    }
+
+    public void start() {
+        mStartTime = ANIMATION_START;
+    }
+
+    public void setStartTime(long time) {
+        mStartTime = time;
+    }
+
+    public boolean isActive() {
+        return mStartTime != NO_ANIMATION;
+    }
+
+    public void forceStop() {
+        mStartTime = NO_ANIMATION;
+    }
+
+    public boolean calculate(long currentTimeMillis) {
+        if (mStartTime == NO_ANIMATION) return false;
+        if (mStartTime == ANIMATION_START) mStartTime = currentTimeMillis;
+        int elapse = (int) (currentTimeMillis - mStartTime);
+        float x = Utils.clamp((float) elapse / mDuration, 0f, 1f);
+        Interpolator i = mInterpolator;
+        onCalculate(i != null ? i.getInterpolation(x) : x);
+        if (elapse >= mDuration) mStartTime = NO_ANIMATION;
+        return mStartTime != NO_ANIMATION;
+    }
+
+    abstract protected void onCalculate(float progress);
+}
diff --git a/src/com/android/gallery3d/anim/AnimationSet.java b/src/com/android/gallery3d/anim/AnimationSet.java
new file mode 100644
index 0000000..773cb43
--- /dev/null
+++ b/src/com/android/gallery3d/anim/AnimationSet.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.anim;
+
+import com.android.gallery3d.ui.GLCanvas;
+
+import java.util.ArrayList;
+
+public class AnimationSet extends CanvasAnimation {
+
+    private final ArrayList<CanvasAnimation> mAnimations =
+            new ArrayList<CanvasAnimation>();
+    private int mSaveFlags = 0;
+
+
+    public void addAnimation(CanvasAnimation anim) {
+        mAnimations.add(anim);
+        mSaveFlags |= anim.getCanvasSaveFlags();
+    }
+
+    @Override
+    public void apply(GLCanvas canvas) {
+        for (int i = 0, n = mAnimations.size(); i < n; i++) {
+            mAnimations.get(i).apply(canvas);
+        }
+    }
+
+    @Override
+    public int getCanvasSaveFlags() {
+        return mSaveFlags;
+    }
+
+    @Override
+    protected void onCalculate(float progress) {
+        // DO NOTHING
+    }
+
+    @Override
+    public boolean calculate(long currentTimeMillis) {
+        boolean more = false;
+        for (CanvasAnimation anim : mAnimations) {
+            more |= anim.calculate(currentTimeMillis);
+        }
+        return more;
+    }
+
+    @Override
+    public void start() {
+        for (CanvasAnimation anim : mAnimations) {
+            anim.start();
+        }
+    }
+
+    @Override
+    public boolean isActive() {
+        for (CanvasAnimation anim : mAnimations) {
+            if (anim.isActive()) return true;
+        }
+        return false;
+    }
+
+}
diff --git a/src/com/android/gallery3d/anim/CanvasAnimation.java b/src/com/android/gallery3d/anim/CanvasAnimation.java
new file mode 100644
index 0000000..4c8bcc8
--- /dev/null
+++ b/src/com/android/gallery3d/anim/CanvasAnimation.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.anim;
+
+import com.android.gallery3d.ui.GLCanvas;
+
+public abstract class CanvasAnimation extends Animation {
+
+    public abstract int getCanvasSaveFlags();
+    public abstract void apply(GLCanvas canvas);
+}
diff --git a/src/com/android/gallery3d/anim/FloatAnimation.java b/src/com/android/gallery3d/anim/FloatAnimation.java
new file mode 100644
index 0000000..1294ec2
--- /dev/null
+++ b/src/com/android/gallery3d/anim/FloatAnimation.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.anim;
+
+public class FloatAnimation extends Animation {
+
+    private final float mFrom;
+    private final float mTo;
+    private float mCurrent;
+
+    public FloatAnimation(float from, float to, int duration) {
+        mFrom = from;
+        mTo = to;
+        mCurrent = from;
+        setDuration(duration);
+    }
+
+    @Override
+    protected void onCalculate(float progress) {
+        mCurrent = mFrom + (mTo - mFrom) * progress;
+    }
+
+    public float get() {
+        return mCurrent;
+    }
+}
diff --git a/src/com/android/gallery3d/app/AbstractGalleryActivity.java b/src/com/android/gallery3d/app/AbstractGalleryActivity.java
new file mode 100644
index 0000000..d0d7b0f
--- /dev/null
+++ b/src/com/android/gallery3d/app/AbstractGalleryActivity.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.ImageCacheService;
+import com.android.gallery3d.ui.GLRoot;
+import com.android.gallery3d.ui.GLRootView;
+import com.android.gallery3d.ui.PositionRepository;
+import com.android.gallery3d.util.ThreadPool;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+
+public class AbstractGalleryActivity extends Activity implements GalleryActivity {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AbstractGalleryActivity";
+    private GLRootView mGLRootView;
+    private StateManager mStateManager;
+    private PositionRepository mPositionRepository = new PositionRepository();
+
+    private AlertDialog mAlertDialog = null;
+    private BroadcastReceiver mMountReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (getExternalCacheDir() != null) onStorageReady();
+        }
+    };
+    private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        mGLRootView.lockRenderThread();
+        try {
+            super.onSaveInstanceState(outState);
+            getStateManager().saveState(outState);
+        } finally {
+            mGLRootView.unlockRenderThread();
+        }
+    }
+
+    public Context getAndroidContext() {
+        return this;
+    }
+
+    public ImageCacheService getImageCacheService() {
+        return ((GalleryApp) getApplication()).getImageCacheService();
+    }
+
+    public DataManager getDataManager() {
+        return ((GalleryApp) getApplication()).getDataManager();
+    }
+
+    public ThreadPool getThreadPool() {
+        return ((GalleryApp) getApplication()).getThreadPool();
+    }
+
+    public GalleryApp getGalleryApplication() {
+        return (GalleryApp) getApplication();
+    }
+
+    public synchronized StateManager getStateManager() {
+        if (mStateManager == null) {
+            mStateManager = new StateManager(this);
+        }
+        return mStateManager;
+    }
+
+    public GLRoot getGLRoot() {
+        return mGLRootView;
+    }
+
+    public PositionRepository getPositionRepository() {
+        return mPositionRepository;
+    }
+
+    @Override
+    public void setContentView(int resId) {
+        super.setContentView(resId);
+        mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
+    }
+
+    public int getActionBarHeight() {
+        ActionBar actionBar = getActionBar();
+        return actionBar != null ? actionBar.getHeight() : 0;
+    }
+
+    protected void onStorageReady() {
+        if (mAlertDialog != null) {
+            mAlertDialog.dismiss();
+            mAlertDialog = null;
+            unregisterReceiver(mMountReceiver);
+        }
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        if (getExternalCacheDir() == null) {
+            OnCancelListener onCancel = new OnCancelListener() {
+                @Override
+                public void onCancel(DialogInterface dialog) {
+                    finish();
+                }
+            };
+            OnClickListener onClick = new OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    dialog.cancel();
+                }
+            };
+            mAlertDialog = new AlertDialog.Builder(this)
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setTitle("No Storage")
+                    .setMessage("No external storage available.")
+                    .setNegativeButton(android.R.string.cancel, onClick)
+                    .setOnCancelListener(onCancel)
+                    .show();
+            registerReceiver(mMountReceiver, mMountFilter);
+        }
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        if (mAlertDialog != null) {
+            unregisterReceiver(mMountReceiver);
+            mAlertDialog.dismiss();
+            mAlertDialog = null;
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mGLRootView.lockRenderThread();
+        try {
+            getStateManager().resume();
+            getDataManager().resume();
+        } finally {
+            mGLRootView.unlockRenderThread();
+        }
+        mGLRootView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mGLRootView.onPause();
+        mGLRootView.lockRenderThread();
+        try {
+            getStateManager().pause();
+            getDataManager().pause();
+        } finally {
+            mGLRootView.unlockRenderThread();
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        mGLRootView.lockRenderThread();
+        try {
+            getStateManager().notifyActivityResult(
+                    requestCode, resultCode, data);
+        } finally {
+            mGLRootView.unlockRenderThread();
+        }
+    }
+
+    @Override
+    public GalleryActionBar getGalleryActionBar() {
+        return null;
+    }
+}
diff --git a/src/com/android/gallery3d/app/ActivityState.java b/src/com/android/gallery3d/app/ActivityState.java
new file mode 100644
index 0000000..bfacc54
--- /dev/null
+++ b/src/com/android/gallery3d/app/ActivityState.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.ui.GLView;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+
+abstract public class ActivityState {
+    public static final int FLAG_HIDE_ACTION_BAR = 1;
+    public static final int FLAG_HIDE_STATUS_BAR = 2;
+
+    protected GalleryActivity mActivity;
+    protected Bundle mData;
+    protected int mFlags;
+
+    protected ResultEntry mReceivedResults;
+    protected ResultEntry mResult;
+
+    protected static class ResultEntry {
+        public int requestCode;
+        public int resultCode = Activity.RESULT_CANCELED;
+        public Intent resultData;
+        ResultEntry next;
+    }
+
+    protected ActivityState() {
+    }
+
+    protected void setContentPane(GLView content) {
+        mActivity.getGLRoot().setContentPane(content);
+    }
+
+    void initialize(GalleryActivity activity, Bundle data) {
+        mActivity = activity;
+        mData = data;
+    }
+
+    public Bundle getData() {
+        return mData;
+    }
+
+    protected void onBackPressed() {
+        mActivity.getStateManager().finishState(this);
+    }
+
+    protected void setStateResult(int resultCode, Intent data) {
+        if (mResult == null) return;
+        mResult.resultCode = resultCode;
+        mResult.resultData = data;
+    }
+
+    protected void onSaveState(Bundle outState) {
+    }
+
+    protected void onStateResult(int requestCode, int resultCode, Intent data) {
+    }
+
+    protected void onCreate(Bundle data, Bundle storedState) {
+    }
+
+    protected void onPause() {
+    }
+
+    // should only be called by StateManager
+    void resume() {
+        Activity activity = (Activity) mActivity;
+        ActionBar actionBar = activity.getActionBar();
+        if (actionBar != null) {
+            if ((mFlags & FLAG_HIDE_ACTION_BAR) != 0) {
+                actionBar.hide();
+            } else {
+                actionBar.show();
+            }
+            int stateCount = mActivity.getStateManager().getStateCount();
+            actionBar.setDisplayOptions(
+                    stateCount == 1 ? 0 : ActionBar.DISPLAY_HOME_AS_UP,
+                    ActionBar.DISPLAY_HOME_AS_UP);
+        }
+
+        activity.invalidateOptionsMenu();
+
+        if ((mFlags & FLAG_HIDE_STATUS_BAR) != 0) {
+            WindowManager.LayoutParams params = ((Activity) mActivity).getWindow().getAttributes();
+            params.systemUiVisibility = View.STATUS_BAR_HIDDEN;
+            ((Activity) mActivity).getWindow().setAttributes(params);
+        } else {
+            WindowManager.LayoutParams params = ((Activity) mActivity).getWindow().getAttributes();
+            params.systemUiVisibility = View.STATUS_BAR_VISIBLE;
+            ((Activity) mActivity).getWindow().setAttributes(params);
+        }
+
+        ResultEntry entry = mReceivedResults;
+        if (entry != null) {
+            mReceivedResults = null;
+            onStateResult(entry.requestCode, entry.resultCode, entry.resultData);
+        }
+        onResume();
+    }
+
+    // a subclass of ActivityState should override the method to resume itself
+    protected void onResume() {
+    }
+
+    protected boolean onCreateActionBar(Menu menu) {
+        return false;
+    }
+
+    protected boolean onItemSelected(MenuItem item) {
+        return false;
+    }
+
+    protected void onDestroy() {
+    }
+}
diff --git a/src/com/android/gallery3d/app/AlbumDataAdapter.java b/src/com/android/gallery3d/app/AlbumDataAdapter.java
new file mode 100644
index 0000000..9934cf8
--- /dev/null
+++ b/src/com/android/gallery3d/app/AlbumDataAdapter.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.ui.AlbumView;
+import com.android.gallery3d.ui.SynchronizedHandler;
+
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+
+public class AlbumDataAdapter implements AlbumView.Model {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AlbumDataAdapter";
+    private static final int DATA_CACHE_SIZE = 1000;
+
+    private static final int MSG_LOAD_START = 1;
+    private static final int MSG_LOAD_FINISH = 2;
+    private static final int MSG_RUN_OBJECT = 3;
+
+    private static final int MIN_LOAD_COUNT = 32;
+    private static final int MAX_LOAD_COUNT = 64;
+
+    private final MediaItem[] mData;
+    private final long[] mItemVersion;
+    private final long[] mSetVersion;
+
+    private int mActiveStart = 0;
+    private int mActiveEnd = 0;
+
+    private int mContentStart = 0;
+    private int mContentEnd = 0;
+
+    private final MediaSet mSource;
+    private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
+
+    private final Handler mMainHandler;
+    private int mSize = 0;
+
+    private AlbumView.ModelListener mModelListener;
+    private MySourceListener mSourceListener = new MySourceListener();
+    private LoadingListener mLoadingListener;
+
+    private ReloadTask mReloadTask;
+
+    public AlbumDataAdapter(GalleryActivity context, MediaSet mediaSet) {
+        mSource = mediaSet;
+
+        mData = new MediaItem[DATA_CACHE_SIZE];
+        mItemVersion = new long[DATA_CACHE_SIZE];
+        mSetVersion = new long[DATA_CACHE_SIZE];
+        Arrays.fill(mItemVersion, MediaObject.INVALID_DATA_VERSION);
+        Arrays.fill(mSetVersion, MediaObject.INVALID_DATA_VERSION);
+
+        mMainHandler = new SynchronizedHandler(context.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_RUN_OBJECT:
+                        ((Runnable) message.obj).run();
+                        return;
+                    case MSG_LOAD_START:
+                        if (mLoadingListener != null) mLoadingListener.onLoadingStarted();
+                        return;
+                    case MSG_LOAD_FINISH:
+                        if (mLoadingListener != null) mLoadingListener.onLoadingFinished();
+                        return;
+                }
+            }
+        };
+    }
+
+    public void resume() {
+        mSource.addContentListener(mSourceListener);
+        mReloadTask = new ReloadTask();
+        mReloadTask.start();
+    }
+
+    public void pause() {
+        mReloadTask.terminate();
+        mReloadTask = null;
+        mSource.removeContentListener(mSourceListener);
+    }
+
+    public MediaItem get(int index) {
+        if (!isActive(index)) {
+            throw new IllegalArgumentException(String.format(
+                    "%s not in (%s, %s)", index, mActiveStart, mActiveEnd));
+        }
+        return mData[index % mData.length];
+    }
+
+    public int getActiveStart() {
+        return mActiveStart;
+    }
+
+    public int getActiveEnd() {
+        return mActiveEnd;
+    }
+
+    public boolean isActive(int index) {
+        return index >= mActiveStart && index < mActiveEnd;
+    }
+
+    public int size() {
+        return mSize;
+    }
+
+    private void clearSlot(int slotIndex) {
+        mData[slotIndex] = null;
+        mItemVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
+        mSetVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
+    }
+
+    private void setContentWindow(int contentStart, int contentEnd) {
+        if (contentStart == mContentStart && contentEnd == mContentEnd) return;
+        int end = mContentEnd;
+        int start = mContentStart;
+
+        // We need change the content window before calling reloadData(...)
+        synchronized (this) {
+            mContentStart = contentStart;
+            mContentEnd = contentEnd;
+        }
+        MediaItem[] data = mData;
+        long[] itemVersion = mItemVersion;
+        long[] setVersion = mSetVersion;
+        if (contentStart >= end || start >= contentEnd) {
+            for (int i = start, n = end; i < n; ++i) {
+                clearSlot(i % DATA_CACHE_SIZE);
+            }
+        } else {
+            for (int i = start; i < contentStart; ++i) {
+                clearSlot(i % DATA_CACHE_SIZE);
+            }
+            for (int i = contentEnd, n = end; i < n; ++i) {
+                clearSlot(i % DATA_CACHE_SIZE);
+            }
+        }
+        if (mReloadTask != null) mReloadTask.notifyDirty();
+    }
+
+    public void setActiveWindow(int start, int end) {
+        if (start == mActiveStart && end == mActiveEnd) return;
+
+        mActiveStart = start;
+        mActiveEnd = end;
+
+        Utils.assertTrue(start <= end
+                && end - start <= mData.length && end <= mSize);
+
+        int length = mData.length;
+        mActiveStart = start;
+        mActiveEnd = end;
+
+        // If no data is visible, keep the cache content
+        if (start == end) return;
+
+        int contentStart = Utils.clamp((start + end) / 2 - length / 2,
+                0, Math.max(0, mSize - length));
+        int contentEnd = Math.min(contentStart + length, mSize);
+        if (mContentStart > start || mContentEnd < end
+                || Math.abs(contentStart - mContentStart) > MIN_LOAD_COUNT) {
+            setContentWindow(contentStart, contentEnd);
+        }
+    }
+
+    private class MySourceListener implements ContentListener {
+        public void onContentDirty() {
+            if (mReloadTask != null) mReloadTask.notifyDirty();
+        }
+    }
+
+    public void setModelListener(AlbumView.ModelListener listener) {
+        mModelListener = listener;
+    }
+
+    public void setLoadingListener(LoadingListener listener) {
+        mLoadingListener = listener;
+    }
+
+    private <T> T executeAndWait(Callable<T> callable) {
+        FutureTask<T> task = new FutureTask<T>(callable);
+        mMainHandler.sendMessage(
+                mMainHandler.obtainMessage(MSG_RUN_OBJECT, task));
+        try {
+            return task.get();
+        } catch (InterruptedException e) {
+            return null;
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static class UpdateInfo {
+        public long version;
+        public int reloadStart;
+        public int reloadCount;
+
+        public int size;
+        public ArrayList<MediaItem> items;
+    }
+
+    private class GetUpdateInfo implements Callable<UpdateInfo> {
+        private final long mVersion;
+
+        public GetUpdateInfo(long version) {
+            mVersion = version;
+        }
+
+        public UpdateInfo call() throws Exception {
+            UpdateInfo info = new UpdateInfo();
+            long version = mVersion;
+            info.version = mSourceVersion;
+            info.size = mSize;
+            long setVersion[] = mSetVersion;
+            for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+                int index = i % DATA_CACHE_SIZE;
+                if (setVersion[index] != version) {
+                    info.reloadStart = i;
+                    info.reloadCount = Math.min(MAX_LOAD_COUNT, n - i);
+                    return info;
+                }
+            }
+            return mSourceVersion == mVersion ? null : info;
+        }
+    }
+
+    private class UpdateContent implements Callable<Void> {
+
+        private UpdateInfo mUpdateInfo;
+
+        public UpdateContent(UpdateInfo info) {
+            mUpdateInfo = info;
+        }
+
+        @Override
+        public Void call() throws Exception {
+            UpdateInfo info = mUpdateInfo;
+            mSourceVersion = info.version;
+            if (mSize != info.size) {
+                mSize = info.size;
+                if (mModelListener != null) mModelListener.onSizeChanged(mSize);
+                if (mContentEnd > mSize) mContentEnd = mSize;
+                if (mActiveEnd > mSize) mActiveEnd = mSize;
+            }
+
+            ArrayList<MediaItem> items = info.items;
+
+            if (items == null) return null;
+            int start = Math.max(info.reloadStart, mContentStart);
+            int end = Math.min(info.reloadStart + items.size(), mContentEnd);
+
+            for (int i = start; i < end; ++i) {
+                int index = i % DATA_CACHE_SIZE;
+                mSetVersion[index] = info.version;
+                MediaItem updateItem = items.get(i - info.reloadStart);
+                long itemVersion = updateItem.getDataVersion();
+                if (mItemVersion[index] != itemVersion) {
+                    mItemVersion[index] = itemVersion;
+                    mData[index] = updateItem;
+                    if (mModelListener != null && i >= mActiveStart && i < mActiveEnd) {
+                        mModelListener.onWindowContentChanged(i);
+                    }
+                }
+            }
+            return null;
+        }
+    }
+
+    /*
+     * The thread model of ReloadTask
+     *      *
+     * [Reload Task]       [Main Thread]
+     *       |                   |
+     * getUpdateInfo() -->       |           (synchronous call)
+     *     (wait) <----    getUpdateInfo()
+     *       |                   |
+     *   Load Data               |
+     *       |                   |
+     * updateContent() -->       |           (synchronous call)
+     *     (wait)          updateContent()
+     *       |                   |
+     *       |                   |
+     */
+    private class ReloadTask extends Thread {
+
+        private volatile boolean mActive = true;
+        private volatile boolean mDirty = true;
+        private boolean mIsLoading = false;
+
+        private void updateLoading(boolean loading) {
+            if (mIsLoading == loading) return;
+            mIsLoading = loading;
+            mMainHandler.sendEmptyMessage(loading ? MSG_LOAD_START : MSG_LOAD_FINISH);
+        }
+
+        @Override
+        public void run() {
+            boolean updateComplete = false;
+            while (mActive) {
+                synchronized (this) {
+                    if (mActive && !mDirty && updateComplete) {
+                        updateLoading(false);
+                        Utils.waitWithoutInterrupt(this);
+                        continue;
+                    }
+                }
+                mDirty = false;
+                updateLoading(true);
+                long version;
+                synchronized (DataManager.LOCK) {
+                    version = mSource.reload();
+                }
+                UpdateInfo info = executeAndWait(new GetUpdateInfo(version));
+                updateComplete = info == null;
+                if (updateComplete) continue;
+                synchronized (DataManager.LOCK) {
+                    if (info.version != version) {
+                        info.size = mSource.getMediaItemCount();
+                        info.version = version;
+                    }
+                    if (info.reloadCount > 0) {
+                        info.items = mSource.getMediaItem(info.reloadStart, info.reloadCount);
+                    }
+                }
+                executeAndWait(new UpdateContent(info));
+            }
+            updateLoading(false);
+        }
+
+        public synchronized void notifyDirty() {
+            mDirty = true;
+            notifyAll();
+        }
+
+        public synchronized void terminate() {
+            mActive = false;
+            notifyAll();
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/AlbumPage.java b/src/com/android/gallery3d/app/AlbumPage.java
new file mode 100644
index 0000000..5c09ce2
--- /dev/null
+++ b/src/com/android/gallery3d/app/AlbumPage.java
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaDetails;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.MtpDevice;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.ActionModeHandler;
+import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
+import com.android.gallery3d.ui.AlbumView;
+import com.android.gallery3d.ui.DetailsWindow;
+import com.android.gallery3d.ui.DetailsWindow.CloseListener;
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.GLView;
+import com.android.gallery3d.ui.GridDrawer;
+import com.android.gallery3d.ui.HighlightDrawer;
+import com.android.gallery3d.ui.PositionProvider;
+import com.android.gallery3d.ui.PositionRepository;
+import com.android.gallery3d.ui.PositionRepository.Position;
+import com.android.gallery3d.ui.SelectionManager;
+import com.android.gallery3d.ui.SlotView;
+import com.android.gallery3d.ui.StaticBackground;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View.MeasureSpec;
+import android.widget.Toast;
+
+import java.util.Random;
+
+public class AlbumPage extends ActivityState implements GalleryActionBar.ClusterRunner,
+        SelectionManager.SelectionListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AlbumPage";
+
+    public static final String KEY_MEDIA_PATH = "media-path";
+    public static final String KEY_SET_CENTER = "set-center";
+    public static final String KEY_AUTO_SELECT_ALL = "auto-select-all";
+    public static final String KEY_SHOW_CLUSTER_MENU = "cluster-menu";
+
+    private static final int REQUEST_SLIDESHOW = 1;
+    private static final int REQUEST_PHOTO = 2;
+    private static final int REQUEST_DO_ANIMATION = 3;
+
+    private static final float USER_DISTANCE_METER = 0.3f;
+
+    private boolean mIsActive = false;
+    private StaticBackground mStaticBackground;
+    private AlbumView mAlbumView;
+    private Path mMediaSetPath;
+
+    private AlbumDataAdapter mAlbumDataAdapter;
+
+    protected SelectionManager mSelectionManager;
+    private GridDrawer mGridDrawer;
+    private HighlightDrawer mHighlightDrawer;
+
+    private boolean mGetContent;
+    private boolean mShowClusterMenu;
+
+    private ActionMode mActionMode;
+    private ActionModeHandler mActionModeHandler;
+    private int mFocusIndex = 0;
+    private DetailsWindow mDetailsWindow;
+    private MediaSet mMediaSet;
+    private boolean mShowDetails;
+    private float mUserDistance; // in pixel
+
+    private ProgressDialog mProgressDialog;
+    private Future<?> mPendingTask;
+
+    private Future<Void> mSyncTask = null;
+
+    private GLView mRootPane = new GLView() {
+        private float mMatrix[] = new float[16];
+
+        @Override
+        protected void onLayout(
+                boolean changed, int left, int top, int right, int bottom) {
+            mStaticBackground.layout(0, 0, right - left, bottom - top);
+
+            int slotViewTop = GalleryActionBar.getHeight((Activity) mActivity);
+            int slotViewBottom = bottom - top;
+            int slotViewRight = right - left;
+
+            if (mShowDetails) {
+                mDetailsWindow.measure(
+                        MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+                int width = mDetailsWindow.getMeasuredWidth();
+                int detailLeft = right - left - width;
+                slotViewRight = detailLeft;
+                mDetailsWindow.layout(detailLeft, slotViewTop, detailLeft + width,
+                        bottom - top);
+            } else {
+                mAlbumView.setSelectionDrawer(mGridDrawer);
+            }
+
+            mAlbumView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
+            GalleryUtils.setViewPointMatrix(mMatrix,
+                    (right - left) / 2, (bottom - top) / 2, -mUserDistance);
+            PositionRepository.getInstance(mActivity).setOffset(
+                    0, slotViewTop);
+        }
+
+        @Override
+        protected void render(GLCanvas canvas) {
+            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+            canvas.multiplyMatrix(mMatrix, 0);
+            super.render(canvas);
+            canvas.restore();
+        }
+    };
+
+    @Override
+    protected void onBackPressed() {
+        if (mShowDetails) {
+            hideDetails();
+        } else if (mSelectionManager.inSelectionMode()) {
+            mSelectionManager.leaveSelectionMode();
+        } else {
+            mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
+            super.onBackPressed();
+        }
+    }
+
+    public void onSingleTapUp(int slotIndex) {
+        MediaItem item = mAlbumDataAdapter.get(slotIndex);
+        if (item == null) {
+            Log.w(TAG, "item not ready yet, ignore the click");
+            return;
+        }
+        if (mShowDetails) {
+            mHighlightDrawer.setHighlightItem(item.getPath());
+            mDetailsWindow.reloadDetails(slotIndex);
+        } else if (!mSelectionManager.inSelectionMode()) {
+            if (mGetContent) {
+                onGetContent(item);
+            } else {
+                boolean playVideo =
+                    (item.getSupportedOperations() & MediaItem.SUPPORT_PLAY) != 0;
+                if (playVideo) {
+                    // Play the video.
+                    PhotoPage.playVideo((Activity) mActivity, item.getPlayUri(), item.getName());
+                } else {
+                    // Get into the PhotoPage.
+                    Bundle data = new Bundle();
+                    mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
+                    data.putInt(PhotoPage.KEY_INDEX_HINT, slotIndex);
+                    data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
+                            mMediaSetPath.toString());
+                    data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH,
+                            item.getPath().toString());
+                    mActivity.getStateManager().startStateForResult(
+                            PhotoPage.class, REQUEST_PHOTO, data);
+                }
+            }
+        } else {
+            mSelectionManager.toggle(item.getPath());
+            mAlbumView.invalidate();
+        }
+    }
+
+    private void onGetContent(final MediaItem item) {
+        DataManager dm = mActivity.getDataManager();
+        Activity activity = (Activity) mActivity;
+        if (mData.getString(Gallery.EXTRA_CROP) != null) {
+            // TODO: Handle MtpImagew
+            Uri uri = dm.getContentUri(item.getPath());
+            Intent intent = new Intent(CropImage.ACTION_CROP, uri)
+                    .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
+                    .putExtras(getData());
+            if (mData.getParcelable(MediaStore.EXTRA_OUTPUT) == null) {
+                intent.putExtra(CropImage.KEY_RETURN_DATA, true);
+            }
+            activity.startActivity(intent);
+            activity.finish();
+        } else {
+            activity.setResult(Activity.RESULT_OK,
+                    new Intent(null, item.getContentUri()));
+            activity.finish();
+        }
+    }
+
+    public void onLongTap(int slotIndex) {
+        if (mGetContent) return;
+        if (mShowDetails) {
+            onSingleTapUp(slotIndex);
+        } else {
+            MediaItem item = mAlbumDataAdapter.get(slotIndex);
+            if (item == null) return;
+            mSelectionManager.setAutoLeaveSelectionMode(true);
+            mSelectionManager.toggle(item.getPath());
+            mAlbumView.invalidate();
+        }
+    }
+
+    public void doCluster(int clusterType) {
+        String basePath = mMediaSet.getPath().toString();
+        String newPath = FilterUtils.newClusterPath(basePath, clusterType);
+        Bundle data = new Bundle(getData());
+        data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
+        if (mShowClusterMenu) {
+            Context context = mActivity.getAndroidContext();
+            data.putString(AlbumSetPage.KEY_SET_TITLE, mMediaSet.getName());
+            data.putString(AlbumSetPage.KEY_SET_SUBTITLE,
+                    GalleryActionBar.getClusterByTypeString(context, clusterType));
+        }
+
+        mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
+        mActivity.getStateManager().startStateForResult(
+                AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
+    }
+
+    public void doFilter(int filterType) {
+        String basePath = mMediaSet.getPath().toString();
+        String newPath = FilterUtils.switchFilterPath(basePath, filterType);
+        Bundle data = new Bundle(getData());
+        data.putString(AlbumPage.KEY_MEDIA_PATH, newPath);
+        mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
+        mActivity.getStateManager().switchState(this, AlbumPage.class, data);
+    }
+
+    public void onOperationComplete() {
+        mAlbumView.invalidate();
+        // TODO: enable animation
+    }
+
+    @Override
+    protected void onCreate(Bundle data, Bundle restoreState) {
+        mUserDistance = GalleryUtils.meterToPixel(USER_DISTANCE_METER);
+        initializeViews();
+        initializeData(data);
+        mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
+        mShowClusterMenu = data.getBoolean(KEY_SHOW_CLUSTER_MENU, false);
+
+        startTransition(data);
+
+        // Enable auto-select-all for mtp album
+        if (data.getBoolean(KEY_AUTO_SELECT_ALL)) {
+            mSelectionManager.selectAll();
+        }
+    }
+
+    private void startTransition() {
+        final PositionRepository repository =
+                PositionRepository.getInstance(mActivity);
+        mAlbumView.startTransition(new PositionProvider() {
+            private Position mTempPosition = new Position();
+            public Position getPosition(long identity, Position target) {
+                Position p = repository.get(identity);
+                if (p != null) return p;
+                mTempPosition.set(target);
+                mTempPosition.z = 128;
+                return mTempPosition;
+            }
+        });
+    }
+
+    private void startTransition(Bundle data) {
+        final PositionRepository repository =
+                PositionRepository.getInstance(mActivity);
+        final int[] center = data == null
+                ? null
+                : data.getIntArray(KEY_SET_CENTER);
+        final Random random = new Random();
+        mAlbumView.startTransition(new PositionProvider() {
+            private Position mTempPosition = new Position();
+            public Position getPosition(long identity, Position target) {
+                Position p = repository.get(identity);
+                if (p != null) return p;
+                if (center != null) {
+                    random.setSeed(identity);
+                    mTempPosition.set(center[0], center[1],
+                            0, random.nextInt(60) - 30, 0);
+                } else {
+                    mTempPosition.set(target);
+                    mTempPosition.z = 128;
+                }
+                return mTempPosition;
+            }
+        });
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mIsActive = true;
+        setContentPane(mRootPane);
+        mAlbumDataAdapter.resume();
+        mAlbumView.resume();
+        mActionModeHandler.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mIsActive = false;
+        mAlbumDataAdapter.pause();
+        mAlbumView.pause();
+        if (mDetailsWindow != null) {
+            mDetailsWindow.pause();
+        }
+        Future<?> task = mPendingTask;
+        if (task != null) {
+            // cancel on going task
+            task.cancel();
+            task.waitDone();
+            if (mProgressDialog != null) {
+                mProgressDialog.dismiss();
+                mProgressDialog = null;
+            }
+        }
+        if (mSyncTask != null) {
+            mSyncTask.cancel();
+            mSyncTask = null;
+        }
+        mActionModeHandler.pause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (mAlbumDataAdapter != null) {
+            mAlbumDataAdapter.setLoadingListener(null);
+        }
+    }
+
+    private void initializeViews() {
+        mStaticBackground = new StaticBackground((Context) mActivity);
+        mRootPane.addComponent(mStaticBackground);
+
+        mSelectionManager = new SelectionManager(mActivity, false);
+        mSelectionManager.setSelectionListener(this);
+        mGridDrawer = new GridDrawer((Context) mActivity, mSelectionManager);
+        Config.AlbumPage config = Config.AlbumPage.get((Context) mActivity);
+        mAlbumView = new AlbumView(mActivity,
+                config.slotWidth, config.slotHeight, config.displayItemSize);
+        mAlbumView.setSelectionDrawer(mGridDrawer);
+        mRootPane.addComponent(mAlbumView);
+        mAlbumView.setListener(new SlotView.SimpleListener() {
+            @Override
+            public void onSingleTapUp(int slotIndex) {
+                AlbumPage.this.onSingleTapUp(slotIndex);
+            }
+            @Override
+            public void onLongTap(int slotIndex) {
+                AlbumPage.this.onLongTap(slotIndex);
+            }
+        });
+        mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
+        mActionModeHandler.setActionModeListener(new ActionModeListener() {
+            public boolean onActionItemClicked(MenuItem item) {
+                return onItemSelected(item);
+            }
+        });
+        mStaticBackground.setImage(R.drawable.background,
+                R.drawable.background_portrait);
+    }
+
+    private void initializeData(Bundle data) {
+        mMediaSetPath = Path.fromString(data.getString(KEY_MEDIA_PATH));
+        mMediaSet = mActivity.getDataManager().getMediaSet(mMediaSetPath);
+        Utils.assertTrue(mMediaSet != null,
+                "MediaSet is null. Path = %s", mMediaSetPath);
+        mSelectionManager.setSourceMediaSet(mMediaSet);
+        mAlbumDataAdapter = new AlbumDataAdapter(mActivity, mMediaSet);
+        mAlbumDataAdapter.setLoadingListener(new MyLoadingListener());
+        mAlbumView.setModel(mAlbumDataAdapter);
+    }
+
+    private void showDetails() {
+        mShowDetails = true;
+        if (mDetailsWindow == null) {
+            mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext());
+            mDetailsWindow = new DetailsWindow(mActivity, new MyDetailsSource());
+            mDetailsWindow.setCloseListener(new CloseListener() {
+                public void onClose() {
+                    hideDetails();
+                }
+            });
+            mRootPane.addComponent(mDetailsWindow);
+        }
+        mAlbumView.setSelectionDrawer(mHighlightDrawer);
+        mDetailsWindow.show();
+    }
+
+    private void hideDetails() {
+        mShowDetails = false;
+        mAlbumView.setSelectionDrawer(mGridDrawer);
+        mDetailsWindow.hide();
+    }
+
+    @Override
+    protected boolean onCreateActionBar(Menu menu) {
+        Activity activity = (Activity) mActivity;
+        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+        MenuInflater inflater = activity.getMenuInflater();
+
+        if (mGetContent) {
+            inflater.inflate(R.menu.pickup, menu);
+            int typeBits = mData.getInt(Gallery.KEY_TYPE_BITS,
+                    DataManager.INCLUDE_IMAGE);
+
+            actionBar.setTitle(GalleryUtils.getSelectionModePrompt(typeBits));
+        } else {
+            inflater.inflate(R.menu.album, menu);
+            actionBar.setTitle(mMediaSet.getName());
+            if (mMediaSet instanceof MtpDevice) {
+                menu.findItem(R.id.action_slideshow).setVisible(false);
+            } else {
+                menu.findItem(R.id.action_slideshow).setVisible(true);
+            }
+
+            MenuItem groupBy = menu.findItem(R.id.action_group_by);
+            FilterUtils.setupMenuItems(actionBar, mMediaSetPath, true);
+
+            if (groupBy != null) {
+                groupBy.setVisible(mShowClusterMenu);
+            }
+
+            actionBar.setTitle(mMediaSet.getName());
+        }
+        actionBar.setSubtitle(null);
+
+        return true;
+    }
+
+    @Override
+    protected boolean onItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.action_select:
+                mSelectionManager.setAutoLeaveSelectionMode(false);
+                mSelectionManager.enterSelectionMode();
+                return true;
+            case R.id.action_group_by: {
+                mActivity.getGalleryActionBar().showClusterDialog(this);
+                return true;
+            }
+            case R.id.action_slideshow: {
+                Bundle data = new Bundle();
+                data.putString(SlideshowPage.KEY_SET_PATH,
+                        mMediaSetPath.toString());
+                data.putBoolean(SlideshowPage.KEY_REPEAT, true);
+                mActivity.getStateManager().startStateForResult(
+                        SlideshowPage.class, REQUEST_SLIDESHOW, data);
+                return true;
+            }
+            case R.id.action_details: {
+                if (mShowDetails) {
+                    hideDetails();
+                } else {
+                    showDetails();
+                }
+                return true;
+            }
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    protected void onStateResult(int request, int result, Intent data) {
+        switch (request) {
+            case REQUEST_SLIDESHOW: {
+                // data could be null, if there is no images in the album
+                if (data == null) return;
+                mFocusIndex = data.getIntExtra(SlideshowPage.KEY_PHOTO_INDEX, 0);
+                mAlbumView.setCenterIndex(mFocusIndex);
+                break;
+            }
+            case REQUEST_PHOTO: {
+                if (data == null) return;
+                mFocusIndex = data.getIntExtra(PhotoPage.KEY_INDEX_HINT, 0);
+                mAlbumView.setCenterIndex(mFocusIndex);
+                startTransition();
+                break;
+            }
+            case REQUEST_DO_ANIMATION: {
+                startTransition(null);
+                break;
+            }
+        }
+    }
+
+    public void onSelectionModeChange(int mode) {
+        switch (mode) {
+            case SelectionManager.ENTER_SELECTION_MODE: {
+                mActionMode = mActionModeHandler.startActionMode();
+                break;
+            }
+            case SelectionManager.LEAVE_SELECTION_MODE: {
+                mActionMode.finish();
+                mRootPane.invalidate();
+                break;
+            }
+            case SelectionManager.SELECT_ALL_MODE: {
+                int count = mSelectionManager.getSelectedCount();
+                String format = mActivity.getResources().getQuantityString(
+                        R.plurals.number_of_items_selected, count);
+                mActionModeHandler.setTitle(String.format(format, count));
+                mActionModeHandler.updateSupportedOperation();
+                mRootPane.invalidate();
+                break;
+            }
+        }
+    }
+
+    public void onSelectionChange(Path path, boolean selected) {
+        Utils.assertTrue(mActionMode != null);
+        int count = mSelectionManager.getSelectedCount();
+        String format = mActivity.getResources().getQuantityString(
+                R.plurals.number_of_items_selected, count);
+        mActionModeHandler.setTitle(String.format(format, count));
+        mActionModeHandler.updateSupportedOperation(path, selected);
+    }
+
+    private class MyLoadingListener implements LoadingListener {
+        @Override
+        public void onLoadingStarted() {
+            GalleryUtils.setSpinnerVisibility((Activity) mActivity, true);
+        }
+
+        @Override
+        public void onLoadingFinished() {
+            if (!mIsActive) return;
+            if (mAlbumDataAdapter.size() == 0) {
+                if (mSyncTask == null) {
+                    mSyncTask = mMediaSet.requestSync();
+                }
+                if (mSyncTask.isDone()){
+                    Toast.makeText((Context) mActivity,
+                            R.string.empty_album, Toast.LENGTH_LONG).show();
+                    mActivity.getStateManager().finishState(AlbumPage.this);
+                }
+            }
+            if (mSyncTask == null || mSyncTask.isDone()) {
+                GalleryUtils.setSpinnerVisibility((Activity) mActivity, false);
+            }
+        }
+    }
+
+    private class MyDetailsSource implements DetailsWindow.DetailsSource {
+        private int mIndex;
+        public int size() {
+            return mAlbumDataAdapter.size();
+        }
+
+        // If requested index is out of active window, suggest a valid index.
+        // If there is no valid index available, return -1.
+        public int findIndex(int indexHint) {
+            if (mAlbumDataAdapter.isActive(indexHint)) {
+                mIndex = indexHint;
+            } else {
+                mIndex = mAlbumDataAdapter.getActiveStart();
+                if (!mAlbumDataAdapter.isActive(mIndex)) {
+                    return -1;
+                }
+            }
+            return mIndex;
+        }
+
+        public MediaDetails getDetails() {
+            MediaObject item = mAlbumDataAdapter.get(mIndex);
+            if (item != null) {
+                mHighlightDrawer.setHighlightItem(item.getPath());
+                return item.getDetails();
+            } else {
+                return null;
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/AlbumPicker.java b/src/com/android/gallery3d/app/AlbumPicker.java
new file mode 100644
index 0000000..b86aee8
--- /dev/null
+++ b/src/com/android/gallery3d/app/AlbumPicker.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.ui.GLRoot;
+import com.android.gallery3d.ui.GLRootView;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+public class AlbumPicker extends AbstractGalleryActivity
+        implements OnClickListener {
+
+    public static final String KEY_ALBUM_PATH = "album-path";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.dialog_picker);
+        ((GLRootView) findViewById(R.id.gl_root_view)).setZOrderOnTop(true);
+        findViewById(R.id.cancel).setOnClickListener(this);
+        setTitle(R.string.select_album);
+        Intent intent = getIntent();
+        Bundle extras = intent.getExtras();
+        Bundle data = extras == null ? new Bundle() : new Bundle(extras);
+
+        data.putBoolean(Gallery.KEY_GET_ALBUM, true);
+        data.putString(AlbumSetPage.KEY_MEDIA_PATH,
+                getDataManager().getTopSetPath(DataManager.INCLUDE_IMAGE));
+        getStateManager().startState(AlbumSetPage.class, data);
+    }
+
+    @Override
+    public void onBackPressed() {
+        // send the back event to the top sub-state
+        GLRoot root = getGLRoot();
+        root.lockRenderThread();
+        try {
+            getStateManager().getTopState().onBackPressed();
+        } finally {
+            root.unlockRenderThread();
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.cancel) finish();
+    }
+}
diff --git a/src/com/android/gallery3d/app/AlbumSetDataAdapter.java b/src/com/android/gallery3d/app/AlbumSetDataAdapter.java
new file mode 100644
index 0000000..9086ddb
--- /dev/null
+++ b/src/com/android/gallery3d/app/AlbumSetDataAdapter.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.ui.AlbumSetView;
+import com.android.gallery3d.ui.SynchronizedHandler;
+
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+
+public class AlbumSetDataAdapter implements AlbumSetView.Model {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AlbumSetDataAdapter";
+
+    private static final int INDEX_NONE = -1;
+
+    private static final int MIN_LOAD_COUNT = 4;
+    private static final int MAX_COVER_COUNT = 4;
+
+    private static final int MSG_LOAD_START = 1;
+    private static final int MSG_LOAD_FINISH = 2;
+    private static final int MSG_RUN_OBJECT = 3;
+
+    private static final MediaItem[] EMPTY_MEDIA_ITEMS = new MediaItem[0];
+
+    private final MediaSet[] mData;
+    private final MediaItem[][] mCoverData;
+    private final long[] mItemVersion;
+    private final long[] mSetVersion;
+
+    private int mActiveStart = 0;
+    private int mActiveEnd = 0;
+
+    private int mContentStart = 0;
+    private int mContentEnd = 0;
+
+    private final MediaSet mSource;
+    private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
+    private int mSize;
+
+    private AlbumSetView.ModelListener mModelListener;
+    private LoadingListener mLoadingListener;
+    private ReloadTask mReloadTask;
+
+    private final Handler mMainHandler;
+
+    private MySourceListener mSourceListener = new MySourceListener();
+
+    public AlbumSetDataAdapter(GalleryActivity activity, MediaSet albumSet, int cacheSize) {
+        mSource = Utils.checkNotNull(albumSet);
+        mCoverData = new MediaItem[cacheSize][];
+        mData = new MediaSet[cacheSize];
+        mItemVersion = new long[cacheSize];
+        mSetVersion = new long[cacheSize];
+        Arrays.fill(mItemVersion, MediaObject.INVALID_DATA_VERSION);
+        Arrays.fill(mSetVersion, MediaObject.INVALID_DATA_VERSION);
+
+        mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_RUN_OBJECT:
+                        ((Runnable) message.obj).run();
+                        return;
+                    case MSG_LOAD_START:
+                        if (mLoadingListener != null) mLoadingListener.onLoadingStarted();
+                        return;
+                    case MSG_LOAD_FINISH:
+                        if (mLoadingListener != null) mLoadingListener.onLoadingFinished();
+                        return;
+                }
+            }
+        };
+    }
+
+    public void pause() {
+        mReloadTask.terminate();
+        mReloadTask = null;
+        mSource.removeContentListener(mSourceListener);
+    }
+
+    public void resume() {
+        mSource.addContentListener(mSourceListener);
+        mReloadTask = new ReloadTask();
+        mReloadTask.start();
+    }
+
+    public MediaSet getMediaSet(int index) {
+        if (index < mActiveStart && index >= mActiveEnd) {
+            throw new IllegalArgumentException(String.format(
+                    "%s not in (%s, %s)", index, mActiveStart, mActiveEnd));
+        }
+        return mData[index % mData.length];
+    }
+
+    public MediaItem[] getCoverItems(int index) {
+        if (index < mActiveStart && index >= mActiveEnd) {
+            throw new IllegalArgumentException(String.format(
+                    "%s not in (%s, %s)", index, mActiveStart, mActiveEnd));
+        }
+        MediaItem[] result = mCoverData[index % mCoverData.length];
+
+        // If the result is not ready yet, return an empty array
+        return result == null ? EMPTY_MEDIA_ITEMS : result;
+    }
+
+    public int getActiveStart() {
+        return mActiveStart;
+    }
+
+    public int getActiveEnd() {
+        return mActiveEnd;
+    }
+
+    public boolean isActive(int index) {
+        return index >= mActiveStart && index < mActiveEnd;
+    }
+
+    public int size() {
+        return mSize;
+    }
+
+    private void clearSlot(int slotIndex) {
+        mData[slotIndex] = null;
+        mCoverData[slotIndex] = null;
+        mItemVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
+        mSetVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
+    }
+
+    private void setContentWindow(int contentStart, int contentEnd) {
+        if (contentStart == mContentStart && contentEnd == mContentEnd) return;
+        MediaItem[][] data = mCoverData;
+        int length = data.length;
+
+        int start = this.mContentStart;
+        int end = this.mContentEnd;
+
+        mContentStart = contentStart;
+        mContentEnd = contentEnd;
+
+        if (contentStart >= end || start >= contentEnd) {
+            for (int i = start, n = end; i < n; ++i) {
+                clearSlot(i % length);
+            }
+        } else {
+            for (int i = start; i < contentStart; ++i) {
+                clearSlot(i % length);
+            }
+            for (int i = contentEnd, n = end; i < n; ++i) {
+                clearSlot(i % length);
+            }
+        }
+        mReloadTask.notifyDirty();
+    }
+
+    public void setActiveWindow(int start, int end) {
+        if (start == mActiveStart && end == mActiveEnd) return;
+
+        Utils.assertTrue(start <= end
+                && end - start <= mCoverData.length && end <= mSize);
+
+        mActiveStart = start;
+        mActiveEnd = end;
+
+        int length = mCoverData.length;
+        // If no data is visible, keep the cache content
+        if (start == end) return;
+
+        int contentStart = Utils.clamp((start + end) / 2 - length / 2,
+                0, Math.max(0, mSize - length));
+        int contentEnd = Math.min(contentStart + length, mSize);
+        if (mContentStart > start || mContentEnd < end
+                || Math.abs(contentStart - mContentStart) > MIN_LOAD_COUNT) {
+            setContentWindow(contentStart, contentEnd);
+        }
+    }
+
+    private class MySourceListener implements ContentListener {
+        public void onContentDirty() {
+            mReloadTask.notifyDirty();
+        }
+    }
+
+    public void setModelListener(AlbumSetView.ModelListener listener) {
+        mModelListener = listener;
+    }
+
+    public void setLoadingListener(LoadingListener listener) {
+        mLoadingListener = listener;
+    }
+
+    private static void getRepresentativeItems(MediaSet set, int wanted,
+            ArrayList<MediaItem> result) {
+        if (set.getMediaItemCount() > 0) {
+            result.addAll(set.getMediaItem(0, wanted));
+        }
+
+        int n = set.getSubMediaSetCount();
+        for (int i = 0; i < n && wanted > result.size(); i++) {
+            MediaSet subset = set.getSubMediaSet(i);
+            double perSet = (double) (wanted - result.size()) / (n - i);
+            int m = (int) Math.ceil(perSet);
+            getRepresentativeItems(subset, m, result);
+        }
+    }
+
+    private static class UpdateInfo {
+        public long version;
+        public int index;
+
+        public int size;
+        public MediaSet item;
+        public MediaItem covers[];
+    }
+
+    private class GetUpdateInfo implements Callable<UpdateInfo> {
+
+        private final long mVersion;
+
+        public GetUpdateInfo(long version) {
+            mVersion = version;
+        }
+
+        private int getInvalidIndex(long version) {
+            long setVersion[] = mSetVersion;
+            int length = setVersion.length;
+            for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+                int index = i % length;
+                if (setVersion[i % length] != version) return i;
+            }
+            return INDEX_NONE;
+        }
+
+        @Override
+        public UpdateInfo call() throws Exception {
+            int index = getInvalidIndex(mVersion);
+            if (index == INDEX_NONE
+                    && mSourceVersion == mVersion) return null;
+            UpdateInfo info = new UpdateInfo();
+            info.version = mSourceVersion;
+            info.index = index;
+            info.size = mSize;
+            return info;
+        }
+    }
+
+    private class UpdateContent implements Callable<Void> {
+        private UpdateInfo mUpdateInfo;
+
+        public UpdateContent(UpdateInfo info) {
+            mUpdateInfo = info;
+        }
+
+        public Void call() {
+            UpdateInfo info = mUpdateInfo;
+            mSourceVersion = info.version;
+            if (mSize != info.size) {
+                mSize = info.size;
+                if (mModelListener != null) mModelListener.onSizeChanged(mSize);
+                if (mContentEnd > mSize) mContentEnd = mSize;
+                if (mActiveEnd > mSize) mActiveEnd = mSize;
+            }
+            // Note: info.index could be INDEX_NONE, i.e., -1
+            if (info.index >= mContentStart && info.index < mContentEnd) {
+                int pos = info.index % mCoverData.length;
+                mSetVersion[pos] = info.version;
+                long itemVersion = info.item.getDataVersion();
+                if (mItemVersion[pos] == itemVersion) return null;
+                mItemVersion[pos] = itemVersion;
+                mData[pos] = info.item;
+                mCoverData[pos] = info.covers;
+                if (mModelListener != null
+                        && info.index >= mActiveStart && info.index < mActiveEnd) {
+                    mModelListener.onWindowContentChanged(info.index);
+                }
+            }
+            return null;
+        }
+    }
+
+    private <T> T executeAndWait(Callable<T> callable) {
+        FutureTask<T> task = new FutureTask<T>(callable);
+        mMainHandler.sendMessage(
+                mMainHandler.obtainMessage(MSG_RUN_OBJECT, task));
+        try {
+            return task.get();
+        } catch (InterruptedException e) {
+            return null;
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // TODO: load active range first
+    private class ReloadTask extends Thread {
+        private volatile boolean mActive = true;
+        private volatile boolean mDirty = true;
+        private volatile boolean mIsLoading = false;
+
+        private void updateLoading(boolean loading) {
+            if (mIsLoading == loading) return;
+            mIsLoading = loading;
+            mMainHandler.sendEmptyMessage(loading ? MSG_LOAD_START : MSG_LOAD_FINISH);
+        }
+
+        @Override
+        public void run() {
+            boolean updateComplete = false;
+            while (mActive) {
+                synchronized (this) {
+                    if (mActive && !mDirty && updateComplete) {
+                        updateLoading(false);
+                        Utils.waitWithoutInterrupt(this);
+                        continue;
+                    }
+                }
+                mDirty = false;
+                updateLoading(true);
+
+                long version;
+                synchronized (DataManager.LOCK) {
+                    version = mSource.reload();
+                }
+                UpdateInfo info = executeAndWait(new GetUpdateInfo(version));
+                updateComplete = info == null;
+                if (updateComplete) continue;
+
+                synchronized (DataManager.LOCK) {
+                    if (info.version != version) {
+                        info.version = version;
+                        info.size = mSource.getSubMediaSetCount();
+                    }
+                    if (info.index != INDEX_NONE) {
+                        info.item = mSource.getSubMediaSet(info.index);
+                        if (info.item == null) continue;
+                        ArrayList<MediaItem> covers = new ArrayList<MediaItem>();
+                        getRepresentativeItems(info.item, MAX_COVER_COUNT, covers);
+                        info.covers = covers.toArray(new MediaItem[covers.size()]);
+                    }
+                }
+                executeAndWait(new UpdateContent(info));
+            }
+            updateLoading(false);
+        }
+
+        public synchronized void notifyDirty() {
+            mDirty = true;
+            notifyAll();
+        }
+
+        public synchronized void terminate() {
+            mActive = false;
+            notifyAll();
+        }
+    }
+}
+
+
diff --git a/src/com/android/gallery3d/app/AlbumSetPage.java b/src/com/android/gallery3d/app/AlbumSetPage.java
new file mode 100644
index 0000000..688ff81
--- /dev/null
+++ b/src/com/android/gallery3d/app/AlbumSetPage.java
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaDetails;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.picasasource.PicasaSource;
+import com.android.gallery3d.settings.GallerySettings;
+import com.android.gallery3d.ui.ActionModeHandler;
+import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
+import com.android.gallery3d.ui.AlbumSetView;
+import com.android.gallery3d.ui.DetailsWindow;
+import com.android.gallery3d.ui.DetailsWindow.CloseListener;
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.GLView;
+import com.android.gallery3d.ui.GridDrawer;
+import com.android.gallery3d.ui.HighlightDrawer;
+import com.android.gallery3d.ui.PositionProvider;
+import com.android.gallery3d.ui.PositionRepository;
+import com.android.gallery3d.ui.PositionRepository.Position;
+import com.android.gallery3d.ui.SelectionManager;
+import com.android.gallery3d.ui.SlotView;
+import com.android.gallery3d.ui.StaticBackground;
+import com.android.gallery3d.ui.SynchronizedHandler;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Message;
+import android.provider.MediaStore;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View.MeasureSpec;
+import android.widget.Toast;
+
+public class AlbumSetPage extends ActivityState implements
+        SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner,
+        EyePosition.EyePositionListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AlbumSetPage";
+
+    public static final String KEY_MEDIA_PATH = "media-path";
+    public static final String KEY_SET_TITLE = "set-title";
+    public static final String KEY_SET_SUBTITLE = "set-subtitle";
+    private static final int DATA_CACHE_SIZE = 256;
+    private static final int REQUEST_DO_ANIMATION = 1;
+    private static final int MSG_GOTO_MANAGE_CACHE_PAGE = 1;
+
+    private boolean mIsActive = false;
+    private StaticBackground mStaticBackground;
+    private AlbumSetView mAlbumSetView;
+
+    private MediaSet mMediaSet;
+    private String mTitle;
+    private String mSubtitle;
+    private boolean mShowClusterTabs;
+
+    protected SelectionManager mSelectionManager;
+    private AlbumSetDataAdapter mAlbumSetDataAdapter;
+    private GridDrawer mGridDrawer;
+    private HighlightDrawer mHighlightDrawer;
+
+    private boolean mGetContent;
+    private boolean mGetAlbum;
+    private ActionMode mActionMode;
+    private ActionModeHandler mActionModeHandler;
+    private DetailsWindow mDetailsWindow;
+    private boolean mShowDetails;
+    private EyePosition mEyePosition;
+
+    // The eyes' position of the user, the origin is at the center of the
+    // device and the unit is in pixels.
+    private float mX;
+    private float mY;
+    private float mZ;
+
+    private SynchronizedHandler mHandler;
+
+    private GLView mRootPane = new GLView() {
+        private float mMatrix[] = new float[16];
+
+        @Override
+        protected void onLayout(
+                boolean changed, int left, int top, int right, int bottom) {
+            mStaticBackground.layout(0, 0, right - left, bottom - top);
+            mEyePosition.resetPosition();
+
+            int slotViewTop = GalleryActionBar.getHeight((Activity) mActivity);
+            int slotViewBottom = bottom - top;
+            int slotViewRight = right - left;
+
+            if (mShowDetails) {
+                mDetailsWindow.measure(
+                        MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+                int width = mDetailsWindow.getMeasuredWidth();
+                int detailLeft = right - left - width;
+                slotViewRight = detailLeft;
+                mDetailsWindow.layout(detailLeft, slotViewTop, detailLeft + width,
+                        bottom - top);
+            } else {
+                mAlbumSetView.setSelectionDrawer(mGridDrawer);
+            }
+
+            mAlbumSetView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
+            PositionRepository.getInstance(mActivity).setOffset(
+                    0, slotViewTop);
+        }
+
+        @Override
+        protected void render(GLCanvas canvas) {
+            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+            GalleryUtils.setViewPointMatrix(mMatrix,
+                    getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
+            canvas.multiplyMatrix(mMatrix, 0);
+            super.render(canvas);
+            canvas.restore();
+        }
+    };
+
+    @Override
+    public void onEyePositionChanged(float x, float y, float z) {
+        mRootPane.lockRendering();
+        mX = x;
+        mY = y;
+        mZ = z;
+        mRootPane.unlockRendering();
+        mRootPane.invalidate();
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (mShowDetails) {
+            hideDetails();
+        } else if (mSelectionManager.inSelectionMode()) {
+            mSelectionManager.leaveSelectionMode();
+        } else {
+            mAlbumSetView.savePositions(
+                    PositionRepository.getInstance(mActivity));
+            super.onBackPressed();
+        }
+    }
+
+    private void savePositions(int slotIndex, int center[]) {
+        Rect offset = new Rect();
+        mRootPane.getBoundsOf(mAlbumSetView, offset);
+        mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
+        Rect r = mAlbumSetView.getSlotRect(slotIndex);
+        int scrollX = mAlbumSetView.getScrollX();
+        int scrollY = mAlbumSetView.getScrollY();
+        center[0] = offset.left + (r.left + r.right) / 2 - scrollX;
+        center[1] = offset.top + (r.top + r.bottom) / 2 - scrollY;
+    }
+
+    public void onSingleTapUp(int slotIndex) {
+        MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
+        if (targetSet == null) return; // Content is dirty, we shall reload soon
+
+        if (mShowDetails) {
+            Path path = targetSet.getPath();
+            mHighlightDrawer.setHighlightItem(path);
+            mDetailsWindow.reloadDetails(slotIndex);
+        } else if (!mSelectionManager.inSelectionMode()) {
+            Bundle data = new Bundle(getData());
+            String mediaPath = targetSet.getPath().toString();
+            int[] center = new int[2];
+            savePositions(slotIndex, center);
+            data.putIntArray(AlbumPage.KEY_SET_CENTER, center);
+            if (mGetAlbum && targetSet.isLeafAlbum()) {
+                Activity activity = (Activity) mActivity;
+                Intent result = new Intent()
+                        .putExtra(AlbumPicker.KEY_ALBUM_PATH, targetSet.getPath().toString());
+                activity.setResult(Activity.RESULT_OK, result);
+                activity.finish();
+            } else if (targetSet.getSubMediaSetCount() > 0) {
+                data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
+                mActivity.getStateManager().startStateForResult(
+                        AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
+            } else {
+                if (!mGetContent && (targetSet.getSupportedOperations()
+                        & MediaObject.SUPPORT_IMPORT) != 0) {
+                    data.putBoolean(AlbumPage.KEY_AUTO_SELECT_ALL, true);
+                }
+                data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);
+                boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
+                // We only show cluster menu in the first AlbumPage in stack
+                data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
+                mActivity.getStateManager().startStateForResult(
+                        AlbumPage.class, REQUEST_DO_ANIMATION, data);
+            }
+        } else {
+            mSelectionManager.toggle(targetSet.getPath());
+            mAlbumSetView.invalidate();
+        }
+    }
+
+    public void onLongTap(int slotIndex) {
+        if (mGetContent || mGetAlbum) return;
+        if (mShowDetails) {
+            onSingleTapUp(slotIndex);
+        } else {
+            MediaSet set = mAlbumSetDataAdapter.getMediaSet(slotIndex);
+            if (set == null) return;
+            mSelectionManager.setAutoLeaveSelectionMode(true);
+            mSelectionManager.toggle(set.getPath());
+            mAlbumSetView.invalidate();
+        }
+    }
+
+    public void doCluster(int clusterType) {
+        String basePath = mMediaSet.getPath().toString();
+        String newPath = FilterUtils.switchClusterPath(basePath, clusterType);
+        Bundle data = new Bundle(getData());
+        data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
+        mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
+        mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
+    }
+
+    public void doFilter(int filterType) {
+        String basePath = mMediaSet.getPath().toString();
+        String newPath = FilterUtils.switchFilterPath(basePath, filterType);
+        Bundle data = new Bundle(getData());
+        data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
+        mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
+        mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
+    }
+
+    public void onOperationComplete() {
+        mAlbumSetView.invalidate();
+        // TODO: enable animation
+    }
+
+    @Override
+    public void onCreate(Bundle data, Bundle restoreState) {
+        mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                Utils.assertTrue(message.what == MSG_GOTO_MANAGE_CACHE_PAGE);
+                Bundle data = new Bundle();
+                String mediaPath = mActivity.getDataManager().getTopSetPath(
+                    DataManager.INCLUDE_ALL);
+                data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
+                mActivity.getStateManager().startState(ManageCachePage.class, data);
+            }
+        };
+
+        initializeViews();
+        initializeData(data);
+        mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
+        mGetAlbum = data.getBoolean(Gallery.KEY_GET_ALBUM, false);
+        mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE);
+        mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE);
+        mEyePosition = new EyePosition(mActivity.getAndroidContext(), this);
+
+        startTransition();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mIsActive = false;
+        mActionModeHandler.pause();
+        mAlbumSetDataAdapter.pause();
+        mAlbumSetView.pause();
+        mEyePosition.pause();
+        if (mDetailsWindow != null) {
+            mDetailsWindow.pause();
+        }
+        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+        if (actionBar != null) actionBar.hideClusterTabs();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mIsActive = true;
+        setContentPane(mRootPane);
+        mAlbumSetDataAdapter.resume();
+        mAlbumSetView.resume();
+        mEyePosition.resume();
+        mActionModeHandler.resume();
+        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+        if (mShowClusterTabs && actionBar != null) actionBar.showClusterTabs(this);
+    }
+
+    private void initializeData(Bundle data) {
+        String mediaPath = data.getString(AlbumSetPage.KEY_MEDIA_PATH);
+        mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
+        mSelectionManager.setSourceMediaSet(mMediaSet);
+        mAlbumSetDataAdapter = new AlbumSetDataAdapter(
+                mActivity, mMediaSet, DATA_CACHE_SIZE);
+        mAlbumSetDataAdapter.setLoadingListener(new MyLoadingListener());
+        mAlbumSetView.setModel(mAlbumSetDataAdapter);
+    }
+
+    private void initializeViews() {
+        mSelectionManager = new SelectionManager(mActivity, true);
+        mSelectionManager.setSelectionListener(this);
+        mStaticBackground = new StaticBackground(mActivity.getAndroidContext());
+        mRootPane.addComponent(mStaticBackground);
+
+        mGridDrawer = new GridDrawer((Context) mActivity, mSelectionManager);
+        Config.AlbumSetPage config = Config.AlbumSetPage.get((Context) mActivity);
+        mAlbumSetView = new AlbumSetView(mActivity, mGridDrawer,
+                config.slotWidth, config.slotHeight,
+                config.displayItemSize, config.labelFontSize,
+                config.labelOffsetY, config.labelMargin);
+        mAlbumSetView.setListener(new SlotView.SimpleListener() {
+            @Override
+            public void onSingleTapUp(int slotIndex) {
+                AlbumSetPage.this.onSingleTapUp(slotIndex);
+            }
+            @Override
+            public void onLongTap(int slotIndex) {
+                AlbumSetPage.this.onLongTap(slotIndex);
+            }
+        });
+
+        mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
+        mActionModeHandler.setActionModeListener(new ActionModeListener() {
+            public boolean onActionItemClicked(MenuItem item) {
+                return onItemSelected(item);
+            }
+        });
+        mRootPane.addComponent(mAlbumSetView);
+
+        mStaticBackground.setImage(R.drawable.background,
+                R.drawable.background_portrait);
+    }
+
+    @Override
+    protected boolean onCreateActionBar(Menu menu) {
+        Activity activity = (Activity) mActivity;
+        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+        MenuInflater inflater = activity.getMenuInflater();
+
+        final boolean inAlbum = mActivity.getStateManager().hasStateClass(
+                AlbumPage.class);
+
+        if (mGetContent) {
+            inflater.inflate(R.menu.pickup, menu);
+            int typeBits = mData.getInt(
+                    Gallery.KEY_TYPE_BITS, DataManager.INCLUDE_IMAGE);
+            int id = R.string.select_image;
+            if ((typeBits & DataManager.INCLUDE_VIDEO) != 0) {
+                id = (typeBits & DataManager.INCLUDE_IMAGE) == 0
+                        ? R.string.select_video
+                        : R.string.select_item;
+            }
+            actionBar.setTitle(id);
+        } else  if (mGetAlbum) {
+            inflater.inflate(R.menu.pickup, menu);
+            actionBar.setTitle(R.string.select_album);
+        } else {
+            mShowClusterTabs = !inAlbum;
+            inflater.inflate(R.menu.albumset, menu);
+            if (mTitle != null) {
+                actionBar.setTitle(mTitle);
+            } else {
+                actionBar.setTitle(activity.getApplicationInfo().labelRes);
+            }
+            MenuItem selectItem = menu.findItem(R.id.action_select);
+
+            if (selectItem != null) {
+                boolean selectAlbums = !inAlbum &&
+                        actionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM;
+                if (selectAlbums) {
+                    selectItem.setTitle(R.string.select_album);
+                } else {
+                    selectItem.setTitle(R.string.select_group);
+                }
+            }
+
+            MenuItem switchCamera = menu.findItem(R.id.action_camera);
+            if (switchCamera != null) {
+                switchCamera.setVisible(GalleryUtils.isCameraAvailable(activity));
+            }
+
+            actionBar.setSubtitle(mSubtitle);
+        }
+        return true;
+    }
+
+    @Override
+    protected boolean onItemSelected(MenuItem item) {
+        Activity activity = (Activity) mActivity;
+        switch (item.getItemId()) {
+            case R.id.action_select:
+                mSelectionManager.setAutoLeaveSelectionMode(false);
+                mSelectionManager.enterSelectionMode();
+                return true;
+            case R.id.action_details:
+                if (mAlbumSetDataAdapter.size() != 0) {
+                    if (mShowDetails) {
+                        hideDetails();
+                    } else {
+                        showDetails();
+                    }
+                } else {
+                    Toast.makeText(activity,
+                            activity.getText(R.string.no_albums_alert),
+                            Toast.LENGTH_SHORT).show();
+                }
+                return true;
+            case R.id.action_camera: {
+                Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
+                        .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+                        | Intent.FLAG_ACTIVITY_NEW_TASK);
+                activity.startActivity(intent);
+                return true;
+            }
+            case R.id.action_manage_offline: {
+                mHandler.sendEmptyMessage(MSG_GOTO_MANAGE_CACHE_PAGE);
+                return true;
+            }
+            case R.id.action_sync_picasa_albums: {
+                PicasaSource.requestSync(activity);
+                return true;
+            }
+            case R.id.action_settings: {
+                activity.startActivity(new Intent(activity, GallerySettings.class));
+                return true;
+            }
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    protected void onStateResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_DO_ANIMATION: {
+                startTransition();
+            }
+        }
+    }
+
+    private void startTransition() {
+        final PositionRepository repository =
+                PositionRepository.getInstance(mActivity);
+        mAlbumSetView.startTransition(new PositionProvider() {
+            private Position mTempPosition = new Position();
+            public Position getPosition(long identity, Position target) {
+                Position p = repository.get(identity);
+                if (p == null) {
+                    p = mTempPosition;
+                    p.set(target.x, target.y, 128, target.theta, 1);
+                }
+                return p;
+            }
+        });
+    }
+
+    private String getSelectedString() {
+        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+        int count = mSelectionManager.getSelectedCount();
+        int action = actionBar.getClusterTypeAction();
+        int string = action == FilterUtils.CLUSTER_BY_ALBUM
+                ? R.plurals.number_of_albums_selected
+                : R.plurals.number_of_groups_selected;
+        String format = mActivity.getResources().getQuantityString(string, count);
+        return String.format(format, count);
+    }
+
+    public void onSelectionModeChange(int mode) {
+
+        switch (mode) {
+            case SelectionManager.ENTER_SELECTION_MODE: {
+                mActivity.getGalleryActionBar().hideClusterTabs();
+                mActionMode = mActionModeHandler.startActionMode();
+                break;
+            }
+            case SelectionManager.LEAVE_SELECTION_MODE: {
+                mActionMode.finish();
+                mActivity.getGalleryActionBar().showClusterTabs(this);
+                mRootPane.invalidate();
+                break;
+            }
+            case SelectionManager.SELECT_ALL_MODE: {
+                mActionModeHandler.setTitle(getSelectedString());
+                mRootPane.invalidate();
+                break;
+            }
+        }
+    }
+
+    public void onSelectionChange(Path path, boolean selected) {
+        Utils.assertTrue(mActionMode != null);
+        mActionModeHandler.setTitle(getSelectedString());
+        mActionModeHandler.updateSupportedOperation(path, selected);
+    }
+
+    private void hideDetails() {
+        mShowDetails = false;
+        mAlbumSetView.setSelectionDrawer(mGridDrawer);
+        mDetailsWindow.hide();
+    }
+
+    private void showDetails() {
+        mShowDetails = true;
+        if (mDetailsWindow == null) {
+            mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext());
+            mDetailsWindow = new DetailsWindow(mActivity, new MyDetailsSource());
+            mDetailsWindow.setCloseListener(new CloseListener() {
+                public void onClose() {
+                    hideDetails();
+                }
+            });
+            mRootPane.addComponent(mDetailsWindow);
+        }
+        mAlbumSetView.setSelectionDrawer(mHighlightDrawer);
+        mDetailsWindow.show();
+    }
+
+    private class MyLoadingListener implements LoadingListener {
+        public void onLoadingStarted() {
+            GalleryUtils.setSpinnerVisibility((Activity) mActivity, true);
+        }
+
+        public void onLoadingFinished() {
+            if (!mIsActive) return;
+            GalleryUtils.setSpinnerVisibility((Activity) mActivity, false);
+            if (mAlbumSetDataAdapter.size() == 0) {
+                Toast.makeText((Context) mActivity,
+                        R.string.empty_album, Toast.LENGTH_LONG).show();
+                if (mActivity.getStateManager().getStateCount() > 1) {
+                    mActivity.getStateManager().finishState(AlbumSetPage.this);
+                }
+            }
+        }
+    }
+
+    private class MyDetailsSource implements DetailsWindow.DetailsSource {
+        private int mIndex;
+        public int size() {
+            return mAlbumSetDataAdapter.size();
+        }
+
+        // If requested index is out of active window, suggest a valid index.
+        // If there is no valid index available, return -1.
+        public int findIndex(int indexHint) {
+            if (mAlbumSetDataAdapter.isActive(indexHint)) {
+                mIndex = indexHint;
+            } else {
+                mIndex = mAlbumSetDataAdapter.getActiveStart();
+                if (!mAlbumSetDataAdapter.isActive(mIndex)) {
+                    return -1;
+                }
+            }
+            return mIndex;
+        }
+
+        public MediaDetails getDetails() {
+            MediaObject item = mAlbumSetDataAdapter.getMediaSet(mIndex);
+            if (item != null) {
+                mHighlightDrawer.setHighlightItem(item.getPath());
+                return item.getDetails();
+            } else {
+                return null;
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/Config.java b/src/com/android/gallery3d/app/Config.java
new file mode 100644
index 0000000..4586235
--- /dev/null
+++ b/src/com/android/gallery3d/app/Config.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+final class Config {
+    public static class AlbumSetPage {
+        private static AlbumSetPage sInstance;
+
+        public final int slotWidth;
+        public final int slotHeight;
+        public final int displayItemSize;
+        public final int labelFontSize;
+        public final int labelOffsetY;
+        public final int labelMargin;
+
+        public static synchronized AlbumSetPage get(Context context) {
+            if (sInstance == null) {
+                sInstance = new AlbumSetPage(context);
+            }
+            return sInstance;
+        }
+
+        private AlbumSetPage(Context context) {
+            Resources r = context.getResources();
+            slotWidth = r.getDimensionPixelSize(R.dimen.albumset_slot_width);
+            slotHeight = r.getDimensionPixelSize(R.dimen.albumset_slot_height);
+            displayItemSize = r.getDimensionPixelSize(R.dimen.albumset_display_item_size);
+            labelFontSize = r.getDimensionPixelSize(R.dimen.albumset_label_font_size);
+            labelOffsetY = r.getDimensionPixelSize(R.dimen.albumset_label_offset_y);
+            labelMargin = r.getDimensionPixelSize(R.dimen.albumset_label_margin);
+        }
+    }
+
+    public static class AlbumPage {
+        private static AlbumPage sInstance;
+
+        public final int slotWidth;
+        public final int slotHeight;
+        public final int displayItemSize;
+
+        public static synchronized AlbumPage get(Context context) {
+            if (sInstance == null) {
+                sInstance = new AlbumPage(context);
+            }
+            return sInstance;
+        }
+
+        private AlbumPage(Context context) {
+            Resources r = context.getResources();
+            slotWidth = r.getDimensionPixelSize(R.dimen.album_slot_width);
+            slotHeight = r.getDimensionPixelSize(R.dimen.album_slot_height);
+            displayItemSize = r.getDimensionPixelSize(R.dimen.album_display_item_size);
+        }
+    }
+
+    public static class ManageCachePage extends AlbumSetPage {
+        private static ManageCachePage sInstance;
+
+        public final int cacheBarHeight;
+        public final int cacheBarPinLeftMargin;
+        public final int cacheBarPinRightMargin;
+        public final int cacheBarButtonRightMargin;
+        public final int cacheBarFontSize;
+
+        public static synchronized ManageCachePage get(Context context) {
+            if (sInstance == null) {
+                sInstance = new ManageCachePage(context);
+            }
+            return sInstance;
+        }
+
+        public ManageCachePage(Context context) {
+            super(context);
+            Resources r = context.getResources();
+            cacheBarHeight = r.getDimensionPixelSize(R.dimen.cache_bar_height);
+            cacheBarPinLeftMargin = r.getDimensionPixelSize(R.dimen.cache_bar_pin_left_margin);
+            cacheBarPinRightMargin = r.getDimensionPixelSize(
+                    R.dimen.cache_bar_pin_right_margin);
+            cacheBarButtonRightMargin = r.getDimensionPixelSize(
+                    R.dimen.cache_bar_button_right_margin);
+            cacheBarFontSize = r.getDimensionPixelSize(R.dimen.cache_bar_font_size);
+        }
+    }
+
+    public static class PhotoPage {
+        private static PhotoPage sInstance;
+
+        // These are all height values. See the comment in FilmStripView for
+        // the meaning of these values.
+        public final int filmstripTopMargin;
+        public final int filmstripMidMargin;
+        public final int filmstripBottomMargin;
+        public final int filmstripThumbSize;
+        public final int filmstripContentSize;
+        public final int filmstripGripSize;
+        public final int filmstripBarSize;
+
+        // These are width values.
+        public final int filmstripGripWidth;
+
+        public static synchronized PhotoPage get(Context context) {
+            if (sInstance == null) {
+                sInstance = new PhotoPage(context);
+            }
+            return sInstance;
+        }
+
+        public PhotoPage(Context context) {
+            Resources r = context.getResources();
+            filmstripTopMargin = r.getDimensionPixelSize(R.dimen.filmstrip_top_margin);
+            filmstripMidMargin = r.getDimensionPixelSize(R.dimen.filmstrip_mid_margin);
+            filmstripBottomMargin = r.getDimensionPixelSize(R.dimen.filmstrip_bottom_margin);
+            filmstripThumbSize = r.getDimensionPixelSize(R.dimen.filmstrip_thumb_size);
+            filmstripContentSize = r.getDimensionPixelSize(R.dimen.filmstrip_content_size);
+            filmstripGripSize = r.getDimensionPixelSize(R.dimen.filmstrip_grip_size);
+            filmstripBarSize = r.getDimensionPixelSize(R.dimen.filmstrip_bar_size);
+            filmstripGripWidth = r.getDimensionPixelSize(R.dimen.filmstrip_grip_width);
+        }
+    }
+}
+
diff --git a/src/com/android/gallery3d/app/CropImage.java b/src/com/android/gallery3d/app/CropImage.java
new file mode 100644
index 0000000..6c0a0c7
--- /dev/null
+++ b/src/com/android/gallery3d/app/CropImage.java
@@ -0,0 +1,850 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.LocalImage;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.picasasource.PicasaSource;
+import com.android.gallery3d.ui.BitmapTileProvider;
+import com.android.gallery3d.ui.CropView;
+import com.android.gallery3d.ui.GLRoot;
+import com.android.gallery3d.ui.SynchronizedHandler;
+import com.android.gallery3d.ui.TileImageViewAdapter;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.InterruptableOutputStream;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.app.ProgressDialog;
+import android.app.WallpaperManager;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.MediaStore;
+import android.provider.MediaStore.Images;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.Window;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The activity can crop specific region of interest from an image.
+ */
+public class CropImage extends AbstractGalleryActivity {
+    private static final String TAG = "CropImage";
+    public static final String ACTION_CROP = "com.android.camera.action.CROP";
+
+    private static final int MAX_PIXEL_COUNT = 5 * 1000000; // 5M pixels
+    private static final int MAX_FILE_INDEX = 1000;
+    private static final int TILE_SIZE = 512;
+    private static final int BACKUP_PIXEL_COUNT = 480000; // around 800x600
+
+    private static final int MSG_LARGE_BITMAP = 1;
+    private static final int MSG_BITMAP = 2;
+    private static final int MSG_SAVE_COMPLETE = 3;
+
+    private static final int MAX_BACKUP_IMAGE_SIZE = 320;
+    private static final int DEFAULT_COMPRESS_QUALITY = 90;
+
+    public static final String KEY_RETURN_DATA = "return-data";
+    public static final String KEY_CROPPED_RECT = "cropped-rect";
+    public static final String KEY_ASPECT_X = "aspectX";
+    public static final String KEY_ASPECT_Y = "aspectY";
+    public static final String KEY_SPOTLIGHT_X = "spotlightX";
+    public static final String KEY_SPOTLIGHT_Y = "spotlightY";
+    public static final String KEY_OUTPUT_X = "outputX";
+    public static final String KEY_OUTPUT_Y = "outputY";
+    public static final String KEY_SCALE = "scale";
+    public static final String KEY_DATA = "data";
+    public static final String KEY_SCALE_UP_IF_NEEDED = "scaleUpIfNeeded";
+    public static final String KEY_OUTPUT_FORMAT = "outputFormat";
+    public static final String KEY_SET_AS_WALLPAPER = "set-as-wallpaper";
+    public static final String KEY_NO_FACE_DETECTION = "noFaceDetection";
+
+    private static final String KEY_STATE = "state";
+
+    private static final int STATE_INIT = 0;
+    private static final int STATE_LOADED = 1;
+    private static final int STATE_SAVING = 2;
+
+    public static final String DOWNLOAD_STRING = "download";
+    public static final File DOWNLOAD_BUCKET = new File(
+            Environment.getExternalStorageDirectory(), DOWNLOAD_STRING);
+
+    public static final String CROP_ACTION = "com.android.camera.action.CROP";
+
+    private int mState = STATE_INIT;
+
+    private CropView mCropView;
+
+    private boolean mDoFaceDetection = true;
+
+    private Handler mMainHandler;
+
+    // We keep the following members so that we can free them
+
+    // mBitmap is the unrotated bitmap we pass in to mCropView for detect faces.
+    // mCropView is responsible for rotating it to the way that it is viewed by users.
+    private Bitmap mBitmap;
+    private BitmapTileProvider mBitmapTileProvider;
+    private BitmapRegionDecoder mRegionDecoder;
+    private Bitmap mBitmapInIntent;
+    private boolean mUseRegionDecoder = false;
+
+    private ProgressDialog mProgressDialog;
+    private Future<BitmapRegionDecoder> mLoadTask;
+    private Future<Bitmap> mLoadBitmapTask;
+    private Future<Intent> mSaveTask;
+
+    private MediaItem mMediaItem;
+
+    @Override
+    public void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        requestWindowFeature(Window.FEATURE_ACTION_BAR);
+        requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
+
+        // Initialize UI
+        setContentView(R.layout.cropimage);
+        mCropView = new CropView(this);
+        getGLRoot().setContentPane(mCropView);
+
+        mMainHandler = new SynchronizedHandler(getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_LARGE_BITMAP: {
+                        mProgressDialog.dismiss();
+                        onBitmapRegionDecoderAvailable((BitmapRegionDecoder) message.obj);
+                        break;
+                    }
+                    case MSG_BITMAP: {
+                        mProgressDialog.dismiss();
+                        onBitmapAvailable((Bitmap) message.obj);
+                        break;
+                    }
+                    case MSG_SAVE_COMPLETE: {
+                        mProgressDialog.dismiss();
+                        setResult(RESULT_OK, (Intent) message.obj);
+                        finish();
+                        break;
+                    }
+                }
+            }
+        };
+
+        setCropParameters();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle saveState) {
+        saveState.putInt(KEY_STATE, mState);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        getMenuInflater().inflate(R.menu.crop, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.cancel: {
+                setResult(RESULT_CANCELED);
+                finish();
+                break;
+            }
+            case R.id.save: {
+                onSaveClicked();
+                break;
+            }
+        }
+        return true;
+    }
+
+    private class SaveOutput implements Job<Intent> {
+        private RectF mCropRect;
+
+        public SaveOutput(RectF cropRect) {
+            mCropRect = cropRect;
+        }
+
+        public Intent run(JobContext jc) {
+            RectF cropRect = mCropRect;
+            Bundle extra = getIntent().getExtras();
+
+            Rect rect = new Rect(
+                    Math.round(cropRect.left), Math.round(cropRect.top),
+                    Math.round(cropRect.right), Math.round(cropRect.bottom));
+
+            Intent result = new Intent();
+            result.putExtra(KEY_CROPPED_RECT, rect);
+            Bitmap cropped = null;
+            boolean outputted = false;
+            if (extra != null) {
+                Uri uri = (Uri) extra.getParcelable(MediaStore.EXTRA_OUTPUT);
+                if (uri != null) {
+                    if (jc.isCancelled()) return null;
+                    outputted = true;
+                    cropped = getCroppedImage(rect);
+                    if (!saveBitmapToUri(jc, cropped, uri)) return null;
+                }
+                if (extra.getBoolean(KEY_RETURN_DATA, false)) {
+                    if (jc.isCancelled()) return null;
+                    outputted = true;
+                    if (cropped == null) cropped = getCroppedImage(rect);
+                    result.putExtra(KEY_DATA, cropped);
+                }
+                if (extra.getBoolean(KEY_SET_AS_WALLPAPER, false)) {
+                    if (jc.isCancelled()) return null;
+                    outputted = true;
+                    if (cropped == null) cropped = getCroppedImage(rect);
+                    if (!setAsWallpaper(jc, cropped)) return null;
+                }
+            }
+            if (!outputted) {
+                if (jc.isCancelled()) return null;
+                if (cropped == null) cropped = getCroppedImage(rect);
+                Uri data = saveToMediaProvider(jc, cropped);
+                if (data != null) result.setData(data);
+            }
+            return result;
+        }
+    }
+
+    public static String determineCompressFormat(MediaObject obj) {
+        String compressFormat = "JPEG";
+        if (obj instanceof MediaItem) {
+            String mime = ((MediaItem) obj).getMimeType();
+            if (mime.contains("png") || mime.contains("gif")) {
+              // Set the compress format to PNG for png and gif images
+              // because they may contain alpha values.
+              compressFormat = "PNG";
+            }
+        }
+        return compressFormat;
+    }
+
+    private boolean setAsWallpaper(JobContext jc, Bitmap wallpaper) {
+        try {
+            WallpaperManager.getInstance(this).setBitmap(wallpaper);
+        } catch (IOException e) {
+            Log.w(TAG, "fail to set wall paper", e);
+        }
+        return true;
+    }
+
+    private File saveMedia(
+            JobContext jc, Bitmap cropped, File directory, String filename) {
+        // Try file-1.jpg, file-2.jpg, ... until we find a filename
+        // which does not exist yet.
+        File candidate = null;
+        String fileExtension = getFileExtension();
+        for (int i = 1; i < MAX_FILE_INDEX; ++i) {
+            candidate = new File(directory, filename + "-" + i + "."
+                    + fileExtension);
+            try {
+                if (candidate.createNewFile()) break;
+            } catch (IOException e) {
+                Log.e(TAG, "fail to create new file: "
+                        + candidate.getAbsolutePath(), e);
+                return null;
+            }
+        }
+        if (!candidate.exists() || !candidate.isFile()) {
+            throw new RuntimeException("cannot create file: " + filename);
+        }
+
+        candidate.setReadable(true, false);
+        candidate.setWritable(true, false);
+
+        try {
+            FileOutputStream fos = new FileOutputStream(candidate);
+            try {
+                saveBitmapToOutputStream(jc, cropped,
+                        convertExtensionToCompressFormat(fileExtension), fos);
+            } finally {
+                fos.close();
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "fail to save image: "
+                    + candidate.getAbsolutePath(), e);
+            candidate.delete();
+            return null;
+        }
+
+        if (jc.isCancelled()) {
+            candidate.delete();
+            return null;
+        }
+
+        return candidate;
+    }
+
+    private Uri saveToMediaProvider(JobContext jc, Bitmap cropped) {
+        if (PicasaSource.isPicasaImage(mMediaItem)) {
+            return savePicasaImage(jc, cropped);
+        } else if (mMediaItem instanceof LocalImage) {
+            return saveLocalImage(jc, cropped);
+        } else {
+            Log.w(TAG, "no output for crop image " + mMediaItem);
+            return null;
+        }
+    }
+
+    private Uri savePicasaImage(JobContext jc, Bitmap cropped) {
+        if (!DOWNLOAD_BUCKET.isDirectory() && !DOWNLOAD_BUCKET.mkdirs()) {
+            throw new RuntimeException("cannot create download folder");
+        }
+
+        String filename = PicasaSource.getImageTitle(mMediaItem);
+        int pos = filename.lastIndexOf('.');
+        if (pos >= 0) filename = filename.substring(0, pos);
+        File output = saveMedia(jc, cropped, DOWNLOAD_BUCKET, filename);
+        if (output == null) return null;
+
+        long now = System.currentTimeMillis() / 1000;
+        ContentValues values = new ContentValues();
+        values.put(Images.Media.TITLE, PicasaSource.getImageTitle(mMediaItem));
+        values.put(Images.Media.DISPLAY_NAME, output.getName());
+        values.put(Images.Media.DATE_TAKEN, PicasaSource.getDateTaken(mMediaItem));
+        values.put(Images.Media.DATE_MODIFIED, now);
+        values.put(Images.Media.DATE_ADDED, now);
+        values.put(Images.Media.MIME_TYPE, "image/jpeg");
+        values.put(Images.Media.ORIENTATION, 0);
+        values.put(Images.Media.DATA, output.getAbsolutePath());
+        values.put(Images.Media.SIZE, output.length());
+
+        double latitude = PicasaSource.getLatitude(mMediaItem);
+        double longitude = PicasaSource.getLongitude(mMediaItem);
+        if (GalleryUtils.isValidLocation(latitude, longitude)) {
+            values.put(Images.Media.LATITUDE, latitude);
+            values.put(Images.Media.LONGITUDE, longitude);
+        }
+        return getContentResolver().insert(
+                Images.Media.EXTERNAL_CONTENT_URI, values);
+    }
+
+    private Uri saveLocalImage(JobContext jc, Bitmap cropped) {
+        LocalImage localImage = (LocalImage) mMediaItem;
+
+        File oldPath = new File(localImage.filePath);
+        File directory = new File(oldPath.getParent());
+
+        String filename = oldPath.getName();
+        int pos = filename.lastIndexOf('.');
+        if (pos >= 0) filename = filename.substring(0, pos);
+        File output = saveMedia(jc, cropped, directory, filename);
+        if (output == null) return null;
+
+        long now = System.currentTimeMillis() / 1000;
+        ContentValues values = new ContentValues();
+        values.put(Images.Media.TITLE, localImage.caption);
+        values.put(Images.Media.DISPLAY_NAME, output.getName());
+        values.put(Images.Media.DATE_TAKEN, localImage.dateTakenInMs);
+        values.put(Images.Media.DATE_MODIFIED, now);
+        values.put(Images.Media.DATE_ADDED, now);
+        values.put(Images.Media.MIME_TYPE, "image/jpeg");
+        values.put(Images.Media.ORIENTATION, 0);
+        values.put(Images.Media.DATA, output.getAbsolutePath());
+        values.put(Images.Media.SIZE, output.length());
+
+        if (GalleryUtils.isValidLocation(localImage.latitude, localImage.longitude)) {
+            values.put(Images.Media.LATITUDE, localImage.latitude);
+            values.put(Images.Media.LONGITUDE, localImage.longitude);
+        }
+        return getContentResolver().insert(
+                Images.Media.EXTERNAL_CONTENT_URI, values);
+    }
+
+    private boolean saveBitmapToOutputStream(
+            JobContext jc, Bitmap bitmap, CompressFormat format, OutputStream os) {
+        // We wrap the OutputStream so that it can be interrupted.
+        final InterruptableOutputStream ios = new InterruptableOutputStream(os);
+        jc.setCancelListener(new CancelListener() {
+                public void onCancel() {
+                    ios.interrupt();
+                }
+            });
+        try {
+            bitmap.compress(format, DEFAULT_COMPRESS_QUALITY, os);
+            if (!jc.isCancelled()) return false;
+        } finally {
+            jc.setCancelListener(null);
+            Utils.closeSilently(os);
+        }
+        return false;
+    }
+
+    private boolean saveBitmapToUri(JobContext jc, Bitmap bitmap, Uri uri) {
+        try {
+            return saveBitmapToOutputStream(jc, bitmap,
+                    convertExtensionToCompressFormat(getFileExtension()),
+                    getContentResolver().openOutputStream(uri));
+        } catch (FileNotFoundException e) {
+            Log.w(TAG, "cannot write output", e);
+        }
+        return true;
+    }
+
+    private CompressFormat convertExtensionToCompressFormat(String extension) {
+        return extension.equals("png")
+                ? CompressFormat.PNG
+                : CompressFormat.JPEG;
+    }
+
+    private String getFileExtension() {
+        String requestFormat = getIntent().getStringExtra(KEY_OUTPUT_FORMAT);
+        String outputFormat = (requestFormat == null)
+                ? determineCompressFormat(mMediaItem)
+                : requestFormat;
+
+        outputFormat = outputFormat.toLowerCase();
+        return (outputFormat.equals("png") || outputFormat.equals("gif"))
+                ? "png" // We don't support gif compression.
+                : "jpg";
+    }
+
+    private void onSaveClicked() {
+        Bundle extra = getIntent().getExtras();
+        RectF cropRect = mCropView.getCropRectangle();
+        if (cropRect == null) return;
+        mState = STATE_SAVING;
+        int messageId = extra != null && extra.getBoolean(KEY_SET_AS_WALLPAPER)
+                ? R.string.wallpaper
+                : R.string.saving_image;
+        mProgressDialog = ProgressDialog.show(
+                this, null, getString(messageId), true, false);
+        mSaveTask = getThreadPool().submit(new SaveOutput(cropRect),
+                new FutureListener<Intent>() {
+            public void onFutureDone(Future<Intent> future) {
+                mSaveTask = null;
+                if (future.get() == null) return;
+                mMainHandler.sendMessage(mMainHandler.obtainMessage(
+                        MSG_SAVE_COMPLETE, future.get()));
+            }
+        });
+    }
+
+    private Bitmap getCroppedImage(Rect rect) {
+        Utils.assertTrue(rect.width() > 0 && rect.height() > 0);
+
+        Bundle extras = getIntent().getExtras();
+        // (outputX, outputY) = the width and height of the returning bitmap.
+        int outputX = rect.width();
+        int outputY = rect.height();
+        if (extras != null) {
+            outputX = extras.getInt(KEY_OUTPUT_X, outputX);
+            outputY = extras.getInt(KEY_OUTPUT_Y, outputY);
+        }
+
+        if (outputX * outputY > MAX_PIXEL_COUNT) {
+            float scale = (float) Math.sqrt(
+                    (double) MAX_PIXEL_COUNT / outputX / outputY);
+            Log.w(TAG, "scale down the cropped image: " + scale);
+            outputX = Math.round(scale * outputX);
+            outputY = Math.round(scale * outputY);
+        }
+
+        // (rect.width() * scaleX, rect.height() * scaleY) =
+        // the size of drawing area in output bitmap
+        float scaleX = 1;
+        float scaleY = 1;
+        Rect dest = new Rect(0, 0, outputX, outputY);
+        if (extras == null || extras.getBoolean(KEY_SCALE, true)) {
+            scaleX = (float) outputX / rect.width();
+            scaleY = (float) outputY / rect.height();
+            if (extras == null || !extras.getBoolean(
+                    KEY_SCALE_UP_IF_NEEDED, false)) {
+                if (scaleX > 1f) scaleX = 1;
+                if (scaleY > 1f) scaleY = 1;
+            }
+        }
+
+        // Keep the content in the center (or crop the content)
+        int rectWidth = Math.round(rect.width() * scaleX);
+        int rectHeight = Math.round(rect.height() * scaleY);
+        dest.set(Math.round((outputX - rectWidth) / 2f),
+                Math.round((outputY - rectHeight) / 2f),
+                Math.round((outputX + rectWidth) / 2f),
+                Math.round((outputY + rectHeight) / 2f));
+
+        if (mBitmapInIntent != null) {
+            Bitmap source = mBitmapInIntent;
+            Bitmap result = Bitmap.createBitmap(
+                    outputX, outputY, Config.ARGB_8888);
+            Canvas canvas = new Canvas(result);
+            canvas.drawBitmap(source, rect, dest, null);
+            return result;
+        }
+
+        int rotation = mMediaItem.getRotation();
+        rotateRectangle(rect, mCropView.getImageWidth(),
+                mCropView.getImageHeight(), 360 - rotation);
+        rotateRectangle(dest, outputX, outputY, 360 - rotation);
+        if (mUseRegionDecoder) {
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            int sample = BitmapUtils.computeSampleSizeLarger(
+                    Math.max(scaleX, scaleY));
+            options.inSampleSize = sample;
+            if ((rect.width() / sample) == dest.width()
+                    && (rect.height() / sample) == dest.height()
+                    && rotation == 0) {
+                // To prevent concurrent access in GLThread
+                synchronized (mRegionDecoder) {
+                    return mRegionDecoder.decodeRegion(rect, options);
+                }
+            }
+            Bitmap result = Bitmap.createBitmap(
+                    outputX, outputY, Config.ARGB_8888);
+            Canvas canvas = new Canvas(result);
+            rotateCanvas(canvas, outputX, outputY, rotation);
+            drawInTiles(canvas, mRegionDecoder, rect, dest, sample);
+            return result;
+        } else {
+            Bitmap result = Bitmap.createBitmap(outputX, outputY, Config.ARGB_8888);
+            Canvas canvas = new Canvas(result);
+            rotateCanvas(canvas, outputX, outputY, rotation);
+            canvas.drawBitmap(mBitmap,
+                    rect, dest, new Paint(Paint.FILTER_BITMAP_FLAG));
+            return result;
+        }
+    }
+
+    private static void rotateCanvas(
+            Canvas canvas, int width, int height, int rotation) {
+        canvas.translate(width / 2, height / 2);
+        canvas.rotate(rotation);
+        if (((rotation / 90) & 0x01) == 0) {
+            canvas.translate(-width / 2, -height / 2);
+        } else {
+            canvas.translate(-height / 2, -width / 2);
+        }
+    }
+
+    private static void rotateRectangle(
+            Rect rect, int width, int height, int rotation) {
+        if (rotation == 0 || rotation == 360) return;
+
+        int w = rect.width();
+        int h = rect.height();
+        switch (rotation) {
+            case 90: {
+                rect.top = rect.left;
+                rect.left = height - rect.bottom;
+                rect.right = rect.left + h;
+                rect.bottom = rect.top + w;
+                return;
+            }
+            case 180: {
+                rect.left = width - rect.right;
+                rect.top = height - rect.bottom;
+                rect.right = rect.left + w;
+                rect.bottom = rect.top + h;
+                return;
+            }
+            case 270: {
+                rect.left = rect.top;
+                rect.top = width - rect.right;
+                rect.right = rect.left + h;
+                rect.bottom = rect.top + w;
+                return;
+            }
+            default: throw new AssertionError();
+        }
+    }
+
+    private void drawInTiles(Canvas canvas,
+            BitmapRegionDecoder decoder, Rect rect, Rect dest, int sample) {
+        int tileSize = TILE_SIZE * sample;
+        Rect tileRect = new Rect();
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inPreferredConfig = Config.ARGB_8888;
+        options.inSampleSize = sample;
+        canvas.translate(dest.left, dest.top);
+        canvas.scale((float) sample * dest.width() / rect.width(),
+                (float) sample * dest.height() / rect.height());
+        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
+        for (int tx = rect.left, x = 0;
+                tx < rect.right; tx += tileSize, x += TILE_SIZE) {
+            for (int ty = rect.top, y = 0;
+                    ty < rect.bottom; ty += tileSize, y += TILE_SIZE) {
+                tileRect.set(tx, ty, tx + tileSize, ty + tileSize);
+                if (tileRect.intersect(rect)) {
+                    Bitmap bitmap;
+
+                    // To prevent concurrent access in GLThread
+                    synchronized (decoder) {
+                        bitmap = decoder.decodeRegion(tileRect, options);
+                    }
+                    canvas.drawBitmap(bitmap, x, y, paint);
+                    bitmap.recycle();
+                }
+            }
+        }
+    }
+
+    private void onBitmapRegionDecoderAvailable(
+            BitmapRegionDecoder regionDecoder) {
+
+        if (regionDecoder == null) {
+            Toast.makeText(this, "fail to load image", Toast.LENGTH_SHORT).show();
+            finish();
+            return;
+        }
+        mRegionDecoder = regionDecoder;
+        mUseRegionDecoder = true;
+        mState = STATE_LOADED;
+
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        int width = regionDecoder.getWidth();
+        int height = regionDecoder.getHeight();
+        options.inSampleSize = BitmapUtils.computeSampleSize(width, height,
+                BitmapUtils.UNCONSTRAINED, BACKUP_PIXEL_COUNT);
+        mBitmap = regionDecoder.decodeRegion(
+                new Rect(0, 0, width, height), options);
+        mCropView.setDataModel(new TileImageViewAdapter(
+                mBitmap, regionDecoder), mMediaItem.getRotation());
+        if (mDoFaceDetection) {
+            mCropView.detectFaces(mBitmap);
+        } else {
+            mCropView.initializeHighlightRectangle();
+        }
+    }
+
+    private void onBitmapAvailable(Bitmap bitmap) {
+        if (bitmap == null) {
+            Toast.makeText(this, "fail to load image", Toast.LENGTH_SHORT).show();
+            finish();
+            return;
+        }
+        mUseRegionDecoder = false;
+        mState = STATE_LOADED;
+
+        mBitmap = bitmap;
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        mCropView.setDataModel(new BitmapTileProvider(bitmap, 512),
+                mMediaItem.getRotation());
+        if (mDoFaceDetection) {
+            mCropView.detectFaces(bitmap);
+        } else {
+            mCropView.initializeHighlightRectangle();
+        }
+    }
+
+    private void setCropParameters() {
+        Bundle extras = getIntent().getExtras();
+        if (extras == null)
+            return;
+        int aspectX = extras.getInt(KEY_ASPECT_X, 0);
+        int aspectY = extras.getInt(KEY_ASPECT_Y, 0);
+        if (aspectX != 0 && aspectY != 0) {
+            mCropView.setAspectRatio((float) aspectX / aspectY);
+        }
+
+        float spotlightX = extras.getFloat(KEY_SPOTLIGHT_X, 0);
+        float spotlightY = extras.getFloat(KEY_SPOTLIGHT_Y, 0);
+        if (spotlightX != 0 && spotlightY != 0) {
+            mCropView.setSpotlightRatio(spotlightX, spotlightY);
+        }
+    }
+
+    private void initializeData() {
+        Bundle extras = getIntent().getExtras();
+
+        if (extras != null) {
+            if (extras.containsKey(KEY_NO_FACE_DETECTION)) {
+                mDoFaceDetection = !extras.getBoolean(KEY_NO_FACE_DETECTION);
+            }
+
+            mBitmapInIntent = extras.getParcelable(KEY_DATA);
+
+            if (mBitmapInIntent != null) {
+                mBitmapTileProvider =
+                        new BitmapTileProvider(mBitmapInIntent, MAX_BACKUP_IMAGE_SIZE);
+                mCropView.setDataModel(mBitmapTileProvider, 0);
+                if (mDoFaceDetection) {
+                    mCropView.detectFaces(mBitmapInIntent);
+                } else {
+                    mCropView.initializeHighlightRectangle();
+                }
+                mState = STATE_LOADED;
+                return;
+            }
+        }
+
+        mProgressDialog = ProgressDialog.show(
+                this, null, getString(R.string.loading_image), true, false);
+
+        mMediaItem = getMediaItemFromIntentData();
+        if (mMediaItem == null) return;
+
+        boolean supportedByBitmapRegionDecoder =
+            (mMediaItem.getSupportedOperations() & MediaItem.SUPPORT_FULL_IMAGE) != 0;
+        if (supportedByBitmapRegionDecoder) {
+            mLoadTask = getThreadPool().submit(new LoadDataTask(mMediaItem),
+                    new FutureListener<BitmapRegionDecoder>() {
+                public void onFutureDone(Future<BitmapRegionDecoder> future) {
+                    mLoadTask = null;
+                    BitmapRegionDecoder decoder = future.get();
+                    if (future.isCancelled()) {
+                        if (decoder != null) decoder.recycle();
+                        return;
+                    }
+                    mMainHandler.sendMessage(mMainHandler.obtainMessage(
+                            MSG_LARGE_BITMAP, decoder));
+                }
+            });
+        } else {
+            mLoadBitmapTask = getThreadPool().submit(new LoadBitmapDataTask(mMediaItem),
+                    new FutureListener<Bitmap>() {
+                public void onFutureDone(Future<Bitmap> future) {
+                    mLoadBitmapTask = null;
+                    Bitmap bitmap = future.get();
+                    if (future.isCancelled()) {
+                        if (bitmap != null) bitmap.recycle();
+                        return;
+                    }
+                    mMainHandler.sendMessage(mMainHandler.obtainMessage(
+                            MSG_BITMAP, bitmap));
+                }
+            });
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (mState == STATE_INIT) initializeData();
+        if (mState == STATE_SAVING) onSaveClicked();
+
+        // TODO: consider to do it in GLView system
+        GLRoot root = getGLRoot();
+        root.lockRenderThread();
+        try {
+            mCropView.resume();
+        } finally {
+            root.unlockRenderThread();
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        Future<BitmapRegionDecoder> loadTask = mLoadTask;
+        if (loadTask != null && !loadTask.isDone()) {
+            // load in progress, try to cancel it
+            loadTask.cancel();
+            loadTask.waitDone();
+            mProgressDialog.dismiss();
+        }
+
+        Future<Bitmap> loadBitmapTask = mLoadBitmapTask;
+        if (loadBitmapTask != null && !loadBitmapTask.isDone()) {
+            // load in progress, try to cancel it
+            loadBitmapTask.cancel();
+            loadBitmapTask.waitDone();
+            mProgressDialog.dismiss();
+        }
+
+        Future<Intent> saveTask = mSaveTask;
+        if (saveTask != null && !saveTask.isDone()) {
+            // save in progress, try to cancel it
+            saveTask.cancel();
+            saveTask.waitDone();
+            mProgressDialog.dismiss();
+        }
+        GLRoot root = getGLRoot();
+        root.lockRenderThread();
+        try {
+            mCropView.pause();
+        } finally {
+            root.unlockRenderThread();
+        }
+    }
+
+    private MediaItem getMediaItemFromIntentData() {
+        Uri uri = getIntent().getData();
+        DataManager manager = getDataManager();
+        if (uri == null) {
+            Log.w(TAG, "no data given");
+            return null;
+        }
+        Path path = manager.findPathByUri(uri);
+        if (path == null) {
+            Log.w(TAG, "cannot get path for: " + uri);
+            return null;
+        }
+        return (MediaItem) manager.getMediaObject(path);
+    }
+
+    private class LoadDataTask implements Job<BitmapRegionDecoder> {
+        MediaItem mItem;
+
+        public LoadDataTask(MediaItem item) {
+            mItem = item;
+        }
+
+        public BitmapRegionDecoder run(JobContext jc) {
+            return mItem == null ? null : mItem.requestLargeImage().run(jc);
+        }
+    }
+
+    private class LoadBitmapDataTask implements Job<Bitmap> {
+        MediaItem mItem;
+
+        public LoadBitmapDataTask(MediaItem item) {
+            mItem = item;
+        }
+        public Bitmap run(JobContext jc) {
+            return mItem == null
+                    ? null
+                    : mItem.requestImage(MediaItem.TYPE_THUMBNAIL).run(jc);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/DialogPicker.java b/src/com/android/gallery3d/app/DialogPicker.java
new file mode 100644
index 0000000..ebfc521
--- /dev/null
+++ b/src/com/android/gallery3d/app/DialogPicker.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.ui.GLRoot;
+import com.android.gallery3d.ui.GLRootView;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+public class DialogPicker extends AbstractGalleryActivity
+        implements OnClickListener {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.dialog_picker);
+        ((GLRootView) findViewById(R.id.gl_root_view)).setZOrderOnTop(true);
+        findViewById(R.id.cancel).setOnClickListener(this);
+
+        int typeBits = GalleryUtils.determineTypeBits(this, getIntent());
+        setTitle(GalleryUtils.getSelectionModePrompt(typeBits));
+        Intent intent = getIntent();
+        Bundle extras = intent.getExtras();
+        Bundle data = extras == null ? new Bundle() : new Bundle(extras);
+
+        data.putBoolean(Gallery.KEY_GET_CONTENT, true);
+        data.putString(AlbumSetPage.KEY_MEDIA_PATH,
+                getDataManager().getTopSetPath(typeBits));
+        getStateManager().startState(AlbumSetPage.class, data);
+    }
+
+    @Override
+    public void onBackPressed() {
+        // send the back event to the top sub-state
+        GLRoot root = getGLRoot();
+        root.lockRenderThread();
+        try {
+            getStateManager().getTopState().onBackPressed();
+        } finally {
+            root.unlockRenderThread();
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.cancel) finish();
+    }
+}
diff --git a/src/com/android/gallery3d/app/EyePosition.java b/src/com/android/gallery3d/app/EyePosition.java
new file mode 100644
index 0000000..1c3aa60
--- /dev/null
+++ b/src/com/android/gallery3d/app/EyePosition.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.SystemClock;
+import android.view.Display;
+import android.view.Surface;
+import android.view.WindowManager;
+
+public class EyePosition {
+    private static final String TAG = "EyePosition";
+
+    public interface EyePositionListener {
+        public void onEyePositionChanged(float x, float y, float z);
+    }
+
+    private static final float GYROSCOPE_THRESHOLD = 0.15f;
+    private static final float GYROSCOPE_LIMIT = 10f;
+    private static final int GYROSCOPE_SETTLE_DOWN = 15;
+    private static final float GYROSCOPE_RESTORE_FACTOR = 0.995f;
+
+    private static final double USER_ANGEL = Math.toRadians(10);
+    private static final float USER_ANGEL_COS = (float) Math.cos(USER_ANGEL);
+    private static final float USER_ANGEL_SIN = (float) Math.sin(USER_ANGEL);
+    private static final float MAX_VIEW_RANGE = (float) 0.5;
+    private static final int NOT_STARTED = -1;
+
+    private static final float USER_DISTANCE_METER = 0.3f;
+
+    private Context mContext;
+    private EyePositionListener mListener;
+    private Display mDisplay;
+    // The eyes' position of the user, the origin is at the center of the
+    // device and the unit is in pixels.
+    private float mX;
+    private float mY;
+    private float mZ;
+
+    private final float mUserDistance; // in pixel
+    private final float mLimit;
+    private long mStartTime = NOT_STARTED;
+    private Sensor mSensor;
+    private PositionListener mPositionListener = new PositionListener();
+
+    private int mGyroscopeCountdown = 0;
+
+    public EyePosition(Context context, EyePositionListener listener) {
+        mContext = context;
+        mListener = listener;
+        mUserDistance = GalleryUtils.meterToPixel(USER_DISTANCE_METER);
+        mLimit = mUserDistance * MAX_VIEW_RANGE;
+
+        WindowManager wManager = (WindowManager) mContext
+                .getSystemService(Context.WINDOW_SERVICE);
+        mDisplay = wManager.getDefaultDisplay();
+
+        SensorManager sManager = (SensorManager) mContext
+                .getSystemService(Context.SENSOR_SERVICE);
+        mSensor = sManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
+        if (mSensor == null) {
+            Log.w(TAG, "no gyroscope, use accelerometer instead");
+            mSensor = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+        }
+        if (mSensor == null) {
+            Log.w(TAG, "no sensor available");
+        }
+    }
+
+    public void resetPosition() {
+        mStartTime = NOT_STARTED;
+        mX = mY = 0;
+        mZ = -mUserDistance;
+        mListener.onEyePositionChanged(mX, mY, mZ);
+    }
+
+    /*
+     * We assume the user is at the following position
+     *
+     *              /|\  user's eye
+     *               |   /
+     *   -G(gravity) |  /
+     *               |_/
+     *             / |/_____\ -Y (-y direction of device)
+     *     user angel
+     */
+    private void onAccelerometerChanged(float gx, float gy, float gz) {
+
+        float x = gx, y = gy, z = gz;
+
+        switch (mDisplay.getRotation()) {
+            case Surface.ROTATION_90: x = -gy; y= gx; break;
+            case Surface.ROTATION_180: x = -gx; y = -gy; break;
+            case Surface.ROTATION_270: x = gy; y = -gx; break;
+        }
+
+        float temp = x * x + y * y + z * z;
+        float t = -y /temp;
+
+        float tx = t * x;
+        float ty = -1 + t * y;
+        float tz = t * z;
+
+        float length = (float) Math.sqrt(tx * tx + ty * ty + tz * tz);
+        float glength = (float) Math.sqrt(temp);
+
+        mX = Utils.clamp((x * USER_ANGEL_COS / glength
+                + tx * USER_ANGEL_SIN / length) * mUserDistance,
+                -mLimit, mLimit);
+        mY = -Utils.clamp((y * USER_ANGEL_COS / glength
+                + ty * USER_ANGEL_SIN / length) * mUserDistance,
+                -mLimit, mLimit);
+        mZ = (float) -Math.sqrt(
+                mUserDistance * mUserDistance - mX * mX - mY * mY);
+        mListener.onEyePositionChanged(mX, mY, mZ);
+    }
+
+    private void onGyroscopeChanged(float gx, float gy, float gz) {
+        long now = SystemClock.elapsedRealtime();
+        float distance = (gx > 0 ? gx : -gx) + (gy > 0 ? gy : - gy);
+        if (distance < GYROSCOPE_THRESHOLD
+                || distance > GYROSCOPE_LIMIT || mGyroscopeCountdown > 0) {
+            --mGyroscopeCountdown;
+            mStartTime = now;
+            float limit = mUserDistance / 20f;
+            if (mX > limit || mX < -limit || mY > limit || mY < -limit) {
+                mX *= GYROSCOPE_RESTORE_FACTOR;
+                mY *= GYROSCOPE_RESTORE_FACTOR;
+                mZ = (float) -Math.sqrt(
+                        mUserDistance * mUserDistance - mX * mX - mY * mY);
+                mListener.onEyePositionChanged(mX, mY, mZ);
+            }
+            return;
+        }
+
+        float t = (now - mStartTime) / 1000f * mUserDistance * (-mZ);
+        mStartTime = now;
+
+        float x = -gy, y = -gx;
+        switch (mDisplay.getRotation()) {
+            case Surface.ROTATION_90: x = -gx; y= gy; break;
+            case Surface.ROTATION_180: x = gy; y = gx; break;
+            case Surface.ROTATION_270: x = gx; y = -gy; break;
+        }
+
+        mX = Utils.clamp((float) (mX + x * t / Math.hypot(mZ, mX)),
+                -mLimit, mLimit) * GYROSCOPE_RESTORE_FACTOR;
+        mY = Utils.clamp((float) (mY + y * t / Math.hypot(mZ, mY)),
+                -mLimit, mLimit) * GYROSCOPE_RESTORE_FACTOR;
+
+        mZ = (float) -Math.sqrt(
+                mUserDistance * mUserDistance - mX * mX - mY * mY);
+        mListener.onEyePositionChanged(mX, mY, mZ);
+    }
+
+    private class PositionListener implements SensorEventListener {
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        }
+
+        public void onSensorChanged(SensorEvent event) {
+            switch (event.sensor.getType()) {
+                case Sensor.TYPE_GYROSCOPE: {
+                    onGyroscopeChanged(
+                            event.values[0], event.values[1], event.values[2]);
+                    break;
+                }
+                case Sensor.TYPE_ACCELEROMETER: {
+                    onAccelerometerChanged(
+                            event.values[0], event.values[1], event.values[2]);
+                }
+            }
+        }
+    }
+
+    public void pause() {
+        if (mSensor != null) {
+            SensorManager sManager = (SensorManager) mContext
+                    .getSystemService(Context.SENSOR_SERVICE);
+            sManager.unregisterListener(mPositionListener);
+        }
+    }
+
+    public void resume() {
+        if (mSensor != null) {
+            SensorManager sManager = (SensorManager) mContext
+                    .getSystemService(Context.SENSOR_SERVICE);
+            sManager.registerListener(mPositionListener,
+                    mSensor, SensorManager.SENSOR_DELAY_GAME);
+        }
+
+        mStartTime = NOT_STARTED;
+        mGyroscopeCountdown = GYROSCOPE_SETTLE_DOWN;
+        mX = mY = 0;
+        mZ = -mUserDistance;
+        mListener.onEyePositionChanged(mX, mY, mZ);
+    }
+}
diff --git a/src/com/android/gallery3d/app/FilterUtils.java b/src/com/android/gallery3d/app/FilterUtils.java
new file mode 100644
index 0000000..9b8ea2d
--- /dev/null
+++ b/src/com/android/gallery3d/app/FilterUtils.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.Path;
+
+// This class handles filtering and clustering.
+//
+// We allow at most only one filter operation at a time (Currently it
+// doesn't make sense to use more than one). Also each clustering operation
+// can be applied at most once. In addition, there is one more constraint
+// ("fixed set constraint") described below.
+//
+// A clustered album (not including album set) and its base sets are fixed.
+// For example,
+//
+// /cluster/{base_set}/time/7
+//
+// This set and all sets inside base_set (recursively) are fixed because
+// 1. We can not change this set to use another clustering condition (like
+//    changing "time" to "location").
+// 2. Neither can we change any set in the base_set.
+// The reason is in both cases the 7th set may not exist in the new clustering.
+// ---------------------
+// newPath operation: create a new path based on a source path and put an extra
+// condition on top of it:
+//
+// T = newFilterPath(S, filterType);
+// T = newClusterPath(S, clusterType);
+//
+// Similar functions can be used to replace the current condition (if there is one).
+//
+// T = switchFilterPath(S, filterType);
+// T = switchClusterPath(S, clusterType);
+//
+// For all fixed set in the path defined above, if some clusterType and
+// filterType are already used, they cannot not be used as parameter for these
+// functions. setupMenuItems() makes sure those types cannot be selected.
+//
+public class FilterUtils {
+    private static final String TAG = "FilterUtils";
+
+    public static final int CLUSTER_BY_ALBUM = 1;
+    public static final int CLUSTER_BY_TIME = 2;
+    public static final int CLUSTER_BY_LOCATION = 4;
+    public static final int CLUSTER_BY_TAG = 8;
+    public static final int CLUSTER_BY_SIZE = 16;
+    public static final int CLUSTER_BY_FACE = 32;
+
+    public static final int FILTER_IMAGE_ONLY = 1;
+    public static final int FILTER_VIDEO_ONLY = 2;
+    public static final int FILTER_ALL = 4;
+
+    // These are indices of the return values of getAppliedFilters().
+    // The _F suffix means "fixed".
+    private static final int CLUSTER_TYPE = 0;
+    private static final int FILTER_TYPE = 1;
+    private static final int CLUSTER_TYPE_F = 2;
+    private static final int FILTER_TYPE_F = 3;
+    private static final int CLUSTER_CURRENT_TYPE = 4;
+    private static final int FILTER_CURRENT_TYPE = 5;
+
+    public static void setupMenuItems(GalleryActionBar model, Path path, boolean inAlbum) {
+        int[] result = new int[6];
+        getAppliedFilters(path, result);
+        int ctype = result[CLUSTER_TYPE];
+        int ftype = result[FILTER_TYPE];
+        int ftypef = result[FILTER_TYPE_F];
+        int ccurrent = result[CLUSTER_CURRENT_TYPE];
+        int fcurrent = result[FILTER_CURRENT_TYPE];
+
+        setMenuItemApplied(model, CLUSTER_BY_TIME,
+                (ctype & CLUSTER_BY_TIME) != 0, (ccurrent & CLUSTER_BY_TIME) != 0);
+        setMenuItemApplied(model, CLUSTER_BY_LOCATION,
+                (ctype & CLUSTER_BY_LOCATION) != 0, (ccurrent & CLUSTER_BY_LOCATION) != 0);
+        setMenuItemApplied(model, CLUSTER_BY_TAG,
+                (ctype & CLUSTER_BY_TAG) != 0, (ccurrent & CLUSTER_BY_TAG) != 0);
+        setMenuItemApplied(model, CLUSTER_BY_FACE,
+                (ctype & CLUSTER_BY_FACE) != 0, (ccurrent & CLUSTER_BY_FACE) != 0);
+
+        model.setClusterItemVisibility(CLUSTER_BY_ALBUM, !inAlbum || ctype == 0);
+
+        setMenuItemApplied(model, R.id.action_cluster_album, ctype == 0,
+                ccurrent == 0);
+
+        // A filtering is available if it's not applied, and the old filtering
+        // (if any) is not fixed.
+        setMenuItemAppliedEnabled(model, R.string.show_images_only,
+                (ftype & FILTER_IMAGE_ONLY) != 0,
+                (ftype & FILTER_IMAGE_ONLY) == 0 && ftypef == 0,
+                (fcurrent & FILTER_IMAGE_ONLY) != 0);
+        setMenuItemAppliedEnabled(model, R.string.show_videos_only,
+                (ftype & FILTER_VIDEO_ONLY) != 0,
+                (ftype & FILTER_VIDEO_ONLY) == 0 && ftypef == 0,
+                (fcurrent & FILTER_VIDEO_ONLY) != 0);
+        setMenuItemAppliedEnabled(model, R.string.show_all,
+                ftype == 0, ftype != 0 && ftypef == 0, fcurrent == 0);
+    }
+
+    // Gets the filters applied in the path.
+    private static void getAppliedFilters(Path path, int[] result) {
+        getAppliedFilters(path, result, false);
+    }
+
+    private static void getAppliedFilters(Path path, int[] result, boolean underCluster) {
+        String[] segments = path.split();
+        // Recurse into sub media sets.
+        for (int i = 0; i < segments.length; i++) {
+            if (segments[i].startsWith("{")) {
+                String[] sets = Path.splitSequence(segments[i]);
+                for (int j = 0; j < sets.length; j++) {
+                    Path sub = Path.fromString(sets[j]);
+                    getAppliedFilters(sub, result, underCluster);
+                }
+            }
+        }
+
+        // update current selection
+        if (segments[0].equals("cluster")) {
+            // if this is a clustered album, set underCluster to true.
+            if (segments.length == 4) {
+                underCluster = true;
+            }
+
+            int ctype = toClusterType(segments[2]);
+            result[CLUSTER_TYPE] |= ctype;
+            result[CLUSTER_CURRENT_TYPE] = ctype;
+            if (underCluster) {
+                result[CLUSTER_TYPE_F] |= ctype;
+            }
+        }
+    }
+
+    private static int toClusterType(String s) {
+        if (s.equals("time")) {
+            return CLUSTER_BY_TIME;
+        } else if (s.equals("location")) {
+            return CLUSTER_BY_LOCATION;
+        } else if (s.equals("tag")) {
+            return CLUSTER_BY_TAG;
+        } else if (s.equals("size")) {
+            return CLUSTER_BY_SIZE;
+        } else if (s.equals("face")) {
+            return CLUSTER_BY_FACE;
+        }
+        return 0;
+    }
+
+    private static void setMenuItemApplied(
+            GalleryActionBar model, int id, boolean applied, boolean updateTitle) {
+        model.setClusterItemEnabled(id, !applied);
+    }
+
+    private static void setMenuItemAppliedEnabled(GalleryActionBar model, int id, boolean applied, boolean enabled, boolean updateTitle) {
+        model.setClusterItemEnabled(id, enabled);
+    }
+
+    // Add a specified filter to the path.
+    public static String newFilterPath(String base, int filterType) {
+        int mediaType;
+        switch (filterType) {
+            case FILTER_IMAGE_ONLY:
+                mediaType = MediaObject.MEDIA_TYPE_IMAGE;
+                break;
+            case FILTER_VIDEO_ONLY:
+                mediaType = MediaObject.MEDIA_TYPE_VIDEO;
+                break;
+            default:  /* FILTER_ALL */
+                return base;
+        }
+
+        return "/filter/mediatype/" + mediaType + "/{" + base + "}";
+    }
+
+    // Add a specified clustering to the path.
+    public static String newClusterPath(String base, int clusterType) {
+        String kind;
+        switch (clusterType) {
+            case CLUSTER_BY_TIME:
+                kind = "time";
+                break;
+            case CLUSTER_BY_LOCATION:
+                kind = "location";
+                break;
+            case CLUSTER_BY_TAG:
+                kind = "tag";
+                break;
+            case CLUSTER_BY_SIZE:
+                kind = "size";
+                break;
+            case CLUSTER_BY_FACE:
+                kind = "face";
+                break;
+            default: /* CLUSTER_BY_ALBUM */
+                return base;
+        }
+
+        return "/cluster/{" + base + "}/" + kind;
+    }
+
+    // Change the topmost filter to the specified type.
+    public static String switchFilterPath(String base, int filterType) {
+        return newFilterPath(removeOneFilterFromPath(base), filterType);
+    }
+
+    // Change the topmost clustering to the specified type.
+    public static String switchClusterPath(String base, int clusterType) {
+        return newClusterPath(removeOneClusterFromPath(base), clusterType);
+    }
+
+    // Remove the topmost clustering (if any) from the path.
+    private static String removeOneClusterFromPath(String base) {
+        boolean[] done = new boolean[1];
+        return removeOneClusterFromPath(base, done);
+    }
+
+    private static String removeOneClusterFromPath(String base, boolean[] done) {
+        if (done[0]) return base;
+
+        String[] segments = Path.split(base);
+        if (segments[0].equals("cluster")) {
+            done[0] = true;
+            return Path.splitSequence(segments[1])[0];
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < segments.length; i++) {
+            sb.append("/");
+            if (segments[i].startsWith("{")) {
+                sb.append("{");
+                String[] sets = Path.splitSequence(segments[i]);
+                for (int j = 0; j < sets.length; j++) {
+                    if (j > 0) {
+                        sb.append(",");
+                    }
+                    sb.append(removeOneClusterFromPath(sets[j], done));
+                }
+                sb.append("}");
+            } else {
+                sb.append(segments[i]);
+            }
+        }
+        return sb.toString();
+    }
+
+    // Remove the topmost filter (if any) from the path.
+    private static String removeOneFilterFromPath(String base) {
+        boolean[] done = new boolean[1];
+        return removeOneFilterFromPath(base, done);
+    }
+
+    private static String removeOneFilterFromPath(String base, boolean[] done) {
+        if (done[0]) return base;
+
+        String[] segments = Path.split(base);
+        if (segments[0].equals("filter") && segments[1].equals("mediatype")) {
+            done[0] = true;
+            return Path.splitSequence(segments[3])[0];
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < segments.length; i++) {
+            sb.append("/");
+            if (segments[i].startsWith("{")) {
+                sb.append("{");
+                String[] sets = Path.splitSequence(segments[i]);
+                for (int j = 0; j < sets.length; j++) {
+                    if (j > 0) {
+                        sb.append(",");
+                    }
+                    sb.append(removeOneFilterFromPath(sets[j], done));
+                }
+                sb.append("}");
+            } else {
+                sb.append(segments[i]);
+            }
+        }
+        return sb.toString();
+    }
+}
diff --git a/src/com/android/gallery3d/app/Gallery.java b/src/com/android/gallery3d/app/Gallery.java
new file mode 100644
index 0000000..2c5263b
--- /dev/null
+++ b/src/com/android/gallery3d/app/Gallery.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.GLRoot;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.ActionBar;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.Window;
+import android.widget.Toast;
+
+public final class Gallery extends AbstractGalleryActivity {
+    public static final String EXTRA_SLIDESHOW = "slideshow";
+    public static final String EXTRA_CROP = "crop";
+
+    public static final String ACTION_REVIEW = "com.android.camera.action.REVIEW";
+    public static final String KEY_GET_CONTENT = "get-content";
+    public static final String KEY_GET_ALBUM = "get-album";
+    public static final String KEY_TYPE_BITS = "type-bits";
+    public static final String KEY_MEDIA_TYPES = "mediaTypes";
+
+    private static final String TAG = "Gallery";
+    private GalleryActionBar mActionBar;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_ACTION_BAR);
+        requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+
+        setContentView(R.layout.main);
+        mActionBar = new GalleryActionBar(this);
+
+        if (savedInstanceState != null) {
+            getStateManager().restoreFromState(savedInstanceState);
+        } else {
+            initializeByIntent();
+        }
+    }
+
+    private void initializeByIntent() {
+        Intent intent = getIntent();
+        String action = intent.getAction();
+
+        if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)) {
+            startGetContent(intent);
+        } else if (Intent.ACTION_PICK.equalsIgnoreCase(action)) {
+            // We do NOT really support the PICK intent. Handle it as
+            // the GET_CONTENT. However, we need to translate the type
+            // in the intent here.
+            Log.w(TAG, "action PICK is not supported");
+            String type = Utils.ensureNotNull(intent.getType());
+            if (type.startsWith("vnd.android.cursor.dir/")) {
+                if (type.endsWith("/image")) intent.setType("image/*");
+                if (type.endsWith("/video")) intent.setType("video/*");
+            }
+            startGetContent(intent);
+        } else if (Intent.ACTION_VIEW.equalsIgnoreCase(action)
+                || ACTION_REVIEW.equalsIgnoreCase(action)){
+            startViewAction(intent);
+        } else {
+            startDefaultPage();
+        }
+    }
+
+    public void startDefaultPage() {
+        Bundle data = new Bundle();
+        data.putString(AlbumSetPage.KEY_MEDIA_PATH,
+                getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));
+        getStateManager().startState(AlbumSetPage.class, data);
+    }
+
+    private void startGetContent(Intent intent) {
+        Bundle data = intent.getExtras() != null
+                ? new Bundle(intent.getExtras())
+                : new Bundle();
+        data.putBoolean(KEY_GET_CONTENT, true);
+        int typeBits = GalleryUtils.determineTypeBits(this, intent);
+        data.putInt(KEY_TYPE_BITS, typeBits);
+        data.putString(AlbumSetPage.KEY_MEDIA_PATH,
+                getDataManager().getTopSetPath(typeBits));
+        getStateManager().startState(AlbumSetPage.class, data);
+    }
+
+    private String getContentType(Intent intent) {
+        String type = intent.getType();
+        if (type != null) return type;
+
+        Uri uri = intent.getData();
+        try {
+            return getContentResolver().getType(uri);
+        } catch (Throwable t) {
+            Log.w(TAG, "get type fail", t);
+            return null;
+        }
+    }
+
+    private void startViewAction(Intent intent) {
+        Boolean slideshow = intent.getBooleanExtra(EXTRA_SLIDESHOW, false);
+        if (slideshow) {
+            getActionBar().hide();
+            DataManager manager = getDataManager();
+            Path path = manager.findPathByUri(intent.getData());
+            if (path == null || manager.getMediaObject(path)
+                    instanceof MediaItem) {
+                path = Path.fromString(
+                        manager.getTopSetPath(DataManager.INCLUDE_IMAGE));
+            }
+            Bundle data = new Bundle();
+            data.putString(SlideshowPage.KEY_SET_PATH, path.toString());
+            data.putBoolean(SlideshowPage.KEY_RANDOM_ORDER, true);
+            data.putBoolean(SlideshowPage.KEY_REPEAT, true);
+            getStateManager().startState(SlideshowPage.class, data);
+        } else {
+            Bundle data = new Bundle();
+            DataManager dm = getDataManager();
+            Uri uri = intent.getData();
+            String contentType = getContentType(intent);
+            if (contentType == null) {
+                Toast.makeText(this,
+                        R.string.no_such_item, Toast.LENGTH_LONG).show();
+                finish();
+                return;
+            }
+            if (contentType.startsWith(
+                    ContentResolver.CURSOR_DIR_BASE_TYPE)) {
+                int mediaType = intent.getIntExtra(KEY_MEDIA_TYPES, 0);
+                if (mediaType != 0) {
+                    uri = uri.buildUpon().appendQueryParameter(
+                            KEY_MEDIA_TYPES, String.valueOf(mediaType))
+                            .build();
+                }
+                Path albumPath = dm.findPathByUri(uri);
+                if (albumPath != null) {
+                    MediaSet mediaSet = (MediaSet) dm.getMediaObject(albumPath);
+                    data.putString(AlbumPage.KEY_MEDIA_PATH, albumPath.toString());
+                    getStateManager().startState(AlbumPage.class, data);
+                } else {
+                    startDefaultPage();
+                }
+            } else {
+                Path itemPath = dm.findPathByUri(uri);
+                Path albumPath = dm.getDefaultSetOf(itemPath);
+                if (albumPath != null) {
+                    data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
+                            albumPath.toString());
+                }
+                data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, itemPath.toString());
+                getStateManager().startState(PhotoPage.class, data);
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        return getStateManager().createOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        GLRoot root = getGLRoot();
+        root.lockRenderThread();
+        try {
+            return getStateManager().itemSelected(item);
+        } finally {
+            root.unlockRenderThread();
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        // send the back event to the top sub-state
+        GLRoot root = getGLRoot();
+        root.lockRenderThread();
+        try {
+            getStateManager().onBackPressed();
+        } finally {
+            root.unlockRenderThread();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        GLRoot root = getGLRoot();
+        root.lockRenderThread();
+        try {
+            getStateManager().destroy();
+        } finally {
+            root.unlockRenderThread();
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        Utils.assertTrue(getStateManager().getStateCount() > 0);
+        super.onResume();
+    }
+
+    @Override
+    public GalleryActionBar getGalleryActionBar() {
+        return mActionBar;
+    }
+}
diff --git a/src/com/android/gallery3d/app/GalleryActionBar.java b/src/com/android/gallery3d/app/GalleryActionBar.java
new file mode 100644
index 0000000..b9b59ee
--- /dev/null
+++ b/src/com/android/gallery3d/app/GalleryActionBar.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import java.util.ArrayList;
+
+import com.android.gallery3d.R;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ShareActionProvider;
+
+public class GalleryActionBar implements ActionBar.TabListener {
+    private static final String TAG = "GalleryActionBar";
+
+    public interface ClusterRunner {
+        public void doCluster(int id);
+    }
+
+    private static class ActionItem {
+        public int action;
+        public boolean enabled;
+        public boolean visible;
+        public int tabTitle;
+        public int dialogTitle;
+        public int clusterBy;
+
+        public ActionItem(int action, boolean applied, boolean enabled, int title,
+                int clusterBy) {
+            this(action, applied, enabled, title, title, clusterBy);
+        }
+
+        public ActionItem(int action, boolean applied, boolean enabled, int tabTitle,
+                int dialogTitle, int clusterBy) {
+            this.action = action;
+            this.enabled = enabled;
+            this.tabTitle = tabTitle;
+            this.dialogTitle = dialogTitle;
+            this.clusterBy = clusterBy;
+            this.visible = true;
+        }
+    }
+
+    private static final ActionItem[] sClusterItems = new ActionItem[] {
+        new ActionItem(FilterUtils.CLUSTER_BY_ALBUM, true, false, R.string.albums,
+                R.string.group_by_album),
+        new ActionItem(FilterUtils.CLUSTER_BY_LOCATION, true, false,
+                R.string.locations, R.string.location, R.string.group_by_location),
+        new ActionItem(FilterUtils.CLUSTER_BY_TIME, true, false, R.string.times,
+                R.string.time, R.string.group_by_time),
+        new ActionItem(FilterUtils.CLUSTER_BY_FACE, true, false, R.string.people,
+                R.string.group_by_faces),
+        new ActionItem(FilterUtils.CLUSTER_BY_TAG, true, false, R.string.tags,
+                R.string.group_by_tags)
+    };
+
+    private ClusterRunner mClusterRunner;
+    private CharSequence[] mTitles;
+    private ArrayList<Integer> mActions;
+    private Context mContext;
+    private ActionBar mActionBar;
+    // We need this because ActionBar.getSelectedTab() doesn't work when
+    // ActionBar is hidden.
+    private Tab mCurrentTab;
+
+    public GalleryActionBar(Activity activity) {
+        mActionBar = activity.getActionBar();
+        mContext = activity;
+
+        for (ActionItem item : sClusterItems) {
+            mActionBar.addTab(mActionBar.newTab().setText(item.tabTitle).
+                    setTag(item).setTabListener(this));
+        }
+    }
+
+    public static int getHeight(Activity activity) {
+        ActionBar actionBar = activity.getActionBar();
+        return actionBar != null ? actionBar.getHeight() : 0;
+    }
+
+    private void createDialogData() {
+        ArrayList<CharSequence> titles = new ArrayList<CharSequence>();
+        mActions = new ArrayList<Integer>();
+        for (ActionItem item : sClusterItems) {
+            if (item.enabled && item.visible) {
+                titles.add(mContext.getString(item.dialogTitle));
+                mActions.add(item.action);
+            }
+        }
+        mTitles = new CharSequence[titles.size()];
+        titles.toArray(mTitles);
+    }
+
+    public void setClusterItemEnabled(int id, boolean enabled) {
+        for (ActionItem item : sClusterItems) {
+            if (item.action == id) {
+                item.enabled = enabled;
+                return;
+            }
+        }
+    }
+
+    public void setClusterItemVisibility(int id, boolean visible) {
+        for (ActionItem item : sClusterItems) {
+            if (item.action == id) {
+                item.visible = visible;
+                return;
+            }
+        }
+    }
+
+    public int getClusterTypeAction() {
+        if (mCurrentTab != null) {
+            ActionItem item = (ActionItem) mCurrentTab.getTag();
+            return item.action;
+        }
+        // By default, it's group-by-album
+        return FilterUtils.CLUSTER_BY_ALBUM;
+    }
+
+    public static String getClusterByTypeString(Context context, int type) {
+        for (ActionItem item : sClusterItems) {
+            if (item.action == type) {
+                return context.getString(item.clusterBy);
+            }
+        }
+        return null;
+    }
+
+    public static ShareActionProvider initializeShareActionProvider(Menu menu) {
+        MenuItem item = menu.findItem(R.id.action_share);
+        ShareActionProvider shareActionProvider = null;
+        if (item != null) {
+            shareActionProvider = (ShareActionProvider) item.getActionProvider();
+            shareActionProvider.setShareHistoryFileName(
+                    ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME);
+        }
+        return shareActionProvider;
+    }
+
+    public void showClusterTabs(ClusterRunner runner) {
+        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+        mClusterRunner = runner;
+    }
+
+    public void hideClusterTabs() {
+        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+        mClusterRunner = null;
+    }
+
+    public void showClusterDialog(final ClusterRunner clusterRunner) {
+        createDialogData();
+        final ArrayList<Integer> actions = mActions;
+        new AlertDialog.Builder(mContext).setTitle(R.string.group_by).setItems(
+                mTitles, new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int which) {
+                clusterRunner.doCluster(actions.get(which).intValue());
+            }
+        }).create().show();
+    }
+
+    public void setTitle(String title) {
+        if (mActionBar != null) mActionBar.setTitle(title);
+    }
+
+    public void setTitle(int titleId) {
+        if (mActionBar != null) mActionBar.setTitle(titleId);
+    }
+
+    public void setSubtitle(String title) {
+        if (mActionBar != null) mActionBar.setSubtitle(title);
+    }
+
+    public void setNavigationMode(int mode) {
+        if (mActionBar != null) mActionBar.setNavigationMode(mode);
+    }
+
+    public int getHeight() {
+        return mActionBar == null ? 0 : mActionBar.getHeight();
+    }
+
+    @Override
+    public void onTabSelected(Tab tab, FragmentTransaction ft) {
+        if (mCurrentTab == tab) return;
+        mCurrentTab = tab;
+        ActionItem item = (ActionItem) tab.getTag();
+        if (mClusterRunner != null) mClusterRunner.doCluster(item.action);
+    }
+
+    @Override
+    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+    }
+
+    @Override
+    public void onTabReselected(Tab tab, FragmentTransaction ft) {
+    }
+}
diff --git a/src/com/android/gallery3d/app/GalleryActivity.java b/src/com/android/gallery3d/app/GalleryActivity.java
new file mode 100644
index 0000000..02f2f72
--- /dev/null
+++ b/src/com/android/gallery3d/app/GalleryActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.ui.GLRoot;
+import com.android.gallery3d.ui.PositionRepository;
+
+public interface GalleryActivity extends GalleryContext {
+    public StateManager getStateManager();
+    public GLRoot getGLRoot();
+    public PositionRepository getPositionRepository();
+    public GalleryApp getGalleryApplication();
+    public GalleryActionBar getGalleryActionBar();
+}
diff --git a/src/com/android/gallery3d/app/GalleryApp.java b/src/com/android/gallery3d/app/GalleryApp.java
new file mode 100644
index 0000000..b3a305e
--- /dev/null
+++ b/src/com/android/gallery3d/app/GalleryApp.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.DownloadCache;
+import com.android.gallery3d.data.ImageCacheService;
+import com.android.gallery3d.util.ThreadPool;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Looper;
+
+public interface GalleryApp {
+    public DataManager getDataManager();
+    public ImageCacheService getImageCacheService();
+    public DownloadCache getDownloadCache();
+    public ThreadPool getThreadPool();
+
+    public Context getAndroidContext();
+    public Looper getMainLooper();
+    public ContentResolver getContentResolver();
+    public Resources getResources();
+}
diff --git a/src/com/android/gallery3d/app/GalleryAppImpl.java b/src/com/android/gallery3d/app/GalleryAppImpl.java
new file mode 100644
index 0000000..a11d920
--- /dev/null
+++ b/src/com/android/gallery3d/app/GalleryAppImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.DownloadCache;
+import com.android.gallery3d.data.ImageCacheService;
+import com.android.gallery3d.picasasource.PicasaSource;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ThreadPool;
+import com.android.gallery3d.widget.WidgetUtils;
+
+import android.app.Application;
+import android.content.Context;
+
+import java.io.File;
+
+public class GalleryAppImpl extends Application implements GalleryApp {
+
+    private static final String DOWNLOAD_FOLDER = "download";
+    private static final long DOWNLOAD_CAPACITY = 64 * 1024 * 1024; // 64M
+
+    private ImageCacheService mImageCacheService;
+    private DataManager mDataManager;
+    private ThreadPool mThreadPool;
+    private DownloadCache mDownloadCache;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        GalleryUtils.initialize(this);
+        WidgetUtils.initialize(this);
+        PicasaSource.initialize(this);
+    }
+
+    public Context getAndroidContext() {
+        return this;
+    }
+
+    public synchronized DataManager getDataManager() {
+        if (mDataManager == null) {
+            mDataManager = new DataManager(this);
+            mDataManager.initializeSourceMap();
+        }
+        return mDataManager;
+    }
+
+    public synchronized ImageCacheService getImageCacheService() {
+        if (mImageCacheService == null) {
+            mImageCacheService = new ImageCacheService(getAndroidContext());
+        }
+        return mImageCacheService;
+    }
+
+    public synchronized ThreadPool getThreadPool() {
+        if (mThreadPool == null) {
+            mThreadPool = new ThreadPool();
+        }
+        return mThreadPool;
+    }
+
+    public synchronized DownloadCache getDownloadCache() {
+        if (mDownloadCache == null) {
+            File cacheDir = new File(getExternalCacheDir(), DOWNLOAD_FOLDER);
+
+            if (!cacheDir.isDirectory()) cacheDir.mkdirs();
+
+            if (!cacheDir.isDirectory()) {
+                throw new RuntimeException(
+                        "fail to create: " + cacheDir.getAbsolutePath());
+            }
+            mDownloadCache = new DownloadCache(this, cacheDir, DOWNLOAD_CAPACITY);
+        }
+        return mDownloadCache;
+    }
+}
diff --git a/src/com/android/gallery3d/app/GalleryContext.java b/src/com/android/gallery3d/app/GalleryContext.java
new file mode 100644
index 0000000..022b4a7
--- /dev/null
+++ b/src/com/android/gallery3d/app/GalleryContext.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.ImageCacheService;
+import com.android.gallery3d.util.ThreadPool;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Looper;
+
+public interface GalleryContext {
+    public ImageCacheService getImageCacheService();
+    public DataManager getDataManager();
+
+    public Context getAndroidContext();
+
+    public Looper getMainLooper();
+    public Resources getResources();
+    public ContentResolver getContentResolver();
+    public ThreadPool getThreadPool();
+}
diff --git a/src/com/android/gallery3d/app/LoadingListener.java b/src/com/android/gallery3d/app/LoadingListener.java
new file mode 100644
index 0000000..ecbd798
--- /dev/null
+++ b/src/com/android/gallery3d/app/LoadingListener.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+public interface LoadingListener {
+    public void onLoadingStarted();
+    public void onLoadingFinished();
+}
diff --git a/src/com/android/gallery3d/app/Log.java b/src/com/android/gallery3d/app/Log.java
new file mode 100644
index 0000000..07a8ea5
--- /dev/null
+++ b/src/com/android/gallery3d/app/Log.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+public class Log {
+    public static int v(String tag, String msg) {
+        return android.util.Log.v(tag, msg);
+    }
+    public static int v(String tag, String msg, Throwable tr) {
+        return android.util.Log.v(tag, msg, tr);
+    }
+    public static int d(String tag, String msg) {
+        return android.util.Log.d(tag, msg);
+    }
+    public static int d(String tag, String msg, Throwable tr) {
+        return android.util.Log.d(tag, msg, tr);
+    }
+    public static int i(String tag, String msg) {
+        return android.util.Log.i(tag, msg);
+    }
+    public static int i(String tag, String msg, Throwable tr) {
+        return android.util.Log.i(tag, msg, tr);
+    }
+    public static int w(String tag, String msg) {
+        return android.util.Log.w(tag, msg);
+    }
+    public static int w(String tag, String msg, Throwable tr) {
+        return android.util.Log.w(tag, msg, tr);
+    }
+    public static int w(String tag, Throwable tr) {
+        return android.util.Log.w(tag, tr);
+    }
+    public static int e(String tag, String msg) {
+        return android.util.Log.e(tag, msg);
+    }
+    public static int e(String tag, String msg, Throwable tr) {
+        return android.util.Log.e(tag, msg, tr);
+    }
+}
diff --git a/src/com/android/gallery3d/app/ManageCachePage.java b/src/com/android/gallery3d/app/ManageCachePage.java
new file mode 100644
index 0000000..a0190db
--- /dev/null
+++ b/src/com/android/gallery3d/app/ManageCachePage.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.AlbumSetView;
+import com.android.gallery3d.ui.CacheBarView;
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.GLView;
+import com.android.gallery3d.ui.ManageCacheDrawer;
+import com.android.gallery3d.ui.MenuExecutor;
+import com.android.gallery3d.ui.SelectionDrawer;
+import com.android.gallery3d.ui.SelectionManager;
+import com.android.gallery3d.ui.SlotView;
+import com.android.gallery3d.ui.StaticBackground;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+public class ManageCachePage extends ActivityState implements
+        SelectionManager.SelectionListener, CacheBarView.Listener,
+        MenuExecutor.ProgressListener, EyePosition.EyePositionListener {
+    public static final String KEY_MEDIA_PATH = "media-path";
+    private static final String TAG = "ManageCachePage";
+
+    private static final float USER_DISTANCE_METER = 0.3f;
+    private static final int DATA_CACHE_SIZE = 256;
+
+    private StaticBackground mStaticBackground;
+    private AlbumSetView mAlbumSetView;
+
+    private MediaSet mMediaSet;
+
+    protected SelectionManager mSelectionManager;
+    protected SelectionDrawer mSelectionDrawer;
+    private AlbumSetDataAdapter mAlbumSetDataAdapter;
+    private float mUserDistance; // in pixel
+
+    private CacheBarView mCacheBar;
+
+    private EyePosition mEyePosition;
+
+    // The eyes' position of the user, the origin is at the center of the
+    // device and the unit is in pixels.
+    private float mX;
+    private float mY;
+    private float mZ;
+
+    private int mAlbumCountToMakeAvailableOffline;
+
+    private GLView mRootPane = new GLView() {
+        private float mMatrix[] = new float[16];
+
+        @Override
+        protected void onLayout(
+                boolean changed, int left, int top, int right, int bottom) {
+            mStaticBackground.layout(0, 0, right - left, bottom - top);
+            mEyePosition.resetPosition();
+
+            Config.ManageCachePage config = Config.ManageCachePage.get((Context) mActivity);
+
+            ActionBar actionBar = ((Activity) mActivity).getActionBar();
+            int slotViewTop = GalleryActionBar.getHeight((Activity) mActivity);
+            int slotViewBottom = bottom - top - config.cacheBarHeight;
+
+            mAlbumSetView.layout(0, slotViewTop, right - left, slotViewBottom);
+            mCacheBar.layout(0, bottom - top - config.cacheBarHeight,
+                    right - left, bottom - top);
+        }
+
+        @Override
+        protected void render(GLCanvas canvas) {
+            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+            GalleryUtils.setViewPointMatrix(mMatrix,
+                        getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
+            canvas.multiplyMatrix(mMatrix, 0);
+            super.render(canvas);
+            canvas.restore();
+        }
+    };
+
+    public void onEyePositionChanged(float x, float y, float z) {
+        mRootPane.lockRendering();
+        mX = x;
+        mY = y;
+        mZ = z;
+        mRootPane.unlockRendering();
+        mRootPane.invalidate();
+    }
+
+    public void onSingleTapUp(int slotIndex) {
+        MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
+        if (targetSet == null) return; // Content is dirty, we shall reload soon
+
+        // ignore selection action if the target set does not support cache
+        // operation (like a local album).
+        if ((targetSet.getSupportedOperations()
+                & MediaSet.SUPPORT_CACHE) == 0) {
+            showToastForLocalAlbum();
+            return;
+        }
+
+        Path path = targetSet.getPath();
+        boolean isFullyCached =
+                (targetSet.getCacheFlag() == MediaObject.CACHE_FLAG_FULL);
+        boolean isSelected = mSelectionManager.isItemSelected(path);
+
+        if (!isFullyCached) {
+            // We only count the media sets that will be made available offline
+            // in this session.
+            if (isSelected) {
+                --mAlbumCountToMakeAvailableOffline;
+            } else {
+                ++mAlbumCountToMakeAvailableOffline;
+            }
+        }
+
+        long sizeOfTarget = targetSet.getCacheSize();
+        if (isFullyCached ^ isSelected) {
+            mCacheBar.increaseTargetCacheSize(-sizeOfTarget);
+        } else {
+            mCacheBar.increaseTargetCacheSize(sizeOfTarget);
+        }
+
+        mSelectionManager.toggle(path);
+        mAlbumSetView.invalidate();
+    }
+
+    @Override
+    public void onCreate(Bundle data, Bundle restoreState) {
+        initializeViews();
+        initializeData(data);
+        mEyePosition = new EyePosition(mActivity.getAndroidContext(), this);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mAlbumSetDataAdapter.pause();
+        mAlbumSetView.pause();
+        mCacheBar.pause();
+        mEyePosition.pause();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        setContentPane(mRootPane);
+        mAlbumSetDataAdapter.resume();
+        mAlbumSetView.resume();
+        mCacheBar.resume();
+        mEyePosition.resume();
+    }
+
+    private void initializeData(Bundle data) {
+        mUserDistance = GalleryUtils.meterToPixel(USER_DISTANCE_METER);
+        String mediaPath = data.getString(ManageCachePage.KEY_MEDIA_PATH);
+        mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
+        mSelectionManager.setSourceMediaSet(mMediaSet);
+
+        // We will always be in selection mode in this page.
+        mSelectionManager.setAutoLeaveSelectionMode(false);
+        mSelectionManager.enterSelectionMode();
+
+        mAlbumSetDataAdapter = new AlbumSetDataAdapter(
+                mActivity, mMediaSet, DATA_CACHE_SIZE);
+        mAlbumSetView.setModel(mAlbumSetDataAdapter);
+    }
+
+    private void initializeViews() {
+        mSelectionManager = new SelectionManager(mActivity, true);
+        mSelectionManager.setSelectionListener(this);
+        mStaticBackground = new StaticBackground(mActivity.getAndroidContext());
+        mRootPane.addComponent(mStaticBackground);
+
+        mSelectionDrawer = new ManageCacheDrawer(
+                (Context) mActivity, mSelectionManager);
+        Config.ManageCachePage config = Config.ManageCachePage.get((Context) mActivity);
+        mAlbumSetView = new AlbumSetView(mActivity, mSelectionDrawer,
+                config.slotWidth, config.slotHeight,
+                config.displayItemSize, config.labelFontSize,
+                config.labelOffsetY, config.labelMargin);
+        mAlbumSetView.setListener(new SlotView.SimpleListener() {
+            @Override
+            public void onSingleTapUp(int slotIndex) {
+                ManageCachePage.this.onSingleTapUp(slotIndex);
+            }
+        });
+        mRootPane.addComponent(mAlbumSetView);
+
+        mCacheBar = new CacheBarView(mActivity, R.drawable.manage_bar,
+                config.cacheBarHeight,
+                config.cacheBarPinLeftMargin,
+                config.cacheBarPinRightMargin,
+                config.cacheBarButtonRightMargin,
+                config.cacheBarFontSize);
+
+        mCacheBar.setListener(this);
+        mRootPane.addComponent(mCacheBar);
+
+        mStaticBackground.setImage(R.drawable.background,
+                R.drawable.background_portrait);
+    }
+
+    public void onDoneClicked() {
+        ArrayList<Path> ids = mSelectionManager.getSelected(false);
+        if (ids.size() == 0) {
+            onBackPressed();
+            return;
+        }
+        showToast();
+
+        MenuExecutor menuExecutor = new MenuExecutor(mActivity,
+                mSelectionManager);
+        menuExecutor.startAction(R.id.action_toggle_full_caching,
+                R.string.process_caching_requests, this);
+    }
+
+    private void showToast() {
+        if (mAlbumCountToMakeAvailableOffline > 0) {
+            Activity activity = (Activity) mActivity;
+            Toast.makeText(activity, activity.getResources().getQuantityString(
+                    R.plurals.make_albums_available_offline,
+                    mAlbumCountToMakeAvailableOffline),
+                    Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    private void showToastForLocalAlbum() {
+        Activity activity = (Activity) mActivity;
+        Toast.makeText(activity, activity.getResources().getString(
+            R.string.try_to_set_local_album_available_offline),
+            Toast.LENGTH_SHORT).show();
+    }
+
+    public void onProgressComplete(int result) {
+        onBackPressed();
+    }
+
+    public void onProgressUpdate(int index) {
+    }
+
+    public void onSelectionModeChange(int mode) {
+    }
+
+    public void onSelectionChange(Path path, boolean selected) {
+    }
+}
diff --git a/src/com/android/gallery3d/app/MovieActivity.java b/src/com/android/gallery3d/app/MovieActivity.java
new file mode 100644
index 0000000..fea364e
--- /dev/null
+++ b/src/com/android/gallery3d/app/MovieActivity.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.database.Cursor;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.provider.MediaStore.Video.VideoColumns;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+
+/**
+ * This activity plays a video from a specified URI.
+ */
+public class MovieActivity extends Activity {
+    @SuppressWarnings("unused")
+    private static final String TAG = "MovieActivity";
+
+    private MoviePlayer mPlayer;
+    private boolean mFinishOnCompletion;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        requestWindowFeature(Window.FEATURE_ACTION_BAR);
+        requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
+
+        setContentView(R.layout.movie_view);
+        View rootView = findViewById(R.id.root);
+        Intent intent = getIntent();
+        setVideoTitle(intent);
+        mPlayer = new MoviePlayer(rootView, this, intent.getData()) {
+            @Override
+            public void onCompletion() {
+                if (mFinishOnCompletion) {
+                    finish();
+                }
+            }
+        };
+        if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) {
+            int orientation = intent.getIntExtra(
+                    MediaStore.EXTRA_SCREEN_ORIENTATION,
+                    ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+            if (orientation != getRequestedOrientation()) {
+                setRequestedOrientation(orientation);
+            }
+        }
+        mFinishOnCompletion = intent.getBooleanExtra(MediaStore.EXTRA_FINISH_ON_COMPLETION, true);
+        Window win = getWindow();
+        WindowManager.LayoutParams winParams = win.getAttributes();
+        winParams.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
+        win.setAttributes(winParams);
+
+    }
+
+    private void setVideoTitle(Intent intent) {
+        String title = intent.getStringExtra(Intent.EXTRA_TITLE);
+        if (title == null) {
+            Cursor cursor = null;
+            try {
+                cursor = getContentResolver().query(intent.getData(),
+                        new String[] {VideoColumns.TITLE}, null, null, null);
+                if (cursor != null && cursor.moveToNext()) {
+                    title = cursor.getString(0);
+                }
+            } catch (Throwable t) {
+                Log.w(TAG, "cannot get title from: " + intent.getDataString(), t);
+            } finally {
+                if (cursor != null) cursor.close();
+            }
+        }
+        if (title != null) getActionBar().setTitle(title);
+    }
+
+    @Override
+    public void onStart() {
+        ((AudioManager) getSystemService(AUDIO_SERVICE))
+                .requestAudioFocus(null, AudioManager.STREAM_MUSIC,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+        super.onStart();
+    }
+
+    @Override
+    protected void onStop() {
+        ((AudioManager) getSystemService(AUDIO_SERVICE))
+                .abandonAudioFocus(null);
+        super.onStop();
+    }
+
+    @Override
+    public void onPause() {
+        mPlayer.onPause();
+        super.onPause();
+    }
+
+    @Override
+    public void onResume() {
+        mPlayer.onResume();
+        super.onResume();
+    }
+
+    @Override
+    public void onDestroy() {
+        mPlayer.onDestroy();
+        super.onDestroy();
+    }
+}
diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java
new file mode 100644
index 0000000..4239944
--- /dev/null
+++ b/src/com/android/gallery3d/app/MoviePlayer.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.BlobCache;
+import com.android.gallery3d.util.CacheManager;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Handler;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.MediaController;
+import android.widget.VideoView;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+public class MoviePlayer implements
+        MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "MoviePlayer";
+
+    // Copied from MediaPlaybackService in the Music Player app.
+    private static final String SERVICECMD = "com.android.music.musicservicecommand";
+    private static final String CMDNAME = "command";
+    private static final String CMDPAUSE = "pause";
+
+    private Context mContext;
+    private final VideoView mVideoView;
+    private final View mProgressView;
+    private final Bookmarker mBookmarker;
+    private final Uri mUri;
+    private final Handler mHandler = new Handler();
+    private final AudioBecomingNoisyReceiver mAudioBecomingNoisyReceiver;
+    private final ActionBar mActionBar;
+
+    private boolean mHasPaused;
+
+    private final Runnable mPlayingChecker = new Runnable() {
+        public void run() {
+            if (mVideoView.isPlaying()) {
+                mProgressView.setVisibility(View.GONE);
+            } else {
+                mHandler.postDelayed(mPlayingChecker, 250);
+            }
+        }
+    };
+
+    public MoviePlayer(View rootView, final MovieActivity movieActivity, Uri videoUri) {
+        mContext = movieActivity.getApplicationContext();
+        mVideoView = (VideoView) rootView.findViewById(R.id.surface_view);
+        mProgressView = rootView.findViewById(R.id.progress_indicator);
+        mBookmarker = new Bookmarker(movieActivity);
+        mActionBar = movieActivity.getActionBar();
+        mUri = videoUri;
+
+        // For streams that we expect to be slow to start up, show a
+        // progress spinner until playback starts.
+        String scheme = mUri.getScheme();
+        if ("http".equalsIgnoreCase(scheme) || "rtsp".equalsIgnoreCase(scheme)) {
+            mHandler.postDelayed(mPlayingChecker, 250);
+        } else {
+            mProgressView.setVisibility(View.GONE);
+        }
+
+        mVideoView.setOnErrorListener(this);
+        mVideoView.setOnCompletionListener(this);
+        mVideoView.setVideoURI(mUri);
+
+        MediaController mediaController = new MediaController(movieActivity) {
+            @Override
+            public void show() {
+                super.show();
+                mActionBar.show();
+            }
+
+            @Override
+            public void hide() {
+                super.hide();
+                mActionBar.hide();
+            }
+        };
+        mVideoView.setMediaController(mediaController);
+        mediaController.setOnKeyListener(new View.OnKeyListener() {
+            public boolean onKey(View v, int keyCode, KeyEvent event) {
+                if (keyCode == KeyEvent.KEYCODE_BACK) {
+                    if (event.getAction() == KeyEvent.ACTION_UP) {
+                        movieActivity.onBackPressed();
+                    }
+                    return true;
+                }
+                return false;
+            }
+        });
+
+        mAudioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver();
+        mAudioBecomingNoisyReceiver.register();
+
+        // make the video view handle keys for seeking and pausing
+        mVideoView.requestFocus();
+
+        Intent i = new Intent(SERVICECMD);
+        i.putExtra(CMDNAME, CMDPAUSE);
+        movieActivity.sendBroadcast(i);
+
+        final Integer bookmark = mBookmarker.getBookmark(mUri);
+        if (bookmark != null) {
+            showResumeDialog(movieActivity, bookmark);
+        } else {
+            mVideoView.start();
+        }
+    }
+
+    private void showResumeDialog(Context context, final int bookmark) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setTitle(R.string.resume_playing_title);
+        builder.setMessage(String.format(
+                context.getString(R.string.resume_playing_message),
+                GalleryUtils.formatDuration(context, bookmark / 1000)));
+        builder.setOnCancelListener(new OnCancelListener() {
+            public void onCancel(DialogInterface dialog) {
+                onCompletion();
+            }
+        });
+        builder.setPositiveButton(
+                R.string.resume_playing_resume, new OnClickListener() {
+            public void onClick(DialogInterface dialog, int which) {
+                mVideoView.seekTo(bookmark);
+                mVideoView.start();
+            }
+        });
+        builder.setNegativeButton(
+                R.string.resume_playing_restart, new OnClickListener() {
+            public void onClick(DialogInterface dialog, int which) {
+                mVideoView.start();
+            }
+        });
+        builder.show();
+    }
+
+    public void onPause() {
+        mHandler.removeCallbacksAndMessages(null);
+        mBookmarker.setBookmark(mUri, mVideoView.getCurrentPosition(),
+                mVideoView.getDuration());
+        mVideoView.suspend();
+        mHasPaused = true;
+    }
+
+    public void onResume() {
+        if (mHasPaused) {
+            Integer bookmark = mBookmarker.getBookmark(mUri);
+            if (bookmark != null) {
+                mVideoView.seekTo(bookmark);
+            }
+        }
+        mVideoView.resume();
+    }
+
+    public void onDestroy() {
+        mVideoView.stopPlayback();
+        mAudioBecomingNoisyReceiver.unregister();
+    }
+
+    public boolean onError(MediaPlayer player, int arg1, int arg2) {
+        mHandler.removeCallbacksAndMessages(null);
+        mProgressView.setVisibility(View.GONE);
+        return false;
+    }
+
+    public void onCompletion(MediaPlayer mp) {
+        onCompletion();
+    }
+
+    public void onCompletion() {
+    }
+
+    private class AudioBecomingNoisyReceiver extends BroadcastReceiver {
+
+        public void register() {
+            mContext.registerReceiver(this,
+                    new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
+        }
+
+        public void unregister() {
+            mContext.unregisterReceiver(this);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mVideoView.isPlaying()) {
+                mVideoView.pause();
+          }
+        }
+    }
+}
+
+class Bookmarker {
+    private static final String TAG = "Bookmarker";
+
+    private static final String BOOKMARK_CACHE_FILE = "bookmark";
+    private static final int BOOKMARK_CACHE_MAX_ENTRIES = 100;
+    private static final int BOOKMARK_CACHE_MAX_BYTES = 10 * 1024;
+    private static final int BOOKMARK_CACHE_VERSION = 1;
+
+    private static final int HALF_MINUTE = 30 * 1000;
+    private static final int TWO_MINUTES = 4 * HALF_MINUTE;
+
+    private final Context mContext;
+
+    public Bookmarker(Context context) {
+        mContext = context;
+    }
+
+    public void setBookmark(Uri uri, int bookmark, int duration) {
+        try {
+            BlobCache cache = CacheManager.getCache(mContext,
+                    BOOKMARK_CACHE_FILE, BOOKMARK_CACHE_MAX_ENTRIES,
+                    BOOKMARK_CACHE_MAX_BYTES, BOOKMARK_CACHE_VERSION);
+
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            DataOutputStream dos = new DataOutputStream(bos);
+            dos.writeUTF(uri.toString());
+            dos.writeInt(bookmark);
+            dos.writeInt(duration);
+            dos.flush();
+            cache.insert(uri.hashCode(), bos.toByteArray());
+        } catch (Throwable t) {
+            Log.w(TAG, "setBookmark failed", t);
+        }
+    }
+
+    public Integer getBookmark(Uri uri) {
+        try {
+            BlobCache cache = CacheManager.getCache(mContext,
+                    BOOKMARK_CACHE_FILE, BOOKMARK_CACHE_MAX_ENTRIES,
+                    BOOKMARK_CACHE_MAX_BYTES, BOOKMARK_CACHE_VERSION);
+
+            byte[] data = cache.lookup(uri.hashCode());
+            if (data == null) return null;
+
+            DataInputStream dis = new DataInputStream(
+                    new ByteArrayInputStream(data));
+
+            String uriString = dis.readUTF(dis);
+            int bookmark = dis.readInt();
+            int duration = dis.readInt();
+
+            if (!uriString.equals(uri.toString())) {
+                return null;
+            }
+
+            if ((bookmark < HALF_MINUTE) || (duration < TWO_MINUTES)
+                    || (bookmark > (duration - HALF_MINUTE))) {
+                return null;
+            }
+            return Integer.valueOf(bookmark);
+        } catch (Throwable t) {
+            Log.w(TAG, "getBookmark failed", t);
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/gallery3d/app/PackagesMonitor.java b/src/com/android/gallery3d/app/PackagesMonitor.java
new file mode 100644
index 0000000..cb202a3
--- /dev/null
+++ b/src/com/android/gallery3d/app/PackagesMonitor.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.picasasource.PicasaSource;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+public class PackagesMonitor extends BroadcastReceiver {
+    public static final String KEY_PACKAGES_VERSION  = "packages-version";
+
+    public synchronized static int getPackagesVersion(Context context) {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        return prefs.getInt(KEY_PACKAGES_VERSION, 1);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+
+        int version = prefs.getInt(KEY_PACKAGES_VERSION, 1);
+        prefs.edit().putInt(KEY_PACKAGES_VERSION, version + 1).commit();
+
+        String action = intent.getAction();
+        String packageName = intent.getData().getSchemeSpecificPart();
+        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+            PicasaSource.onPackageAdded(context, packageName);
+        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+            PicasaSource.onPackageRemoved(context, packageName);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java
new file mode 100644
index 0000000..c05c89a
--- /dev/null
+++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.PhotoView;
+import com.android.gallery3d.ui.PhotoView.ImageData;
+import com.android.gallery3d.ui.SynchronizedHandler;
+import com.android.gallery3d.ui.TileImageViewAdapter;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.ThreadPool;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapRegionDecoder;
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+
+public class PhotoDataAdapter implements PhotoPage.Model {
+    @SuppressWarnings("unused")
+    private static final String TAG = "PhotoDataAdapter";
+
+    private static final int MSG_LOAD_START = 1;
+    private static final int MSG_LOAD_FINISH = 2;
+    private static final int MSG_RUN_OBJECT = 3;
+
+    private static final int MIN_LOAD_COUNT = 8;
+    private static final int DATA_CACHE_SIZE = 32;
+    private static final int IMAGE_CACHE_SIZE = 5;
+
+    private static final int BIT_SCREEN_NAIL = 1;
+    private static final int BIT_FULL_IMAGE = 2;
+
+    private static final long VERSION_OUT_OF_RANGE = MediaObject.nextVersionNumber();
+
+    // sImageFetchSeq is the fetching sequence for images.
+    // We want to fetch the current screennail first (offset = 0), the next
+    // screennail (offset = +1), then the previous screennail (offset = -1) etc.
+    // After all the screennail are fetched, we fetch the full images (only some
+    // of them because of we don't want to use too much memory).
+    private static ImageFetch[] sImageFetchSeq;
+
+    private static class ImageFetch {
+        int indexOffset;
+        int imageBit;
+        public ImageFetch(int offset, int bit) {
+            indexOffset = offset;
+            imageBit = bit;
+        }
+    }
+
+    static {
+        int k = 0;
+        sImageFetchSeq = new ImageFetch[1 + (IMAGE_CACHE_SIZE - 1) * 2 + 3];
+        sImageFetchSeq[k++] = new ImageFetch(0, BIT_SCREEN_NAIL);
+
+        for (int i = 1; i < IMAGE_CACHE_SIZE; ++i) {
+            sImageFetchSeq[k++] = new ImageFetch(i, BIT_SCREEN_NAIL);
+            sImageFetchSeq[k++] = new ImageFetch(-i, BIT_SCREEN_NAIL);
+        }
+
+        sImageFetchSeq[k++] = new ImageFetch(0, BIT_FULL_IMAGE);
+        sImageFetchSeq[k++] = new ImageFetch(1, BIT_FULL_IMAGE);
+        sImageFetchSeq[k++] = new ImageFetch(-1, BIT_FULL_IMAGE);
+    }
+
+    private final TileImageViewAdapter mTileProvider = new TileImageViewAdapter();
+
+    // PhotoDataAdapter caches MediaItems (data) and ImageEntries (image).
+    //
+    // The MediaItems are stored in the mData array, which has DATA_CACHE_SIZE
+    // entries. The valid index range are [mContentStart, mContentEnd). We keep
+    // mContentEnd - mContentStart <= DATA_CACHE_SIZE, so we can use
+    // (i % DATA_CACHE_SIZE) as index to the array.
+    //
+    // The valid MediaItem window size (mContentEnd - mContentStart) may be
+    // smaller than DATA_CACHE_SIZE because we only update the window and reload
+    // the MediaItems when there are significant changes to the window position
+    // (>= MIN_LOAD_COUNT).
+    private final MediaItem mData[] = new MediaItem[DATA_CACHE_SIZE];
+    private int mContentStart = 0;
+    private int mContentEnd = 0;
+
+    /*
+     * The ImageCache is a version-to-ImageEntry map. It only holds
+     * the ImageEntries in the range of [mActiveStart, mActiveEnd).
+     * We also keep mActiveEnd - mActiveStart <= IMAGE_CACHE_SIZE.
+     * Besides, the [mActiveStart, mActiveEnd) range must be contained
+     * within the[mContentStart, mContentEnd) range.
+     */
+    private HashMap<Long, ImageEntry> mImageCache = new HashMap<Long, ImageEntry>();
+    private int mActiveStart = 0;
+    private int mActiveEnd = 0;
+
+    // mCurrentIndex is the "center" image the user is viewing. The change of
+    // mCurrentIndex triggers the data loading and image loading.
+    private int mCurrentIndex;
+
+    // mChanges keeps the version number (of MediaItem) about the previous,
+    // current, and next image. If the version number changes, we invalidate
+    // the model. This is used after a database reload or mCurrentIndex changes.
+    private final long mChanges[] = new long[3];
+
+    private final Handler mMainHandler;
+    private final ThreadPool mThreadPool;
+
+    private final PhotoView mPhotoView;
+    private final MediaSet mSource;
+    private ReloadTask mReloadTask;
+
+    private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
+    private int mSize = 0;
+    private Path mItemPath;
+    private boolean mIsActive;
+
+    public interface DataListener extends LoadingListener {
+        public void onPhotoChanged(int index, Path item);
+    }
+
+    private DataListener mDataListener;
+
+    private final SourceListener mSourceListener = new SourceListener();
+
+    // The path of the current viewing item will be stored in mItemPath.
+    // If mItemPath is not null, mCurrentIndex is only a hint for where we
+    // can find the item. If mItemPath is null, then we use the mCurrentIndex to
+    // find the image being viewed.
+    public PhotoDataAdapter(GalleryActivity activity,
+            PhotoView view, MediaSet mediaSet, Path itemPath, int indexHint) {
+        mSource = Utils.checkNotNull(mediaSet);
+        mPhotoView = Utils.checkNotNull(view);
+        mItemPath = Utils.checkNotNull(itemPath);
+        mCurrentIndex = indexHint;
+        mThreadPool = activity.getThreadPool();
+
+        Arrays.fill(mChanges, MediaObject.INVALID_DATA_VERSION);
+
+        mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_RUN_OBJECT:
+                        ((Runnable) message.obj).run();
+                        return;
+                    case MSG_LOAD_START: {
+                        if (mDataListener != null) mDataListener.onLoadingStarted();
+                        return;
+                    }
+                    case MSG_LOAD_FINISH: {
+                        if (mDataListener != null) mDataListener.onLoadingFinished();
+                        return;
+                    }
+                    default: throw new AssertionError();
+                }
+            }
+        };
+
+        updateSlidingWindow();
+    }
+
+    private long getVersion(int index) {
+        if (index < 0 || index >= mSize) return VERSION_OUT_OF_RANGE;
+        if (index >= mContentStart && index < mContentEnd) {
+            MediaItem item = mData[index % DATA_CACHE_SIZE];
+            if (item != null) return item.getDataVersion();
+        }
+        return MediaObject.INVALID_DATA_VERSION;
+    }
+
+    private void fireModelInvalidated() {
+        for (int i = -1; i <= 1; ++i) {
+            long current = getVersion(mCurrentIndex + i);
+            long change = mChanges[i + 1];
+            if (current != change) {
+                mPhotoView.notifyImageInvalidated(i);
+                mChanges[i + 1] = current;
+            }
+        }
+    }
+
+    public void setDataListener(DataListener listener) {
+        mDataListener = listener;
+    }
+
+    private void updateScreenNail(long version, Future<Bitmap> future) {
+        ImageEntry entry = mImageCache.get(version);
+        if (entry == null || entry.screenNailTask == null) {
+            Bitmap screenNail = future.get();
+            if (screenNail != null) screenNail.recycle();
+            return;
+        }
+        entry.screenNailTask = null;
+        entry.screenNail = future.get();
+
+        if (entry.screenNail == null) {
+            entry.failToLoad = true;
+        } else {
+            for (int i = -1; i <=1; ++i) {
+                if (version == getVersion(mCurrentIndex + i)) {
+                    if (i == 0) updateTileProvider(entry);
+                    mPhotoView.notifyImageInvalidated(i);
+                }
+            }
+        }
+        updateImageRequests();
+    }
+
+    private void updateFullImage(long version, Future<BitmapRegionDecoder> future) {
+        ImageEntry entry = mImageCache.get(version);
+        if (entry == null || entry.fullImageTask == null) {
+            BitmapRegionDecoder fullImage = future.get();
+            if (fullImage != null) fullImage.recycle();
+            return;
+        }
+        entry.fullImageTask = null;
+        entry.fullImage = future.get();
+        if (entry.fullImage != null) {
+            if (version == getVersion(mCurrentIndex)) {
+                updateTileProvider(entry);
+                mPhotoView.notifyImageInvalidated(0);
+            }
+        }
+        updateImageRequests();
+    }
+
+    public void resume() {
+        mIsActive = true;
+        mSource.addContentListener(mSourceListener);
+        updateImageCache();
+        updateImageRequests();
+
+        mReloadTask = new ReloadTask();
+        mReloadTask.start();
+
+        mPhotoView.notifyModelInvalidated();
+    }
+
+    public void pause() {
+        mIsActive = false;
+
+        mReloadTask.terminate();
+        mReloadTask = null;
+
+        mSource.removeContentListener(mSourceListener);
+
+        for (ImageEntry entry : mImageCache.values()) {
+            if (entry.fullImageTask != null) entry.fullImageTask.cancel();
+            if (entry.screenNailTask != null) entry.screenNailTask.cancel();
+        }
+        mImageCache.clear();
+        mTileProvider.clear();
+    }
+
+    private ImageData getImage(int index) {
+        if (index < 0 || index >= mSize || !mIsActive) return null;
+        Utils.assertTrue(index >= mActiveStart && index < mActiveEnd);
+
+        ImageEntry entry = mImageCache.get(getVersion(index));
+        Bitmap screennail = entry == null ? null : entry.screenNail;
+        if (screennail != null) {
+            return new ImageData(screennail, entry.rotation);
+        } else {
+            return new ImageData(null, 0);
+        }
+    }
+
+    public ImageData getPreviousImage() {
+        return getImage(mCurrentIndex - 1);
+    }
+
+    public ImageData getNextImage() {
+        return getImage(mCurrentIndex + 1);
+    }
+
+    private void updateCurrentIndex(int index) {
+        mCurrentIndex = index;
+        updateSlidingWindow();
+
+        MediaItem item = mData[index % DATA_CACHE_SIZE];
+        mItemPath = item == null ? null : item.getPath();
+
+        updateImageCache();
+        updateImageRequests();
+        updateTileProvider();
+        mPhotoView.notifyOnNewImage();
+
+        if (mDataListener != null) {
+            mDataListener.onPhotoChanged(index, mItemPath);
+        }
+        fireModelInvalidated();
+    }
+
+    public void next() {
+        updateCurrentIndex(mCurrentIndex + 1);
+    }
+
+    public void previous() {
+        updateCurrentIndex(mCurrentIndex - 1);
+    }
+
+    public void jumpTo(int index) {
+        if (mCurrentIndex == index) return;
+        updateCurrentIndex(index);
+    }
+
+    public Bitmap getBackupImage() {
+        return mTileProvider.getBackupImage();
+    }
+
+    public int getImageHeight() {
+        return mTileProvider.getImageHeight();
+    }
+
+    public int getImageWidth() {
+        return mTileProvider.getImageWidth();
+    }
+
+    public int getImageRotation() {
+        ImageEntry entry = mImageCache.get(getVersion(mCurrentIndex));
+        return entry == null ? 0 : entry.rotation;
+    }
+
+    public int getLevelCount() {
+        return mTileProvider.getLevelCount();
+    }
+
+    public Bitmap getTile(int level, int x, int y, int tileSize) {
+        return mTileProvider.getTile(level, x, y, tileSize);
+    }
+
+    public boolean isFailedToLoad() {
+        return mTileProvider.isFailedToLoad();
+    }
+
+    public boolean isEmpty() {
+        return mSize == 0;
+    }
+
+    public int getCurrentIndex() {
+        return mCurrentIndex;
+    }
+
+    public MediaItem getCurrentMediaItem() {
+        return mData[mCurrentIndex % DATA_CACHE_SIZE];
+    }
+
+    public void setCurrentPhoto(Path path, int indexHint) {
+        if (mItemPath == path) return;
+        mItemPath = path;
+        mCurrentIndex = indexHint;
+        updateSlidingWindow();
+        updateImageCache();
+        fireModelInvalidated();
+
+        // We need to reload content if the path doesn't match.
+        MediaItem item = getCurrentMediaItem();
+        if (item != null && item.getPath() != path) {
+            if (mReloadTask != null) mReloadTask.notifyDirty();
+        }
+    }
+
+    private void updateTileProvider() {
+        ImageEntry entry = mImageCache.get(getVersion(mCurrentIndex));
+        if (entry == null) { // in loading
+            mTileProvider.clear();
+        } else {
+            updateTileProvider(entry);
+        }
+    }
+
+    private void updateTileProvider(ImageEntry entry) {
+        Bitmap screenNail = entry.screenNail;
+        BitmapRegionDecoder fullImage = entry.fullImage;
+        if (screenNail != null) {
+            if (fullImage != null) {
+                mTileProvider.setBackupImage(screenNail,
+                        fullImage.getWidth(), fullImage.getHeight());
+                mTileProvider.setRegionDecoder(fullImage);
+            } else {
+                int width = screenNail.getWidth();
+                int height = screenNail.getHeight();
+                mTileProvider.setBackupImage(screenNail, width, height);
+            }
+        } else {
+            mTileProvider.clear();
+            if (entry.failToLoad) mTileProvider.setFailedToLoad();
+        }
+    }
+
+    private void updateSlidingWindow() {
+        // 1. Update the image window
+        int start = Utils.clamp(mCurrentIndex - IMAGE_CACHE_SIZE / 2,
+                0, Math.max(0, mSize - IMAGE_CACHE_SIZE));
+        int end = Math.min(mSize, start + IMAGE_CACHE_SIZE);
+
+        if (mActiveStart == start && mActiveEnd == end) return;
+
+        mActiveStart = start;
+        mActiveEnd = end;
+
+        // 2. Update the data window
+        start = Utils.clamp(mCurrentIndex - DATA_CACHE_SIZE / 2,
+                0, Math.max(0, mSize - DATA_CACHE_SIZE));
+        end = Math.min(mSize, start + DATA_CACHE_SIZE);
+        if (mContentStart > mActiveStart || mContentEnd < mActiveEnd
+                || Math.abs(start - mContentStart) > MIN_LOAD_COUNT) {
+            for (int i = mContentStart; i < mContentEnd; ++i) {
+                if (i < start || i >= end) {
+                    mData[i % DATA_CACHE_SIZE] = null;
+                }
+            }
+            mContentStart = start;
+            mContentEnd = end;
+            if (mReloadTask != null) mReloadTask.notifyDirty();
+        }
+    }
+
+    private void updateImageRequests() {
+        if (!mIsActive) return;
+
+        int currentIndex = mCurrentIndex;
+        MediaItem item = mData[currentIndex % DATA_CACHE_SIZE];
+        if (item == null || item.getPath() != mItemPath) {
+            // current item mismatch - don't request image
+            return;
+        }
+
+        // 1. Find the most wanted request and start it (if not already started).
+        Future<?> task = null;
+        for (int i = 0; i < sImageFetchSeq.length; i++) {
+            int offset = sImageFetchSeq[i].indexOffset;
+            int bit = sImageFetchSeq[i].imageBit;
+            task = startTaskIfNeeded(currentIndex + offset, bit);
+            if (task != null) break;
+        }
+
+        // 2. Cancel everything else.
+        for (ImageEntry entry : mImageCache.values()) {
+            if (entry.screenNailTask != null && entry.screenNailTask != task) {
+                entry.screenNailTask.cancel();
+                entry.screenNailTask = null;
+                entry.requestedBits &= ~BIT_SCREEN_NAIL;
+            }
+            if (entry.fullImageTask != null && entry.fullImageTask != task) {
+                entry.fullImageTask.cancel();
+                entry.fullImageTask = null;
+                entry.requestedBits &= ~BIT_FULL_IMAGE;
+            }
+        }
+    }
+
+    // Returns the task if we started the task or the task is already started.
+    private Future<?> startTaskIfNeeded(int index, int which) {
+        if (index < mActiveStart || index >= mActiveEnd) return null;
+
+        ImageEntry entry = mImageCache.get(getVersion(index));
+        if (entry == null) return null;
+
+        if (which == BIT_SCREEN_NAIL && entry.screenNailTask != null) {
+            return entry.screenNailTask;
+        } else if (which == BIT_FULL_IMAGE && entry.fullImageTask != null) {
+            return entry.fullImageTask;
+        }
+
+        MediaItem item = mData[index % DATA_CACHE_SIZE];
+        Utils.assertTrue(item != null);
+
+        if (which == BIT_SCREEN_NAIL
+                && (entry.requestedBits & BIT_SCREEN_NAIL) == 0) {
+            entry.requestedBits |= BIT_SCREEN_NAIL;
+            entry.screenNailTask = mThreadPool.submit(
+                    item.requestImage(MediaItem.TYPE_THUMBNAIL),
+                    new ScreenNailListener(item.getDataVersion()));
+            // request screen nail
+            return entry.screenNailTask;
+        }
+        if (which == BIT_FULL_IMAGE
+                && (entry.requestedBits & BIT_FULL_IMAGE) == 0
+                && (item.getSupportedOperations()
+                & MediaItem.SUPPORT_FULL_IMAGE) != 0) {
+            entry.requestedBits |= BIT_FULL_IMAGE;
+            entry.fullImageTask = mThreadPool.submit(
+                    item.requestLargeImage(),
+                    new FullImageListener(item.getDataVersion()));
+            // request full image
+            return entry.fullImageTask;
+        }
+        return null;
+    }
+
+    private void updateImageCache() {
+        HashSet<Long> toBeRemoved = new HashSet<Long>(mImageCache.keySet());
+        for (int i = mActiveStart; i < mActiveEnd; ++i) {
+            MediaItem item = mData[i % DATA_CACHE_SIZE];
+            long version = item == null
+                    ? MediaObject.INVALID_DATA_VERSION
+                    : item.getDataVersion();
+            if (version == MediaObject.INVALID_DATA_VERSION) continue;
+            ImageEntry entry = mImageCache.get(version);
+            toBeRemoved.remove(version);
+            if (entry != null) {
+                if (Math.abs(i - mCurrentIndex) > 1) {
+                    if (entry.fullImageTask != null) {
+                        entry.fullImageTask.cancel();
+                        entry.fullImageTask = null;
+                    }
+                    entry.fullImage = null;
+                    entry.requestedBits &= ~BIT_FULL_IMAGE;
+                }
+            } else {
+                entry = new ImageEntry();
+                entry.rotation = item.getRotation();
+                mImageCache.put(version, entry);
+            }
+        }
+
+        // Clear the data and requests for ImageEntries outside the new window.
+        for (Long version : toBeRemoved) {
+            ImageEntry entry = mImageCache.remove(version);
+            if (entry.fullImageTask != null) entry.fullImageTask.cancel();
+            if (entry.screenNailTask != null) entry.screenNailTask.cancel();
+        }
+    }
+
+    private class FullImageListener
+            implements Runnable, FutureListener<BitmapRegionDecoder> {
+        private final long mVersion;
+        private Future<BitmapRegionDecoder> mFuture;
+
+        public FullImageListener(long version) {
+            mVersion = version;
+        }
+
+        public void onFutureDone(Future<BitmapRegionDecoder> future) {
+            mFuture = future;
+            mMainHandler.sendMessage(
+                    mMainHandler.obtainMessage(MSG_RUN_OBJECT, this));
+        }
+
+        public void run() {
+            updateFullImage(mVersion, mFuture);
+        }
+    }
+
+    private class ScreenNailListener
+            implements Runnable, FutureListener<Bitmap> {
+        private final long mVersion;
+        private Future<Bitmap> mFuture;
+
+        public ScreenNailListener(long version) {
+            mVersion = version;
+        }
+
+        public void onFutureDone(Future<Bitmap> future) {
+            mFuture = future;
+            mMainHandler.sendMessage(
+                    mMainHandler.obtainMessage(MSG_RUN_OBJECT, this));
+        }
+
+        public void run() {
+            updateScreenNail(mVersion, mFuture);
+        }
+    }
+
+    private static class ImageEntry {
+        public int requestedBits = 0;
+        public int rotation;
+        public BitmapRegionDecoder fullImage;
+        public Bitmap screenNail;
+        public Future<Bitmap> screenNailTask;
+        public Future<BitmapRegionDecoder> fullImageTask;
+        public boolean failToLoad = false;
+    }
+
+    private class SourceListener implements ContentListener {
+        public void onContentDirty() {
+            if (mReloadTask != null) mReloadTask.notifyDirty();
+        }
+    }
+
+    private <T> T executeAndWait(Callable<T> callable) {
+        FutureTask<T> task = new FutureTask<T>(callable);
+        mMainHandler.sendMessage(
+                mMainHandler.obtainMessage(MSG_RUN_OBJECT, task));
+        try {
+            return task.get();
+        } catch (InterruptedException e) {
+            return null;
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static class UpdateInfo {
+        public long version;
+        public boolean reloadContent;
+        public Path target;
+        public int indexHint;
+        public int contentStart;
+        public int contentEnd;
+
+        public int size;
+        public ArrayList<MediaItem> items;
+    }
+
+    private class GetUpdateInfo implements Callable<UpdateInfo> {
+
+        private boolean needContentReload() {
+            for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+                if (mData[i % DATA_CACHE_SIZE] == null) return true;
+            }
+            MediaItem current = mData[mCurrentIndex % DATA_CACHE_SIZE];
+            return current == null || current.getPath() != mItemPath;
+        }
+
+        @Override
+        public UpdateInfo call() throws Exception {
+            UpdateInfo info = new UpdateInfo();
+            info.version = mSourceVersion;
+            info.reloadContent = needContentReload();
+            info.target = mItemPath;
+            info.indexHint = mCurrentIndex;
+            info.contentStart = mContentStart;
+            info.contentEnd = mContentEnd;
+            info.size = mSize;
+            return info;
+        }
+    }
+
+    private class UpdateContent implements Callable<Void> {
+        UpdateInfo mUpdateInfo;
+
+        public UpdateContent(UpdateInfo updateInfo) {
+            mUpdateInfo = updateInfo;
+        }
+
+        @Override
+        public Void call() throws Exception {
+            UpdateInfo info = mUpdateInfo;
+            mSourceVersion = info.version;
+
+            if (info.size != mSize) {
+                mSize = info.size;
+                if (mContentEnd > mSize) mContentEnd = mSize;
+                if (mActiveEnd > mSize) mActiveEnd = mSize;
+            }
+
+            if (info.indexHint == MediaSet.INDEX_NOT_FOUND) {
+                // The image has been deleted, clear mItemPath, the
+                // mCurrentIndex will be updated in the updateCurrentItem().
+                mItemPath = null;
+                updateCurrentItem();
+            } else {
+                mCurrentIndex = info.indexHint;
+            }
+
+            updateSlidingWindow();
+
+            if (info.items != null) {
+                int start = Math.max(info.contentStart, mContentStart);
+                int end = Math.min(info.contentStart + info.items.size(), mContentEnd);
+                int dataIndex = start % DATA_CACHE_SIZE;
+                for (int i = start; i < end; ++i) {
+                    mData[dataIndex] = info.items.get(i - info.contentStart);
+                    if (++dataIndex == DATA_CACHE_SIZE) dataIndex = 0;
+                }
+            }
+            if (mItemPath == null) {
+                MediaItem current = mData[mCurrentIndex % DATA_CACHE_SIZE];
+                mItemPath = current == null ? null : current.getPath();
+            }
+            updateImageCache();
+            updateTileProvider();
+            updateImageRequests();
+            fireModelInvalidated();
+            return null;
+        }
+
+        private void updateCurrentItem() {
+            if (mSize == 0) return;
+            if (mCurrentIndex >= mSize) {
+                mCurrentIndex = mSize - 1;
+                mPhotoView.notifyOnNewImage();
+                mPhotoView.startSlideInAnimation(PhotoView.TRANS_SLIDE_IN_LEFT);
+            } else {
+                mPhotoView.notifyOnNewImage();
+                mPhotoView.startSlideInAnimation(PhotoView.TRANS_SLIDE_IN_RIGHT);
+            }
+        }
+    }
+
+    private class ReloadTask extends Thread {
+        private volatile boolean mActive = true;
+        private volatile boolean mDirty = true;
+
+        private boolean mIsLoading = false;
+
+        private void updateLoading(boolean loading) {
+            if (mIsLoading == loading) return;
+            mIsLoading = loading;
+            mMainHandler.sendEmptyMessage(loading ? MSG_LOAD_START : MSG_LOAD_FINISH);
+        }
+
+        @Override
+        public void run() {
+            while (mActive) {
+                synchronized (this) {
+                    if (!mDirty && mActive) {
+                        updateLoading(false);
+                        Utils.waitWithoutInterrupt(this);
+                        continue;
+                    }
+                }
+                mDirty = false;
+                UpdateInfo info = executeAndWait(new GetUpdateInfo());
+                synchronized (DataManager.LOCK) {
+                    updateLoading(true);
+                    long version = mSource.reload();
+                    if (info.version != version) {
+                        info.reloadContent = true;
+                        info.size = mSource.getMediaItemCount();
+                    }
+                    if (!info.reloadContent) continue;
+                    info.items =  mSource.getMediaItem(info.contentStart, info.contentEnd);
+                    MediaItem item = findCurrentMediaItem(info);
+                    if (item == null || item.getPath() != info.target) {
+                        info.indexHint = findIndexOfTarget(info);
+                    }
+                }
+                executeAndWait(new UpdateContent(info));
+            }
+        }
+
+        public synchronized void notifyDirty() {
+            mDirty = true;
+            notifyAll();
+        }
+
+        public synchronized void terminate() {
+            mActive = false;
+            notifyAll();
+        }
+
+        private MediaItem findCurrentMediaItem(UpdateInfo info) {
+            ArrayList<MediaItem> items = info.items;
+            int index = info.indexHint - info.contentStart;
+            return index < 0 || index >= items.size() ? null : items.get(index);
+        }
+
+        private int findIndexOfTarget(UpdateInfo info) {
+            if (info.target == null) return info.indexHint;
+            ArrayList<MediaItem> items = info.items;
+
+            // First, try to find the item in the data just loaded
+            if (items != null) {
+                for (int i = 0, n = items.size(); i < n; ++i) {
+                    if (items.get(i).getPath() == info.target) return i + info.contentStart;
+                }
+            }
+
+            // Not found, find it in mSource.
+            return mSource.getIndexOfItem(info.target, info.indexHint);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
new file mode 100644
index 0000000..f28eb22
--- /dev/null
+++ b/src/com/android/gallery3d/app/PhotoPage.java
@@ -0,0 +1,581 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaDetails;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.MtpDevice;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.picasasource.PicasaSource;
+import com.android.gallery3d.ui.DetailsWindow;
+import com.android.gallery3d.ui.DetailsWindow.CloseListener;
+import com.android.gallery3d.ui.DetailsWindow.DetailsSource;
+import com.android.gallery3d.ui.FilmStripView;
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.GLView;
+import com.android.gallery3d.ui.ImportCompleteListener;
+import com.android.gallery3d.ui.MenuExecutor;
+import com.android.gallery3d.ui.PhotoView;
+import com.android.gallery3d.ui.PositionRepository;
+import com.android.gallery3d.ui.PositionRepository.Position;
+import com.android.gallery3d.ui.SelectionManager;
+import com.android.gallery3d.ui.SynchronizedHandler;
+import com.android.gallery3d.ui.UserInteractionListener;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.ActionBar;
+import android.app.ActionBar.OnMenuVisibilityListener;
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.WindowManager;
+import android.widget.ShareActionProvider;
+import android.widget.Toast;
+
+public class PhotoPage extends ActivityState
+        implements PhotoView.PhotoTapListener, FilmStripView.Listener,
+        UserInteractionListener {
+    private static final String TAG = "PhotoPage";
+
+    private static final int MSG_HIDE_BARS = 1;
+    private static final int HIDE_BARS_TIMEOUT = 3500;
+
+    private static final int REQUEST_SLIDESHOW = 1;
+    private static final int REQUEST_CROP = 2;
+    private static final int REQUEST_CROP_PICASA = 3;
+
+    public static final String KEY_MEDIA_SET_PATH = "media-set-path";
+    public static final String KEY_MEDIA_ITEM_PATH = "media-item-path";
+    public static final String KEY_INDEX_HINT = "index-hint";
+
+    private GalleryApp mApplication;
+    private SelectionManager mSelectionManager;
+
+    private PhotoView mPhotoView;
+    private PhotoPage.Model mModel;
+    private FilmStripView mFilmStripView;
+    private DetailsWindow mDetailsWindow;
+    private boolean mShowDetails;
+
+    // mMediaSet could be null if there is no KEY_MEDIA_SET_PATH supplied.
+    // E.g., viewing a photo in gmail attachment
+    private MediaSet mMediaSet;
+    private Menu mMenu;
+
+    private Intent mResultIntent = new Intent();
+    private int mCurrentIndex = 0;
+    private Handler mHandler;
+    private boolean mShowBars;
+    private ActionBar mActionBar;
+    private MyMenuVisibilityListener mMenuVisibilityListener;
+    private boolean mIsMenuVisible;
+    private boolean mIsInteracting;
+    private MediaItem mCurrentPhoto = null;
+    private MenuExecutor mMenuExecutor;
+    private boolean mIsActive;
+    private ShareActionProvider mShareActionProvider;
+
+    public static interface Model extends PhotoView.Model {
+        public void resume();
+        public void pause();
+        public boolean isEmpty();
+        public MediaItem getCurrentMediaItem();
+        public int getCurrentIndex();
+        public void setCurrentPhoto(Path path, int indexHint);
+    }
+
+    private class MyMenuVisibilityListener implements OnMenuVisibilityListener {
+        public void onMenuVisibilityChanged(boolean isVisible) {
+            mIsMenuVisible = isVisible;
+            refreshHidingMessage();
+        }
+    }
+
+    private GLView mRootPane = new GLView() {
+
+        @Override
+        protected void renderBackground(GLCanvas view) {
+            view.clearBuffer();
+        }
+
+        @Override
+        protected void onLayout(
+                boolean changed, int left, int top, int right, int bottom) {
+            mPhotoView.layout(0, 0, right - left, bottom - top);
+            PositionRepository.getInstance(mActivity).setOffset(0, 0);
+            int filmStripHeight = 0;
+            if (mFilmStripView != null) {
+                mFilmStripView.measure(
+                        MeasureSpec.makeMeasureSpec(right - left, MeasureSpec.EXACTLY),
+                        MeasureSpec.UNSPECIFIED);
+                filmStripHeight = mFilmStripView.getMeasuredHeight();
+                mFilmStripView.layout(0, bottom - top - filmStripHeight,
+                        right - left, bottom - top);
+            }
+            if (mShowDetails) {
+                mDetailsWindow.measure(
+                        MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+                int width = mDetailsWindow.getMeasuredWidth();
+                int viewTop = GalleryActionBar.getHeight((Activity) mActivity);
+                mDetailsWindow.layout(
+                        0, viewTop, width, bottom - top - filmStripHeight);
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle data, Bundle restoreState) {
+        mActionBar = ((Activity) mActivity).getActionBar();
+        mSelectionManager = new SelectionManager(mActivity, false);
+        mMenuExecutor = new MenuExecutor(mActivity, mSelectionManager);
+
+        mPhotoView = new PhotoView(mActivity);
+        mPhotoView.setPhotoTapListener(this);
+        mRootPane.addComponent(mPhotoView);
+        mApplication = (GalleryApp)((Activity) mActivity).getApplication();
+
+        String setPathString = data.getString(KEY_MEDIA_SET_PATH);
+        Path itemPath = Path.fromString(data.getString(KEY_MEDIA_ITEM_PATH));
+
+        if (setPathString != null) {
+            mMediaSet = mActivity.getDataManager().getMediaSet(setPathString);
+            mCurrentIndex = data.getInt(KEY_INDEX_HINT, 0);
+            mMediaSet = (MediaSet)
+                    mActivity.getDataManager().getMediaObject(setPathString);
+            if (mMediaSet == null) {
+                Log.w(TAG, "failed to restore " + setPathString);
+            }
+            PhotoDataAdapter pda = new PhotoDataAdapter(
+                    mActivity, mPhotoView, mMediaSet, itemPath, mCurrentIndex);
+            mModel = pda;
+            mPhotoView.setModel(mModel);
+
+            Config.PhotoPage config = Config.PhotoPage.get((Context) mActivity);
+
+            mFilmStripView = new FilmStripView(mActivity, mMediaSet,
+                    config.filmstripTopMargin, config.filmstripMidMargin, config.filmstripBottomMargin,
+                    config.filmstripContentSize, config.filmstripThumbSize, config.filmstripBarSize,
+                    config.filmstripGripSize, config.filmstripGripWidth);
+            mRootPane.addComponent(mFilmStripView);
+            mFilmStripView.setListener(this);
+            mFilmStripView.setUserInteractionListener(this);
+            mFilmStripView.setFocusIndex(mCurrentIndex);
+            mFilmStripView.setStartIndex(mCurrentIndex);
+
+            mResultIntent.putExtra(KEY_INDEX_HINT, mCurrentIndex);
+            setStateResult(Activity.RESULT_OK, mResultIntent);
+
+            pda.setDataListener(new PhotoDataAdapter.DataListener() {
+
+                public void onPhotoChanged(int index, Path item) {
+                    mFilmStripView.setFocusIndex(index);
+                    mCurrentIndex = index;
+                    mResultIntent.putExtra(KEY_INDEX_HINT, index);
+                    if (item != null) {
+                        mResultIntent.putExtra(KEY_MEDIA_ITEM_PATH, item.toString());
+                        MediaItem photo = mModel.getCurrentMediaItem();
+                        if (photo != null) updateCurrentPhoto(photo);
+                    } else {
+                        mResultIntent.removeExtra(KEY_MEDIA_ITEM_PATH);
+                    }
+                    setStateResult(Activity.RESULT_OK, mResultIntent);
+                }
+
+                @Override
+                public void onLoadingFinished() {
+                    GalleryUtils.setSpinnerVisibility((Activity) mActivity, false);
+                    if (!mModel.isEmpty()) {
+                        MediaItem photo = mModel.getCurrentMediaItem();
+                        if (photo != null) updateCurrentPhoto(photo);
+                    } else if (mIsActive) {
+                        mActivity.getStateManager().finishState(PhotoPage.this);
+                    }
+                }
+
+
+                @Override
+                public void onLoadingStarted() {
+                    GalleryUtils.setSpinnerVisibility((Activity) mActivity, true);
+                }
+            });
+        } else {
+            // Get default media set by the URI
+            MediaItem mediaItem = (MediaItem)
+                    mActivity.getDataManager().getMediaObject(itemPath);
+            mModel = new SinglePhotoDataAdapter(mActivity, mPhotoView, mediaItem);
+            mPhotoView.setModel(mModel);
+            updateCurrentPhoto(mediaItem);
+        }
+        mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_HIDE_BARS: {
+                        hideBars();
+                        break;
+                    }
+                    default: throw new AssertionError(message.what);
+                }
+            }
+        };
+
+        // start the opening animation
+        mPhotoView.setOpenedItem(itemPath);
+    }
+
+    private void updateCurrentPhoto(MediaItem photo) {
+        if (mCurrentPhoto == photo) return;
+        mCurrentPhoto = photo;
+        if (mCurrentPhoto == null) return;
+        updateMenuOperations();
+        if (mShowDetails) {
+            mDetailsWindow.reloadDetails(mModel.getCurrentIndex());
+        }
+        String title = photo.getName();
+        if (title != null) mActionBar.setTitle(title);
+        mPhotoView.showVideoPlayIcon(photo.getMediaType()
+                == MediaObject.MEDIA_TYPE_VIDEO);
+
+        // If we have an ActionBar then we update the share intent
+        if (mShareActionProvider != null) {
+            Path path = photo.getPath();
+            DataManager manager = mActivity.getDataManager();
+            int type = manager.getMediaType(path);
+            Intent intent = new Intent(Intent.ACTION_SEND);
+            intent.setType(MenuExecutor.getMimeType(type));
+            intent.putExtra(Intent.EXTRA_STREAM, manager.getContentUri(path));
+            mShareActionProvider.setShareIntent(intent);
+        }
+    }
+
+    private void updateMenuOperations() {
+        if (mCurrentPhoto == null || mMenu == null) return;
+        int supportedOperations = mCurrentPhoto.getSupportedOperations();
+        if (!GalleryUtils.isEditorAvailable((Context) mActivity, "image/*")) {
+            supportedOperations &= ~MediaObject.SUPPORT_EDIT;
+        }
+        MenuExecutor.updateMenuOperation(mMenu, supportedOperations);
+    }
+
+    private void showBars() {
+        if (mShowBars) return;
+        mShowBars = true;
+        mActionBar.show();
+        WindowManager.LayoutParams params = ((Activity) mActivity).getWindow().getAttributes();
+        params.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+        ((Activity) mActivity).getWindow().setAttributes(params);
+        if (mFilmStripView != null) {
+            mFilmStripView.show();
+        }
+    }
+
+    private void hideBars() {
+        if (!mShowBars) return;
+        mShowBars = false;
+        mActionBar.hide();
+        WindowManager.LayoutParams params = ((Activity) mActivity).getWindow().getAttributes();
+        params.systemUiVisibility = View. SYSTEM_UI_FLAG_LOW_PROFILE;
+        ((Activity) mActivity).getWindow().setAttributes(params);
+        if (mFilmStripView != null) {
+            mFilmStripView.hide();
+        }
+    }
+
+    private void refreshHidingMessage() {
+        mHandler.removeMessages(MSG_HIDE_BARS);
+        if (!mIsMenuVisible && !mIsInteracting) {
+            mHandler.sendEmptyMessageDelayed(MSG_HIDE_BARS, HIDE_BARS_TIMEOUT);
+        }
+    }
+
+    public void onUserInteraction() {
+        showBars();
+        refreshHidingMessage();
+    }
+
+    public void onUserInteractionTap() {
+        if (mShowBars) {
+            hideBars();
+            mHandler.removeMessages(MSG_HIDE_BARS);
+        } else {
+            showBars();
+            refreshHidingMessage();
+        }
+    }
+
+    public void onUserInteractionBegin() {
+        showBars();
+        mIsInteracting = true;
+        refreshHidingMessage();
+    }
+
+    public void onUserInteractionEnd() {
+        mIsInteracting = false;
+        refreshHidingMessage();
+    }
+
+    @Override
+    protected void onBackPressed() {
+        if (mShowDetails) {
+            hideDetails();
+        } else {
+            PositionRepository repository = PositionRepository.getInstance(mActivity);
+            repository.clear();
+            if (mCurrentPhoto != null) {
+                Position position = new Position();
+                position.x = mRootPane.getWidth() / 2;
+                position.y = mRootPane.getHeight() / 2;
+                position.z = -1000;
+                repository.putPosition(
+                        Long.valueOf(System.identityHashCode(mCurrentPhoto.getPath())),
+                        position);
+            }
+            super.onBackPressed();
+        }
+    }
+
+    @Override
+    protected boolean onCreateActionBar(Menu menu) {
+        MenuInflater inflater = ((Activity) mActivity).getMenuInflater();
+        inflater.inflate(R.menu.photo, menu);
+        menu.findItem(R.id.action_slideshow).setVisible(
+                mMediaSet != null && !(mMediaSet instanceof MtpDevice));
+        mShareActionProvider = GalleryActionBar.initializeShareActionProvider(menu);
+        mMenu = menu;
+        mShowBars = true;
+        updateMenuOperations();
+        return true;
+    }
+
+    @Override
+    protected boolean onItemSelected(MenuItem item) {
+        MediaItem current = mModel.getCurrentMediaItem();
+
+        if (current == null) {
+            // item is not ready, ignore
+            return true;
+        }
+
+        int currentIndex = mModel.getCurrentIndex();
+        Path path = current.getPath();
+
+        DataManager manager = mActivity.getDataManager();
+        int action = item.getItemId();
+        switch (action) {
+            case R.id.action_slideshow: {
+                Bundle data = new Bundle();
+                data.putString(SlideshowPage.KEY_SET_PATH,
+                        mMediaSet.getPath().toString());
+                data.putInt(SlideshowPage.KEY_PHOTO_INDEX, currentIndex);
+                data.putBoolean(SlideshowPage.KEY_REPEAT, true);
+                mActivity.getStateManager().startStateForResult(
+                        SlideshowPage.class, REQUEST_SLIDESHOW, data);
+                return true;
+            }
+            case R.id.action_crop: {
+                Activity activity = (Activity) mActivity;
+                Intent intent = new Intent(CropImage.CROP_ACTION);
+                intent.setClass(activity, CropImage.class);
+                intent.setData(manager.getContentUri(path));
+                activity.startActivityForResult(intent, PicasaSource.isPicasaImage(current)
+                        ? REQUEST_CROP_PICASA
+                        : REQUEST_CROP);
+                return true;
+            }
+            case R.id.action_details: {
+                if (mShowDetails) {
+                    hideDetails();
+                } else {
+                    showDetails(currentIndex);
+                }
+                return true;
+            }
+            case R.id.action_setas:
+            case R.id.action_confirm_delete:
+            case R.id.action_rotate_ccw:
+            case R.id.action_rotate_cw:
+            case R.id.action_show_on_map:
+            case R.id.action_edit:
+                mSelectionManager.deSelectAll();
+                mSelectionManager.toggle(path);
+                mMenuExecutor.onMenuClicked(item, null);
+                return true;
+            case R.id.action_import:
+                mSelectionManager.deSelectAll();
+                mSelectionManager.toggle(path);
+                mMenuExecutor.onMenuClicked(item,
+                        new ImportCompleteListener(mActivity));
+                return true;
+            default :
+                return false;
+        }
+    }
+
+    private void hideDetails() {
+        mShowDetails = false;
+        mDetailsWindow.hide();
+    }
+
+    private void showDetails(int index) {
+        mShowDetails = true;
+        if (mDetailsWindow == null) {
+            mDetailsWindow = new DetailsWindow(mActivity, new MyDetailsSource());
+            mDetailsWindow.setCloseListener(new CloseListener() {
+                public void onClose() {
+                    hideDetails();
+                }
+            });
+            mRootPane.addComponent(mDetailsWindow);
+        }
+        mDetailsWindow.reloadDetails(index);
+        mDetailsWindow.show();
+    }
+
+    public void onSingleTapUp(int x, int y) {
+        MediaItem item = mModel.getCurrentMediaItem();
+        if (item == null) {
+            // item is not ready, ignore
+            return;
+        }
+
+        boolean playVideo =
+                (item.getSupportedOperations() & MediaItem.SUPPORT_PLAY) != 0;
+
+        if (playVideo) {
+            // determine if the point is at center (1/6) of the photo view.
+            // (The position of the "play" icon is at center (1/6) of the photo)
+            int w = mPhotoView.getWidth();
+            int h = mPhotoView.getHeight();
+            playVideo = (Math.abs(x - w / 2) * 12 <= w)
+                && (Math.abs(y - h / 2) * 12 <= h);
+        }
+
+        if (playVideo) {
+            playVideo((Activity) mActivity, item.getPlayUri(), item.getName());
+        } else {
+            onUserInteractionTap();
+        }
+    }
+
+    public static void playVideo(Activity activity, Uri uri, String title) {
+        try {
+            Intent intent = new Intent(Intent.ACTION_VIEW)
+                    .setDataAndType(uri, "video/*");
+            intent.putExtra(Intent.EXTRA_TITLE, title);
+            activity.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            Toast.makeText(activity, activity.getString(R.string.video_err),
+                    Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    // Called by FileStripView
+    public void onSlotSelected(int slotIndex) {
+        ((PhotoDataAdapter) mModel).jumpTo(slotIndex);
+    }
+
+    @Override
+    protected void onStateResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_CROP:
+                if (resultCode == Activity.RESULT_OK) {
+                    if (data == null) break;
+                    Path path = mApplication
+                            .getDataManager().findPathByUri(data.getData());
+                    if (path != null) {
+                        mModel.setCurrentPhoto(path, mCurrentIndex);
+                    }
+                }
+                break;
+            case REQUEST_CROP_PICASA: {
+                int message = resultCode == Activity.RESULT_OK
+                        ? R.string.crop_saved
+                        : R.string.crop_not_saved;
+                Toast.makeText(mActivity.getAndroidContext(),
+                        message, Toast.LENGTH_SHORT).show();
+                break;
+            }
+            case REQUEST_SLIDESHOW: {
+                if (data == null) break;
+                String path = data.getStringExtra(SlideshowPage.KEY_ITEM_PATH);
+                int index = data.getIntExtra(SlideshowPage.KEY_PHOTO_INDEX, 0);
+                if (path != null) {
+                    mModel.setCurrentPhoto(Path.fromString(path), index);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mIsActive = false;
+        if (mFilmStripView != null) {
+            mFilmStripView.pause();
+        }
+        if (mDetailsWindow != null) {
+            mDetailsWindow.pause();
+        }
+        mPhotoView.pause();
+        mModel.pause();
+        mHandler.removeMessages(MSG_HIDE_BARS);
+        mActionBar.removeOnMenuVisibilityListener(mMenuVisibilityListener);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mIsActive = true;
+        setContentPane(mRootPane);
+        mModel.resume();
+        mPhotoView.resume();
+        if (mFilmStripView != null) {
+            mFilmStripView.resume();
+        }
+        if (mMenuVisibilityListener == null) {
+            mMenuVisibilityListener = new MyMenuVisibilityListener();
+        }
+        mActionBar.addOnMenuVisibilityListener(mMenuVisibilityListener);
+        onUserInteraction();
+    }
+
+    private class MyDetailsSource implements DetailsSource {
+        public MediaDetails getDetails() {
+            return mModel.getCurrentMediaItem().getDetails();
+        }
+        public int size() {
+            return mMediaSet != null ? mMediaSet.getMediaItemCount() : 1;
+        }
+        public int findIndex(int indexHint) {
+            return indexHint;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
new file mode 100644
index 0000000..11e0013
--- /dev/null
+++ b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.PhotoView;
+import com.android.gallery3d.ui.PhotoView.ImageData;
+import com.android.gallery3d.ui.SynchronizedHandler;
+import com.android.gallery3d.ui.TileImageViewAdapter;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.ThreadPool;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Message;
+
+public class SinglePhotoDataAdapter extends TileImageViewAdapter
+        implements PhotoPage.Model {
+
+    private static final String TAG = "SinglePhotoDataAdapter";
+    private static final int SIZE_BACKUP = 640;
+    private static final int MSG_UPDATE_IMAGE = 1;
+
+    private MediaItem mItem;
+    private boolean mHasFullImage;
+    private Future<?> mTask;
+    private BitmapRegionDecoder mDecoder;
+    private Bitmap mBackup;
+    private Handler mHandler;
+
+    private PhotoView mPhotoView;
+    private ThreadPool mThreadPool;
+
+    public SinglePhotoDataAdapter(
+            GalleryActivity activity, PhotoView view, MediaItem item) {
+        mItem = Utils.checkNotNull(item);
+        mHasFullImage = (item.getSupportedOperations() &
+                MediaItem.SUPPORT_FULL_IMAGE) != 0;
+        mPhotoView = Utils.checkNotNull(view);
+        mHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            @SuppressWarnings("unchecked")
+            public void handleMessage(Message message) {
+                Utils.assertTrue(message.what == MSG_UPDATE_IMAGE);
+                if (mHasFullImage) {
+                    onDecodeLargeComplete((Future<BitmapRegionDecoder>)
+                            message.obj);
+                } else {
+                    onDecodeThumbComplete((Future<Bitmap>) message.obj);
+                }
+            }
+        };
+        mThreadPool = activity.getThreadPool();
+    }
+
+    private FutureListener<BitmapRegionDecoder> mLargeListener =
+            new FutureListener<BitmapRegionDecoder>() {
+        public void onFutureDone(Future<BitmapRegionDecoder> future) {
+            mHandler.sendMessage(
+                    mHandler.obtainMessage(MSG_UPDATE_IMAGE, future));
+        }
+    };
+
+    private FutureListener<Bitmap> mThumbListener =
+            new FutureListener<Bitmap>() {
+        public void onFutureDone(Future<Bitmap> future) {
+            mHandler.sendMessage(
+                    mHandler.obtainMessage(MSG_UPDATE_IMAGE, future));
+        }
+    };
+
+    public boolean isEmpty() {
+        return false;
+    }
+
+    public int getImageRotation() {
+        return mItem.getRotation();
+    }
+
+    private void onDecodeLargeComplete(Future<BitmapRegionDecoder> future) {
+        try {
+            mDecoder = future.get();
+            if (mDecoder == null) return;
+            int width = mDecoder.getWidth();
+            int height = mDecoder.getHeight();
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            options.inSampleSize = BitmapUtils.computeSampleSizeLarger(
+                    width, height, SIZE_BACKUP);
+            mBackup = mDecoder.decodeRegion(
+                    new Rect(0, 0, width, height), options);
+            setBackupImage(mBackup, width, height);
+            setRegionDecoder(mDecoder);
+            mPhotoView.notifyImageInvalidated(0);
+        } catch (Throwable t) {
+            Log.w(TAG, "fail to decode large", t);
+        }
+    }
+
+    private void onDecodeThumbComplete(Future<Bitmap> future) {
+        try {
+            mBackup = future.get();
+            if (mBackup == null) return;
+            setBackupImage(mBackup, mBackup.getWidth(), mBackup.getHeight());
+            mPhotoView.notifyOnNewImage();
+            mPhotoView.notifyImageInvalidated(0); // the current image
+        } catch (Throwable t) {
+            Log.w(TAG, "fail to decode thumb", t);
+        }
+    }
+
+    public void resume() {
+        if (mTask == null) {
+            if (mHasFullImage) {
+                mTask = mThreadPool.submit(
+                        mItem.requestLargeImage(), mLargeListener);
+            } else {
+                mTask = mThreadPool.submit(
+                        mItem.requestImage(MediaItem.TYPE_THUMBNAIL),
+                        mThumbListener);
+            }
+        }
+    }
+
+    public void pause() {
+        Future<?> task = mTask;
+        task.cancel();
+        task.waitDone();
+        if (task.get() == null) {
+            mTask = null;
+        }
+    }
+
+    public ImageData getNextImage() {
+        return null;
+    }
+
+    public ImageData getPreviousImage() {
+        return null;
+    }
+
+    public void next() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void previous() {
+        throw new UnsupportedOperationException();
+    }
+
+    public MediaItem getCurrentMediaItem() {
+        return mItem;
+    }
+
+    public int getCurrentIndex() {
+        return 0;
+    }
+
+    public void setCurrentPhoto(Path path, int indexHint) {
+        // ignore
+    }
+}
diff --git a/src/com/android/gallery3d/app/SlideshowDataAdapter.java b/src/com/android/gallery3d/app/SlideshowDataAdapter.java
new file mode 100644
index 0000000..6f9b98e
--- /dev/null
+++ b/src/com/android/gallery3d/app/SlideshowDataAdapter.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.app.SlideshowPage.Slide;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.ThreadPool;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.graphics.Bitmap;
+
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class SlideshowDataAdapter implements SlideshowPage.Model {
+    @SuppressWarnings("unused")
+    private static final String TAG = "SlideshowDataAdapter";
+
+    private static final int IMAGE_QUEUE_CAPACITY = 3;
+
+    public interface SlideshowSource {
+        public void addContentListener(ContentListener listener);
+        public void removeContentListener(ContentListener listener);
+        public long reload();
+        public MediaItem getMediaItem(int index);
+    }
+
+    private final SlideshowSource mSource;
+
+    private int mLoadIndex = 0;
+    private int mNextOutput = 0;
+    private boolean mIsActive = false;
+    private boolean mNeedReset;
+    private boolean mDataReady;
+
+    private final LinkedList<Slide> mImageQueue = new LinkedList<Slide>();
+
+    private Future<Void> mReloadTask;
+    private final ThreadPool mThreadPool;
+
+    private long mDataVersion = MediaObject.INVALID_DATA_VERSION;
+    private final AtomicBoolean mNeedReload = new AtomicBoolean(false);
+    private final SourceListener mSourceListener = new SourceListener();
+
+    public SlideshowDataAdapter(GalleryContext context, SlideshowSource source, int index) {
+        mSource = source;
+        mLoadIndex = index;
+        mNextOutput = index;
+        mThreadPool = context.getThreadPool();
+    }
+
+    public MediaItem loadItem() {
+        if (mNeedReload.compareAndSet(true, false)) {
+            long v = mSource.reload();
+            if (v != mDataVersion) {
+                mDataVersion = v;
+                mNeedReset = true;
+                return null;
+            }
+        }
+        return mSource.getMediaItem(mLoadIndex);
+    }
+
+    private class ReloadTask implements Job<Void> {
+        public Void run(JobContext jc) {
+            while (true) {
+                synchronized (SlideshowDataAdapter.this) {
+                    while (mIsActive && (!mDataReady
+                            || mImageQueue.size() >= IMAGE_QUEUE_CAPACITY)) {
+                        try {
+                            SlideshowDataAdapter.this.wait();
+                        } catch (InterruptedException ex) {
+                            // ignored.
+                        }
+                        continue;
+                    }
+                }
+                if (!mIsActive) return null;
+                mNeedReset = false;
+
+                MediaItem item = loadItem();
+
+                if (mNeedReset) {
+                    synchronized (SlideshowDataAdapter.this) {
+                        mImageQueue.clear();
+                        mLoadIndex = mNextOutput;
+                    }
+                    continue;
+                }
+
+                if (item == null) {
+                    synchronized (SlideshowDataAdapter.this) {
+                        if (!mNeedReload.get()) mDataReady = false;
+                        SlideshowDataAdapter.this.notifyAll();
+                    }
+                    continue;
+                }
+
+                Bitmap bitmap = item
+                        .requestImage(MediaItem.TYPE_THUMBNAIL)
+                        .run(jc);
+
+                if (bitmap != null) {
+                    synchronized (SlideshowDataAdapter.this) {
+                        mImageQueue.addLast(
+                                new Slide(item, mLoadIndex, bitmap));
+                        if (mImageQueue.size() == 1) {
+                            SlideshowDataAdapter.this.notifyAll();
+                        }
+                    }
+                }
+                ++mLoadIndex;
+            }
+        }
+    }
+
+    private class SourceListener implements ContentListener {
+        public void onContentDirty() {
+            synchronized (SlideshowDataAdapter.this) {
+                mNeedReload.set(true);
+                mDataReady = true;
+                SlideshowDataAdapter.this.notifyAll();
+            }
+        }
+    }
+
+    private synchronized Slide innerNextBitmap() {
+        while (mIsActive && mDataReady && mImageQueue.isEmpty()) {
+            try {
+                wait();
+            } catch (InterruptedException t) {
+                throw new AssertionError();
+            }
+        }
+        if (mImageQueue.isEmpty()) return null;
+        mNextOutput++;
+        this.notifyAll();
+        return mImageQueue.removeFirst();
+    }
+
+    public Future<Slide> nextSlide(FutureListener<Slide> listener) {
+        return mThreadPool.submit(new Job<Slide>() {
+            public Slide run(JobContext jc) {
+                jc.setMode(ThreadPool.MODE_NONE);
+                return innerNextBitmap();
+            }
+        }, listener);
+    }
+
+    public void pause() {
+        synchronized (this) {
+            mIsActive = false;
+            notifyAll();
+        }
+        mSource.removeContentListener(mSourceListener);
+        mReloadTask.cancel();
+        mReloadTask.waitDone();
+        mReloadTask = null;
+    }
+
+    public synchronized void resume() {
+        mIsActive = true;
+        mSource.addContentListener(mSourceListener);
+        mNeedReload.set(true);
+        mDataReady = true;
+        mReloadTask = mThreadPool.submit(new ReloadTask());
+    }
+}
diff --git a/src/com/android/gallery3d/app/SlideshowDream.java b/src/com/android/gallery3d/app/SlideshowDream.java
new file mode 100644
index 0000000..f4abe86
--- /dev/null
+++ b/src/com/android/gallery3d/app/SlideshowDream.java
@@ -0,0 +1,28 @@
+package com.android.gallery3d.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.support.v13.dreams.BasicDream;
+import android.graphics.Canvas;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ViewFlipper;
+
+public class SlideshowDream extends BasicDream {
+    @Override
+    public void onCreate(Bundle bndl) {
+        super.onCreate(bndl);
+        Intent i = new Intent(
+            Intent.ACTION_VIEW,
+            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+//            Uri.fromFile(Environment.getExternalStoragePublicDirectory(
+//                        Environment.DIRECTORY_PICTURES)))
+                .putExtra(Gallery.EXTRA_SLIDESHOW, true)
+                .setFlags(getIntent().getFlags());
+        startActivity(i);
+        finish();
+    }
+}
diff --git a/src/com/android/gallery3d/app/SlideshowPage.java b/src/com/android/gallery3d/app/SlideshowPage.java
new file mode 100644
index 0000000..cdf9308
--- /dev/null
+++ b/src/com/android/gallery3d/app/SlideshowPage.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.GLView;
+import com.android.gallery3d.ui.SlideshowView;
+import com.android.gallery3d.ui.SynchronizedHandler;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+public class SlideshowPage extends ActivityState {
+    private static final String TAG = "SlideshowPage";
+
+    public static final String KEY_SET_PATH = "media-set-path";
+    public static final String KEY_ITEM_PATH = "media-item-path";
+    public static final String KEY_PHOTO_INDEX = "photo-index";
+    public static final String KEY_RANDOM_ORDER = "random-order";
+    public static final String KEY_REPEAT = "repeat";
+
+    private static final long SLIDESHOW_DELAY = 3000; // 3 seconds
+
+    private static final int MSG_LOAD_NEXT_BITMAP = 1;
+    private static final int MSG_SHOW_PENDING_BITMAP = 2;
+
+    public static interface Model {
+        public void pause();
+        public void resume();
+        public Future<Slide> nextSlide(FutureListener<Slide> listener);
+    }
+
+    public static class Slide {
+        public Bitmap bitmap;
+        public MediaItem item;
+        public int index;
+
+        public Slide(MediaItem item, int index, Bitmap bitmap) {
+            this.bitmap = bitmap;
+            this.item = item;
+            this.index = index;
+        }
+    }
+
+    private Handler mHandler;
+    private Model mModel;
+    private SlideshowView mSlideshowView;
+
+    private Slide mPendingSlide = null;
+    private boolean mIsActive = false;
+    private WakeLock mWakeLock;
+    private Intent mResultIntent = new Intent();
+
+    private GLView mRootPane = new GLView() {
+        @Override
+        protected void onLayout(
+                boolean changed, int left, int top, int right, int bottom) {
+            mSlideshowView.layout(0, 0, right - left, bottom - top);
+        }
+
+        @Override
+        protected boolean onTouch(MotionEvent event) {
+            if (event.getAction() == MotionEvent.ACTION_UP) {
+                onBackPressed();
+            }
+            return true;
+        }
+
+        @Override
+        protected void renderBackground(GLCanvas canvas) {
+            canvas.clearBuffer();
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle data, Bundle restoreState) {
+        mFlags |= (FLAG_HIDE_ACTION_BAR | FLAG_HIDE_STATUS_BAR);
+
+        PowerManager pm = (PowerManager) mActivity.getAndroidContext()
+                .getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
+                | PowerManager.ON_AFTER_RELEASE, TAG);
+
+        mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_SHOW_PENDING_BITMAP:
+                        showPendingBitmap();
+                        break;
+                    case MSG_LOAD_NEXT_BITMAP:
+                        loadNextBitmap();
+                        break;
+                    default: throw new AssertionError();
+                }
+            }
+        };
+        initializeViews();
+        initializeData(data);
+    }
+
+    private void loadNextBitmap() {
+        mModel.nextSlide(new FutureListener<Slide>() {
+            public void onFutureDone(Future<Slide> future) {
+                mPendingSlide = future.get();
+                mHandler.sendEmptyMessage(MSG_SHOW_PENDING_BITMAP);
+            }
+        });
+    }
+
+    private void showPendingBitmap() {
+        // mPendingBitmap could be null, if
+        //    1.) there is no more items
+        //    2.) mModel is paused
+        Slide slide = mPendingSlide;
+        if (slide == null) {
+            if (mIsActive) {
+                mActivity.getStateManager().finishState(SlideshowPage.this);
+            }
+            return;
+        }
+
+        mSlideshowView.next(slide.bitmap, slide.item.getRotation());
+
+        setStateResult(Activity.RESULT_OK, mResultIntent
+                .putExtra(KEY_ITEM_PATH, slide.item.getPath().toString())
+                .putExtra(KEY_PHOTO_INDEX, slide.index));
+        mHandler.sendEmptyMessageDelayed(MSG_LOAD_NEXT_BITMAP,
+                SLIDESHOW_DELAY);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mWakeLock.release();
+        mIsActive = false;
+        mModel.pause();
+        mSlideshowView.release();
+
+        mHandler.removeMessages(MSG_LOAD_NEXT_BITMAP);
+        mHandler.removeMessages(MSG_SHOW_PENDING_BITMAP);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mWakeLock.acquire();
+        mIsActive = true;
+        mModel.resume();
+
+        if (mPendingSlide != null) {
+            showPendingBitmap();
+        } else {
+            loadNextBitmap();
+        }
+    }
+
+    private void initializeData(Bundle data) {
+        String mediaPath = data.getString(KEY_SET_PATH);
+        boolean random = data.getBoolean(KEY_RANDOM_ORDER, false);
+        MediaSet mediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
+
+        if (random) {
+            boolean repeat = data.getBoolean(KEY_REPEAT);
+            mModel = new SlideshowDataAdapter(
+                    mActivity, new ShuffleSource(mediaSet, repeat), 0);
+            setStateResult(Activity.RESULT_OK,
+                    mResultIntent.putExtra(KEY_PHOTO_INDEX, 0));
+        } else {
+            int index = data.getInt(KEY_PHOTO_INDEX);
+            boolean repeat = data.getBoolean(KEY_REPEAT);
+            mModel = new SlideshowDataAdapter(mActivity,
+                    new SequentialSource(mediaSet, repeat), index);
+            setStateResult(Activity.RESULT_OK,
+                    mResultIntent.putExtra(KEY_PHOTO_INDEX, index));
+        }
+    }
+
+    private void initializeViews() {
+        mSlideshowView = new SlideshowView();
+        mRootPane.addComponent(mSlideshowView);
+        setContentPane(mRootPane);
+    }
+
+    private static MediaItem findMediaItem(MediaSet mediaSet, int index) {
+        for (int i = 0, n = mediaSet.getSubMediaSetCount(); i < n; ++i) {
+            MediaSet subset = mediaSet.getSubMediaSet(i);
+            int count = subset.getTotalMediaItemCount();
+            if (index < count) {
+                return findMediaItem(subset, index);
+            }
+            index -= count;
+        }
+        ArrayList<MediaItem> list = mediaSet.getMediaItem(index, 1);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    private static class ShuffleSource implements SlideshowDataAdapter.SlideshowSource {
+        private static final int RETRY_COUNT = 5;
+        private final MediaSet mMediaSet;
+        private final Random mRandom = new Random();
+        private int mOrder[] = new int[0];
+        private boolean mRepeat;
+        private long mSourceVersion = MediaSet.INVALID_DATA_VERSION;
+        private int mLastIndex = -1;
+
+        public ShuffleSource(MediaSet mediaSet, boolean repeat) {
+            mMediaSet = Utils.checkNotNull(mediaSet);
+            mRepeat = repeat;
+        }
+
+        public MediaItem getMediaItem(int index) {
+            if (!mRepeat && index >= mOrder.length) return null;
+            mLastIndex = mOrder[index % mOrder.length];
+            MediaItem item = findMediaItem(mMediaSet, mLastIndex);
+            for (int i = 0; i < RETRY_COUNT && item == null; ++i) {
+                Log.w(TAG, "fail to find image: " + mLastIndex);
+                mLastIndex = mRandom.nextInt(mOrder.length);
+                item = findMediaItem(mMediaSet, mLastIndex);
+            }
+            return item;
+        }
+
+        public long reload() {
+            long version = mMediaSet.reload();
+            if (version != mSourceVersion) {
+                mSourceVersion = version;
+                int count = mMediaSet.getTotalMediaItemCount();
+                if (count != mOrder.length) generateOrderArray(count);
+            }
+            return version;
+        }
+
+        private void generateOrderArray(int totalCount) {
+            if (mOrder.length != totalCount) {
+                mOrder = new int[totalCount];
+                for (int i = 0; i < totalCount; ++i) {
+                    mOrder[i] = i;
+                }
+            }
+            for (int i = totalCount - 1; i > 0; --i) {
+                Utils.swap(mOrder, i, mRandom.nextInt(i + 1));
+            }
+            if (mOrder[0] == mLastIndex && totalCount > 1) {
+                Utils.swap(mOrder, 0, mRandom.nextInt(totalCount - 1) + 1);
+            }
+        }
+
+        public void addContentListener(ContentListener listener) {
+            mMediaSet.addContentListener(listener);
+        }
+
+        public void removeContentListener(ContentListener listener) {
+            mMediaSet.removeContentListener(listener);
+        }
+    }
+
+    private static class SequentialSource implements SlideshowDataAdapter.SlideshowSource {
+        private static final int DATA_SIZE = 32;
+
+        private ArrayList<MediaItem> mData = new ArrayList<MediaItem>();
+        private int mDataStart = 0;
+        private long mDataVersion = MediaObject.INVALID_DATA_VERSION;
+        private final MediaSet mMediaSet;
+        private final boolean mRepeat;
+
+        public SequentialSource(MediaSet mediaSet, boolean repeat) {
+            mMediaSet = mediaSet;
+            mRepeat = repeat;
+        }
+
+        public MediaItem getMediaItem(int index) {
+            int dataEnd = mDataStart + mData.size();
+
+            if (mRepeat) {
+                index = index % mMediaSet.getMediaItemCount();
+            }
+            if (index < mDataStart || index >= dataEnd) {
+                mData = mMediaSet.getMediaItem(index, DATA_SIZE);
+                mDataStart = index;
+                dataEnd = index + mData.size();
+            }
+
+            return (index < mDataStart || index >= dataEnd)
+                    ? null
+                    : mData.get(index - mDataStart);
+        }
+
+        public long reload() {
+            long version = mMediaSet.reload();
+            if (version != mDataVersion) {
+                mDataVersion = version;
+                mData.clear();
+            }
+            return mDataVersion;
+        }
+
+        public void addContentListener(ContentListener listener) {
+            mMediaSet.addContentListener(listener);
+        }
+
+        public void removeContentListener(ContentListener listener) {
+            mMediaSet.removeContentListener(listener);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/StateManager.java b/src/com/android/gallery3d/app/StateManager.java
new file mode 100644
index 0000000..b551f69
--- /dev/null
+++ b/src/com/android/gallery3d/app/StateManager.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import com.android.gallery3d.common.Utils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import java.util.Stack;
+
+public class StateManager {
+    @SuppressWarnings("unused")
+    private static final String TAG = "StateManager";
+    private boolean mIsResumed = false;
+
+    private static final String KEY_MAIN = "activity-state";
+    private static final String KEY_DATA = "data";
+    private static final String KEY_STATE = "bundle";
+    private static final String KEY_CLASS = "class";
+
+    private GalleryActivity mContext;
+    private Stack<StateEntry> mStack = new Stack<StateEntry>();
+    private ActivityState.ResultEntry mResult;
+
+    public StateManager(GalleryActivity context) {
+        mContext = context;
+    }
+
+    public void startState(Class<? extends ActivityState> klass,
+            Bundle data) {
+        Log.v(TAG, "startState " + klass);
+        ActivityState state = null;
+        try {
+            state = klass.newInstance();
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+        if (!mStack.isEmpty()) {
+            ActivityState top = getTopState();
+            if (mIsResumed) top.onPause();
+        }
+        state.initialize(mContext, data);
+
+        mStack.push(new StateEntry(data, state));
+        state.onCreate(data, null);
+        if (mIsResumed) state.resume();
+    }
+
+    public void startStateForResult(Class<? extends ActivityState> klass,
+            int requestCode, Bundle data) {
+        Log.v(TAG, "startStateForResult " + klass + ", " + requestCode);
+        ActivityState state = null;
+        try {
+            state = klass.newInstance();
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+        state.initialize(mContext, data);
+        state.mResult = new ActivityState.ResultEntry();
+        state.mResult.requestCode = requestCode;
+
+        if (!mStack.isEmpty()) {
+            ActivityState as = getTopState();
+            as.mReceivedResults = state.mResult;
+            if (mIsResumed) as.onPause();
+        } else {
+            mResult = state.mResult;
+        }
+
+        mStack.push(new StateEntry(data, state));
+        state.onCreate(data, null);
+        if (mIsResumed) state.resume();
+    }
+
+    public boolean createOptionsMenu(Menu menu) {
+        if (!mStack.isEmpty()) {
+            ((Activity) mContext).setProgressBarIndeterminateVisibility(false);
+            return getTopState().onCreateActionBar(menu);
+        } else {
+            return false;
+        }
+    }
+
+    public void resume() {
+        if (mIsResumed) return;
+        mIsResumed = true;
+        if (!mStack.isEmpty()) getTopState().resume();
+    }
+
+    public void pause() {
+        if (!mIsResumed) return;
+        mIsResumed = false;
+        if (!mStack.isEmpty()) getTopState().onPause();
+    }
+
+    public void notifyActivityResult(int requestCode, int resultCode, Intent data) {
+        getTopState().onStateResult(requestCode, resultCode, data);
+    }
+
+    public int getStateCount() {
+        return mStack.size();
+    }
+
+    public boolean itemSelected(MenuItem item) {
+        if (!mStack.isEmpty()) {
+            if (mStack.size() > 1 && item.getItemId() == android.R.id.home) {
+                getTopState().onBackPressed();
+                return true;
+            } else {
+                return getTopState().onItemSelected(item);
+            }
+        }
+        return false;
+    }
+
+    public void onBackPressed() {
+        if (!mStack.isEmpty()) {
+            getTopState().onBackPressed();
+        }
+    }
+
+    void finishState(ActivityState state) {
+        Log.v(TAG, "finishState " + state.getClass());
+        if (state != mStack.peek().activityState) {
+            throw new IllegalArgumentException("The stateview to be finished"
+                    + " is not at the top of the stack: " + state + ", "
+                    + mStack.peek().activityState);
+        }
+
+        // Remove the top state.
+        mStack.pop();
+        if (mIsResumed) state.onPause();
+        mContext.getGLRoot().setContentPane(null);
+        state.onDestroy();
+
+        if (mStack.isEmpty()) {
+            Log.v(TAG, "no more state, finish activity");
+            Activity activity = (Activity) mContext.getAndroidContext();
+            if (mResult != null) {
+                activity.setResult(mResult.resultCode, mResult.resultData);
+            }
+            activity.finish();
+
+            // The finish() request is rejected (only happens under Monkey),
+            // so we start the default page instead.
+            if (!activity.isFinishing()) {
+                Log.v(TAG, "finish() failed, start default page");
+                ((Gallery) mContext).startDefaultPage();
+            }
+        } else {
+            // Restore the immediately previous state
+            ActivityState top = mStack.peek().activityState;
+            if (mIsResumed) top.resume();
+        }
+    }
+
+    void switchState(ActivityState oldState,
+            Class<? extends ActivityState> klass, Bundle data) {
+        Log.v(TAG, "switchState " + oldState + ", " + klass);
+        if (oldState != mStack.peek().activityState) {
+            throw new IllegalArgumentException("The stateview to be finished"
+                    + " is not at the top of the stack: " + oldState + ", "
+                    + mStack.peek().activityState);
+        }
+        // Remove the top state.
+        mStack.pop();
+        if (mIsResumed) oldState.onPause();
+        oldState.onDestroy();
+
+        // Create new state.
+        ActivityState state = null;
+        try {
+            state = klass.newInstance();
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+        state.initialize(mContext, data);
+        mStack.push(new StateEntry(data, state));
+        state.onCreate(data, null);
+        if (mIsResumed) state.resume();
+    }
+
+    public void destroy() {
+        Log.v(TAG, "destroy");
+        while (!mStack.isEmpty()) {
+            mStack.pop().activityState.onDestroy();
+        }
+        mStack.clear();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void restoreFromState(Bundle inState) {
+        Log.v(TAG, "restoreFromState");
+        Parcelable list[] = inState.getParcelableArray(KEY_MAIN);
+
+        for (Parcelable parcelable : list) {
+            Bundle bundle = (Bundle) parcelable;
+            Class<? extends ActivityState> klass =
+                    (Class<? extends ActivityState>) bundle.getSerializable(KEY_CLASS);
+
+            Bundle data = bundle.getBundle(KEY_DATA);
+            Bundle state = bundle.getBundle(KEY_STATE);
+
+            ActivityState activityState;
+            try {
+                Log.v(TAG, "restoreFromState " + klass);
+                activityState = klass.newInstance();
+            } catch (Exception e) {
+                throw new AssertionError(e);
+            }
+            activityState.initialize(mContext, data);
+            activityState.onCreate(data, state);
+            mStack.push(new StateEntry(data, activityState));
+        }
+    }
+
+    public void saveState(Bundle outState) {
+        Log.v(TAG, "saveState");
+        Parcelable list[] = new Parcelable[mStack.size()];
+
+        int i = 0;
+        for (StateEntry entry : mStack) {
+            Bundle bundle = new Bundle();
+            bundle.putSerializable(KEY_CLASS, entry.activityState.getClass());
+            bundle.putBundle(KEY_DATA, entry.data);
+            Bundle state = new Bundle();
+            entry.activityState.onSaveState(state);
+            bundle.putBundle(KEY_STATE, state);
+            Log.v(TAG, "saveState " + entry.activityState.getClass());
+            list[i++] = bundle;
+        }
+        outState.putParcelableArray(KEY_MAIN, list);
+    }
+
+    public boolean hasStateClass(Class<? extends ActivityState> klass) {
+        for (StateEntry entry : mStack) {
+            if (klass.isInstance(entry.activityState)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public ActivityState getTopState() {
+        Utils.assertTrue(!mStack.isEmpty());
+        return mStack.peek().activityState;
+    }
+
+    private static class StateEntry {
+        public Bundle data;
+        public ActivityState activityState;
+
+        public StateEntry(Bundle data, ActivityState state) {
+            this.data = data;
+            this.activityState = state;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/app/UsbDeviceActivity.java b/src/com/android/gallery3d/app/UsbDeviceActivity.java
new file mode 100644
index 0000000..28bd667
--- /dev/null
+++ b/src/com/android/gallery3d/app/UsbDeviceActivity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+/* This Activity does nothing but receive USB_DEVICE_ATTACHED events from the
+ * USB service and springboards to the main Gallery activity
+ */
+public final class UsbDeviceActivity extends Activity {
+
+    static final String TAG = "UsbDeviceActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        //
+        Intent intent = new Intent(this, Gallery.class);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        try {
+            startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            Log.e(TAG, "unable to start Gallery activity", e);
+        }
+        finish();
+    }
+}
diff --git a/src/com/android/gallery3d/app/Wallpaper.java b/src/com/android/gallery3d/app/Wallpaper.java
new file mode 100644
index 0000000..07a3d53
--- /dev/null
+++ b/src/com/android/gallery3d/app/Wallpaper.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Display;
+
+/**
+ * Wallpaper picker for the gallery application. This just redirects to the
+ * standard pick action.
+ */
+public class Wallpaper extends Activity {
+    @SuppressWarnings("unused")
+    private static final String TAG = "Wallpaper";
+
+    private static final String IMAGE_TYPE = "image/*";
+    private static final String KEY_STATE = "activity-state";
+    private static final String KEY_PICKED_ITEM = "picked-item";
+
+    private static final int STATE_INIT = 0;
+    private static final int STATE_PHOTO_PICKED = 1;
+
+    private int mState = STATE_INIT;
+    private Uri mPickedItem;
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        if (bundle != null) {
+            mState = bundle.getInt(KEY_STATE);
+            mPickedItem = (Uri) bundle.getParcelable(KEY_PICKED_ITEM);
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle saveState) {
+        saveState.putInt(KEY_STATE, mState);
+        if (mPickedItem != null) {
+            saveState.putParcelable(KEY_PICKED_ITEM, mPickedItem);
+        }
+    }
+
+    @SuppressWarnings("fallthrough")
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Intent intent = getIntent();
+        switch (mState) {
+            case STATE_INIT: {
+                mPickedItem = intent.getData();
+                if (mPickedItem == null) {
+                    Intent request = new Intent(Intent.ACTION_GET_CONTENT)
+                            .setClass(this, DialogPicker.class)
+                            .setType(IMAGE_TYPE);
+                    startActivityForResult(request, STATE_PHOTO_PICKED);
+                    return;
+                }
+                mState = STATE_PHOTO_PICKED;
+                // fall-through
+            }
+            case STATE_PHOTO_PICKED: {
+                int width = getWallpaperDesiredMinimumWidth();
+                int height = getWallpaperDesiredMinimumHeight();
+                Display display = getWindowManager().getDefaultDisplay();
+                float spotlightX = (float) display.getWidth() / width;
+                float spotlightY = (float) display.getHeight() / height;
+                Intent request = new Intent(CropImage.ACTION_CROP)
+                        .setDataAndType(mPickedItem, IMAGE_TYPE)
+                        .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
+                        .putExtra(CropImage.KEY_OUTPUT_X, width)
+                        .putExtra(CropImage.KEY_OUTPUT_Y, height)
+                        .putExtra(CropImage.KEY_ASPECT_X, width)
+                        .putExtra(CropImage.KEY_ASPECT_Y, height)
+                        .putExtra(CropImage.KEY_SPOTLIGHT_X, spotlightX)
+                        .putExtra(CropImage.KEY_SPOTLIGHT_Y, spotlightY)
+                        .putExtra(CropImage.KEY_SCALE, true)
+                        .putExtra(CropImage.KEY_NO_FACE_DETECTION, true)
+                        .putExtra(CropImage.KEY_SET_AS_WALLPAPER, true);
+                startActivity(request);
+                finish();
+            }
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode != RESULT_OK) {
+            setResult(resultCode);
+            finish();
+            return;
+        }
+        mState = requestCode;
+        if (mState == STATE_PHOTO_PICKED) {
+            mPickedItem = data.getData();
+        }
+
+        // onResume() would be called next
+    }
+}
diff --git a/src/com/android/gallery3d/data/ChangeNotifier.java b/src/com/android/gallery3d/data/ChangeNotifier.java
new file mode 100644
index 0000000..e1e601d
--- /dev/null
+++ b/src/com/android/gallery3d/data/ChangeNotifier.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+import android.net.Uri;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+// This handles change notification for media sets.
+public class ChangeNotifier {
+
+    private MediaSet mMediaSet;
+    private AtomicBoolean mContentDirty = new AtomicBoolean(true);
+
+    public ChangeNotifier(MediaSet set, Uri uri, GalleryApp application) {
+        mMediaSet = set;
+        application.getDataManager().registerChangeNotifier(uri, this);
+    }
+
+    // Returns the dirty flag and clear it.
+    public boolean isDirty() {
+        return mContentDirty.compareAndSet(true, false);
+    }
+
+    public void fakeChange() {
+        onChange(false);
+    }
+
+    public void clearDirty() {
+        mContentDirty.set(false);
+    }
+
+    protected void onChange(boolean selfChange) {
+        if (mContentDirty.compareAndSet(false, true)) {
+            mMediaSet.notifyContentChanged();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/data/ClusterAlbum.java b/src/com/android/gallery3d/data/ClusterAlbum.java
new file mode 100644
index 0000000..32f9023
--- /dev/null
+++ b/src/com/android/gallery3d/data/ClusterAlbum.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import java.util.ArrayList;
+
+public class ClusterAlbum extends MediaSet implements ContentListener {
+    private static final String TAG = "ClusterAlbum";
+    private ArrayList<Path> mPaths = new ArrayList<Path>();
+    private String mName = "";
+    private DataManager mDataManager;
+    private MediaSet mClusterAlbumSet;
+
+    public ClusterAlbum(Path path, DataManager dataManager,
+            MediaSet clusterAlbumSet) {
+        super(path, nextVersionNumber());
+        mDataManager = dataManager;
+        mClusterAlbumSet = clusterAlbumSet;
+        mClusterAlbumSet.addContentListener(this);
+    }
+
+    void setMediaItems(ArrayList<Path> paths) {
+        mPaths = paths;
+    }
+
+    ArrayList<Path> getMediaItems() {
+        return mPaths;
+    }
+
+    public void setName(String name) {
+        mName = name;
+    }
+
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public int getMediaItemCount() {
+        return mPaths.size();
+    }
+
+    @Override
+    public ArrayList<MediaItem> getMediaItem(int start, int count) {
+        return getMediaItemFromPath(mPaths, start, count, mDataManager);
+    }
+
+    public static ArrayList<MediaItem> getMediaItemFromPath(
+            ArrayList<Path> paths, int start, int count,
+            DataManager dataManager) {
+        if (start >= paths.size()) {
+            return new ArrayList<MediaItem>();
+        }
+        int end = Math.min(start + count, paths.size());
+        ArrayList<Path> subset = new ArrayList<Path>(paths.subList(start, end));
+        final MediaItem[] buf = new MediaItem[end - start];
+        ItemConsumer consumer = new ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                buf[index] = item;
+            }
+        };
+        dataManager.mapMediaItems(subset, consumer, 0);
+        ArrayList<MediaItem> result = new ArrayList<MediaItem>(end - start);
+        for (int i = 0; i < buf.length; i++) {
+            result.add(buf[i]);
+        }
+        return result;
+    }
+
+    @Override
+    protected int enumerateMediaItems(ItemConsumer consumer, int startIndex) {
+        mDataManager.mapMediaItems(mPaths, consumer, startIndex);
+        return mPaths.size();
+    }
+
+    @Override
+    public int getTotalMediaItemCount() {
+        return mPaths.size();
+    }
+
+    @Override
+    public long reload() {
+        if (mClusterAlbumSet.reload() > mDataVersion) {
+            mDataVersion = nextVersionNumber();
+        }
+        return mDataVersion;
+    }
+
+    public void onContentDirty() {
+        notifyContentChanged();
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        return SUPPORT_SHARE | SUPPORT_DELETE | SUPPORT_INFO;
+    }
+
+    @Override
+    public void delete() {
+        ItemConsumer consumer = new ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                if ((item.getSupportedOperations() & SUPPORT_DELETE) != 0) {
+                    item.delete();
+                }
+            }
+        };
+        mDataManager.mapMediaItems(mPaths, consumer, 0);
+    }
+
+    @Override
+    public boolean isLeafAlbum() {
+        return true;
+    }
+}
diff --git a/src/com/android/gallery3d/data/ClusterAlbumSet.java b/src/com/android/gallery3d/data/ClusterAlbumSet.java
new file mode 100644
index 0000000..5b0569a
--- /dev/null
+++ b/src/com/android/gallery3d/data/ClusterAlbumSet.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+import android.content.Context;
+import android.net.Uri;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class ClusterAlbumSet extends MediaSet implements ContentListener {
+    private static final String TAG = "ClusterAlbumSet";
+    private GalleryApp mApplication;
+    private MediaSet mBaseSet;
+    private int mKind;
+    private ArrayList<ClusterAlbum> mAlbums = new ArrayList<ClusterAlbum>();
+    private boolean mFirstReloadDone;
+
+    public ClusterAlbumSet(Path path, GalleryApp application,
+            MediaSet baseSet, int kind) {
+        super(path, INVALID_DATA_VERSION);
+        mApplication = application;
+        mBaseSet = baseSet;
+        mKind = kind;
+        baseSet.addContentListener(this);
+    }
+
+    @Override
+    public MediaSet getSubMediaSet(int index) {
+        return mAlbums.get(index);
+    }
+
+    @Override
+    public int getSubMediaSetCount() {
+        return mAlbums.size();
+    }
+
+    @Override
+    public String getName() {
+        return mBaseSet.getName();
+    }
+
+    @Override
+    public long reload() {
+        if (mBaseSet.reload() > mDataVersion) {
+            if (mFirstReloadDone) {
+                updateClustersContents();
+            } else {
+                updateClusters();
+                mFirstReloadDone = true;
+            }
+            mDataVersion = nextVersionNumber();
+        }
+        return mDataVersion;
+    }
+
+    public void onContentDirty() {
+        notifyContentChanged();
+    }
+
+    private void updateClusters() {
+        mAlbums.clear();
+        Clustering clustering;
+        Context context = mApplication.getAndroidContext();
+        switch (mKind) {
+            case ClusterSource.CLUSTER_ALBUMSET_TIME:
+                clustering = new TimeClustering(context);
+                break;
+            case ClusterSource.CLUSTER_ALBUMSET_LOCATION:
+                clustering = new LocationClustering(context);
+                break;
+            case ClusterSource.CLUSTER_ALBUMSET_TAG:
+                clustering = new TagClustering(context);
+                break;
+            case ClusterSource.CLUSTER_ALBUMSET_FACE:
+                clustering = new FaceClustering(context);
+                break;
+            default: /* CLUSTER_ALBUMSET_SIZE */
+                clustering = new SizeClustering(context);
+                break;
+        }
+
+        clustering.run(mBaseSet);
+        int n = clustering.getNumberOfClusters();
+        DataManager dataManager = mApplication.getDataManager();
+        for (int i = 0; i < n; i++) {
+            Path childPath;
+            String childName = clustering.getClusterName(i);
+            if (mKind == ClusterSource.CLUSTER_ALBUMSET_TAG) {
+                childPath = mPath.getChild(Uri.encode(childName));
+            } else if (mKind == ClusterSource.CLUSTER_ALBUMSET_SIZE) {
+                long minSize = ((SizeClustering) clustering).getMinSize(i);
+                childPath = mPath.getChild(minSize);
+            } else {
+                childPath = mPath.getChild(i);
+            }
+            ClusterAlbum album = (ClusterAlbum) dataManager.peekMediaObject(
+                        childPath);
+            if (album == null) {
+                album = new ClusterAlbum(childPath, dataManager, this);
+            }
+            album.setMediaItems(clustering.getCluster(i));
+            album.setName(childName);
+            mAlbums.add(album);
+        }
+    }
+
+    private void updateClustersContents() {
+        final HashSet<Path> existing = new HashSet<Path>();
+        mBaseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                existing.add(item.getPath());
+            }
+        });
+
+        int n = mAlbums.size();
+
+        // The loop goes backwards because we may remove empty albums from
+        // mAlbums.
+        for (int i = n - 1; i >= 0; i--) {
+            ArrayList<Path> oldPaths = mAlbums.get(i).getMediaItems();
+            ArrayList<Path> newPaths = new ArrayList<Path>();
+            int m = oldPaths.size();
+            for (int j = 0; j < m; j++) {
+                Path p = oldPaths.get(j);
+                if (existing.contains(p)) {
+                    newPaths.add(p);
+                }
+            }
+            mAlbums.get(i).setMediaItems(newPaths);
+            if (newPaths.isEmpty()) {
+                mAlbums.remove(i);
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/ClusterSource.java b/src/com/android/gallery3d/data/ClusterSource.java
new file mode 100644
index 0000000..a1f22e5
--- /dev/null
+++ b/src/com/android/gallery3d/data/ClusterSource.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+class ClusterSource extends MediaSource {
+    static final int CLUSTER_ALBUMSET_TIME = 0;
+    static final int CLUSTER_ALBUMSET_LOCATION = 1;
+    static final int CLUSTER_ALBUMSET_TAG = 2;
+    static final int CLUSTER_ALBUMSET_SIZE = 3;
+    static final int CLUSTER_ALBUMSET_FACE = 4;
+
+    static final int CLUSTER_ALBUM_TIME = 0x100;
+    static final int CLUSTER_ALBUM_LOCATION = 0x101;
+    static final int CLUSTER_ALBUM_TAG = 0x102;
+    static final int CLUSTER_ALBUM_SIZE = 0x103;
+    static final int CLUSTER_ALBUM_FACE = 0x104;
+
+    GalleryApp mApplication;
+    PathMatcher mMatcher;
+
+    public ClusterSource(GalleryApp application) {
+        super("cluster");
+        mApplication = application;
+        mMatcher = new PathMatcher();
+        mMatcher.add("/cluster/*/time", CLUSTER_ALBUMSET_TIME);
+        mMatcher.add("/cluster/*/location", CLUSTER_ALBUMSET_LOCATION);
+        mMatcher.add("/cluster/*/tag", CLUSTER_ALBUMSET_TAG);
+        mMatcher.add("/cluster/*/size", CLUSTER_ALBUMSET_SIZE);
+        mMatcher.add("/cluster/*/face", CLUSTER_ALBUMSET_FACE);
+
+        mMatcher.add("/cluster/*/time/*", CLUSTER_ALBUM_TIME);
+        mMatcher.add("/cluster/*/location/*", CLUSTER_ALBUM_LOCATION);
+        mMatcher.add("/cluster/*/tag/*", CLUSTER_ALBUM_TAG);
+        mMatcher.add("/cluster/*/size/*", CLUSTER_ALBUM_SIZE);
+        mMatcher.add("/cluster/*/face/*", CLUSTER_ALBUM_FACE);
+    }
+
+    // The names we accept are:
+    // /cluster/{set}/time      /cluster/{set}/time/k
+    // /cluster/{set}/location  /cluster/{set}/location/k
+    // /cluster/{set}/tag       /cluster/{set}/tag/encoded_tag
+    // /cluster/{set}/size      /cluster/{set}/size/min_size
+    @Override
+    public MediaObject createMediaObject(Path path) {
+        int matchType = mMatcher.match(path);
+        String setsName = mMatcher.getVar(0);
+        DataManager dataManager = mApplication.getDataManager();
+        MediaSet[] sets = dataManager.getMediaSetsFromString(setsName);
+        switch (matchType) {
+            case CLUSTER_ALBUMSET_TIME:
+            case CLUSTER_ALBUMSET_LOCATION:
+            case CLUSTER_ALBUMSET_TAG:
+            case CLUSTER_ALBUMSET_SIZE:
+            case CLUSTER_ALBUMSET_FACE:
+                return new ClusterAlbumSet(path, mApplication, sets[0], matchType);
+            case CLUSTER_ALBUM_TIME:
+            case CLUSTER_ALBUM_LOCATION:
+            case CLUSTER_ALBUM_TAG:
+            case CLUSTER_ALBUM_SIZE:
+            case CLUSTER_ALBUM_FACE: {
+                MediaSet parent = dataManager.getMediaSet(path.getParent());
+                // The actual content in the ClusterAlbum will be filled later
+                // when the reload() method in the parent is run.
+                return new ClusterAlbum(path, dataManager, parent);
+            }
+            default:
+                throw new RuntimeException("bad path: " + path);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/Clustering.java b/src/com/android/gallery3d/data/Clustering.java
new file mode 100644
index 0000000..542dda2
--- /dev/null
+++ b/src/com/android/gallery3d/data/Clustering.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import java.util.ArrayList;
+
+public abstract class Clustering {
+    public abstract void run(MediaSet baseSet);
+    public abstract int getNumberOfClusters();
+    public abstract ArrayList<Path> getCluster(int index);
+    public abstract String getClusterName(int index);
+}
diff --git a/src/com/android/gallery3d/data/ComboAlbum.java b/src/com/android/gallery3d/data/ComboAlbum.java
new file mode 100644
index 0000000..8ca2077
--- /dev/null
+++ b/src/com/android/gallery3d/data/ComboAlbum.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+import java.util.ArrayList;
+
+// ComboAlbum combines multiple media sets into one. It lists all media items
+// from the input albums.
+// This only handles SubMediaSets, not MediaItems. (That's all we need now)
+public class ComboAlbum extends MediaSet implements ContentListener {
+    private static final String TAG = "ComboAlbum";
+    private final MediaSet[] mSets;
+    private final String mName;
+
+    public ComboAlbum(Path path, MediaSet[] mediaSets, String name) {
+        super(path, nextVersionNumber());
+        mSets = mediaSets;
+        for (MediaSet set : mSets) {
+            set.addContentListener(this);
+        }
+        mName = name;
+    }
+
+    @Override
+    public ArrayList<MediaItem> getMediaItem(int start, int count) {
+        ArrayList<MediaItem> items = new ArrayList<MediaItem>();
+        for (MediaSet set : mSets) {
+            int size = set.getMediaItemCount();
+            if (count < 1) break;
+            if (start < size) {
+                int fetchCount = (start + count <= size) ? count : size - start;
+                ArrayList<MediaItem> fetchItems = set.getMediaItem(start, fetchCount);
+                items.addAll(fetchItems);
+                count -= fetchItems.size();
+                start = 0;
+            } else {
+                start -= size;
+            }
+        }
+        return items;
+    }
+
+    @Override
+    public int getMediaItemCount() {
+        int count = 0;
+        for (MediaSet set : mSets) {
+            count += set.getMediaItemCount();
+        }
+        return count;
+    }
+
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public long reload() {
+        boolean changed = false;
+        for (int i = 0, n = mSets.length; i < n; ++i) {
+            long version = mSets[i].reload();
+            if (version > mDataVersion) changed = true;
+        }
+        if (changed) mDataVersion = nextVersionNumber();
+        return mDataVersion;
+    }
+
+    public void onContentDirty() {
+        notifyContentChanged();
+    }
+}
diff --git a/src/com/android/gallery3d/data/ComboAlbumSet.java b/src/com/android/gallery3d/data/ComboAlbumSet.java
new file mode 100644
index 0000000..aa19603
--- /dev/null
+++ b/src/com/android/gallery3d/data/ComboAlbumSet.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryApp;
+
+// ComboAlbumSet combines multiple media sets into one. It lists all sub
+// media sets from the input album sets.
+// This only handles SubMediaSets, not MediaItems. (That's all we need now)
+public class ComboAlbumSet extends MediaSet implements ContentListener {
+    private static final String TAG = "ComboAlbumSet";
+    private final MediaSet[] mSets;
+    private final String mName;
+
+    public ComboAlbumSet(Path path, GalleryApp application, MediaSet[] mediaSets) {
+        super(path, nextVersionNumber());
+        mSets = mediaSets;
+        for (MediaSet set : mSets) {
+            set.addContentListener(this);
+        }
+        mName = application.getResources().getString(
+                R.string.set_label_all_albums);
+    }
+
+    @Override
+    public MediaSet getSubMediaSet(int index) {
+        for (MediaSet set : mSets) {
+            int size = set.getSubMediaSetCount();
+            if (index < size) {
+                return set.getSubMediaSet(index);
+            }
+            index -= size;
+        }
+        return null;
+    }
+
+    @Override
+    public int getSubMediaSetCount() {
+        int count = 0;
+        for (MediaSet set : mSets) {
+            count += set.getSubMediaSetCount();
+        }
+        return count;
+    }
+
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public long reload() {
+        boolean changed = false;
+        for (int i = 0, n = mSets.length; i < n; ++i) {
+            long version = mSets[i].reload();
+            if (version > mDataVersion) changed = true;
+        }
+        if (changed) mDataVersion = nextVersionNumber();
+        return mDataVersion;
+    }
+
+    public void onContentDirty() {
+        notifyContentChanged();
+    }
+}
diff --git a/src/com/android/gallery3d/data/ComboSource.java b/src/com/android/gallery3d/data/ComboSource.java
new file mode 100644
index 0000000..867d47e
--- /dev/null
+++ b/src/com/android/gallery3d/data/ComboSource.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+class ComboSource extends MediaSource {
+    private static final int COMBO_ALBUMSET = 0;
+    private static final int COMBO_ALBUM = 1;
+    private GalleryApp mApplication;
+    private PathMatcher mMatcher;
+
+    public ComboSource(GalleryApp application) {
+        super("combo");
+        mApplication = application;
+        mMatcher = new PathMatcher();
+        mMatcher.add("/combo/*", COMBO_ALBUMSET);
+        mMatcher.add("/combo/*/*", COMBO_ALBUM);
+    }
+
+    // The only path we accept is "/combo/{set1, set2, ...} and /combo/item/{set1, set2, ...}"
+    @Override
+    public MediaObject createMediaObject(Path path) {
+        String[] segments = path.split();
+        if (segments.length < 2) {
+            throw new RuntimeException("bad path: " + path);
+        }
+
+        DataManager dataManager = mApplication.getDataManager();
+        switch (mMatcher.match(path)) {
+            case COMBO_ALBUMSET:
+                return new ComboAlbumSet(path, mApplication,
+                        dataManager.getMediaSetsFromString(segments[1]));
+
+            case COMBO_ALBUM:
+                return new ComboAlbum(path,
+                        dataManager.getMediaSetsFromString(segments[2]), segments[1]);
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/gallery3d/data/ContentListener.java b/src/com/android/gallery3d/data/ContentListener.java
new file mode 100644
index 0000000..5e29526
--- /dev/null
+++ b/src/com/android/gallery3d/data/ContentListener.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+public interface ContentListener {
+    public void onContentDirty();
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/data/DataManager.java b/src/com/android/gallery3d/data/DataManager.java
new file mode 100644
index 0000000..f7dac5e
--- /dev/null
+++ b/src/com/android/gallery3d/data/DataManager.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.MediaSet.ItemConsumer;
+import com.android.gallery3d.data.MediaSource.PathId;
+import com.android.gallery3d.picasasource.PicasaSource;
+
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map.Entry;
+import java.util.WeakHashMap;
+
+// DataManager manages all media sets and media items in the system.
+//
+// Each MediaSet and MediaItem has a unique 64 bits id. The most significant
+// 32 bits represents its parent, and the least significant 32 bits represents
+// the self id. For MediaSet the self id is is globally unique, but for
+// MediaItem it's unique only relative to its parent.
+//
+// To make sure the id is the same when the MediaSet is re-created, a child key
+// is provided to obtainSetId() to make sure the same self id will be used as
+// when the parent and key are the same. A sequence of child keys is called a
+// path. And it's used to identify a specific media set even if the process is
+// killed and re-created, so child keys should be stable identifiers.
+
+public class DataManager {
+    public static final int INCLUDE_IMAGE = 1;
+    public static final int INCLUDE_VIDEO = 2;
+    public static final int INCLUDE_ALL = INCLUDE_IMAGE | INCLUDE_VIDEO;
+    public static final int INCLUDE_LOCAL_ONLY = 4;
+    public static final int INCLUDE_LOCAL_IMAGE_ONLY =
+            INCLUDE_LOCAL_ONLY | INCLUDE_IMAGE;
+    public static final int INCLUDE_LOCAL_VIDEO_ONLY =
+            INCLUDE_LOCAL_ONLY | INCLUDE_VIDEO;
+    public static final int INCLUDE_LOCAL_ALL_ONLY =
+            INCLUDE_LOCAL_ONLY | INCLUDE_IMAGE | INCLUDE_VIDEO;
+
+    // Any one who would like to access data should require this lock
+    // to prevent concurrency issue.
+    public static final Object LOCK = new Object();
+
+    private static final String TAG = "DataManager";
+
+    // This is the path for the media set seen by the user at top level.
+    private static final String TOP_SET_PATH =
+            "/combo/{/mtp,/local/all,/picasa/all}";
+    private static final String TOP_IMAGE_SET_PATH =
+            "/combo/{/mtp,/local/image,/picasa/image}";
+    private static final String TOP_VIDEO_SET_PATH =
+            "/combo/{/local/video,/picasa/video}";
+    private static final String TOP_LOCAL_SET_PATH =
+            "/local/all";
+    private static final String TOP_LOCAL_IMAGE_SET_PATH =
+            "/local/image";
+    private static final String TOP_LOCAL_VIDEO_SET_PATH =
+            "/local/video";
+
+    public static final Comparator<MediaItem> sDateTakenComparator =
+            new DateTakenComparator();
+
+    private static class DateTakenComparator implements Comparator<MediaItem> {
+        public int compare(MediaItem item1, MediaItem item2) {
+            return -Utils.compare(item1.getDateInMs(), item2.getDateInMs());
+        }
+    }
+
+    private final Handler mDefaultMainHandler;
+
+    private GalleryApp mApplication;
+    private int mActiveCount = 0;
+
+    private HashMap<Uri, NotifyBroker> mNotifierMap =
+            new HashMap<Uri, NotifyBroker>();
+
+
+    private HashMap<String, MediaSource> mSourceMap =
+            new LinkedHashMap<String, MediaSource>();
+
+    public DataManager(GalleryApp application) {
+        mApplication = application;
+        mDefaultMainHandler = new Handler(application.getMainLooper());
+    }
+
+    public synchronized void initializeSourceMap() {
+        if (!mSourceMap.isEmpty()) return;
+
+        // the order matters, the UriSource must come last
+        addSource(new LocalSource(mApplication));
+        addSource(new PicasaSource(mApplication));
+        addSource(new MtpSource(mApplication));
+        addSource(new ComboSource(mApplication));
+        addSource(new ClusterSource(mApplication));
+        addSource(new FilterSource(mApplication));
+        addSource(new UriSource(mApplication));
+
+        if (mActiveCount > 0) {
+            for (MediaSource source : mSourceMap.values()) {
+                source.resume();
+            }
+        }
+    }
+
+    public String getTopSetPath(int typeBits) {
+
+        switch (typeBits) {
+            case INCLUDE_IMAGE: return TOP_IMAGE_SET_PATH;
+            case INCLUDE_VIDEO: return TOP_VIDEO_SET_PATH;
+            case INCLUDE_ALL: return TOP_SET_PATH;
+            case INCLUDE_LOCAL_IMAGE_ONLY: return TOP_LOCAL_IMAGE_SET_PATH;
+            case INCLUDE_LOCAL_VIDEO_ONLY: return TOP_LOCAL_VIDEO_SET_PATH;
+            case INCLUDE_LOCAL_ALL_ONLY: return TOP_LOCAL_SET_PATH;
+            default: throw new IllegalArgumentException();
+        }
+    }
+
+    // open for debug
+    void addSource(MediaSource source) {
+        mSourceMap.put(source.getPrefix(), source);
+    }
+
+    public MediaObject peekMediaObject(Path path) {
+        return path.getObject();
+    }
+
+    public MediaSet peekMediaSet(Path path) {
+        return (MediaSet) path.getObject();
+    }
+
+    public MediaObject getMediaObject(Path path) {
+        MediaObject obj = path.getObject();
+        if (obj != null) return obj;
+
+        MediaSource source = mSourceMap.get(path.getPrefix());
+        if (source == null) {
+            Log.w(TAG, "cannot find media source for path: " + path);
+            return null;
+        }
+
+        MediaObject object = source.createMediaObject(path);
+        if (object == null) {
+            Log.w(TAG, "cannot create media object: " + path);
+        }
+        return object;
+    }
+
+    public MediaObject getMediaObject(String s) {
+        return getMediaObject(Path.fromString(s));
+    }
+
+    public MediaSet getMediaSet(Path path) {
+        return (MediaSet) getMediaObject(path);
+    }
+
+    public MediaSet getMediaSet(String s) {
+        return (MediaSet) getMediaObject(s);
+    }
+
+    public MediaSet[] getMediaSetsFromString(String segment) {
+        String[] seq = Path.splitSequence(segment);
+        int n = seq.length;
+        MediaSet[] sets = new MediaSet[n];
+        for (int i = 0; i < n; i++) {
+            sets[i] = getMediaSet(seq[i]);
+        }
+        return sets;
+    }
+
+    // Maps a list of Paths to MediaItems, and invoke consumer.consume()
+    // for each MediaItem (may not be in the same order as the input list).
+    // An index number is also passed to consumer.consume() to identify
+    // the original position in the input list of the corresponding Path (plus
+    // startIndex).
+    public void mapMediaItems(ArrayList<Path> list, ItemConsumer consumer,
+            int startIndex) {
+        HashMap<String, ArrayList<PathId>> map =
+                new HashMap<String, ArrayList<PathId>>();
+
+        // Group the path by the prefix.
+        int n = list.size();
+        for (int i = 0; i < n; i++) {
+            Path path = list.get(i);
+            String prefix = path.getPrefix();
+            ArrayList<PathId> group = map.get(prefix);
+            if (group == null) {
+                group = new ArrayList<PathId>();
+                map.put(prefix, group);
+            }
+            group.add(new PathId(path, i + startIndex));
+        }
+
+        // For each group, ask the corresponding media source to map it.
+        for (Entry<String, ArrayList<PathId>> entry : map.entrySet()) {
+            String prefix = entry.getKey();
+            MediaSource source = mSourceMap.get(prefix);
+            source.mapMediaItems(entry.getValue(), consumer);
+        }
+    }
+
+    // The following methods forward the request to the proper object.
+    public int getSupportedOperations(Path path) {
+        return getMediaObject(path).getSupportedOperations();
+    }
+
+    public void delete(Path path) {
+        getMediaObject(path).delete();
+    }
+
+    public void rotate(Path path, int degrees) {
+        getMediaObject(path).rotate(degrees);
+    }
+
+    public Uri getContentUri(Path path) {
+        return getMediaObject(path).getContentUri();
+    }
+
+    public int getMediaType(Path path) {
+        return getMediaObject(path).getMediaType();
+    }
+
+    public MediaDetails getDetails(Path path) {
+        return getMediaObject(path).getDetails();
+    }
+
+    public void cache(Path path, int flag) {
+        getMediaObject(path).cache(flag);
+    }
+
+    public Path findPathByUri(Uri uri) {
+        if (uri == null) return null;
+        for (MediaSource source : mSourceMap.values()) {
+            Path path = source.findPathByUri(uri);
+            if (path != null) return path;
+        }
+        return null;
+    }
+
+    public Path getDefaultSetOf(Path item) {
+        MediaSource source = mSourceMap.get(item.getPrefix());
+        return source == null ? null : source.getDefaultSetOf(item);
+    }
+
+    // Returns number of bytes used by cached pictures currently downloaded.
+    public long getTotalUsedCacheSize() {
+        long sum = 0;
+        for (MediaSource source : mSourceMap.values()) {
+            sum += source.getTotalUsedCacheSize();
+        }
+        return sum;
+    }
+
+    // Returns number of bytes used by cached pictures if all pending
+    // downloads and removals are completed.
+    public long getTotalTargetCacheSize() {
+        long sum = 0;
+        for (MediaSource source : mSourceMap.values()) {
+            sum += source.getTotalTargetCacheSize();
+        }
+        return sum;
+    }
+
+    public void registerChangeNotifier(Uri uri, ChangeNotifier notifier) {
+        NotifyBroker broker = null;
+        synchronized (mNotifierMap) {
+            broker = mNotifierMap.get(uri);
+            if (broker == null) {
+                broker = new NotifyBroker(mDefaultMainHandler);
+                mApplication.getContentResolver()
+                        .registerContentObserver(uri, true, broker);
+                mNotifierMap.put(uri, broker);
+            }
+        }
+        broker.registerNotifier(notifier);
+    }
+
+    public void resume() {
+        if (++mActiveCount == 1) {
+            for (MediaSource source : mSourceMap.values()) {
+                source.resume();
+            }
+        }
+    }
+
+    public void pause() {
+        if (--mActiveCount == 0) {
+            for (MediaSource source : mSourceMap.values()) {
+                source.pause();
+            }
+        }
+    }
+
+    private static class NotifyBroker extends ContentObserver {
+        private WeakHashMap<ChangeNotifier, Object> mNotifiers =
+                new WeakHashMap<ChangeNotifier, Object>();
+
+        public NotifyBroker(Handler handler) {
+            super(handler);
+        }
+
+        public synchronized void registerNotifier(ChangeNotifier notifier) {
+            mNotifiers.put(notifier, null);
+        }
+
+        @Override
+        public synchronized void onChange(boolean selfChange) {
+            for(ChangeNotifier notifier : mNotifiers.keySet()) {
+                notifier.onChange(selfChange);
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/DecodeUtils.java b/src/com/android/gallery3d/data/DecodeUtils.java
new file mode 100644
index 0000000..e7ae638
--- /dev/null
+++ b/src/com/android/gallery3d/data/DecodeUtils.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.ContentResolver;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapFactory.Options;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+
+public class DecodeUtils {
+    private static final String TAG = "DecodeService";
+
+    private static class DecodeCanceller implements CancelListener {
+        Options mOptions;
+        public DecodeCanceller(Options options) {
+            mOptions = options;
+        }
+        public void onCancel() {
+            mOptions.requestCancelDecode();
+        }
+    }
+
+    public static Bitmap requestDecode(JobContext jc, final String filePath,
+            Options options) {
+        if (options == null) options = new Options();
+        jc.setCancelListener(new DecodeCanceller(options));
+        return ensureGLCompatibleBitmap(
+                BitmapFactory.decodeFile(filePath, options));
+    }
+
+    public static Bitmap requestDecode(JobContext jc, byte[] bytes,
+            Options options) {
+        return requestDecode(jc, bytes, 0, bytes.length, options);
+    }
+
+    public static Bitmap requestDecode(JobContext jc, byte[] bytes, int offset,
+            int length, Options options) {
+        if (options == null) options = new Options();
+        jc.setCancelListener(new DecodeCanceller(options));
+        return ensureGLCompatibleBitmap(
+                BitmapFactory.decodeByteArray(bytes, offset, length, options));
+    }
+
+    public static Bitmap requestDecode(JobContext jc, final String filePath,
+            Options options, int targetSize) {
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(filePath);
+            FileDescriptor fd = fis.getFD();
+            return requestDecode(jc, fd, options, targetSize);
+        } catch (Exception ex) {
+            Log.w(TAG, ex);
+            return null;
+        } finally {
+            Utils.closeSilently(fis);
+        }
+    }
+
+    public static Bitmap requestDecode(JobContext jc, FileDescriptor fd,
+            Options options, int targetSize) {
+        if (options == null) options = new Options();
+        jc.setCancelListener(new DecodeCanceller(options));
+
+        options.inJustDecodeBounds = true;
+        BitmapFactory.decodeFileDescriptor(fd, null, options);
+        if (jc.isCancelled()) return null;
+
+        options.inSampleSize = BitmapUtils.computeSampleSizeLarger(
+                options.outWidth, options.outHeight, targetSize);
+        options.inJustDecodeBounds = false;
+        return ensureGLCompatibleBitmap(
+                BitmapFactory.decodeFileDescriptor(fd, null, options));
+    }
+
+    public static Bitmap requestDecode(JobContext jc,
+            FileDescriptor fileDescriptor, Rect paddings, Options options) {
+        if (options == null) options = new Options();
+        jc.setCancelListener(new DecodeCanceller(options));
+        return ensureGLCompatibleBitmap(BitmapFactory.decodeFileDescriptor
+                (fileDescriptor, paddings, options));
+    }
+
+    // TODO: This function should not be called directly from
+    // DecodeUtils.requestDecode(...), since we don't have the knowledge
+    // if the bitmap will be uploaded to GL.
+    public static Bitmap ensureGLCompatibleBitmap(Bitmap bitmap) {
+        if (bitmap == null || bitmap.getConfig() != null) return bitmap;
+        Bitmap newBitmap = bitmap.copy(Config.ARGB_8888, false);
+        bitmap.recycle();
+        return newBitmap;
+    }
+
+    public static BitmapRegionDecoder requestCreateBitmapRegionDecoder(
+            JobContext jc, byte[] bytes, int offset, int length,
+            boolean shareable) {
+        if (offset < 0 || length <= 0 || offset + length > bytes.length) {
+            throw new IllegalArgumentException(String.format(
+                    "offset = %s, length = %s, bytes = %s",
+                    offset, length, bytes.length));
+        }
+
+        try {
+            return BitmapRegionDecoder.newInstance(
+                    bytes, offset, length, shareable);
+        } catch (Throwable t)  {
+            Log.w(TAG, t);
+            return null;
+        }
+    }
+
+    public static BitmapRegionDecoder requestCreateBitmapRegionDecoder(
+            JobContext jc, String filePath, boolean shareable) {
+        try {
+            return BitmapRegionDecoder.newInstance(filePath, shareable);
+        } catch (Throwable t)  {
+            Log.w(TAG, t);
+            return null;
+        }
+    }
+
+    public static BitmapRegionDecoder requestCreateBitmapRegionDecoder(
+            JobContext jc, FileDescriptor fd, boolean shareable) {
+        try {
+            return BitmapRegionDecoder.newInstance(fd, shareable);
+        } catch (Throwable t)  {
+            Log.w(TAG, t);
+            return null;
+        }
+    }
+
+    public static BitmapRegionDecoder requestCreateBitmapRegionDecoder(
+            JobContext jc, Uri uri, ContentResolver resolver,
+            boolean shareable) {
+        ParcelFileDescriptor pfd = null;
+        try {
+            pfd = resolver.openFileDescriptor(uri, "r");
+            return BitmapRegionDecoder.newInstance(
+                    pfd.getFileDescriptor(), shareable);
+        } catch (Throwable t) {
+            Log.w(TAG, t);
+            return null;
+        } finally {
+            Utils.closeSilently(pfd);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/DownloadCache.java b/src/com/android/gallery3d/data/DownloadCache.java
new file mode 100644
index 0000000..30ba668
--- /dev/null
+++ b/src/com/android/gallery3d/data/DownloadCache.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.LruCache;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DownloadEntry.Columns;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.ThreadPool;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.WeakHashMap;
+
+public class DownloadCache {
+    private static final String TAG = "DownloadCache";
+    private static final int MAX_DELETE_COUNT = 16;
+    private static final int LRU_CAPACITY = 4;
+
+    private static final String TABLE_NAME = DownloadEntry.SCHEMA.getTableName();
+
+    private static final String QUERY_PROJECTION[] = {Columns.ID, Columns.DATA};
+    private static final String WHERE_HASH_AND_URL = String.format(
+            "%s = ? AND %s = ?", Columns.HASH_CODE, Columns.CONTENT_URL);
+    private static final int QUERY_INDEX_ID = 0;
+    private static final int QUERY_INDEX_DATA = 1;
+
+    private static final String FREESPACE_PROJECTION[] = {
+            Columns.ID, Columns.DATA, Columns.CONTENT_URL, Columns.CONTENT_SIZE};
+    private static final String FREESPACE_ORDER_BY =
+            String.format("%s ASC", Columns.LAST_ACCESS);
+    private static final int FREESPACE_IDNEX_ID = 0;
+    private static final int FREESPACE_IDNEX_DATA = 1;
+    private static final int FREESPACE_INDEX_CONTENT_URL = 2;
+    private static final int FREESPACE_INDEX_CONTENT_SIZE = 3;
+
+    private static final String ID_WHERE = Columns.ID + " = ?";
+
+    private static final String SUM_PROJECTION[] =
+            {String.format("sum(%s)", Columns.CONTENT_SIZE)};
+    private static final int SUM_INDEX_SUM = 0;
+
+    private final LruCache<String, Entry> mEntryMap =
+            new LruCache<String, Entry>(LRU_CAPACITY);
+    private final HashMap<String, DownloadTask> mTaskMap =
+            new HashMap<String, DownloadTask>();
+    private final File mRoot;
+    private final GalleryApp mApplication;
+    private final SQLiteDatabase mDatabase;
+    private final long mCapacity;
+
+    private long mTotalBytes = 0;
+    private boolean mInitialized = false;
+    private WeakHashMap<Object, Entry> mAssociateMap = new WeakHashMap<Object, Entry>();
+
+    public DownloadCache(GalleryApp application, File root, long capacity) {
+        mRoot = Utils.checkNotNull(root);
+        mApplication = Utils.checkNotNull(application);
+        mCapacity = capacity;
+        mDatabase = new DatabaseHelper(application.getAndroidContext())
+                .getWritableDatabase();
+    }
+
+    private Entry findEntryInDatabase(String stringUrl) {
+        long hash = Utils.crc64Long(stringUrl);
+        String whereArgs[] = {String.valueOf(hash), stringUrl};
+        Cursor cursor = mDatabase.query(TABLE_NAME, QUERY_PROJECTION,
+                WHERE_HASH_AND_URL, whereArgs, null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                File file = new File(cursor.getString(QUERY_INDEX_DATA));
+                long id = cursor.getInt(QUERY_INDEX_ID);
+                Entry entry = null;
+                synchronized (mEntryMap) {
+                    entry = mEntryMap.get(stringUrl);
+                    if (entry == null) {
+                        entry = new Entry(id, file);
+                        mEntryMap.put(stringUrl, entry);
+                    }
+                }
+                return entry;
+            }
+        } finally {
+            cursor.close();
+        }
+        return null;
+    }
+
+    public Entry lookup(URL url) {
+        if (!mInitialized) initialize();
+        String stringUrl = url.toString();
+
+        // First find in the entry-pool
+        synchronized (mEntryMap) {
+            Entry entry = mEntryMap.get(stringUrl);
+            if (entry != null) {
+                updateLastAccess(entry.mId);
+                return entry;
+            }
+        }
+
+        // Then, find it in database
+        TaskProxy proxy = new TaskProxy();
+        synchronized (mTaskMap) {
+            Entry entry = findEntryInDatabase(stringUrl);
+            if (entry != null) {
+                updateLastAccess(entry.mId);
+                return entry;
+            }
+        }
+        return null;
+    }
+
+    public Entry download(JobContext jc, URL url) {
+        if (!mInitialized) initialize();
+
+        String stringUrl = url.toString();
+
+        // First find in the entry-pool
+        synchronized (mEntryMap) {
+            Entry entry = mEntryMap.get(stringUrl);
+            if (entry != null) {
+                updateLastAccess(entry.mId);
+                return entry;
+            }
+        }
+
+        // Then, find it in database
+        TaskProxy proxy = new TaskProxy();
+        synchronized (mTaskMap) {
+            Entry entry = findEntryInDatabase(stringUrl);
+            if (entry != null) {
+                updateLastAccess(entry.mId);
+                return entry;
+            }
+
+            // Finally, we need to download the file ....
+            // First check if we are downloading it now ...
+            DownloadTask task = mTaskMap.get(stringUrl);
+            if (task == null) { // if not, start the download task now
+                task = new DownloadTask(stringUrl);
+                mTaskMap.put(stringUrl, task);
+                task.mFuture = mApplication.getThreadPool().submit(task, task);
+            }
+            task.addProxy(proxy);
+        }
+
+        return proxy.get(jc);
+    }
+
+    private void updateLastAccess(long id) {
+        ContentValues values = new ContentValues();
+        values.put(Columns.LAST_ACCESS, System.currentTimeMillis());
+        mDatabase.update(TABLE_NAME, values,
+                ID_WHERE, new String[] {String.valueOf(id)});
+    }
+
+    private synchronized void freeSomeSpaceIfNeed(int maxDeleteFileCount) {
+        if (mTotalBytes <= mCapacity) return;
+        Cursor cursor = mDatabase.query(TABLE_NAME,
+                FREESPACE_PROJECTION, null, null, null, null, FREESPACE_ORDER_BY);
+        try {
+            while (maxDeleteFileCount > 0
+                    && mTotalBytes > mCapacity && cursor.moveToNext()) {
+                long id = cursor.getLong(FREESPACE_IDNEX_ID);
+                String url = cursor.getString(FREESPACE_INDEX_CONTENT_URL);
+                long size = cursor.getLong(FREESPACE_INDEX_CONTENT_SIZE);
+                String path = cursor.getString(FREESPACE_IDNEX_DATA);
+                boolean containsKey;
+                synchronized (mEntryMap) {
+                    containsKey = mEntryMap.containsKey(url);
+                }
+                if (!containsKey) {
+                    --maxDeleteFileCount;
+                    mTotalBytes -= size;
+                    new File(path).delete();
+                    mDatabase.delete(TABLE_NAME,
+                            ID_WHERE, new String[]{String.valueOf(id)});
+                } else {
+                    // skip delete, since it is being used
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private synchronized long insertEntry(String url, File file) {
+        long size = file.length();
+        mTotalBytes += size;
+
+        ContentValues values = new ContentValues();
+        String hashCode = String.valueOf(Utils.crc64Long(url));
+        values.put(Columns.DATA, file.getAbsolutePath());
+        values.put(Columns.HASH_CODE, hashCode);
+        values.put(Columns.CONTENT_URL, url);
+        values.put(Columns.CONTENT_SIZE, size);
+        values.put(Columns.LAST_UPDATED, System.currentTimeMillis());
+        return mDatabase.insert(TABLE_NAME, "", values);
+    }
+
+    private synchronized void initialize() {
+        if (mInitialized) return;
+        mInitialized = true;
+        if (!mRoot.isDirectory()) mRoot.mkdirs();
+        if (!mRoot.isDirectory()) {
+            throw new RuntimeException("cannot create " + mRoot.getAbsolutePath());
+        }
+
+        Cursor cursor = mDatabase.query(
+                TABLE_NAME, SUM_PROJECTION, null, null, null, null, null);
+        mTotalBytes = 0;
+        try {
+            if (cursor.moveToNext()) {
+                mTotalBytes = cursor.getLong(SUM_INDEX_SUM);
+            }
+        } finally {
+            cursor.close();
+        }
+        if (mTotalBytes > mCapacity) freeSomeSpaceIfNeed(MAX_DELETE_COUNT);
+    }
+
+    private final class DatabaseHelper extends SQLiteOpenHelper {
+        public static final String DATABASE_NAME = "download.db";
+        public static final int DATABASE_VERSION = 2;
+
+        public DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            DownloadEntry.SCHEMA.createTables(db);
+            // Delete old files
+            for (File file : mRoot.listFiles()) {
+                if (!file.delete()) {
+                    Log.w(TAG, "fail to remove: " + file.getAbsolutePath());
+                }
+            }
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            //reset everything
+            DownloadEntry.SCHEMA.dropTables(db);
+            onCreate(db);
+        }
+    }
+
+    public class Entry {
+        public File cacheFile;
+        protected long mId;
+
+        Entry(long id, File cacheFile) {
+            mId = id;
+            this.cacheFile = Utils.checkNotNull(cacheFile);
+        }
+
+        public void associateWith(Object object) {
+            mAssociateMap.put(Utils.checkNotNull(object), this);
+        }
+    }
+
+    private class DownloadTask implements Job<File>, FutureListener<File> {
+        private HashSet<TaskProxy> mProxySet = new HashSet<TaskProxy>();
+        private Future<File> mFuture;
+        private final String mUrl;
+
+        public DownloadTask(String url) {
+            mUrl = Utils.checkNotNull(url);
+        }
+
+        public void removeProxy(TaskProxy proxy) {
+            synchronized (mTaskMap) {
+                Utils.assertTrue(mProxySet.remove(proxy));
+                if (mProxySet.isEmpty()) {
+                    mFuture.cancel();
+                    mTaskMap.remove(mUrl);
+                }
+            }
+        }
+
+        // should be used in synchronized block of mDatabase
+        public void addProxy(TaskProxy proxy) {
+            proxy.mTask = this;
+            mProxySet.add(proxy);
+        }
+
+        public void onFutureDone(Future<File> future) {
+            File file = future.get();
+            long id = 0;
+            if (file != null) { // insert to database
+                id = insertEntry(mUrl, file);
+            }
+
+            if (future.isCancelled()) {
+                Utils.assertTrue(mProxySet.isEmpty());
+                return;
+            }
+
+            synchronized (mTaskMap) {
+                Entry entry = null;
+                synchronized (mEntryMap) {
+                    if (file != null) {
+                        entry = new Entry(id, file);
+                        Utils.assertTrue(mEntryMap.put(mUrl, entry) == null);
+                    }
+                }
+                for (TaskProxy proxy : mProxySet) {
+                    proxy.setResult(entry);
+                }
+                mTaskMap.remove(mUrl);
+                freeSomeSpaceIfNeed(MAX_DELETE_COUNT);
+            }
+        }
+
+        public File run(JobContext jc) {
+            // TODO: utilize etag
+            jc.setMode(ThreadPool.MODE_NETWORK);
+            File tempFile = null;
+            try {
+                URL url = new URL(mUrl);
+                tempFile = File.createTempFile("cache", ".tmp", mRoot);
+                // download from url to tempFile
+                jc.setMode(ThreadPool.MODE_NETWORK);
+                boolean downloaded = DownloadUtils.requestDownload(jc, url, tempFile);
+                jc.setMode(ThreadPool.MODE_NONE);
+                if (downloaded) return tempFile;
+            } catch (Exception e) {
+                Log.e(TAG, String.format("fail to download %s", mUrl), e);
+            } finally {
+                jc.setMode(ThreadPool.MODE_NONE);
+            }
+            if (tempFile != null) tempFile.delete();
+            return null;
+        }
+    }
+
+    public static class TaskProxy {
+        private DownloadTask mTask;
+        private boolean mIsCancelled = false;
+        private Entry mEntry;
+
+        synchronized void setResult(Entry entry) {
+            if (mIsCancelled) return;
+            mEntry = entry;
+            notifyAll();
+        }
+
+        public synchronized Entry get(JobContext jc) {
+            jc.setCancelListener(new CancelListener() {
+                public void onCancel() {
+                    mTask.removeProxy(TaskProxy.this);
+                    synchronized (TaskProxy.this) {
+                        mIsCancelled = true;
+                        TaskProxy.this.notifyAll();
+                    }
+                }
+            });
+            while (!mIsCancelled && mEntry == null) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    Log.w(TAG, "ignore interrupt", e);
+                }
+            }
+            jc.setCancelListener(null);
+            return mEntry;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/DownloadEntry.java b/src/com/android/gallery3d/data/DownloadEntry.java
new file mode 100644
index 0000000..578523f
--- /dev/null
+++ b/src/com/android/gallery3d/data/DownloadEntry.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.common.Entry;
+import com.android.gallery3d.common.EntrySchema;
+
+
+@Entry.Table("download")
+public class DownloadEntry extends Entry {
+    public static final EntrySchema SCHEMA = new EntrySchema(DownloadEntry.class);
+
+    public static interface Columns extends Entry.Columns {
+        public static final String HASH_CODE = "hash_code";
+        public static final String CONTENT_URL = "content_url";
+        public static final String CONTENT_SIZE = "_size";
+        public static final String ETAG = "etag";
+        public static final String LAST_ACCESS = "last_access";
+        public static final String LAST_UPDATED = "last_updated";
+        public static final String DATA = "_data";
+    }
+
+    @Column(value = "hash_code", indexed = true)
+    public long hashCode;
+
+    @Column("content_url")
+    public String contentUrl;
+
+    @Column("_size")
+    public long contentSize;
+
+    @Column("etag")
+    public String eTag;
+
+    @Column(value = "last_access", indexed = true)
+    public long lastAccessTime;
+
+    @Column(value = "last_updated")
+    public long lastUpdatedTime;
+
+    @Column("_data")
+    public String path;
+
+    @Override
+    public String toString() {
+        // Note: THIS IS REQUIRED. We used all the fields here. Otherwise,
+        //       ProGuard will remove these UNUSED fields. However, these
+        //       fields are needed to generate database.
+        return new StringBuilder()
+                .append("hash_code: ").append(hashCode).append(", ")
+                .append("content_url").append(contentUrl).append(", ")
+                .append("_size").append(contentSize).append(", ")
+                .append("etag").append(eTag).append(", ")
+                .append("last_access").append(lastAccessTime).append(", ")
+                .append("last_updated").append(lastUpdatedTime).append(",")
+                .append("_data").append(path)
+                .toString();
+    }
+}
diff --git a/src/com/android/gallery3d/data/DownloadUtils.java b/src/com/android/gallery3d/data/DownloadUtils.java
new file mode 100644
index 0000000..9632db9
--- /dev/null
+++ b/src/com/android/gallery3d/data/DownloadUtils.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.URL;
+
+public class DownloadUtils {
+    private static final String TAG = "DownloadService";
+
+    public static boolean requestDownload(JobContext jc, URL url, File file) {
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(file);
+            return download(jc, url, fos);
+        } catch (Throwable t) {
+            return false;
+        } finally {
+            Utils.closeSilently(fos);
+        }
+    }
+
+    public static byte[] requestDownload(JobContext jc, URL url) {
+        ByteArrayOutputStream baos = null;
+        try {
+            baos = new ByteArrayOutputStream();
+            if (!download(jc, url, baos)) {
+                return null;
+            }
+            return baos.toByteArray();
+        } catch (Throwable t) {
+            Log.w(TAG, t);
+            return null;
+        } finally {
+            Utils.closeSilently(baos);
+        }
+    }
+
+    public static void dump(JobContext jc, InputStream is, OutputStream os)
+            throws IOException {
+        byte buffer[] = new byte[4096];
+        int rc = is.read(buffer, 0, buffer.length);
+        final Thread thread = Thread.currentThread();
+        jc.setCancelListener(new CancelListener() {
+            public void onCancel() {
+                thread.interrupt();
+            }
+        });
+        while (rc > 0) {
+            if (jc.isCancelled()) throw new InterruptedIOException();
+            os.write(buffer, 0, rc);
+            rc = is.read(buffer, 0, buffer.length);
+        }
+        jc.setCancelListener(null);
+        Thread.interrupted(); // consume the interrupt signal
+    }
+
+    public static boolean download(JobContext jc, URL url, OutputStream output) {
+        InputStream input = null;
+        try {
+            input = url.openStream();
+            dump(jc, input, output);
+            return true;
+        } catch (Throwable t) {
+            Log.w(TAG, "fail to download", t);
+            return false;
+        } finally {
+            Utils.closeSilently(input);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/data/Face.java b/src/com/android/gallery3d/data/Face.java
new file mode 100644
index 0000000..cc1a2d3
--- /dev/null
+++ b/src/com/android/gallery3d/data/Face.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.common.Utils;
+
+public class Face implements Comparable<Face> {
+    private String mName;
+    private String mPersonId;
+
+    public Face(String name, String personId) {
+        mName = name;
+        mPersonId = personId;
+        Utils.assertTrue(mName != null && mPersonId != null);
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public String getPersonId() {
+        return mPersonId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Face) {
+            Face face = (Face) obj;
+            return mPersonId.equals(face.mPersonId);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return mPersonId.hashCode();
+    }
+
+    public int compareTo(Face another) {
+        return mPersonId.compareTo(another.mPersonId);
+    }
+}
diff --git a/src/com/android/gallery3d/data/FaceClustering.java b/src/com/android/gallery3d/data/FaceClustering.java
new file mode 100644
index 0000000..6ed73b5
--- /dev/null
+++ b/src/com/android/gallery3d/data/FaceClustering.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class FaceClustering extends Clustering {
+    @SuppressWarnings("unused")
+    private static final String TAG = "FaceClustering";
+
+    private ArrayList<ArrayList<Path>> mClusters;
+    private String[] mNames;
+    private String mUntaggedString;
+
+    public FaceClustering(Context context) {
+        mUntaggedString = context.getResources().getString(R.string.untagged);
+    }
+
+    @Override
+    public void run(MediaSet baseSet) {
+        final TreeMap<Face, ArrayList<Path>> map =
+                new TreeMap<Face, ArrayList<Path>>();
+        final ArrayList<Path> untagged = new ArrayList<Path>();
+
+        baseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                Path path = item.getPath();
+
+                Face[] faces = item.getFaces();
+                if (faces == null || faces.length == 0) {
+                    untagged.add(path);
+                    return;
+                }
+                for (int j = 0; j < faces.length; j++) {
+                    Face key = faces[j];
+                    ArrayList<Path> list = map.get(key);
+                    if (list == null) {
+                        list = new ArrayList<Path>();
+                        map.put(key, list);
+                    }
+                    list.add(path);
+                }
+            }
+        });
+
+        int m = map.size();
+        mClusters = new ArrayList<ArrayList<Path>>();
+        mNames = new String[m + ((untagged.size() > 0) ? 1 : 0)];
+        int i = 0;
+        for (Map.Entry<Face, ArrayList<Path>> entry : map.entrySet()) {
+            mNames[i++] = entry.getKey().getName();
+            mClusters.add(entry.getValue());
+        }
+        if (untagged.size() > 0) {
+            mNames[i++] = mUntaggedString;
+            mClusters.add(untagged);
+        }
+    }
+
+    @Override
+    public int getNumberOfClusters() {
+        return mClusters.size();
+    }
+
+    @Override
+    public ArrayList<Path> getCluster(int index) {
+        return mClusters.get(index);
+    }
+
+    @Override
+    public String getClusterName(int index) {
+        return mNames[index];
+    }
+}
diff --git a/src/com/android/gallery3d/data/FilterSet.java b/src/com/android/gallery3d/data/FilterSet.java
new file mode 100644
index 0000000..9cb7e02
--- /dev/null
+++ b/src/com/android/gallery3d/data/FilterSet.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import java.util.ArrayList;
+
+// FilterSet filters a base MediaSet according to a condition. Currently the
+// condition is a matching media type. It can be extended to other conditions
+// if needed.
+public class FilterSet extends MediaSet implements ContentListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "FilterSet";
+
+    private final DataManager mDataManager;
+    private final MediaSet mBaseSet;
+    private final int mMediaType;
+    private final ArrayList<Path> mPaths = new ArrayList<Path>();
+    private final ArrayList<MediaSet> mAlbums = new ArrayList<MediaSet>();
+
+    public FilterSet(Path path, DataManager dataManager, MediaSet baseSet,
+            int mediaType) {
+        super(path, INVALID_DATA_VERSION);
+        mDataManager = dataManager;
+        mBaseSet = baseSet;
+        mMediaType = mediaType;
+        mBaseSet.addContentListener(this);
+    }
+
+    @Override
+    public String getName() {
+        return mBaseSet.getName();
+    }
+
+    @Override
+    public MediaSet getSubMediaSet(int index) {
+        return mAlbums.get(index);
+    }
+
+    @Override
+    public int getSubMediaSetCount() {
+        return mAlbums.size();
+    }
+
+    @Override
+    public int getMediaItemCount() {
+        return mPaths.size();
+    }
+
+    @Override
+    public ArrayList<MediaItem> getMediaItem(int start, int count) {
+        return ClusterAlbum.getMediaItemFromPath(
+                mPaths, start, count, mDataManager);
+    }
+
+    @Override
+    public long reload() {
+        if (mBaseSet.reload() > mDataVersion) {
+            updateData();
+            mDataVersion = nextVersionNumber();
+        }
+        return mDataVersion;
+    }
+
+    @Override
+    public void onContentDirty() {
+        notifyContentChanged();
+    }
+
+    private void updateData() {
+        // Albums
+        mAlbums.clear();
+        String basePath = "/filter/mediatype/" + mMediaType;
+
+        for (int i = 0, n = mBaseSet.getSubMediaSetCount(); i < n; i++) {
+            MediaSet set = mBaseSet.getSubMediaSet(i);
+            String filteredPath = basePath + "/{" + set.getPath().toString() + "}";
+            MediaSet filteredSet = mDataManager.getMediaSet(filteredPath);
+            filteredSet.reload();
+            if (filteredSet.getMediaItemCount() > 0
+                    || filteredSet.getSubMediaSetCount() > 0) {
+                mAlbums.add(filteredSet);
+            }
+        }
+
+        // Items
+        mPaths.clear();
+        final int total = mBaseSet.getMediaItemCount();
+        final Path[] buf = new Path[total];
+
+        mBaseSet.enumerateMediaItems(new MediaSet.ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                if (item.getMediaType() == mMediaType) {
+                    if (index < 0 || index >= total) return;
+                    Path path = item.getPath();
+                    buf[index] = path;
+                }
+            }
+        });
+
+        for (int i = 0; i < total; i++) {
+            if (buf[i] != null) {
+                mPaths.add(buf[i]);
+            }
+        }
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        return SUPPORT_SHARE | SUPPORT_DELETE;
+    }
+
+    @Override
+    public void delete() {
+        ItemConsumer consumer = new ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                if ((item.getSupportedOperations() & SUPPORT_DELETE) != 0) {
+                    item.delete();
+                }
+            }
+        };
+        mDataManager.mapMediaItems(mPaths, consumer, 0);
+    }
+}
diff --git a/src/com/android/gallery3d/data/FilterSource.java b/src/com/android/gallery3d/data/FilterSource.java
new file mode 100644
index 0000000..d1a04c9
--- /dev/null
+++ b/src/com/android/gallery3d/data/FilterSource.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+class FilterSource extends MediaSource {
+    private static final String TAG = "FilterSource";
+    private static final int FILTER_BY_MEDIATYPE = 0;
+
+    private GalleryApp mApplication;
+    private PathMatcher mMatcher;
+
+    public FilterSource(GalleryApp application) {
+        super("filter");
+        mApplication = application;
+        mMatcher = new PathMatcher();
+        mMatcher.add("/filter/mediatype/*/*", FILTER_BY_MEDIATYPE);
+    }
+
+    // The name we accept is:
+    // /filter/mediatype/k/{set}
+    // where k is the media type we want.
+    @Override
+    public MediaObject createMediaObject(Path path) {
+        int matchType = mMatcher.match(path);
+        int mediaType = mMatcher.getIntVar(0);
+        String setsName = mMatcher.getVar(1);
+        DataManager dataManager = mApplication.getDataManager();
+        MediaSet[] sets = dataManager.getMediaSetsFromString(setsName);
+        switch (matchType) {
+            case FILTER_BY_MEDIATYPE:
+                return new FilterSet(path, dataManager, sets[0], mediaType);
+            default:
+                throw new RuntimeException("bad path: " + path);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/ImageCacheRequest.java b/src/com/android/gallery3d/data/ImageCacheRequest.java
new file mode 100644
index 0000000..104ff48
--- /dev/null
+++ b/src/com/android/gallery3d/data/ImageCacheRequest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.data.ImageCacheService.ImageData;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+abstract class ImageCacheRequest implements Job<Bitmap> {
+    private static final String TAG = "ImageCacheRequest";
+
+    protected GalleryApp mApplication;
+    private Path mPath;
+    private int mType;
+    private int mTargetSize;
+
+    public ImageCacheRequest(GalleryApp application,
+            Path path, int type, int targetSize) {
+        mApplication = application;
+        mPath = path;
+        mType = type;
+        mTargetSize = targetSize;
+    }
+
+    public Bitmap run(JobContext jc) {
+        String debugTag = mPath + "," +
+                 ((mType == MediaItem.TYPE_THUMBNAIL) ? "THUMB" :
+                 (mType == MediaItem.TYPE_MICROTHUMBNAIL) ? "MICROTHUMB" : "?");
+        ImageCacheService cacheService = mApplication.getImageCacheService();
+
+        ImageData data = cacheService.getImageData(mPath, mType);
+        if (jc.isCancelled()) return null;
+
+        if (data != null) {
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+            Bitmap bitmap = DecodeUtils.requestDecode(jc, data.mData,
+                    data.mOffset, data.mData.length - data.mOffset, options);
+            if (bitmap == null && !jc.isCancelled()) {
+                Log.w(TAG, "decode cached failed " + debugTag);
+            }
+            return bitmap;
+        } else {
+            Bitmap bitmap = onDecodeOriginal(jc, mType);
+            if (jc.isCancelled()) return null;
+
+            if (bitmap == null) {
+                Log.w(TAG, "decode orig failed " + debugTag);
+                return null;
+            }
+
+            if (mType == MediaItem.TYPE_MICROTHUMBNAIL) {
+                bitmap = BitmapUtils.resizeDownAndCropCenter(bitmap,
+                        mTargetSize, true);
+            } else {
+                bitmap = BitmapUtils.resizeDownBySideLength(bitmap,
+                        mTargetSize, true);
+            }
+            if (jc.isCancelled()) return null;
+
+            byte[] array = BitmapUtils.compressBitmap(bitmap);
+            if (jc.isCancelled()) return null;
+
+            cacheService.putImageData(mPath, mType, array);
+            return bitmap;
+        }
+    }
+
+    public abstract Bitmap onDecodeOriginal(JobContext jc, int targetSize);
+}
diff --git a/src/com/android/gallery3d/data/ImageCacheService.java b/src/com/android/gallery3d/data/ImageCacheService.java
new file mode 100644
index 0000000..3adce13
--- /dev/null
+++ b/src/com/android/gallery3d/data/ImageCacheService.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.common.BlobCache;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.CacheManager;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.Context;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class ImageCacheService {
+    @SuppressWarnings("unused")
+    private static final String TAG = "ImageCacheService";
+
+    private static final String IMAGE_CACHE_FILE = "imgcache";
+    private static final int IMAGE_CACHE_MAX_ENTRIES = 5000;
+    private static final int IMAGE_CACHE_MAX_BYTES = 200 * 1024 * 1024;
+    private static final int IMAGE_CACHE_VERSION = 3;
+
+    private BlobCache mCache;
+
+    public ImageCacheService(Context context) {
+        mCache = CacheManager.getCache(context, IMAGE_CACHE_FILE,
+                IMAGE_CACHE_MAX_ENTRIES, IMAGE_CACHE_MAX_BYTES,
+                IMAGE_CACHE_VERSION);
+    }
+
+    public static class ImageData {
+        public ImageData(byte[] data, int offset) {
+            mData = data;
+            mOffset = offset;
+        }
+        public byte[] mData;
+        public int mOffset;
+    }
+
+    public ImageData getImageData(Path path, int type) {
+        byte[] key = makeKey(path, type);
+        long cacheKey = Utils.crc64Long(key);
+        try {
+            byte[] value = null;
+            synchronized (mCache) {
+                value = mCache.lookup(cacheKey);
+            }
+            if (value == null) return null;
+            if (isSameKey(key, value)) {
+                int offset = key.length;
+                return new ImageData(value, offset);
+            }
+        } catch (IOException ex) {
+            // ignore.
+        }
+        return null;
+    }
+
+    public void putImageData(Path path, int type, byte[] value) {
+        byte[] key = makeKey(path, type);
+        long cacheKey = Utils.crc64Long(key);
+        ByteBuffer buffer = ByteBuffer.allocate(key.length + value.length);
+        buffer.put(key);
+        buffer.put(value);
+        synchronized (mCache) {
+            try {
+                mCache.insert(cacheKey, buffer.array());
+            } catch (IOException ex) {
+                // ignore.
+            }
+        }
+    }
+
+    private static byte[] makeKey(Path path, int type) {
+        return GalleryUtils.getBytes(path.toString() + "+" + type);
+    }
+
+    private static boolean isSameKey(byte[] key, byte[] buffer) {
+        int n = key.length;
+        if (buffer.length < n) {
+            return false;
+        }
+        for (int i = 0; i < n; ++i) {
+            if (key[i] != buffer[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocalAlbum.java b/src/com/android/gallery3d/data/LocalAlbum.java
new file mode 100644
index 0000000..5bd4398
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalAlbum.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.MediaStore.Images;
+import android.provider.MediaStore.Images.ImageColumns;
+import android.provider.MediaStore.Video;
+import android.provider.MediaStore.Video.VideoColumns;
+
+import java.util.ArrayList;
+
+// LocalAlbumSet lists all media items in one bucket on local storage.
+// The media items need to be all images or all videos, but not both.
+public class LocalAlbum extends MediaSet {
+    private static final String TAG = "LocalAlbum";
+    private static final String[] COUNT_PROJECTION = { "count(*)" };
+
+    private static final int INVALID_COUNT = -1;
+    private final String mWhereClause;
+    private final String mOrderClause;
+    private final Uri mBaseUri;
+    private final String[] mProjection;
+
+    private final GalleryApp mApplication;
+    private final ContentResolver mResolver;
+    private final int mBucketId;
+    private final String mBucketName;
+    private final boolean mIsImage;
+    private final ChangeNotifier mNotifier;
+    private final Path mItemPath;
+    private int mCachedCount = INVALID_COUNT;
+
+    public LocalAlbum(Path path, GalleryApp application, int bucketId,
+            boolean isImage, String name) {
+        super(path, nextVersionNumber());
+        mApplication = application;
+        mResolver = application.getContentResolver();
+        mBucketId = bucketId;
+        mBucketName = name;
+        mIsImage = isImage;
+
+        if (isImage) {
+            mWhereClause = ImageColumns.BUCKET_ID + " = ?";
+            mOrderClause = ImageColumns.DATE_TAKEN + " DESC, "
+                    + ImageColumns._ID + " DESC";
+            mBaseUri = Images.Media.EXTERNAL_CONTENT_URI;
+            mProjection = LocalImage.PROJECTION;
+            mItemPath = LocalImage.ITEM_PATH;
+        } else {
+            mWhereClause = VideoColumns.BUCKET_ID + " = ?";
+            mOrderClause = VideoColumns.DATE_TAKEN + " DESC, "
+                    + VideoColumns._ID + " DESC";
+            mBaseUri = Video.Media.EXTERNAL_CONTENT_URI;
+            mProjection = LocalVideo.PROJECTION;
+            mItemPath = LocalVideo.ITEM_PATH;
+        }
+
+        mNotifier = new ChangeNotifier(this, mBaseUri, application);
+    }
+
+    public LocalAlbum(Path path, GalleryApp application, int bucketId,
+            boolean isImage) {
+        this(path, application, bucketId, isImage,
+                LocalAlbumSet.getBucketName(application.getContentResolver(),
+                bucketId));
+    }
+
+    @Override
+    public ArrayList<MediaItem> getMediaItem(int start, int count) {
+        DataManager dataManager = mApplication.getDataManager();
+        Uri uri = mBaseUri.buildUpon()
+                .appendQueryParameter("limit", start + "," + count).build();
+        ArrayList<MediaItem> list = new ArrayList<MediaItem>();
+        GalleryUtils.assertNotInRenderThread();
+        Cursor cursor = mResolver.query(
+                uri, mProjection, mWhereClause,
+                new String[]{String.valueOf(mBucketId)},
+                mOrderClause);
+        if (cursor == null) {
+            Log.w(TAG, "query fail: " + uri);
+            return list;
+        }
+
+        try {
+            while (cursor.moveToNext()) {
+                int id = cursor.getInt(0);  // _id must be in the first column
+                Path childPath = mItemPath.getChild(id);
+                MediaItem item = loadOrUpdateItem(childPath, cursor,
+                        dataManager, mApplication, mIsImage);
+                list.add(item);
+            }
+        } finally {
+            cursor.close();
+        }
+        return list;
+    }
+
+    private static MediaItem loadOrUpdateItem(Path path, Cursor cursor,
+            DataManager dataManager, GalleryApp app, boolean isImage) {
+        LocalMediaItem item = (LocalMediaItem) dataManager.peekMediaObject(path);
+        if (item == null) {
+            if (isImage) {
+                item = new LocalImage(path, app, cursor);
+            } else {
+                item = new LocalVideo(path, app, cursor);
+            }
+        } else {
+            item.updateContent(cursor);
+        }
+        return item;
+    }
+
+    // The pids array are sorted by the (path) id.
+    public static MediaItem[] getMediaItemById(
+            GalleryApp application, boolean isImage, ArrayList<Integer> ids) {
+        // get the lower and upper bound of (path) id
+        MediaItem[] result = new MediaItem[ids.size()];
+        if (ids.isEmpty()) return result;
+        int idLow = ids.get(0);
+        int idHigh = ids.get(ids.size() - 1);
+
+        // prepare the query parameters
+        Uri baseUri;
+        String[] projection;
+        Path itemPath;
+        if (isImage) {
+            baseUri = Images.Media.EXTERNAL_CONTENT_URI;
+            projection = LocalImage.PROJECTION;
+            itemPath = LocalImage.ITEM_PATH;
+        } else {
+            baseUri = Video.Media.EXTERNAL_CONTENT_URI;
+            projection = LocalVideo.PROJECTION;
+            itemPath = LocalVideo.ITEM_PATH;
+        }
+
+        ContentResolver resolver = application.getContentResolver();
+        DataManager dataManager = application.getDataManager();
+        Cursor cursor = resolver.query(baseUri, projection, "_id BETWEEN ? AND ?",
+                new String[]{String.valueOf(idLow), String.valueOf(idHigh)},
+                "_id");
+        if (cursor == null) {
+            Log.w(TAG, "query fail" + baseUri);
+            return result;
+        }
+        try {
+            int n = ids.size();
+            int i = 0;
+
+            while (i < n && cursor.moveToNext()) {
+                int id = cursor.getInt(0);  // _id must be in the first column
+
+                // Match id with the one on the ids list.
+                if (ids.get(i) > id) {
+                    continue;
+                }
+
+                while (ids.get(i) < id) {
+                    if (++i >= n) {
+                        return result;
+                    }
+                }
+
+                Path childPath = itemPath.getChild(id);
+                MediaItem item = loadOrUpdateItem(childPath, cursor, dataManager,
+                        application, isImage);
+                result[i] = item;
+                ++i;
+            }
+            return result;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    public static Cursor getItemCursor(ContentResolver resolver, Uri uri,
+            String[] projection, int id) {
+        return resolver.query(uri, projection, "_id=?",
+                new String[]{String.valueOf(id)}, null);
+    }
+
+    @Override
+    public int getMediaItemCount() {
+        if (mCachedCount == INVALID_COUNT) {
+            Cursor cursor = mResolver.query(
+                    mBaseUri, COUNT_PROJECTION, mWhereClause,
+                    new String[]{String.valueOf(mBucketId)}, null);
+            if (cursor == null) {
+                Log.w(TAG, "query fail");
+                return 0;
+            }
+            try {
+                Utils.assertTrue(cursor.moveToNext());
+                mCachedCount = cursor.getInt(0);
+            } finally {
+                cursor.close();
+            }
+        }
+        return mCachedCount;
+    }
+
+    @Override
+    public String getName() {
+        return mBucketName;
+    }
+
+    @Override
+    public long reload() {
+        if (mNotifier.isDirty()) {
+            mDataVersion = nextVersionNumber();
+            mCachedCount = INVALID_COUNT;
+        }
+        return mDataVersion;
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        return SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_INFO;
+    }
+
+    @Override
+    public void delete() {
+        GalleryUtils.assertNotInRenderThread();
+        mResolver.delete(mBaseUri, mWhereClause,
+                new String[]{String.valueOf(mBucketId)});
+    }
+
+    @Override
+    public boolean isLeafAlbum() {
+        return true;
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocalAlbumSet.java b/src/com/android/gallery3d/data/LocalAlbumSet.java
new file mode 100644
index 0000000..60bef9a
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalAlbumSet.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.MediaSetUtils;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.MediaStore.Files;
+import android.provider.MediaStore.Files.FileColumns;
+import android.provider.MediaStore.Images;
+import android.provider.MediaStore.Images.ImageColumns;
+import android.provider.MediaStore.Video;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+
+// LocalAlbumSet lists all image or video albums in the local storage.
+// The path should be "/local/image", "local/video" or "/local/all"
+public class LocalAlbumSet extends MediaSet {
+    public static final Path PATH_ALL = Path.fromString("/local/all");
+    public static final Path PATH_IMAGE = Path.fromString("/local/image");
+    public static final Path PATH_VIDEO = Path.fromString("/local/video");
+
+    private static final String TAG = "LocalAlbumSet";
+    private static final String EXTERNAL_MEDIA = "external";
+
+    // The indices should match the following projections.
+    private static final int INDEX_BUCKET_ID = 0;
+    private static final int INDEX_MEDIA_TYPE = 1;
+    private static final int INDEX_BUCKET_NAME = 2;
+
+    private static final Uri mBaseUri = Files.getContentUri(EXTERNAL_MEDIA);
+    private static final Uri mWatchUriImage = Images.Media.EXTERNAL_CONTENT_URI;
+    private static final Uri mWatchUriVideo = Video.Media.EXTERNAL_CONTENT_URI;
+
+    // The order is import it must match to the index in MediaStore.
+    private static final String[] PROJECTION_BUCKET = {
+            ImageColumns.BUCKET_ID,
+            FileColumns.MEDIA_TYPE,
+            ImageColumns.BUCKET_DISPLAY_NAME };
+
+    private final GalleryApp mApplication;
+    private final int mType;
+    private ArrayList<MediaSet> mAlbums = new ArrayList<MediaSet>();
+    private final ChangeNotifier mNotifierImage;
+    private final ChangeNotifier mNotifierVideo;
+    private final String mName;
+
+    public LocalAlbumSet(Path path, GalleryApp application) {
+        super(path, nextVersionNumber());
+        mApplication = application;
+        mType = getTypeFromPath(path);
+        mNotifierImage = new ChangeNotifier(this, mWatchUriImage, application);
+        mNotifierVideo = new ChangeNotifier(this, mWatchUriVideo, application);
+        mName = application.getResources().getString(
+                R.string.set_label_local_albums);
+    }
+
+    private static int getTypeFromPath(Path path) {
+        String name[] = path.split();
+        if (name.length < 2) {
+            throw new IllegalArgumentException(path.toString());
+        }
+        if ("all".equals(name[1])) return MEDIA_TYPE_ALL;
+        if ("image".equals(name[1])) return MEDIA_TYPE_IMAGE;
+        if ("video".equals(name[1])) return MEDIA_TYPE_VIDEO;
+        throw new IllegalArgumentException(path.toString());
+    }
+
+    @Override
+    public MediaSet getSubMediaSet(int index) {
+        return mAlbums.get(index);
+    }
+
+    @Override
+    public int getSubMediaSetCount() {
+        return mAlbums.size();
+    }
+
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    private BucketEntry[] loadBucketEntries(Cursor cursor) {
+        HashSet<BucketEntry> buffer = new HashSet<BucketEntry>();
+        int typeBits = 0;
+        if ((mType & MEDIA_TYPE_IMAGE) != 0) {
+            typeBits |= (1 << FileColumns.MEDIA_TYPE_IMAGE);
+        }
+        if ((mType & MEDIA_TYPE_VIDEO) != 0) {
+            typeBits |= (1 << FileColumns.MEDIA_TYPE_VIDEO);
+        }
+        try {
+            while (cursor.moveToNext()) {
+                if ((typeBits & (1 << cursor.getInt(INDEX_MEDIA_TYPE))) != 0) {
+                    buffer.add(new BucketEntry(
+                            cursor.getInt(INDEX_BUCKET_ID),
+                            cursor.getString(INDEX_BUCKET_NAME)));
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+        return buffer.toArray(new BucketEntry[buffer.size()]);
+    }
+
+
+    private static int findBucket(BucketEntry entries[], int bucketId) {
+        for (int i = 0, n = entries.length; i < n ; ++i) {
+            if (entries[i].bucketId == bucketId) return i;
+        }
+        return -1;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected ArrayList<MediaSet> loadSubMediaSets() {
+        // Note: it will be faster if we only select media_type and bucket_id.
+        //       need to test the performance if that is worth
+
+        Uri uri = mBaseUri.buildUpon().
+                appendQueryParameter("distinct", "true").build();
+        GalleryUtils.assertNotInRenderThread();
+        Cursor cursor = mApplication.getContentResolver().query(
+                uri, PROJECTION_BUCKET, null, null, null);
+        if (cursor == null) {
+            Log.w(TAG, "cannot open local database: " + uri);
+            return new ArrayList<MediaSet>();
+        }
+        BucketEntry[] entries = loadBucketEntries(cursor);
+        int offset = 0;
+
+        int index = findBucket(entries, MediaSetUtils.CAMERA_BUCKET_ID);
+        if (index != -1) {
+            Utils.swap(entries, index, offset++);
+        }
+        index = findBucket(entries, MediaSetUtils.DOWNLOAD_BUCKET_ID);
+        if (index != -1) {
+            Utils.swap(entries, index, offset++);
+        }
+
+        Arrays.sort(entries, offset, entries.length, new Comparator<BucketEntry>() {
+            @Override
+            public int compare(BucketEntry a, BucketEntry b) {
+                int result = a.bucketName.compareTo(b.bucketName);
+                return result != 0
+                        ? result
+                        : Utils.compare(a.bucketId, b.bucketId);
+            }
+        });
+        ArrayList<MediaSet> albums = new ArrayList<MediaSet>();
+        DataManager dataManager = mApplication.getDataManager();
+        for (BucketEntry entry : entries) {
+            albums.add(getLocalAlbum(dataManager,
+                    mType, mPath, entry.bucketId, entry.bucketName));
+        }
+        for (int i = 0, n = albums.size(); i < n; ++i) {
+            albums.get(i).reload();
+        }
+        return albums;
+    }
+
+    private MediaSet getLocalAlbum(
+            DataManager manager, int type, Path parent, int id, String name) {
+        Path path = parent.getChild(id);
+        MediaObject object = manager.peekMediaObject(path);
+        if (object != null) return (MediaSet) object;
+        switch (type) {
+            case MEDIA_TYPE_IMAGE:
+                return new LocalAlbum(path, mApplication, id, true, name);
+            case MEDIA_TYPE_VIDEO:
+                return new LocalAlbum(path, mApplication, id, false, name);
+            case MEDIA_TYPE_ALL:
+                Comparator<MediaItem> comp = DataManager.sDateTakenComparator;
+                return new LocalMergeAlbum(path, comp, new MediaSet[] {
+                        getLocalAlbum(manager, MEDIA_TYPE_IMAGE, PATH_IMAGE, id, name),
+                        getLocalAlbum(manager, MEDIA_TYPE_VIDEO, PATH_VIDEO, id, name)});
+        }
+        throw new IllegalArgumentException(String.valueOf(type));
+    }
+
+    public static String getBucketName(ContentResolver resolver, int bucketId) {
+        Uri uri = mBaseUri.buildUpon()
+                .appendQueryParameter("limit", "1")
+                .build();
+
+        Cursor cursor = resolver.query(
+                uri, PROJECTION_BUCKET, "bucket_id = ?",
+                new String[]{String.valueOf(bucketId)}, null);
+
+        if (cursor == null) {
+            Log.w(TAG, "query fail: " + uri);
+            return "";
+        }
+        try {
+            return cursor.moveToNext()
+                    ? cursor.getString(INDEX_BUCKET_NAME)
+                    : "";
+        } finally {
+            cursor.close();
+        }
+    }
+
+    @Override
+    public long reload() {
+        // "|" is used instead of "||" because we want to clear both flags.
+        if (mNotifierImage.isDirty() | mNotifierVideo.isDirty()) {
+            mDataVersion = nextVersionNumber();
+            mAlbums = loadSubMediaSets();
+        }
+        return mDataVersion;
+    }
+
+    // For debug only. Fake there is a ContentObserver.onChange() event.
+    void fakeChange() {
+        mNotifierImage.fakeChange();
+        mNotifierVideo.fakeChange();
+    }
+
+    private static class BucketEntry {
+        public String bucketName;
+        public int bucketId;
+
+        public BucketEntry(int id, String name) {
+            bucketId = id;
+            bucketName = Utils.ensureNotNull(name);
+        }
+
+        @Override
+        public int hashCode() {
+            return bucketId;
+        }
+
+        @Override
+        public boolean equals(Object object) {
+            if (!(object instanceof BucketEntry)) return false;
+            BucketEntry entry = (BucketEntry) object;
+            return bucketId == entry.bucketId;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java
new file mode 100644
index 0000000..f3dedf0
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalImage.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.util.UpdateHelper;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.media.ExifInterface;
+import android.net.Uri;
+import android.provider.MediaStore.Images;
+import android.provider.MediaStore.Images.ImageColumns;
+
+import java.io.File;
+import java.io.IOException;
+
+// LocalImage represents an image in the local storage.
+public class LocalImage extends LocalMediaItem {
+    private static final int THUMBNAIL_TARGET_SIZE = 640;
+    private static final int MICROTHUMBNAIL_TARGET_SIZE = 200;
+
+    private static final String TAG = "LocalImage";
+
+    static final Path ITEM_PATH = Path.fromString("/local/image/item");
+
+    // Must preserve order between these indices and the order of the terms in
+    // the following PROJECTION array.
+    private static final int INDEX_ID = 0;
+    private static final int INDEX_CAPTION = 1;
+    private static final int INDEX_MIME_TYPE = 2;
+    private static final int INDEX_LATITUDE = 3;
+    private static final int INDEX_LONGITUDE = 4;
+    private static final int INDEX_DATE_TAKEN = 5;
+    private static final int INDEX_DATE_ADDED = 6;
+    private static final int INDEX_DATE_MODIFIED = 7;
+    private static final int INDEX_DATA = 8;
+    private static final int INDEX_ORIENTATION = 9;
+    private static final int INDEX_BUCKET_ID = 10;
+    private static final int INDEX_SIZE_ID = 11;
+
+    static final String[] PROJECTION =  {
+            ImageColumns._ID,           // 0
+            ImageColumns.TITLE,         // 1
+            ImageColumns.MIME_TYPE,     // 2
+            ImageColumns.LATITUDE,      // 3
+            ImageColumns.LONGITUDE,     // 4
+            ImageColumns.DATE_TAKEN,    // 5
+            ImageColumns.DATE_ADDED,    // 6
+            ImageColumns.DATE_MODIFIED, // 7
+            ImageColumns.DATA,          // 8
+            ImageColumns.ORIENTATION,   // 9
+            ImageColumns.BUCKET_ID,     // 10
+            ImageColumns.SIZE           // 11
+    };
+
+    private final GalleryApp mApplication;
+
+    public int rotation;
+
+    public LocalImage(Path path, GalleryApp application, Cursor cursor) {
+        super(path, nextVersionNumber());
+        mApplication = application;
+        loadFromCursor(cursor);
+    }
+
+    public LocalImage(Path path, GalleryApp application, int id) {
+        super(path, nextVersionNumber());
+        mApplication = application;
+        ContentResolver resolver = mApplication.getContentResolver();
+        Uri uri = Images.Media.EXTERNAL_CONTENT_URI;
+        Cursor cursor = LocalAlbum.getItemCursor(resolver, uri, PROJECTION, id);
+        if (cursor == null) {
+            throw new RuntimeException("cannot get cursor for: " + path);
+        }
+        try {
+            if (cursor.moveToNext()) {
+                loadFromCursor(cursor);
+            } else {
+                throw new RuntimeException("cannot find data for: " + path);
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private void loadFromCursor(Cursor cursor) {
+        id = cursor.getInt(INDEX_ID);
+        caption = cursor.getString(INDEX_CAPTION);
+        mimeType = cursor.getString(INDEX_MIME_TYPE);
+        latitude = cursor.getDouble(INDEX_LATITUDE);
+        longitude = cursor.getDouble(INDEX_LONGITUDE);
+        dateTakenInMs = cursor.getLong(INDEX_DATE_TAKEN);
+        filePath = cursor.getString(INDEX_DATA);
+        rotation = cursor.getInt(INDEX_ORIENTATION);
+        bucketId = cursor.getInt(INDEX_BUCKET_ID);
+        fileSize = cursor.getLong(INDEX_SIZE_ID);
+    }
+
+    @Override
+    protected boolean updateFromCursor(Cursor cursor) {
+        UpdateHelper uh = new UpdateHelper();
+        id = uh.update(id, cursor.getInt(INDEX_ID));
+        caption = uh.update(caption, cursor.getString(INDEX_CAPTION));
+        mimeType = uh.update(mimeType, cursor.getString(INDEX_MIME_TYPE));
+        latitude = uh.update(latitude, cursor.getDouble(INDEX_LATITUDE));
+        longitude = uh.update(longitude, cursor.getDouble(INDEX_LONGITUDE));
+        dateTakenInMs = uh.update(
+                dateTakenInMs, cursor.getLong(INDEX_DATE_TAKEN));
+        dateAddedInSec = uh.update(
+                dateAddedInSec, cursor.getLong(INDEX_DATE_ADDED));
+        dateModifiedInSec = uh.update(
+                dateModifiedInSec, cursor.getLong(INDEX_DATE_MODIFIED));
+        filePath = uh.update(filePath, cursor.getString(INDEX_DATA));
+        rotation = uh.update(rotation, cursor.getInt(INDEX_ORIENTATION));
+        bucketId = uh.update(bucketId, cursor.getInt(INDEX_BUCKET_ID));
+        fileSize = uh.update(fileSize, cursor.getLong(INDEX_SIZE_ID));
+        return uh.isUpdated();
+    }
+
+    @Override
+    public Job<Bitmap> requestImage(int type) {
+        return new LocalImageRequest(mApplication, mPath, type, filePath);
+    }
+
+    public static class LocalImageRequest extends ImageCacheRequest {
+        private String mLocalFilePath;
+
+        LocalImageRequest(GalleryApp application, Path path, int type,
+                String localFilePath) {
+            super(application, path, type, getTargetSize(type));
+            mLocalFilePath = localFilePath;
+        }
+
+        @Override
+        public Bitmap onDecodeOriginal(JobContext jc, int type) {
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+            return DecodeUtils.requestDecode(
+                    jc, mLocalFilePath, options, getTargetSize(type));
+        }
+    }
+
+    static int getTargetSize(int type) {
+        switch (type) {
+            case TYPE_THUMBNAIL:
+                return THUMBNAIL_TARGET_SIZE;
+            case TYPE_MICROTHUMBNAIL:
+                return MICROTHUMBNAIL_TARGET_SIZE;
+            default:
+                throw new RuntimeException(
+                    "should only request thumb/microthumb from cache");
+        }
+    }
+
+    @Override
+    public Job<BitmapRegionDecoder> requestLargeImage() {
+        return new LocalLargeImageRequest(filePath);
+    }
+
+    public static class LocalLargeImageRequest
+            implements Job<BitmapRegionDecoder> {
+        String mLocalFilePath;
+
+        public LocalLargeImageRequest(String localFilePath) {
+            mLocalFilePath = localFilePath;
+        }
+
+        public BitmapRegionDecoder run(JobContext jc) {
+            return DecodeUtils.requestCreateBitmapRegionDecoder(
+                    jc, mLocalFilePath, false);
+        }
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        int operation = SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_CROP
+                | SUPPORT_SETAS | SUPPORT_EDIT | SUPPORT_INFO;
+        if (BitmapUtils.isSupportedByRegionDecoder(mimeType)) {
+            operation |= SUPPORT_FULL_IMAGE;
+        }
+
+        if (BitmapUtils.isRotationSupported(mimeType)) {
+            operation |= SUPPORT_ROTATE;
+        }
+
+        if (GalleryUtils.isValidLocation(latitude, longitude)) {
+            operation |= SUPPORT_SHOW_ON_MAP;
+        }
+        return operation;
+    }
+
+    @Override
+    public void delete() {
+        GalleryUtils.assertNotInRenderThread();
+        Uri baseUri = Images.Media.EXTERNAL_CONTENT_URI;
+        mApplication.getContentResolver().delete(baseUri, "_id=?",
+                new String[]{String.valueOf(id)});
+    }
+
+    private static String getExifOrientation(int orientation) {
+        switch (orientation) {
+            case 0:
+                return String.valueOf(ExifInterface.ORIENTATION_NORMAL);
+            case 90:
+                return String.valueOf(ExifInterface.ORIENTATION_ROTATE_90);
+            case 180:
+                return String.valueOf(ExifInterface.ORIENTATION_ROTATE_180);
+            case 270:
+                return String.valueOf(ExifInterface.ORIENTATION_ROTATE_270);
+            default:
+                throw new AssertionError("invalid: " + orientation);
+        }
+    }
+
+    @Override
+    public void rotate(int degrees) {
+        GalleryUtils.assertNotInRenderThread();
+        Uri baseUri = Images.Media.EXTERNAL_CONTENT_URI;
+        ContentValues values = new ContentValues();
+        int rotation = (this.rotation + degrees) % 360;
+        if (rotation < 0) rotation += 360;
+
+        if (mimeType.equalsIgnoreCase("image/jpeg")) {
+            try {
+                ExifInterface exif = new ExifInterface(filePath);
+                exif.setAttribute(ExifInterface.TAG_ORIENTATION,
+                        getExifOrientation(rotation));
+                exif.saveAttributes();
+            } catch (IOException e) {
+                Log.w(TAG, "cannot set exif data: " + filePath);
+            }
+
+            // We need to update the filesize as well
+            fileSize = new File(filePath).length();
+            values.put(Images.Media.SIZE, fileSize);
+        }
+
+        values.put(Images.Media.ORIENTATION, rotation);
+        mApplication.getContentResolver().update(baseUri, values, "_id=?",
+                new String[]{String.valueOf(id)});
+    }
+
+    @Override
+    public Uri getContentUri() {
+        Uri baseUri = Images.Media.EXTERNAL_CONTENT_URI;
+        return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
+    }
+
+    @Override
+    public int getMediaType() {
+        return MEDIA_TYPE_IMAGE;
+    }
+
+    @Override
+    public MediaDetails getDetails() {
+        MediaDetails details = super.getDetails();
+        details.addDetail(MediaDetails.INDEX_ORIENTATION, Integer.valueOf(rotation));
+        MediaDetails.extractExifInfo(details, filePath);
+        return details;
+    }
+
+    @Override
+    public int getRotation() {
+        return rotation;
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocalMediaItem.java b/src/com/android/gallery3d/data/LocalMediaItem.java
new file mode 100644
index 0000000..a76fedf
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalMediaItem.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.database.Cursor;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+//
+// LocalMediaItem is an abstract class captures those common fields
+// in LocalImage and LocalVideo.
+//
+public abstract class LocalMediaItem extends MediaItem {
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "LocalMediaItem";
+
+    // database fields
+    public int id;
+    public String caption;
+    public String mimeType;
+    public long fileSize;
+    public double latitude = INVALID_LATLNG;
+    public double longitude = INVALID_LATLNG;
+    public long dateTakenInMs;
+    public long dateAddedInSec;
+    public long dateModifiedInSec;
+    public String filePath;
+    public int bucketId;
+
+    public LocalMediaItem(Path path, long version) {
+        super(path, version);
+    }
+
+    @Override
+    public long getDateInMs() {
+        return dateTakenInMs;
+    }
+
+    @Override
+    public String getName() {
+        return caption;
+    }
+
+    @Override
+    public void getLatLong(double[] latLong) {
+        latLong[0] = latitude;
+        latLong[1] = longitude;
+    }
+
+    abstract protected boolean updateFromCursor(Cursor cursor);
+
+    public int getBucketId() {
+        return bucketId;
+    }
+
+    protected void updateContent(Cursor cursor) {
+        if (updateFromCursor(cursor)) {
+            mDataVersion = nextVersionNumber();
+        }
+    }
+
+    @Override
+    public MediaDetails getDetails() {
+        MediaDetails details = super.getDetails();
+        details.addDetail(MediaDetails.INDEX_PATH, filePath);
+        details.addDetail(MediaDetails.INDEX_TITLE, caption);
+        DateFormat formater = DateFormat.getDateTimeInstance();
+        details.addDetail(MediaDetails.INDEX_DATETIME, formater.format(new Date(dateTakenInMs)));
+
+        if (GalleryUtils.isValidLocation(latitude, longitude)) {
+            details.addDetail(MediaDetails.INDEX_LOCATION, new double[] {latitude, longitude});
+        }
+        if (fileSize > 0) details.addDetail(MediaDetails.INDEX_SIZE, fileSize);
+        return details;
+    }
+
+    @Override
+    public String getMimeType() {
+        return mimeType;
+    }
+
+    public long getSize() {
+        return fileSize;
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocalMergeAlbum.java b/src/com/android/gallery3d/data/LocalMergeAlbum.java
new file mode 100644
index 0000000..bb796d5
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalMergeAlbum.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+// MergeAlbum merges items from two or more MediaSets. It uses a Comparator to
+// determine the order of items. The items are assumed to be sorted in the input
+// media sets (with the same order that the Comparator uses).
+//
+// This only handles MediaItems, not SubMediaSets.
+public class LocalMergeAlbum extends MediaSet implements ContentListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "LocalMergeAlbum";
+    private static final int PAGE_SIZE = 64;
+
+    private final Comparator<MediaItem> mComparator;
+    private final MediaSet[] mSources;
+
+    private String mName;
+    private FetchCache[] mFetcher;
+    private int mSupportedOperation;
+
+    // mIndex maps global position to the position of each underlying media sets.
+    private TreeMap<Integer, int[]> mIndex = new TreeMap<Integer, int[]>();
+
+    public LocalMergeAlbum(
+            Path path, Comparator<MediaItem> comparator, MediaSet[] sources) {
+        super(path, INVALID_DATA_VERSION);
+        mComparator = comparator;
+        mSources = sources;
+        mName = sources.length == 0 ? "" : sources[0].getName();
+        for (MediaSet set : mSources) {
+            set.addContentListener(this);
+        }
+    }
+
+    private void updateData() {
+        ArrayList<MediaSet> matches = new ArrayList<MediaSet>();
+        int supported = mSources.length == 0 ? 0 : MediaItem.SUPPORT_ALL;
+        mFetcher = new FetchCache[mSources.length];
+        for (int i = 0, n = mSources.length; i < n; ++i) {
+            mFetcher[i] = new FetchCache(mSources[i]);
+            supported &= mSources[i].getSupportedOperations();
+        }
+        mSupportedOperation = supported;
+        mIndex.clear();
+        mIndex.put(0, new int[mSources.length]);
+        mName = mSources.length == 0 ? "" : mSources[0].getName();
+    }
+
+    private void invalidateCache() {
+        for (int i = 0, n = mSources.length; i < n; i++) {
+            mFetcher[i].invalidate();
+        }
+        mIndex.clear();
+        mIndex.put(0, new int[mSources.length]);
+    }
+
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public int getMediaItemCount() {
+        return getTotalMediaItemCount();
+    }
+
+    @Override
+    public ArrayList<MediaItem> getMediaItem(int start, int count) {
+
+        // First find the nearest mark position <= start.
+        SortedMap<Integer, int[]> head = mIndex.headMap(start + 1);
+        int markPos = head.lastKey();
+        int[] subPos = head.get(markPos).clone();
+        MediaItem[] slot = new MediaItem[mSources.length];
+
+        int size = mSources.length;
+
+        // fill all slots
+        for (int i = 0; i < size; i++) {
+            slot[i] = mFetcher[i].getItem(subPos[i]);
+        }
+
+        ArrayList<MediaItem> result = new ArrayList<MediaItem>();
+
+        for (int i = markPos; i < start + count; i++) {
+            int k = -1;  // k points to the best slot up to now.
+            for (int j = 0; j < size; j++) {
+                if (slot[j] != null) {
+                    if (k == -1 || mComparator.compare(slot[j], slot[k]) < 0) {
+                        k = j;
+                    }
+                }
+            }
+
+            // If we don't have anything, all streams are exhausted.
+            if (k == -1) break;
+
+            // Pick the best slot and refill it.
+            subPos[k]++;
+            if (i >= start) {
+                result.add(slot[k]);
+            }
+            slot[k] = mFetcher[k].getItem(subPos[k]);
+
+            // Periodically leave a mark in the index, so we can come back later.
+            if ((i + 1) % PAGE_SIZE == 0) {
+                mIndex.put(i + 1, subPos.clone());
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public int getTotalMediaItemCount() {
+        int count = 0;
+        for (MediaSet set : mSources) {
+            count += set.getTotalMediaItemCount();
+        }
+        return count;
+    }
+
+    @Override
+    public long reload() {
+        boolean changed = false;
+        for (int i = 0, n = mSources.length; i < n; ++i) {
+            if (mSources[i].reload() > mDataVersion) changed = true;
+        }
+        if (changed) {
+            mDataVersion = nextVersionNumber();
+            updateData();
+            invalidateCache();
+        }
+        return mDataVersion;
+    }
+
+    @Override
+    public void onContentDirty() {
+        notifyContentChanged();
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        return mSupportedOperation;
+    }
+
+    @Override
+    public void delete() {
+        for (MediaSet set : mSources) {
+            set.delete();
+        }
+    }
+
+    @Override
+    public void rotate(int degrees) {
+        for (MediaSet set : mSources) {
+            set.rotate(degrees);
+        }
+    }
+
+    private static class FetchCache {
+        private MediaSet mBaseSet;
+        private SoftReference<ArrayList<MediaItem>> mCacheRef;
+        private int mStartPos;
+
+        public FetchCache(MediaSet baseSet) {
+            mBaseSet = baseSet;
+        }
+
+        public void invalidate() {
+            mCacheRef = null;
+        }
+
+        public MediaItem getItem(int index) {
+            boolean needLoading = false;
+            ArrayList<MediaItem> cache = null;
+            if (mCacheRef == null
+                    || index < mStartPos || index >= mStartPos + PAGE_SIZE) {
+                needLoading = true;
+            } else {
+                cache = mCacheRef.get();
+                if (cache == null) {
+                    needLoading = true;
+                }
+            }
+
+            if (needLoading) {
+                cache = mBaseSet.getMediaItem(index, PAGE_SIZE);
+                mCacheRef = new SoftReference<ArrayList<MediaItem>>(cache);
+                mStartPos = index;
+            }
+
+            if (index < mStartPos || index >= mStartPos + cache.size()) {
+                return null;
+            }
+
+            return cache.get(index - mStartPos);
+        }
+    }
+
+    @Override
+    public boolean isLeafAlbum() {
+        return true;
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocalSource.java b/src/com/android/gallery3d/data/LocalSource.java
new file mode 100644
index 0000000..58ac224
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalSource.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.Gallery;
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.data.MediaSet.ItemConsumer;
+
+import android.content.ContentProviderClient;
+import android.content.ContentUris;
+import android.content.UriMatcher;
+import android.net.Uri;
+import android.provider.MediaStore;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+class LocalSource extends MediaSource {
+
+    public static final String KEY_BUCKET_ID = "bucketId";
+
+    private GalleryApp mApplication;
+    private PathMatcher mMatcher;
+    private static final int NO_MATCH = -1;
+    private final UriMatcher mUriMatcher = new UriMatcher(NO_MATCH);
+    public static final Comparator<PathId> sIdComparator = new IdComparator();
+
+    private static final int LOCAL_IMAGE_ALBUMSET = 0;
+    private static final int LOCAL_VIDEO_ALBUMSET = 1;
+    private static final int LOCAL_IMAGE_ALBUM = 2;
+    private static final int LOCAL_VIDEO_ALBUM = 3;
+    private static final int LOCAL_IMAGE_ITEM = 4;
+    private static final int LOCAL_VIDEO_ITEM = 5;
+    private static final int LOCAL_ALL_ALBUMSET = 6;
+    private static final int LOCAL_ALL_ALBUM = 7;
+
+    private static final String TAG = "LocalSource";
+
+    private ContentProviderClient mClient;
+
+    public LocalSource(GalleryApp context) {
+        super("local");
+        mApplication = context;
+        mMatcher = new PathMatcher();
+        mMatcher.add("/local/image", LOCAL_IMAGE_ALBUMSET);
+        mMatcher.add("/local/video", LOCAL_VIDEO_ALBUMSET);
+        mMatcher.add("/local/all", LOCAL_ALL_ALBUMSET);
+
+        mMatcher.add("/local/image/*", LOCAL_IMAGE_ALBUM);
+        mMatcher.add("/local/video/*", LOCAL_VIDEO_ALBUM);
+        mMatcher.add("/local/all/*", LOCAL_ALL_ALBUM);
+        mMatcher.add("/local/image/item/*", LOCAL_IMAGE_ITEM);
+        mMatcher.add("/local/video/item/*", LOCAL_VIDEO_ITEM);
+
+        mUriMatcher.addURI(MediaStore.AUTHORITY,
+                "external/images/media/#", LOCAL_IMAGE_ITEM);
+        mUriMatcher.addURI(MediaStore.AUTHORITY,
+                "external/video/media/#", LOCAL_VIDEO_ITEM);
+        mUriMatcher.addURI(MediaStore.AUTHORITY,
+                "external/images/media", LOCAL_IMAGE_ALBUM);
+        mUriMatcher.addURI(MediaStore.AUTHORITY,
+                "external/video/media", LOCAL_VIDEO_ALBUM);
+    }
+
+    @Override
+    public MediaObject createMediaObject(Path path) {
+        GalleryApp app = mApplication;
+        switch (mMatcher.match(path)) {
+            case LOCAL_ALL_ALBUMSET:
+            case LOCAL_IMAGE_ALBUMSET:
+            case LOCAL_VIDEO_ALBUMSET:
+                return new LocalAlbumSet(path, mApplication);
+            case LOCAL_IMAGE_ALBUM:
+                return new LocalAlbum(path, app, mMatcher.getIntVar(0), true);
+            case LOCAL_VIDEO_ALBUM:
+                return new LocalAlbum(path, app, mMatcher.getIntVar(0), false);
+            case LOCAL_ALL_ALBUM: {
+                int bucketId = mMatcher.getIntVar(0);
+                DataManager dataManager = app.getDataManager();
+                MediaSet imageSet = (MediaSet) dataManager.getMediaObject(
+                        LocalAlbumSet.PATH_IMAGE.getChild(bucketId));
+                MediaSet videoSet = (MediaSet) dataManager.getMediaObject(
+                        LocalAlbumSet.PATH_VIDEO.getChild(bucketId));
+                Comparator<MediaItem> comp = DataManager.sDateTakenComparator;
+                return new LocalMergeAlbum(
+                        path, comp, new MediaSet[] {imageSet, videoSet});
+            }
+            case LOCAL_IMAGE_ITEM:
+                return new LocalImage(path, mApplication, mMatcher.getIntVar(0));
+            case LOCAL_VIDEO_ITEM:
+                return new LocalVideo(path, mApplication, mMatcher.getIntVar(0));
+            default:
+                throw new RuntimeException("bad path: " + path);
+        }
+    }
+
+    private static int getMediaType(String type, int defaultType) {
+        if (type == null) return defaultType;
+        try {
+            int value = Integer.parseInt(type);
+            if ((value & (MEDIA_TYPE_IMAGE
+                    | MEDIA_TYPE_VIDEO)) != 0) return value;
+        } catch (NumberFormatException e) {
+            Log.w(TAG, "invalid type: " + type, e);
+        }
+        return defaultType;
+    }
+
+    // The media type bit passed by the intent
+    private static final int MEDIA_TYPE_IMAGE = 1;
+    private static final int MEDIA_TYPE_VIDEO = 4;
+
+    private Path getAlbumPath(Uri uri, int defaultType) {
+        int mediaType = getMediaType(
+                uri.getQueryParameter(Gallery.KEY_MEDIA_TYPES),
+                defaultType);
+        String bucketId = uri.getQueryParameter(KEY_BUCKET_ID);
+        int id = 0;
+        try {
+            id = Integer.parseInt(bucketId);
+        } catch (NumberFormatException e) {
+            Log.w(TAG, "invalid bucket id: " + bucketId, e);
+            return null;
+        }
+        switch (mediaType) {
+            case MEDIA_TYPE_IMAGE:
+                return Path.fromString("/local/image").getChild(id);
+            case MEDIA_TYPE_VIDEO:
+                return Path.fromString("/local/video").getChild(id);
+            default:
+                return Path.fromString("/merge/{/local/image,/local/video}")
+                        .getChild(id);
+        }
+    }
+
+    @Override
+    public Path findPathByUri(Uri uri) {
+        try {
+            switch (mUriMatcher.match(uri)) {
+                case LOCAL_IMAGE_ITEM: {
+                    long id = ContentUris.parseId(uri);
+                    return id >= 0 ? LocalImage.ITEM_PATH.getChild(id) : null;
+                }
+                case LOCAL_VIDEO_ITEM: {
+                    long id = ContentUris.parseId(uri);
+                    return id >= 0 ? LocalVideo.ITEM_PATH.getChild(id) : null;
+                }
+                case LOCAL_IMAGE_ALBUM: {
+                    return getAlbumPath(uri, MEDIA_TYPE_IMAGE);
+                }
+                case LOCAL_VIDEO_ALBUM: {
+                    return getAlbumPath(uri, MEDIA_TYPE_VIDEO);
+                }
+            }
+        } catch (NumberFormatException e) {
+            Log.w(TAG, "uri: " + uri.toString(), e);
+        }
+        return null;
+    }
+
+    @Override
+    public Path getDefaultSetOf(Path item) {
+        MediaObject object = mApplication.getDataManager().getMediaObject(item);
+        if (object instanceof LocalImage) {
+            return Path.fromString("/local/image/").getChild(
+                    String.valueOf(((LocalImage) object).getBucketId()));
+        } else if (object instanceof LocalVideo) {
+            return Path.fromString("/local/video/").getChild(
+                    String.valueOf(((LocalVideo) object).getBucketId()));
+        }
+        return null;
+    }
+
+    @Override
+    public void mapMediaItems(ArrayList<PathId> list, ItemConsumer consumer) {
+        ArrayList<PathId> imageList = new ArrayList<PathId>();
+        ArrayList<PathId> videoList = new ArrayList<PathId>();
+        int n = list.size();
+        for (int i = 0; i < n; i++) {
+            PathId pid = list.get(i);
+            // We assume the form is: "/local/{image,video}/item/#"
+            // We don't use mMatcher for efficiency's reason.
+            Path parent = pid.path.getParent();
+            if (parent == LocalImage.ITEM_PATH) {
+                imageList.add(pid);
+            } else if (parent == LocalVideo.ITEM_PATH) {
+                videoList.add(pid);
+            }
+        }
+        // TODO: use "files" table so we can merge the two cases.
+        processMapMediaItems(imageList, consumer, true);
+        processMapMediaItems(videoList, consumer, false);
+    }
+
+    private void processMapMediaItems(ArrayList<PathId> list,
+            ItemConsumer consumer, boolean isImage) {
+        // Sort path by path id
+        Collections.sort(list, sIdComparator);
+        int n = list.size();
+        for (int i = 0; i < n; ) {
+            PathId pid = list.get(i);
+
+            // Find a range of items.
+            ArrayList<Integer> ids = new ArrayList<Integer>();
+            int startId = Integer.parseInt(pid.path.getSuffix());
+            ids.add(startId);
+
+            int j;
+            for (j = i + 1; j < n; j++) {
+                PathId pid2 = list.get(j);
+                int curId = Integer.parseInt(pid2.path.getSuffix());
+                if (curId - startId >= MediaSet.MEDIAITEM_BATCH_FETCH_COUNT) {
+                    break;
+                }
+                ids.add(curId);
+            }
+
+            MediaItem[] items = LocalAlbum.getMediaItemById(
+                    mApplication, isImage, ids);
+            for(int k = i ; k < j; k++) {
+                PathId pid2 = list.get(k);
+                consumer.consume(pid2.id, items[k - i]);
+            }
+
+            i = j;
+        }
+    }
+
+    // This is a comparator which compares the suffix number in two Paths.
+    private static class IdComparator implements Comparator<PathId> {
+        public int compare(PathId p1, PathId p2) {
+            String s1 = p1.path.getSuffix();
+            String s2 = p2.path.getSuffix();
+            int len1 = s1.length();
+            int len2 = s2.length();
+            if (len1 < len2) {
+                return -1;
+            } else if (len1 > len2) {
+                return 1;
+            } else {
+                return s1.compareTo(s2);
+            }
+        }
+    }
+
+    @Override
+    public void resume() {
+        mClient = mApplication.getContentResolver()
+                .acquireContentProviderClient(MediaStore.AUTHORITY);
+    }
+
+    @Override
+    public void pause() {
+        mClient.release();
+        mClient = null;
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocalVideo.java b/src/com/android/gallery3d/data/LocalVideo.java
new file mode 100644
index 0000000..d1498e8
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocalVideo.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.util.UpdateHelper;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.net.Uri;
+import android.provider.MediaStore.Video;
+import android.provider.MediaStore.Video.VideoColumns;
+
+import java.io.File;
+
+// LocalVideo represents a video in the local storage.
+public class LocalVideo extends LocalMediaItem {
+
+    static final Path ITEM_PATH = Path.fromString("/local/video/item");
+
+    // Must preserve order between these indices and the order of the terms in
+    // the following PROJECTION array.
+    private static final int INDEX_ID = 0;
+    private static final int INDEX_CAPTION = 1;
+    private static final int INDEX_MIME_TYPE = 2;
+    private static final int INDEX_LATITUDE = 3;
+    private static final int INDEX_LONGITUDE = 4;
+    private static final int INDEX_DATE_TAKEN = 5;
+    private static final int INDEX_DATE_ADDED = 6;
+    private static final int INDEX_DATE_MODIFIED = 7;
+    private static final int INDEX_DATA = 8;
+    private static final int INDEX_DURATION = 9;
+    private static final int INDEX_BUCKET_ID = 10;
+    private static final int INDEX_SIZE_ID = 11;
+
+    static final String[] PROJECTION = new String[] {
+            VideoColumns._ID,
+            VideoColumns.TITLE,
+            VideoColumns.MIME_TYPE,
+            VideoColumns.LATITUDE,
+            VideoColumns.LONGITUDE,
+            VideoColumns.DATE_TAKEN,
+            VideoColumns.DATE_ADDED,
+            VideoColumns.DATE_MODIFIED,
+            VideoColumns.DATA,
+            VideoColumns.DURATION,
+            VideoColumns.BUCKET_ID,
+            VideoColumns.SIZE
+    };
+
+    private final GalleryApp mApplication;
+    private static Bitmap sOverlay;
+
+    public int durationInSec;
+
+    public LocalVideo(Path path, GalleryApp application, Cursor cursor) {
+        super(path, nextVersionNumber());
+        mApplication = application;
+        loadFromCursor(cursor);
+    }
+
+    public LocalVideo(Path path, GalleryApp context, int id) {
+        super(path, nextVersionNumber());
+        mApplication = context;
+        ContentResolver resolver = mApplication.getContentResolver();
+        Uri uri = Video.Media.EXTERNAL_CONTENT_URI;
+        Cursor cursor = LocalAlbum.getItemCursor(resolver, uri, PROJECTION, id);
+        if (cursor == null) {
+            throw new RuntimeException("cannot get cursor for: " + path);
+        }
+        try {
+            if (cursor.moveToNext()) {
+                loadFromCursor(cursor);
+            } else {
+                throw new RuntimeException("cannot find data for: " + path);
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private void loadFromCursor(Cursor cursor) {
+        id = cursor.getInt(INDEX_ID);
+        caption = cursor.getString(INDEX_CAPTION);
+        mimeType = cursor.getString(INDEX_MIME_TYPE);
+        latitude = cursor.getDouble(INDEX_LATITUDE);
+        longitude = cursor.getDouble(INDEX_LONGITUDE);
+        dateTakenInMs = cursor.getLong(INDEX_DATE_TAKEN);
+        filePath = cursor.getString(INDEX_DATA);
+        durationInSec = cursor.getInt(INDEX_DURATION) / 1000;
+        bucketId = cursor.getInt(INDEX_BUCKET_ID);
+        fileSize = cursor.getLong(INDEX_SIZE_ID);
+    }
+
+    @Override
+    protected boolean updateFromCursor(Cursor cursor) {
+        UpdateHelper uh = new UpdateHelper();
+        id = uh.update(id, cursor.getInt(INDEX_ID));
+        caption = uh.update(caption, cursor.getString(INDEX_CAPTION));
+        mimeType = uh.update(mimeType, cursor.getString(INDEX_MIME_TYPE));
+        latitude = uh.update(latitude, cursor.getDouble(INDEX_LATITUDE));
+        longitude = uh.update(longitude, cursor.getDouble(INDEX_LONGITUDE));
+        dateTakenInMs = uh.update(
+                dateTakenInMs, cursor.getLong(INDEX_DATE_TAKEN));
+        dateAddedInSec = uh.update(
+                dateAddedInSec, cursor.getLong(INDEX_DATE_ADDED));
+        dateModifiedInSec = uh.update(
+                dateModifiedInSec, cursor.getLong(INDEX_DATE_MODIFIED));
+        filePath = uh.update(filePath, cursor.getString(INDEX_DATA));
+        durationInSec = uh.update(
+                durationInSec, cursor.getInt(INDEX_DURATION) / 1000);
+        bucketId = uh.update(bucketId, cursor.getInt(INDEX_BUCKET_ID));
+        fileSize = uh.update(fileSize, cursor.getLong(INDEX_SIZE_ID));
+        return uh.isUpdated();
+    }
+
+    @Override
+    public Job<Bitmap> requestImage(int type) {
+        return new LocalVideoRequest(mApplication, getPath(), type, filePath);
+    }
+
+    public static class LocalVideoRequest extends ImageCacheRequest {
+        private String mLocalFilePath;
+
+        LocalVideoRequest(GalleryApp application, Path path, int type,
+                String localFilePath) {
+            super(application, path, type, LocalImage.getTargetSize(type));
+            mLocalFilePath = localFilePath;
+        }
+
+        @Override
+        public Bitmap onDecodeOriginal(JobContext jc, int type) {
+            Bitmap bitmap = BitmapUtils.createVideoThumbnail(mLocalFilePath);
+            if (bitmap == null || jc.isCancelled()) return null;
+            return bitmap;
+        }
+    }
+
+    @Override
+    public Job<BitmapRegionDecoder> requestLargeImage() {
+        throw new UnsupportedOperationException("Cannot regquest a large image"
+                + " to a local video!");
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        return SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_PLAY | SUPPORT_INFO;
+    }
+
+    @Override
+    public void delete() {
+        GalleryUtils.assertNotInRenderThread();
+        Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
+        mApplication.getContentResolver().delete(baseUri, "_id=?",
+                new String[]{String.valueOf(id)});
+    }
+
+    @Override
+    public void rotate(int degrees) {
+        // TODO
+    }
+
+    @Override
+    public Uri getContentUri() {
+        Uri baseUri = Video.Media.EXTERNAL_CONTENT_URI;
+        return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
+    }
+
+    @Override
+    public Uri getPlayUri() {
+        return Uri.fromFile(new File(filePath));
+    }
+
+    @Override
+    public int getMediaType() {
+        return MEDIA_TYPE_VIDEO;
+    }
+
+    @Override
+    public MediaDetails getDetails() {
+        MediaDetails details = super.getDetails();
+        int s = durationInSec;
+        if (s > 0) {
+            details.addDetail(MediaDetails.INDEX_DURATION, GalleryUtils.formatDuration(
+                    mApplication.getAndroidContext(), durationInSec));
+        }
+        return details;
+    }
+}
diff --git a/src/com/android/gallery3d/data/LocationClustering.java b/src/com/android/gallery3d/data/LocationClustering.java
new file mode 100644
index 0000000..3cb1399
--- /dev/null
+++ b/src/com/android/gallery3d/data/LocationClustering.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.util.ReverseGeocoder;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.Context;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+class LocationClustering extends Clustering {
+    private static final String TAG = "LocationClustering";
+
+    private static final int MIN_GROUPS = 1;
+    private static final int MAX_GROUPS = 20;
+    private static final int MAX_ITERATIONS = 30;
+
+    // If the total distance change is less than this ratio, stop iterating.
+    private static final float STOP_CHANGE_RATIO = 0.01f;
+    private Context mContext;
+    private ArrayList<ArrayList<SmallItem>> mClusters;
+    private ArrayList<String> mNames;
+    private String mNoLocationString;
+
+    private static class Point {
+        public Point(double lat, double lng) {
+            latRad = Math.toRadians(lat);
+            lngRad = Math.toRadians(lng);
+        }
+        public Point() {}
+        public double latRad, lngRad;
+    }
+
+    private static class SmallItem {
+        Path path;
+        double lat, lng;
+    }
+
+    public LocationClustering(Context context) {
+        mContext = context;
+        mNoLocationString = mContext.getResources().getString(R.string.no_location);
+    }
+
+    @Override
+    public void run(MediaSet baseSet) {
+        final int total = baseSet.getTotalMediaItemCount();
+        final SmallItem[] buf = new SmallItem[total];
+        // Separate items to two sets: with or without lat-long.
+        final double[] latLong = new double[2];
+        baseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                if (index < 0 || index >= total) return;
+                SmallItem s = new SmallItem();
+                s.path = item.getPath();
+                item.getLatLong(latLong);
+                s.lat = latLong[0];
+                s.lng = latLong[1];
+                buf[index] = s;
+            }
+        });
+
+        final ArrayList<SmallItem> withLatLong = new ArrayList<SmallItem>();
+        final ArrayList<SmallItem> withoutLatLong = new ArrayList<SmallItem>();
+        final ArrayList<Point> points = new ArrayList<Point>();
+        for (int i = 0; i < total; i++) {
+            SmallItem s = buf[i];
+            if (s == null) continue;
+            if (GalleryUtils.isValidLocation(s.lat, s.lng)) {
+                withLatLong.add(s);
+                points.add(new Point(s.lat, s.lng));
+            } else {
+                withoutLatLong.add(s);
+            }
+        }
+
+        ArrayList<ArrayList<SmallItem>> clusters = new ArrayList<ArrayList<SmallItem>>();
+
+        int m = withLatLong.size();
+        if (m > 0) {
+            // cluster the items with lat-long
+            Point[] pointsArray = new Point[m];
+            pointsArray = points.toArray(pointsArray);
+            int[] bestK = new int[1];
+            int[] index = kMeans(pointsArray, bestK);
+
+            for (int i = 0; i < bestK[0]; i++) {
+                clusters.add(new ArrayList<SmallItem>());
+            }
+
+            for (int i = 0; i < m; i++) {
+                clusters.get(index[i]).add(withLatLong.get(i));
+            }
+        }
+
+        ReverseGeocoder geocoder = new ReverseGeocoder(mContext);
+        mNames = new ArrayList<String>();
+        boolean hasUnresolvedAddress = false;
+        mClusters = new ArrayList<ArrayList<SmallItem>>();
+        for (ArrayList<SmallItem> cluster : clusters) {
+            String name = generateName(cluster, geocoder);
+            if (name != null) {
+                mNames.add(name);
+                mClusters.add(cluster);
+            } else {
+                // move cluster-i to no location cluster
+                withoutLatLong.addAll(cluster);
+                hasUnresolvedAddress = true;
+            }
+        }
+
+        if (withoutLatLong.size() > 0) {
+            mNames.add(mNoLocationString);
+            mClusters.add(withoutLatLong);
+        }
+
+        if (hasUnresolvedAddress) {
+            Toast.makeText(mContext, R.string.no_connectivity,
+                    Toast.LENGTH_LONG).show();
+        }
+    }
+
+    private static String generateName(ArrayList<SmallItem> items,
+            ReverseGeocoder geocoder) {
+        ReverseGeocoder.SetLatLong set = new ReverseGeocoder.SetLatLong();
+
+        int n = items.size();
+        for (int i = 0; i < n; i++) {
+            SmallItem item = items.get(i);
+            double itemLatitude = item.lat;
+            double itemLongitude = item.lng;
+
+            if (set.mMinLatLatitude > itemLatitude) {
+                set.mMinLatLatitude = itemLatitude;
+                set.mMinLatLongitude = itemLongitude;
+            }
+            if (set.mMaxLatLatitude < itemLatitude) {
+                set.mMaxLatLatitude = itemLatitude;
+                set.mMaxLatLongitude = itemLongitude;
+            }
+            if (set.mMinLonLongitude > itemLongitude) {
+                set.mMinLonLatitude = itemLatitude;
+                set.mMinLonLongitude = itemLongitude;
+            }
+            if (set.mMaxLonLongitude < itemLongitude) {
+                set.mMaxLonLatitude = itemLatitude;
+                set.mMaxLonLongitude = itemLongitude;
+            }
+        }
+
+        return geocoder.computeAddress(set);
+    }
+
+    @Override
+    public int getNumberOfClusters() {
+        return mClusters.size();
+    }
+
+    @Override
+    public ArrayList<Path> getCluster(int index) {
+        ArrayList<SmallItem> items = mClusters.get(index);
+        ArrayList<Path> result = new ArrayList<Path>(items.size());
+        for (int i = 0, n = items.size(); i < n; i++) {
+            result.add(items.get(i).path);
+        }
+        return result;
+    }
+
+    @Override
+    public String getClusterName(int index) {
+        return mNames.get(index);
+    }
+
+    // Input: n points
+    // Output: the best k is stored in bestK[0], and the return value is the
+    // an array which specifies the group that each point belongs (0 to k - 1).
+    private static int[] kMeans(Point points[], int[] bestK) {
+        int n = points.length;
+
+        // min and max number of groups wanted
+        int minK = Math.min(n, MIN_GROUPS);
+        int maxK = Math.min(n, MAX_GROUPS);
+
+        Point[] center = new Point[maxK];  // center of each group.
+        Point[] groupSum = new Point[maxK];  // sum of points in each group.
+        int[] groupCount = new int[maxK];  // number of points in each group.
+        int[] grouping = new int[n]; // The group assignment for each point.
+
+        for (int i = 0; i < maxK; i++) {
+            center[i] = new Point();
+            groupSum[i] = new Point();
+        }
+
+        // The score we want to minimize is:
+        //   (sum of distance from each point to its group center) * sqrt(k).
+        float bestScore = Float.MAX_VALUE;
+        // The best group assignment up to now.
+        int[] bestGrouping = new int[n];
+        // The best K up to now.
+        bestK[0] = 1;
+
+        float lastDistance = 0;
+        float totalDistance = 0;
+
+        for (int k = minK; k <= maxK; k++) {
+            // step 1: (arbitrarily) pick k points as the initial centers.
+            int delta = n / k;
+            for (int i = 0; i < k; i++) {
+                Point p = points[i * delta];
+                center[i].latRad = p.latRad;
+                center[i].lngRad = p.lngRad;
+            }
+
+            for (int iter = 0; iter < MAX_ITERATIONS; iter++) {
+                // step 2: assign each point to the nearest center.
+                for (int i = 0; i < k; i++) {
+                    groupSum[i].latRad = 0;
+                    groupSum[i].lngRad = 0;
+                    groupCount[i] = 0;
+                }
+                totalDistance = 0;
+
+                for (int i = 0; i < n; i++) {
+                    Point p = points[i];
+                    float bestDistance = Float.MAX_VALUE;
+                    int bestIndex = 0;
+                    for (int j = 0; j < k; j++) {
+                        float distance = (float) GalleryUtils.fastDistanceMeters(
+                                p.latRad, p.lngRad, center[j].latRad, center[j].lngRad);
+                        // We may have small non-zero distance introduced by
+                        // floating point calculation, so zero out small
+                        // distances less than 1 meter.
+                        if (distance < 1) {
+                            distance = 0;
+                        }
+                        if (distance < bestDistance) {
+                            bestDistance = distance;
+                            bestIndex = j;
+                        }
+                    }
+                    grouping[i] = bestIndex;
+                    groupCount[bestIndex]++;
+                    groupSum[bestIndex].latRad += p.latRad;
+                    groupSum[bestIndex].lngRad += p.lngRad;
+                    totalDistance += bestDistance;
+                }
+
+                // step 3: calculate new centers
+                for (int i = 0; i < k; i++) {
+                    if (groupCount[i] > 0) {
+                        center[i].latRad = groupSum[i].latRad / groupCount[i];
+                        center[i].lngRad = groupSum[i].lngRad / groupCount[i];
+                    }
+                }
+
+                if (totalDistance == 0 || (Math.abs(lastDistance - totalDistance)
+                        / totalDistance) < STOP_CHANGE_RATIO) {
+                    break;
+                }
+                lastDistance = totalDistance;
+            }
+
+            // step 4: remove empty groups and reassign group number
+            int reassign[] = new int[k];
+            int realK = 0;
+            for (int i = 0; i < k; i++) {
+                if (groupCount[i] > 0) {
+                    reassign[i] = realK++;
+                }
+            }
+
+            // step 5: calculate the final score
+            float score = totalDistance * (float) Math.sqrt(realK);
+
+            if (score < bestScore) {
+                bestScore = score;
+                bestK[0] = realK;
+                for (int i = 0; i < n; i++) {
+                    bestGrouping[i] = reassign[grouping[i]];
+                }
+                if (score == 0) {
+                    break;
+                }
+            }
+        }
+        return bestGrouping;
+    }
+}
diff --git a/src/com/android/gallery3d/data/Log.java b/src/com/android/gallery3d/data/Log.java
new file mode 100644
index 0000000..3384eb6
--- /dev/null
+++ b/src/com/android/gallery3d/data/Log.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+public class Log {
+    public static int v(String tag, String msg) {
+        return android.util.Log.v(tag, msg);
+    }
+    public static int v(String tag, String msg, Throwable tr) {
+        return android.util.Log.v(tag, msg, tr);
+    }
+    public static int d(String tag, String msg) {
+        return android.util.Log.d(tag, msg);
+    }
+    public static int d(String tag, String msg, Throwable tr) {
+        return android.util.Log.d(tag, msg, tr);
+    }
+    public static int i(String tag, String msg) {
+        return android.util.Log.i(tag, msg);
+    }
+    public static int i(String tag, String msg, Throwable tr) {
+        return android.util.Log.i(tag, msg, tr);
+    }
+    public static int w(String tag, String msg) {
+        return android.util.Log.w(tag, msg);
+    }
+    public static int w(String tag, String msg, Throwable tr) {
+        return android.util.Log.w(tag, msg, tr);
+    }
+    public static int w(String tag, Throwable tr) {
+        return android.util.Log.w(tag, tr);
+    }
+    public static int e(String tag, String msg) {
+        return android.util.Log.e(tag, msg);
+    }
+    public static int e(String tag, String msg, Throwable tr) {
+        return android.util.Log.e(tag, msg, tr);
+    }
+}
diff --git a/src/com/android/gallery3d/data/MediaDetails.java b/src/com/android/gallery3d/data/MediaDetails.java
new file mode 100644
index 0000000..1b56ac4
--- /dev/null
+++ b/src/com/android/gallery3d/data/MediaDetails.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+
+import android.media.ExifInterface;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+public class MediaDetails implements Iterable<Entry<Integer, Object>> {
+    @SuppressWarnings("unused")
+    private static final String TAG = "MediaDetails";
+
+    private TreeMap<Integer, Object> mDetails = new TreeMap<Integer, Object>();
+    private HashMap<Integer, Integer> mUnits = new HashMap<Integer, Integer>();
+
+    public static final int INDEX_TITLE = 1;
+    public static final int INDEX_DESCRIPTION = 2;
+    public static final int INDEX_DATETIME = 3;
+    public static final int INDEX_LOCATION = 4;
+    public static final int INDEX_WIDTH = 5;
+    public static final int INDEX_HEIGHT = 6;
+    public static final int INDEX_ORIENTATION = 7;
+    public static final int INDEX_DURATION = 8;
+    public static final int INDEX_MIMETYPE = 9;
+    public static final int INDEX_SIZE = 10;
+
+    // for EXIF
+    public static final int INDEX_MAKE = 100;
+    public static final int INDEX_MODEL = 101;
+    public static final int INDEX_FLASH = 102;
+    public static final int INDEX_FOCAL_LENGTH = 103;
+    public static final int INDEX_WHITE_BALANCE = 104;
+    public static final int INDEX_APERTURE = 105;
+    public static final int INDEX_SHUTTER_SPEED = 106;
+    public static final int INDEX_EXPOSURE_TIME = 107;
+    public static final int INDEX_ISO = 108;
+
+    // Put this last because it may be long.
+    public static final int INDEX_PATH = 200;
+
+    public static class FlashState {
+        private static int FLASH_FIRED_MASK = 1;
+        private static int FLASH_RETURN_MASK = 2 | 4;
+        private static int FLASH_MODE_MASK = 8 | 16;
+        private static int FLASH_FUNCTION_MASK = 32;
+        private static int FLASH_RED_EYE_MASK = 64;
+        private int mState;
+
+        public FlashState(int state) {
+            mState = state;
+        }
+
+        public boolean isFlashFired() {
+            return (mState & FLASH_FIRED_MASK) != 0;
+        }
+
+        public int getFlashReturn() {
+            return (mState & FLASH_RETURN_MASK) >> 1;
+        }
+
+        public int getFlashMode() {
+            return (mState & FLASH_MODE_MASK) >> 3;
+        }
+
+        public boolean isFlashPresent() {
+            return (mState & FLASH_FUNCTION_MASK) != 0;
+        }
+
+        public boolean isRedEyeModePresent() {
+            return (mState & FLASH_RED_EYE_MASK) != 0;
+        }
+    }
+
+    public void addDetail(int index, Object value) {
+        mDetails.put(index, value);
+    }
+
+    public Object getDetail(int index) {
+        return mDetails.get(index);
+    }
+
+    public int size() {
+        return mDetails.size();
+    }
+
+    public Iterator<Entry<Integer, Object>> iterator() {
+        return mDetails.entrySet().iterator();
+    }
+
+    public void setUnit(int index, int unit) {
+        mUnits.put(index, unit);
+    }
+
+    public boolean hasUnit(int index) {
+        return mUnits.containsKey(index);
+    }
+
+    public int getUnit(int index) {
+        return mUnits.get(index);
+    }
+
+    private static void setExifData(MediaDetails details, ExifInterface exif, String tag,
+            int key) {
+        String value = exif.getAttribute(tag);
+        if (value != null) {
+            if (key == MediaDetails.INDEX_FLASH) {
+                MediaDetails.FlashState state = new MediaDetails.FlashState(
+                        Integer.valueOf(value.toString()));
+                details.addDetail(key, state);
+            } else {
+                details.addDetail(key, value);
+            }
+        }
+    }
+
+    public static void extractExifInfo(MediaDetails details, String filePath) {
+        try {
+            ExifInterface exif = new ExifInterface(filePath);
+            setExifData(details, exif, ExifInterface.TAG_FLASH, MediaDetails.INDEX_FLASH);
+            setExifData(details, exif, ExifInterface.TAG_IMAGE_WIDTH, MediaDetails.INDEX_WIDTH);
+            setExifData(details, exif, ExifInterface.TAG_IMAGE_LENGTH,
+                    MediaDetails.INDEX_HEIGHT);
+            setExifData(details, exif, ExifInterface.TAG_MAKE, MediaDetails.INDEX_MAKE);
+            setExifData(details, exif, ExifInterface.TAG_MODEL, MediaDetails.INDEX_MODEL);
+            setExifData(details, exif, ExifInterface.TAG_APERTURE, MediaDetails.INDEX_APERTURE);
+            setExifData(details, exif, ExifInterface.TAG_ISO, MediaDetails.INDEX_ISO);
+            setExifData(details, exif, ExifInterface.TAG_WHITE_BALANCE,
+                    MediaDetails.INDEX_WHITE_BALANCE);
+            setExifData(details, exif, ExifInterface.TAG_EXPOSURE_TIME,
+                    MediaDetails.INDEX_EXPOSURE_TIME);
+
+            double data = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0);
+            if (data != 0f) {
+                details.addDetail(MediaDetails.INDEX_FOCAL_LENGTH, data);
+                details.setUnit(MediaDetails.INDEX_FOCAL_LENGTH, R.string.unit_mm);
+            }
+        } catch (IOException ex) {
+            // ignore it.
+            Log.w(TAG, "", ex);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/MediaItem.java b/src/com/android/gallery3d/data/MediaItem.java
new file mode 100644
index 0000000..430d832
--- /dev/null
+++ b/src/com/android/gallery3d/data/MediaItem.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.util.ThreadPool.Job;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapRegionDecoder;
+
+// MediaItem represents an image or a video item.
+public abstract class MediaItem extends MediaObject {
+    // NOTE: These type numbers are stored in the image cache, so it should not
+    // not be changed without resetting the cache.
+    public static final int TYPE_THUMBNAIL = 1;
+    public static final int TYPE_MICROTHUMBNAIL = 2;
+
+    public static final int IMAGE_READY = 0;
+    public static final int IMAGE_WAIT = 1;
+    public static final int IMAGE_ERROR = -1;
+
+    // TODO: fix default value for latlng and change this.
+    public static final double INVALID_LATLNG = 0f;
+
+    public abstract Job<Bitmap> requestImage(int type);
+    public abstract Job<BitmapRegionDecoder> requestLargeImage();
+
+    public MediaItem(Path path, long version) {
+        super(path, version);
+    }
+
+    public long getDateInMs() {
+        return 0;
+    }
+
+    public String getName() {
+        return null;
+    }
+
+    public void getLatLong(double[] latLong) {
+        latLong[0] = INVALID_LATLNG;
+        latLong[1] = INVALID_LATLNG;
+    }
+
+    public String[] getTags() {
+        return null;
+    }
+
+    public Face[] getFaces() {
+        return null;
+    }
+
+    public int getRotation() {
+        return 0;
+    }
+
+    public long getSize() {
+        return 0;
+    }
+
+    public abstract String getMimeType();
+}
diff --git a/src/com/android/gallery3d/data/MediaObject.java b/src/com/android/gallery3d/data/MediaObject.java
new file mode 100644
index 0000000..d0f1672
--- /dev/null
+++ b/src/com/android/gallery3d/data/MediaObject.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import android.net.Uri;
+
+public abstract class MediaObject {
+    @SuppressWarnings("unused")
+    private static final String TAG = "MediaObject";
+    public static final long INVALID_DATA_VERSION = -1;
+
+    // These are the bits returned from getSupportedOperations():
+    public static final int SUPPORT_DELETE = 1 << 0;
+    public static final int SUPPORT_ROTATE = 1 << 1;
+    public static final int SUPPORT_SHARE = 1 << 2;
+    public static final int SUPPORT_CROP = 1 << 3;
+    public static final int SUPPORT_SHOW_ON_MAP = 1 << 4;
+    public static final int SUPPORT_SETAS = 1 << 5;
+    public static final int SUPPORT_FULL_IMAGE = 1 << 6;
+    public static final int SUPPORT_PLAY = 1 << 7;
+    public static final int SUPPORT_CACHE = 1 << 8;
+    public static final int SUPPORT_EDIT = 1 << 9;
+    public static final int SUPPORT_INFO = 1 << 10;
+    public static final int SUPPORT_IMPORT = 1 << 11;
+    public static final int SUPPORT_ALL = 0xffffffff;
+
+    // These are the bits returned from getMediaType():
+    public static final int MEDIA_TYPE_UNKNOWN = 1;
+    public static final int MEDIA_TYPE_IMAGE = 2;
+    public static final int MEDIA_TYPE_VIDEO = 4;
+    public static final int MEDIA_TYPE_ALL = MEDIA_TYPE_IMAGE | MEDIA_TYPE_VIDEO;
+
+    // These are flags for cache() and return values for getCacheFlag():
+    public static final int CACHE_FLAG_NO = 0;
+    public static final int CACHE_FLAG_SCREENNAIL = 1;
+    public static final int CACHE_FLAG_FULL = 2;
+
+    // These are return values for getCacheStatus():
+    public static final int CACHE_STATUS_NOT_CACHED = 0;
+    public static final int CACHE_STATUS_CACHING = 1;
+    public static final int CACHE_STATUS_CACHED_SCREENNAIL = 2;
+    public static final int CACHE_STATUS_CACHED_FULL = 3;
+
+    private static long sVersionSerial = 0;
+
+    protected long mDataVersion;
+
+    protected final Path mPath;
+
+    public MediaObject(Path path, long version) {
+        path.setObject(this);
+        mPath = path;
+        mDataVersion = version;
+    }
+
+    public Path getPath() {
+        return mPath;
+    }
+
+    public int getSupportedOperations() {
+        return 0;
+    }
+
+    public void delete() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void rotate(int degrees) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Uri getContentUri() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Uri getPlayUri() {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getMediaType() {
+        return MEDIA_TYPE_UNKNOWN;
+    }
+
+    public boolean Import() {
+        throw new UnsupportedOperationException();
+    }
+
+    public MediaDetails getDetails() {
+        MediaDetails details = new MediaDetails();
+        return details;
+    }
+
+    public long getDataVersion() {
+        return mDataVersion;
+    }
+
+    public int getCacheFlag() {
+        return CACHE_FLAG_NO;
+    }
+
+    public int getCacheStatus() {
+        throw new UnsupportedOperationException();
+    }
+
+    public long getCacheSize() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void cache(int flag) {
+        throw new UnsupportedOperationException();
+    }
+
+    public static synchronized long nextVersionNumber() {
+        return ++MediaObject.sVersionSerial;
+    }
+}
diff --git a/src/com/android/gallery3d/data/MediaSet.java b/src/com/android/gallery3d/data/MediaSet.java
new file mode 100644
index 0000000..99f00a0
--- /dev/null
+++ b/src/com/android/gallery3d/data/MediaSet.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.util.Future;
+
+import java.util.ArrayList;
+import java.util.WeakHashMap;
+
+// MediaSet is a directory-like data structure.
+// It contains MediaItems and sub-MediaSets.
+//
+// The primary interface are:
+// getMediaItemCount(), getMediaItem() and
+// getSubMediaSetCount(), getSubMediaSet().
+//
+// getTotalMediaItemCount() returns the number of all MediaItems, including
+// those in sub-MediaSets.
+public abstract class MediaSet extends MediaObject {
+    public static final int MEDIAITEM_BATCH_FETCH_COUNT = 500;
+    public static final int INDEX_NOT_FOUND = -1;
+
+    public MediaSet(Path path, long version) {
+        super(path, version);
+    }
+
+    public int getMediaItemCount() {
+        return 0;
+    }
+
+    // Returns the media items in the range [start, start + count).
+    //
+    // The number of media items returned may be less than the specified count
+    // if there are not enough media items available. The number of
+    // media items available may not be consistent with the return value of
+    // getMediaItemCount() because the contents of database may have already
+    // changed.
+    public ArrayList<MediaItem> getMediaItem(int start, int count) {
+        return new ArrayList<MediaItem>();
+    }
+
+    public int getSubMediaSetCount() {
+        return 0;
+    }
+
+    public MediaSet getSubMediaSet(int index) {
+        throw new IndexOutOfBoundsException();
+    }
+
+    public boolean isLeafAlbum() {
+        return false;
+    }
+
+    public int getTotalMediaItemCount() {
+        int total = getMediaItemCount();
+        for (int i = 0, n = getSubMediaSetCount(); i < n; i++) {
+            total += getSubMediaSet(i).getTotalMediaItemCount();
+        }
+        return total;
+    }
+
+    // TODO: we should have better implementation of sub classes
+    public int getIndexOfItem(Path path, int hint) {
+        // hint < 0 is handled below
+        // first, try to find it around the hint
+        int start = Math.max(0,
+                hint - MEDIAITEM_BATCH_FETCH_COUNT / 2);
+        ArrayList<MediaItem> list = getMediaItem(
+                start, MEDIAITEM_BATCH_FETCH_COUNT);
+        int index = getIndexOf(path, list);
+        if (index != INDEX_NOT_FOUND) return start + index;
+
+        // try to find it globally
+        start = start == 0 ? MEDIAITEM_BATCH_FETCH_COUNT : 0;
+        list = getMediaItem(start, MEDIAITEM_BATCH_FETCH_COUNT);
+        while (true) {
+            index = getIndexOf(path, list);
+            if (index != INDEX_NOT_FOUND) return start + index;
+            if (list.size() < MEDIAITEM_BATCH_FETCH_COUNT) return INDEX_NOT_FOUND;
+            start += MEDIAITEM_BATCH_FETCH_COUNT;
+            list = getMediaItem(start, MEDIAITEM_BATCH_FETCH_COUNT);
+        }
+    }
+
+    protected int getIndexOf(Path path, ArrayList<MediaItem> list) {
+        for (int i = 0, n = list.size(); i < n; ++i) {
+            if (list.get(i).mPath == path) return i;
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    public abstract String getName();
+
+    private WeakHashMap<ContentListener, Object> mListeners =
+            new WeakHashMap<ContentListener, Object>();
+
+    // NOTE: The MediaSet only keeps a weak reference to the listener. The
+    // listener is automatically removed when there is no other reference to
+    // the listener.
+    public void addContentListener(ContentListener listener) {
+        if (mListeners.containsKey(listener)) {
+            throw new IllegalArgumentException();
+        }
+        mListeners.put(listener, null);
+    }
+
+    public void removeContentListener(ContentListener listener) {
+        if (!mListeners.containsKey(listener)) {
+            throw new IllegalArgumentException();
+        }
+        mListeners.remove(listener);
+    }
+
+    // This should be called by subclasses when the content is changed.
+    public void notifyContentChanged() {
+        for (ContentListener listener : mListeners.keySet()) {
+            listener.onContentDirty();
+        }
+    }
+
+    // Reload the content. Return the current data version. reload() should be called
+    // in the same thread as getMediaItem(int, int) and getSubMediaSet(int).
+    public abstract long reload();
+
+    @Override
+    public MediaDetails getDetails() {
+        MediaDetails details = super.getDetails();
+        details.addDetail(MediaDetails.INDEX_TITLE, getName());
+        return details;
+    }
+
+    // Enumerate all media items in this media set (including the ones in sub
+    // media sets), in an efficient order. ItemConsumer.consumer() will be
+    // called for each media item with its index.
+    public void enumerateMediaItems(ItemConsumer consumer) {
+        enumerateMediaItems(consumer, 0);
+    }
+
+    public void enumerateTotalMediaItems(ItemConsumer consumer) {
+        enumerateTotalMediaItems(consumer, 0);
+    }
+
+    public static interface ItemConsumer {
+        void consume(int index, MediaItem item);
+    }
+
+    // The default implementation uses getMediaItem() for enumerateMediaItems().
+    // Subclasses may override this and use more efficient implementations.
+    // Returns the number of items enumerated.
+    protected int enumerateMediaItems(ItemConsumer consumer, int startIndex) {
+        int total = getMediaItemCount();
+        int start = 0;
+        while (start < total) {
+            int count = Math.min(MEDIAITEM_BATCH_FETCH_COUNT, total - start);
+            ArrayList<MediaItem> items = getMediaItem(start, count);
+            for (int i = 0, n = items.size(); i < n; i++) {
+                MediaItem item = items.get(i);
+                consumer.consume(startIndex + start + i, item);
+            }
+            start += count;
+        }
+        return total;
+    }
+
+    // Recursively enumerate all media items under this set.
+    // Returns the number of items enumerated.
+    protected int enumerateTotalMediaItems(
+            ItemConsumer consumer, int startIndex) {
+        int start = 0;
+        start += enumerateMediaItems(consumer, startIndex);
+        int m = getSubMediaSetCount();
+        for (int i = 0; i < m; i++) {
+            start += getSubMediaSet(i).enumerateTotalMediaItems(
+                    consumer, startIndex + start);
+        }
+        return start;
+    }
+
+    public Future<Void> requestSync() {
+        return FUTURE_STUB;
+    }
+
+    private static final Future<Void> FUTURE_STUB = new Future<Void>() {
+        @Override
+        public void cancel() {}
+
+        @Override
+        public boolean isCancelled() {
+            return false;
+        }
+
+        @Override
+        public boolean isDone() {
+            return true;
+        }
+
+        @Override
+        public Void get() {
+            return null;
+        }
+
+        @Override
+        public void waitDone() {}
+    };
+}
diff --git a/src/com/android/gallery3d/data/MediaSource.java b/src/com/android/gallery3d/data/MediaSource.java
new file mode 100644
index 0000000..ae98e0f
--- /dev/null
+++ b/src/com/android/gallery3d/data/MediaSource.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.data.MediaSet.ItemConsumer;
+
+import android.net.Uri;
+
+import java.util.ArrayList;
+
+public abstract class MediaSource {
+    private static final String TAG = "MediaSource";
+    private String mPrefix;
+
+    protected MediaSource(String prefix) {
+        mPrefix = prefix;
+    }
+
+    public String getPrefix() {
+        return mPrefix;
+    }
+
+    public Path findPathByUri(Uri uri) {
+        return null;
+    }
+
+    public abstract MediaObject createMediaObject(Path path);
+
+    public void pause() {
+    }
+
+    public void resume() {
+    }
+
+    public Path getDefaultSetOf(Path item) {
+        return null;
+    }
+
+    public long getTotalUsedCacheSize() {
+        return 0;
+    }
+
+    public long getTotalTargetCacheSize() {
+        return 0;
+    }
+
+    public static class PathId {
+        public PathId(Path path, int id) {
+            this.path = path;
+            this.id = id;
+        }
+        public Path path;
+        public int id;
+    }
+
+    // Maps a list of Paths (all belong to this MediaSource) to MediaItems,
+    // and invoke consumer.consume() for each MediaItem with the given id.
+    //
+    // This default implementation uses getMediaObject for each Path. Subclasses
+    // may override this and provide more efficient implementation (like
+    // batching the database query).
+    public void mapMediaItems(ArrayList<PathId> list, ItemConsumer consumer) {
+        int n = list.size();
+        for (int i = 0; i < n; i++) {
+            PathId pid = list.get(i);
+            MediaObject obj = pid.path.getObject();
+            if (obj == null) {
+                try {
+                    obj = createMediaObject(pid.path);
+                } catch (Throwable th) {
+                    Log.w(TAG, "cannot create media object: " + pid.path, th);
+                }
+            }
+            if (obj != null) {
+                consumer.consume(pid.id, (MediaItem) obj);
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/MtpClient.java b/src/com/android/gallery3d/data/MtpClient.java
new file mode 100644
index 0000000..6991c16
--- /dev/null
+++ b/src/com/android/gallery3d/data/MtpClient.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.mtp.MtpDevice;
+import android.mtp.MtpDeviceInfo;
+import android.mtp.MtpObjectInfo;
+import android.mtp.MtpStorageInfo;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * This class helps an application manage a list of connected MTP or PTP devices.
+ * It listens for MTP devices being attached and removed from the USB host bus
+ * and notifies the application when the MTP device list changes.
+ */
+public class MtpClient {
+
+    private static final String TAG = "MtpClient";
+
+    private static final String ACTION_USB_PERMISSION =
+            "android.mtp.MtpClient.action.USB_PERMISSION";
+
+    private final Context mContext;
+    private final UsbManager mUsbManager;
+    private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
+    // mDevices contains all MtpDevices that have been seen by our client,
+    // so we can inform when the device has been detached.
+    // mDevices is also used for synchronization in this class.
+    private final HashMap<String, MtpDevice> mDevices = new HashMap<String, MtpDevice>();
+    // List of MTP devices we should not try to open for which we are currently
+    // asking for permission to open.
+    private final ArrayList<String> mRequestPermissionDevices = new ArrayList<String>();
+    // List of MTP devices we should not try to open.
+    // We add devices to this list if the user canceled a permission request or we were
+    // unable to open the device.
+    private final ArrayList<String> mIgnoredDevices = new ArrayList<String>();
+
+    private final PendingIntent mPermissionIntent;
+
+    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            UsbDevice usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+            String deviceName = usbDevice.getDeviceName();
+
+            synchronized (mDevices) {
+                MtpDevice mtpDevice = mDevices.get(deviceName);
+
+                if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
+                    if (mtpDevice == null) {
+                        mtpDevice = openDeviceLocked(usbDevice);
+                    }
+                    if (mtpDevice != null) {
+                        for (Listener listener : mListeners) {
+                            listener.deviceAdded(mtpDevice);
+                        }
+                    }
+                } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
+                    if (mtpDevice != null) {
+                        mDevices.remove(deviceName);
+                        mRequestPermissionDevices.remove(deviceName);
+                        mIgnoredDevices.remove(deviceName);
+                        for (Listener listener : mListeners) {
+                            listener.deviceRemoved(mtpDevice);
+                        }
+                    }
+                } else if (ACTION_USB_PERMISSION.equals(action)) {
+                    mRequestPermissionDevices.remove(deviceName);
+                    boolean permission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED,
+                            false);
+                    Log.d(TAG, "ACTION_USB_PERMISSION: " + permission);
+                    if (permission) {
+                        if (mtpDevice == null) {
+                            mtpDevice = openDeviceLocked(usbDevice);
+                        }
+                        if (mtpDevice != null) {
+                            for (Listener listener : mListeners) {
+                                listener.deviceAdded(mtpDevice);
+                            }
+                        }
+                    } else {
+                        // so we don't ask for permission again
+                        mIgnoredDevices.add(deviceName);
+                    }
+                }
+            }
+        }
+    };
+
+    /**
+     * An interface for being notified when MTP or PTP devices are attached
+     * or removed.  In the current implementation, only PTP devices are supported.
+     */
+    public interface Listener {
+        /**
+         * Called when a new device has been added
+         *
+         * @param device the new device that was added
+         */
+        public void deviceAdded(MtpDevice device);
+
+        /**
+         * Called when a new device has been removed
+         *
+         * @param device the device that was removed
+         */
+        public void deviceRemoved(MtpDevice device);
+    }
+
+    /**
+     * Tests to see if a {@link android.hardware.usb.UsbDevice}
+     * supports the PTP protocol (typically used by digital cameras)
+     *
+     * @param device the device to test
+     * @return true if the device is a PTP device.
+     */
+    static public boolean isCamera(UsbDevice device) {
+        int count = device.getInterfaceCount();
+        for (int i = 0; i < count; i++) {
+            UsbInterface intf = device.getInterface(i);
+            if (intf.getInterfaceClass() == UsbConstants.USB_CLASS_STILL_IMAGE &&
+                    intf.getInterfaceSubclass() == 1 &&
+                    intf.getInterfaceProtocol() == 1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * MtpClient constructor
+     *
+     * @param context the {@link android.content.Context} to use for the MtpClient
+     */
+    public MtpClient(Context context) {
+        mContext = context;
+        mUsbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);
+        mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+        filter.addAction(ACTION_USB_PERMISSION);
+        context.registerReceiver(mUsbReceiver, filter);
+    }
+
+    /**
+     * Opens the {@link android.hardware.usb.UsbDevice} for an MTP or PTP
+     * device and return an {@link android.mtp.MtpDevice} for it.
+     *
+     * @param device the device to open
+     * @return an MtpDevice for the device.
+     */
+    private MtpDevice openDeviceLocked(UsbDevice usbDevice) {
+        String deviceName = usbDevice.getDeviceName();
+
+        // don't try to open devices that we have decided to ignore
+        // or are currently asking permission for
+        if (isCamera(usbDevice) && !mIgnoredDevices.contains(deviceName)
+                && !mRequestPermissionDevices.contains(deviceName)) {
+            if (!mUsbManager.hasPermission(usbDevice)) {
+                mUsbManager.requestPermission(usbDevice, mPermissionIntent);
+                mRequestPermissionDevices.add(deviceName);
+            } else {
+                UsbDeviceConnection connection = mUsbManager.openDevice(usbDevice);
+                if (connection != null) {
+                    MtpDevice mtpDevice = new MtpDevice(usbDevice);
+                    if (mtpDevice.open(connection)) {
+                        mDevices.put(usbDevice.getDeviceName(), mtpDevice);
+                        return mtpDevice;
+                    } else {
+                        // so we don't try to open it again
+                        mIgnoredDevices.add(deviceName);
+                    }
+                } else {
+                    // so we don't try to open it again
+                    mIgnoredDevices.add(deviceName);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Closes all resources related to the MtpClient object
+     */
+    public void close() {
+        mContext.unregisterReceiver(mUsbReceiver);
+    }
+
+    /**
+     * Registers a {@link android.mtp.MtpClient.Listener} interface to receive
+     * notifications when MTP or PTP devices are added or removed.
+     *
+     * @param listener the listener to register
+     */
+    public void addListener(Listener listener) {
+        synchronized (mDevices) {
+            if (!mListeners.contains(listener)) {
+                mListeners.add(listener);
+            }
+        }
+    }
+
+    /**
+     * Unregisters a {@link android.mtp.MtpClient.Listener} interface.
+     *
+     * @param listener the listener to unregister
+     */
+    public void removeListener(Listener listener) {
+        synchronized (mDevices) {
+            mListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Retrieves an {@link android.mtp.MtpDevice} object for the USB device
+     * with the given name.
+     *
+     * @param deviceName the name of the USB device
+     * @return the MtpDevice, or null if it does not exist
+     */
+    public MtpDevice getDevice(String deviceName) {
+        synchronized (mDevices) {
+            return mDevices.get(deviceName);
+        }
+    }
+
+    /**
+     * Retrieves an {@link android.mtp.MtpDevice} object for the USB device
+     * with the given ID.
+     *
+     * @param id the ID of the USB device
+     * @return the MtpDevice, or null if it does not exist
+     */
+    public MtpDevice getDevice(int id) {
+        synchronized (mDevices) {
+            return mDevices.get(UsbDevice.getDeviceName(id));
+        }
+    }
+
+    /**
+     * Retrieves a list of all currently connected {@link android.mtp.MtpDevice}.
+     *
+     * @return the list of MtpDevices
+     */
+    public List<MtpDevice> getDeviceList() {
+        synchronized (mDevices) {
+            // Query the USB manager since devices might have attached
+            // before we added our listener.
+            for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
+                if (mDevices.get(usbDevice.getDeviceName()) == null) {
+                    openDeviceLocked(usbDevice);
+                }
+            }
+
+            return new ArrayList<MtpDevice>(mDevices.values());
+        }
+    }
+
+    /**
+     * Retrieves a list of all {@link android.mtp.MtpStorageInfo}
+     * for the MTP or PTP device with the given USB device name
+     *
+     * @param deviceName the name of the USB device
+     * @return the list of MtpStorageInfo
+     */
+    public List<MtpStorageInfo> getStorageList(String deviceName) {
+        MtpDevice device = getDevice(deviceName);
+        if (device == null) {
+            return null;
+        }
+        int[] storageIds = device.getStorageIds();
+        if (storageIds == null) {
+            return null;
+        }
+
+        int length = storageIds.length;
+        ArrayList<MtpStorageInfo> storageList = new ArrayList<MtpStorageInfo>(length);
+        for (int i = 0; i < length; i++) {
+            MtpStorageInfo info = device.getStorageInfo(storageIds[i]);
+            if (info == null) {
+                Log.w(TAG, "getStorageInfo failed");
+            } else {
+                storageList.add(info);
+            }
+        }
+        return storageList;
+    }
+
+    /**
+     * Retrieves the {@link android.mtp.MtpObjectInfo} for an object on
+     * the MTP or PTP device with the given USB device name with the given
+     * object handle
+     *
+     * @param deviceName the name of the USB device
+     * @param objectHandle handle of the object to query
+     * @return the MtpObjectInfo
+     */
+    public MtpObjectInfo getObjectInfo(String deviceName, int objectHandle) {
+        MtpDevice device = getDevice(deviceName);
+        if (device == null) {
+            return null;
+        }
+        return device.getObjectInfo(objectHandle);
+    }
+
+    /**
+     * Deletes an object on the MTP or PTP device with the given USB device name.
+     *
+     * @param deviceName the name of the USB device
+     * @param objectHandle handle of the object to delete
+     * @return true if the deletion succeeds
+     */
+    public boolean deleteObject(String deviceName, int objectHandle) {
+        MtpDevice device = getDevice(deviceName);
+        if (device == null) {
+            return false;
+        }
+        return device.deleteObject(objectHandle);
+    }
+
+    /**
+     * Retrieves a list of {@link android.mtp.MtpObjectInfo} for all objects
+     * on the MTP or PTP device with the given USB device name and given storage ID
+     * and/or object handle.
+     * If the object handle is zero, then all objects in the root of the storage unit
+     * will be returned. Otherwise, all immediate children of the object will be returned.
+     * If the storage ID is also zero, then all objects on all storage units will be returned.
+     *
+     * @param deviceName the name of the USB device
+     * @param storageId the ID of the storage unit to query, or zero for all
+     * @param objectHandle the handle of the parent object to query, or zero for the storage root
+     * @return the list of MtpObjectInfo
+     */
+    public List<MtpObjectInfo> getObjectList(String deviceName, int storageId, int objectHandle) {
+        MtpDevice device = getDevice(deviceName);
+        if (device == null) {
+            return null;
+        }
+        if (objectHandle == 0) {
+            // all objects in root of storage
+            objectHandle = 0xFFFFFFFF;
+        }
+        int[] handles = device.getObjectHandles(storageId, 0, objectHandle);
+        if (handles == null) {
+            return null;
+        }
+
+        int length = handles.length;
+        ArrayList<MtpObjectInfo> objectList = new ArrayList<MtpObjectInfo>(length);
+        for (int i = 0; i < length; i++) {
+            MtpObjectInfo info = device.getObjectInfo(handles[i]);
+            if (info == null) {
+                Log.w(TAG, "getObjectInfo failed");
+            } else {
+                objectList.add(info);
+            }
+        }
+        return objectList;
+    }
+
+    /**
+     * Returns the data for an object as a byte array.
+     *
+     * @param deviceName the name of the USB device containing the object
+     * @param objectHandle handle of the object to read
+     * @param objectSize the size of the object (this should match
+     *      {@link android.mtp.MtpObjectInfo#getCompressedSize}
+     * @return the object's data, or null if reading fails
+     */
+    public byte[] getObject(String deviceName, int objectHandle, int objectSize) {
+        MtpDevice device = getDevice(deviceName);
+        if (device == null) {
+            return null;
+        }
+        return device.getObject(objectHandle, objectSize);
+    }
+
+    /**
+     * Returns the thumbnail data for an object as a byte array.
+     *
+     * @param deviceName the name of the USB device containing the object
+     * @param objectHandle handle of the object to read
+     * @return the object's thumbnail, or null if reading fails
+     */
+    public byte[] getThumbnail(String deviceName, int objectHandle) {
+        MtpDevice device = getDevice(deviceName);
+        if (device == null) {
+            return null;
+        }
+        return device.getThumbnail(objectHandle);
+    }
+
+    /**
+     * Copies the data for an object to a file in external storage.
+     *
+     * @param deviceName the name of the USB device containing the object
+     * @param objectHandle handle of the object to read
+     * @param destPath path to destination for the file transfer.
+     *      This path should be in the external storage as defined by
+     *      {@link android.os.Environment#getExternalStorageDirectory}
+     * @return true if the file transfer succeeds
+     */
+    public boolean importFile(String deviceName, int objectHandle, String destPath) {
+        MtpDevice device = getDevice(deviceName);
+        if (device == null) {
+            return false;
+        }
+        return device.importFile(objectHandle, destPath);
+    }
+}
diff --git a/src/com/android/gallery3d/data/MtpContext.java b/src/com/android/gallery3d/data/MtpContext.java
new file mode 100644
index 0000000..6528494
--- /dev/null
+++ b/src/com/android/gallery3d/data/MtpContext.java
@@ -0,0 +1,141 @@
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.Context;
+import android.hardware.usb.UsbDevice;
+import android.media.MediaScannerConnection;
+import android.media.MediaScannerConnection.MediaScannerConnectionClient;
+import android.mtp.MtpObjectInfo;
+import android.net.Uri;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MtpContext implements MtpClient.Listener {
+    private static final String TAG = "MtpContext";
+
+    public static final String NAME_IMPORTED_FOLDER = "Imported";
+
+    private ScannerClient mScannerClient;
+    private Context mContext;
+    private MtpClient mClient;
+
+    private static final class ScannerClient implements MediaScannerConnectionClient {
+        ArrayList<String> mPaths = new ArrayList<String>();
+        MediaScannerConnection mScannerConnection;
+        boolean mConnected;
+        Object mLock = new Object();
+
+        public ScannerClient(Context context) {
+            mScannerConnection = new MediaScannerConnection(context, this);
+        }
+
+        public void scanPath(String path) {
+            synchronized (mLock) {
+                if (mConnected) {
+                    mScannerConnection.scanFile(path, null);
+                } else {
+                    mPaths.add(path);
+                    mScannerConnection.connect();
+                }
+            }
+        }
+
+        @Override
+        public void onMediaScannerConnected() {
+            synchronized (mLock) {
+                mConnected = true;
+                if (!mPaths.isEmpty()) {
+                    for (String path : mPaths) {
+                        mScannerConnection.scanFile(path, null);
+                    }
+                    mPaths.clear();
+                }
+            }
+        }
+
+        @Override
+        public void onScanCompleted(String path, Uri uri) {
+        }
+    }
+
+    public MtpContext(Context context) {
+        mContext = context;
+        mScannerClient = new ScannerClient(context);
+        mClient = new MtpClient(mContext);
+    }
+
+    public void pause() {
+        mClient.removeListener(this);
+    }
+
+    public void resume() {
+        mClient.addListener(this);
+        notifyDirty();
+    }
+
+    public void deviceAdded(android.mtp.MtpDevice device) {
+        notifyDirty();
+        showToast(R.string.camera_connected);
+    }
+
+    public void deviceRemoved(android.mtp.MtpDevice device) {
+        notifyDirty();
+        showToast(R.string.camera_disconnected);
+    }
+
+    private void notifyDirty() {
+        mContext.getContentResolver().notifyChange(Uri.parse("mtp://"), null);
+    }
+
+    private void showToast(final int msg) {
+        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
+    }
+
+    public MtpClient getMtpClient() {
+        return mClient;
+    }
+
+    public boolean copyFile(String deviceName, MtpObjectInfo objInfo) {
+        if (GalleryUtils.hasSpaceForSize(objInfo.getCompressedSize())) {
+            File dest = Environment.getExternalStorageDirectory();
+            dest = new File(dest, NAME_IMPORTED_FOLDER);
+            dest.mkdirs();
+            String destPath = new File(dest, objInfo.getName()).getAbsolutePath();
+            int objectId = objInfo.getObjectHandle();
+            if (mClient.importFile(deviceName, objectId, destPath)) {
+                mScannerClient.scanPath(destPath);
+                return true;
+            }
+        } else {
+            Log.w(TAG, "No space to import " + objInfo.getName() +
+                    " whose size = " + objInfo.getCompressedSize());
+        }
+        return false;
+    }
+
+    public boolean copyAlbum(String deviceName, String albumName,
+            List<MtpObjectInfo> children) {
+        File dest = Environment.getExternalStorageDirectory();
+        dest = new File(dest, albumName);
+        dest.mkdirs();
+        int success = 0;
+        for (MtpObjectInfo child : children) {
+            if (!GalleryUtils.hasSpaceForSize(child.getCompressedSize())) continue;
+
+            File importedFile = new File(dest, child.getName());
+            String path = importedFile.getAbsolutePath();
+            if (mClient.importFile(deviceName, child.getObjectHandle(), path)) {
+                mScannerClient.scanPath(path);
+                success++;
+            }
+        }
+        return success == children.size();
+    }
+}
diff --git a/src/com/android/gallery3d/data/MtpDevice.java b/src/com/android/gallery3d/data/MtpDevice.java
new file mode 100644
index 0000000..e654583
--- /dev/null
+++ b/src/com/android/gallery3d/data/MtpDevice.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+import android.hardware.usb.UsbDevice;
+import android.mtp.MtpConstants;
+import android.mtp.MtpObjectInfo;
+import android.mtp.MtpStorageInfo;
+import android.net.Uri;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MtpDevice extends MediaSet {
+    private static final String TAG = "MtpDevice";
+
+    private final GalleryApp mApplication;
+    private final int mDeviceId;
+    private final String mDeviceName;
+    private final DataManager mDataManager;
+    private final MtpContext mMtpContext;
+    private final String mName;
+    private final ChangeNotifier mNotifier;
+    private final Path mItemPath;
+    private List<MtpObjectInfo> mJpegChildren;
+
+    public MtpDevice(Path path, GalleryApp application, int deviceId,
+            String name, MtpContext mtpContext) {
+        super(path, nextVersionNumber());
+        mApplication = application;
+        mDeviceId = deviceId;
+        mDeviceName = UsbDevice.getDeviceName(deviceId);
+        mDataManager = application.getDataManager();
+        mMtpContext = mtpContext;
+        mName = name;
+        mNotifier = new ChangeNotifier(this, Uri.parse("mtp://"), application);
+        mItemPath = Path.fromString("/mtp/item/" + String.valueOf(deviceId));
+        mJpegChildren = new ArrayList<MtpObjectInfo>();
+    }
+
+    public MtpDevice(Path path, GalleryApp application, int deviceId,
+            MtpContext mtpContext) {
+        this(path, application, deviceId,
+                MtpDeviceSet.getDeviceName(mtpContext, deviceId), mtpContext);
+    }
+
+    private List<MtpObjectInfo> loadItems() {
+        ArrayList<MtpObjectInfo> result = new ArrayList<MtpObjectInfo>();
+
+        List<MtpStorageInfo> storageList = mMtpContext.getMtpClient()
+                 .getStorageList(mDeviceName);
+        if (storageList == null) return result;
+
+        for (MtpStorageInfo info : storageList) {
+            collectJpegChildren(info.getStorageId(), 0, result);
+        }
+
+        return result;
+    }
+
+    private void collectJpegChildren(int storageId, int objectId,
+            ArrayList<MtpObjectInfo> result) {
+        ArrayList<MtpObjectInfo> dirChildren = new ArrayList<MtpObjectInfo>();
+
+        queryChildren(storageId, objectId, result, dirChildren);
+
+        for (int i = 0, n = dirChildren.size(); i < n; i++) {
+            MtpObjectInfo info = dirChildren.get(i);
+            collectJpegChildren(storageId, info.getObjectHandle(), result);
+        }
+    }
+
+    private void queryChildren(int storageId, int objectId,
+            ArrayList<MtpObjectInfo> jpeg, ArrayList<MtpObjectInfo> dir) {
+        List<MtpObjectInfo> children = mMtpContext.getMtpClient().getObjectList(
+                mDeviceName, storageId, objectId);
+        if (children == null) return;
+
+        for (MtpObjectInfo obj : children) {
+            int format = obj.getFormat();
+            switch (format) {
+                case MtpConstants.FORMAT_JFIF:
+                case MtpConstants.FORMAT_EXIF_JPEG:
+                    jpeg.add(obj);
+                    break;
+                case MtpConstants.FORMAT_ASSOCIATION:
+                    dir.add(obj);
+                    break;
+                default:
+                    Log.w(TAG, "other type: name = " + obj.getName()
+                            + ", format = " + format);
+            }
+        }
+    }
+
+    public static MtpObjectInfo getObjectInfo(MtpContext mtpContext, int deviceId,
+            int objectId) {
+        String deviceName = UsbDevice.getDeviceName(deviceId);
+        return mtpContext.getMtpClient().getObjectInfo(deviceName, objectId);
+    }
+
+    @Override
+    public ArrayList<MediaItem> getMediaItem(int start, int count) {
+        ArrayList<MediaItem> result = new ArrayList<MediaItem>();
+        int begin = start;
+        int end = Math.min(start + count, mJpegChildren.size());
+
+        DataManager dataManager = mApplication.getDataManager();
+        for (int i = begin; i < end; i++) {
+            MtpObjectInfo child = mJpegChildren.get(i);
+            Path childPath = mItemPath.getChild(child.getObjectHandle());
+            MtpImage image = (MtpImage) dataManager.peekMediaObject(childPath);
+            if (image == null) {
+                image = new MtpImage(
+                        childPath, mApplication, mDeviceId, child, mMtpContext);
+            } else {
+                image.updateContent(child);
+            }
+            result.add(image);
+        }
+        return result;
+    }
+
+    @Override
+    public int getMediaItemCount() {
+        return mJpegChildren.size();
+    }
+
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public long reload() {
+        if (mNotifier.isDirty()) {
+            mDataVersion = nextVersionNumber();
+            mJpegChildren = loadItems();
+        }
+        return mDataVersion;
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        return SUPPORT_IMPORT;
+    }
+
+    @Override
+    public boolean Import() {
+        return mMtpContext.copyAlbum(mDeviceName, mName, mJpegChildren);
+    }
+
+    @Override
+    public boolean isLeafAlbum() {
+        return true;
+    }
+}
diff --git a/src/com/android/gallery3d/data/MtpDeviceSet.java b/src/com/android/gallery3d/data/MtpDeviceSet.java
new file mode 100644
index 0000000..6521623
--- /dev/null
+++ b/src/com/android/gallery3d/data/MtpDeviceSet.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.util.MediaSetUtils;
+
+import android.mtp.MtpDeviceInfo;
+import android.net.Uri;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+// MtpDeviceSet -- MtpDevice -- MtpImage
+public class MtpDeviceSet extends MediaSet {
+    private static final String TAG = "MtpDeviceSet";
+
+    private GalleryApp mApplication;
+    private final ArrayList<MediaSet> mDeviceSet = new ArrayList<MediaSet>();
+    private final ChangeNotifier mNotifier;
+    private final MtpContext mMtpContext;
+    private final String mName;
+
+    public MtpDeviceSet(Path path, GalleryApp application, MtpContext mtpContext) {
+        super(path, nextVersionNumber());
+        mApplication = application;
+        mNotifier = new ChangeNotifier(this, Uri.parse("mtp://"), application);
+        mMtpContext = mtpContext;
+        mName = application.getResources().getString(R.string.set_label_mtp_devices);
+    }
+
+    private void loadDevices() {
+        DataManager dataManager = mApplication.getDataManager();
+        // Enumerate all devices
+        mDeviceSet.clear();
+        List<android.mtp.MtpDevice> devices = mMtpContext.getMtpClient().getDeviceList();
+        Log.v(TAG, "loadDevices: " + devices + ", size=" + devices.size());
+        for (android.mtp.MtpDevice mtpDevice : devices) {
+            int deviceId = mtpDevice.getDeviceId();
+            Path childPath = mPath.getChild(deviceId);
+            MtpDevice device = (MtpDevice) dataManager.peekMediaObject(childPath);
+            if (device == null) {
+                device = new MtpDevice(childPath, mApplication, deviceId, mMtpContext);
+            }
+            Log.d(TAG, "add device " + device);
+            mDeviceSet.add(device);
+        }
+
+        Collections.sort(mDeviceSet, MediaSetUtils.NAME_COMPARATOR);
+        for (int i = 0, n = mDeviceSet.size(); i < n; i++) {
+            mDeviceSet.get(i).reload();
+        }
+    }
+
+    public static String getDeviceName(MtpContext mtpContext, int deviceId) {
+        android.mtp.MtpDevice device = mtpContext.getMtpClient().getDevice(deviceId);
+        if (device == null) {
+            return "";
+        }
+        MtpDeviceInfo info = device.getDeviceInfo();
+        if (info == null) {
+            return "";
+        }
+        String manufacturer = info.getManufacturer().trim();
+        String model = info.getModel().trim();
+        return manufacturer + " " + model;
+    }
+
+    @Override
+    public MediaSet getSubMediaSet(int index) {
+        return index < mDeviceSet.size() ? mDeviceSet.get(index) : null;
+    }
+
+    @Override
+    public int getSubMediaSetCount() {
+        return mDeviceSet.size();
+    }
+
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public long reload() {
+        if (mNotifier.isDirty()) {
+            mDataVersion = nextVersionNumber();
+            loadDevices();
+        }
+        return mDataVersion;
+    }
+}
diff --git a/src/com/android/gallery3d/data/MtpImage.java b/src/com/android/gallery3d/data/MtpImage.java
new file mode 100644
index 0000000..4766d88
--- /dev/null
+++ b/src/com/android/gallery3d/data/MtpImage.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.provider.GalleryProvider;
+import com.android.gallery3d.util.ThreadPool;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapRegionDecoder;
+import android.hardware.usb.UsbDevice;
+import android.mtp.MtpObjectInfo;
+import android.net.Uri;
+import android.util.Log;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+public class MtpImage extends MediaItem {
+    private static final String TAG = "MtpImage";
+
+    private final int mDeviceId;
+    private int mObjectId;
+    private int mObjectSize;
+    private long mDateTaken;
+    private String mFileName;
+    private final ThreadPool mThreadPool;
+    private final MtpContext mMtpContext;
+    private final MtpObjectInfo mObjInfo;
+    private final int mImageWidth;
+    private final int mImageHeight;
+
+    MtpImage(Path path, GalleryApp application, int deviceId,
+            MtpObjectInfo objInfo, MtpContext mtpContext) {
+        super(path, nextVersionNumber());
+        mDeviceId = deviceId;
+        mObjInfo = objInfo;
+        mObjectId = objInfo.getObjectHandle();
+        mObjectSize = objInfo.getCompressedSize();
+        mDateTaken = objInfo.getDateCreated();
+        mFileName = objInfo.getName();
+        mImageWidth = objInfo.getImagePixWidth();
+        mImageHeight = objInfo.getImagePixHeight();
+        mThreadPool = application.getThreadPool();
+        mMtpContext = mtpContext;
+    }
+
+    MtpImage(Path path, GalleryApp app, int deviceId, int objectId, MtpContext mtpContext) {
+        this(path, app, deviceId, MtpDevice.getObjectInfo(mtpContext, deviceId, objectId),
+                mtpContext);
+    }
+
+    @Override
+    public long getDateInMs() {
+        return mDateTaken;
+    }
+
+    @Override
+    public Job<Bitmap> requestImage(int type) {
+        return new Job<Bitmap>() {
+            public Bitmap run(JobContext jc) {
+                GetThumbnailBytes job = new GetThumbnailBytes();
+                byte[] thumbnail = mThreadPool.submit(job).get();
+                if (thumbnail == null) {
+                    Log.w(TAG, "decoding thumbnail failed");
+                    return null;
+                }
+                return DecodeUtils.requestDecode(jc, thumbnail, null);
+            }
+        };
+    }
+
+    @Override
+    public Job<BitmapRegionDecoder> requestLargeImage() {
+        return new Job<BitmapRegionDecoder>() {
+            public BitmapRegionDecoder run(JobContext jc) {
+                byte[] bytes = mMtpContext.getMtpClient().getObject(
+                        UsbDevice.getDeviceName(mDeviceId), mObjectId, mObjectSize);
+                return DecodeUtils.requestCreateBitmapRegionDecoder(
+                        jc, bytes, 0, bytes.length, false);
+            }
+        };
+    }
+
+    public byte[] getImageData() {
+        return mMtpContext.getMtpClient().getObject(
+                UsbDevice.getDeviceName(mDeviceId), mObjectId, mObjectSize);
+    }
+
+    @Override
+    public boolean Import() {
+        return mMtpContext.copyFile(UsbDevice.getDeviceName(mDeviceId), mObjInfo);
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        return SUPPORT_FULL_IMAGE | SUPPORT_IMPORT;
+    }
+
+    private class GetThumbnailBytes implements Job<byte[]> {
+        public byte[] run(JobContext jc) {
+            return mMtpContext.getMtpClient().getThumbnail(
+                    UsbDevice.getDeviceName(mDeviceId), mObjectId);
+        }
+    }
+
+    public void updateContent(MtpObjectInfo info) {
+        if (mObjectId != info.getObjectHandle() || mDateTaken != info.getDateCreated()) {
+            mObjectId = info.getObjectHandle();
+            mDateTaken = info.getDateCreated();
+            mDataVersion = nextVersionNumber();
+        }
+    }
+
+    @Override
+    public String getMimeType() {
+        // Currently only JPEG is supported in MTP.
+        return "image/jpeg";
+    }
+
+    @Override
+    public int getMediaType() {
+        return MEDIA_TYPE_IMAGE;
+    }
+
+    @Override
+    public long getSize() {
+        return mObjectSize;
+    }
+
+    @Override
+    public Uri getContentUri() {
+        return GalleryProvider.BASE_URI.buildUpon()
+                .appendEncodedPath(mPath.toString().substring(1))
+                .build();
+    }
+
+    @Override
+    public MediaDetails getDetails() {
+        MediaDetails details = super.getDetails();
+        DateFormat formater = DateFormat.getDateTimeInstance();
+        details.addDetail(MediaDetails.INDEX_TITLE, mFileName);
+        details.addDetail(MediaDetails.INDEX_DATETIME, formater.format(new Date(mDateTaken)));
+        details.addDetail(MediaDetails.INDEX_WIDTH, mImageWidth);
+        details.addDetail(MediaDetails.INDEX_HEIGHT, mImageHeight);
+        details.addDetail(MediaDetails.INDEX_SIZE, Long.valueOf(mObjectSize));
+        return details;
+    }
+
+}
diff --git a/src/com/android/gallery3d/data/MtpSource.java b/src/com/android/gallery3d/data/MtpSource.java
new file mode 100644
index 0000000..683a402
--- /dev/null
+++ b/src/com/android/gallery3d/data/MtpSource.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+class MtpSource extends MediaSource {
+    private static final String TAG = "MtpSource";
+
+    private static final int MTP_DEVICESET = 0;
+    private static final int MTP_DEVICE = 1;
+    private static final int MTP_ITEM = 2;
+
+    GalleryApp mApplication;
+    PathMatcher mMatcher;
+    MtpContext mMtpContext;
+
+    public MtpSource(GalleryApp application) {
+        super("mtp");
+        mApplication = application;
+        mMatcher = new PathMatcher();
+        mMatcher.add("/mtp", MTP_DEVICESET);
+        mMatcher.add("/mtp/*", MTP_DEVICE);
+        mMatcher.add("/mtp/item/*/*", MTP_ITEM);
+        mMtpContext = new MtpContext(mApplication.getAndroidContext());
+    }
+
+    @Override
+    public MediaObject createMediaObject(Path path) {
+        switch (mMatcher.match(path)) {
+            case MTP_DEVICESET: {
+                return new MtpDeviceSet(path, mApplication, mMtpContext);
+            }
+            case MTP_DEVICE: {
+                int deviceId = mMatcher.getIntVar(0);
+                return new MtpDevice(path, mApplication, deviceId, mMtpContext);
+            }
+            case MTP_ITEM: {
+                int deviceId = mMatcher.getIntVar(0);
+                int objectId = mMatcher.getIntVar(1);
+                return new MtpImage(path, mApplication, deviceId, objectId, mMtpContext);
+            }
+            default:
+                throw new RuntimeException("bad path: " + path);
+        }
+    }
+
+    @Override
+    public void pause() {
+        mMtpContext.pause();
+    }
+
+    @Override
+    public void resume() {
+        mMtpContext.resume();
+    }
+}
diff --git a/src/com/android/gallery3d/data/Path.java b/src/com/android/gallery3d/data/Path.java
new file mode 100644
index 0000000..3de1c7c
--- /dev/null
+++ b/src/com/android/gallery3d/data/Path.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.IdentityCache;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+public class Path {
+    private static final String TAG = "Path";
+    private static Path sRoot = new Path(null, "ROOT");
+
+    private final Path mParent;
+    private final String mSegment;
+    private WeakReference<MediaObject> mObject;
+    private IdentityCache<String, Path> mChildren;
+
+    private Path(Path parent, String segment) {
+        mParent = parent;
+        mSegment = segment;
+    }
+
+    public Path getChild(String segment) {
+        synchronized (Path.class) {
+            if (mChildren == null) {
+                mChildren = new IdentityCache<String, Path>();
+            } else {
+                Path p = mChildren.get(segment);
+                if (p != null) return p;
+            }
+
+            Path p = new Path(this, segment);
+            mChildren.put(segment, p);
+            return p;
+        }
+    }
+
+    public Path getParent() {
+        synchronized (Path.class) {
+            return mParent;
+        }
+    }
+
+    public Path getChild(int segment) {
+        return getChild(String.valueOf(segment));
+    }
+
+    public Path getChild(long segment) {
+        return getChild(String.valueOf(segment));
+    }
+
+    public void setObject(MediaObject object) {
+        synchronized (Path.class) {
+            Utils.assertTrue(mObject == null || mObject.get() == null);
+            mObject = new WeakReference<MediaObject>(object);
+        }
+    }
+
+    public MediaObject getObject() {
+        synchronized (Path.class) {
+            return (mObject == null) ? null : mObject.get();
+        }
+    }
+
+    @Override
+    public String toString() {
+        synchronized (Path.class) {
+            StringBuilder sb = new StringBuilder();
+            String[] segments = split();
+            for (int i = 0; i < segments.length; i++) {
+                sb.append("/");
+                sb.append(segments[i]);
+            }
+            return sb.toString();
+        }
+    }
+
+    public static Path fromString(String s) {
+        synchronized (Path.class) {
+            String[] segments = split(s);
+            Path current = sRoot;
+            for (int i = 0; i < segments.length; i++) {
+                current = current.getChild(segments[i]);
+            }
+            return current;
+        }
+    }
+
+    public String[] split() {
+        synchronized (Path.class) {
+            int n = 0;
+            for (Path p = this; p != sRoot; p = p.mParent) {
+                n++;
+            }
+            String[] segments = new String[n];
+            int i = n - 1;
+            for (Path p = this; p != sRoot; p = p.mParent) {
+                segments[i--] = p.mSegment;
+            }
+            return segments;
+        }
+    }
+
+    public static String[] split(String s) {
+        int n = s.length();
+        if (n == 0) return new String[0];
+        if (s.charAt(0) != '/') {
+            throw new RuntimeException("malformed path:" + s);
+        }
+        ArrayList<String> segments = new ArrayList<String>();
+        int i = 1;
+        while (i < n) {
+            int brace = 0;
+            int j;
+            for (j = i; j < n; j++) {
+                char c = s.charAt(j);
+                if (c == '{') ++brace;
+                else if (c == '}') --brace;
+                else if (brace == 0 && c == '/') break;
+            }
+            if (brace != 0) {
+                throw new RuntimeException("unbalanced brace in path:" + s);
+            }
+            segments.add(s.substring(i, j));
+            i = j + 1;
+        }
+        String[] result = new String[segments.size()];
+        segments.toArray(result);
+        return result;
+    }
+
+    // Splits a string to an array of strings.
+    // For example, "{foo,bar,baz}" -> {"foo","bar","baz"}.
+    public static String[] splitSequence(String s) {
+        int n = s.length();
+        if (s.charAt(0) != '{' || s.charAt(n-1) != '}') {
+            throw new RuntimeException("bad sequence: " + s);
+        }
+        ArrayList<String> segments = new ArrayList<String>();
+        int i = 1;
+        while (i < n - 1) {
+            int brace = 0;
+            int j;
+            for (j = i; j < n - 1; j++) {
+                char c = s.charAt(j);
+                if (c == '{') ++brace;
+                else if (c == '}') --brace;
+                else if (brace == 0 && c == ',') break;
+            }
+            if (brace != 0) {
+                throw new RuntimeException("unbalanced brace in path:" + s);
+            }
+            segments.add(s.substring(i, j));
+            i = j + 1;
+        }
+        String[] result = new String[segments.size()];
+        segments.toArray(result);
+        return result;
+    }
+
+    public String getPrefix() {
+        synchronized (Path.class) {
+            Path current = this;
+            if (current == sRoot) return "";
+            while (current.mParent != sRoot) {
+                current = current.mParent;
+            }
+            return current.mSegment;
+        }
+    }
+
+    public String getSuffix() {
+        // We don't need lock because mSegment is final.
+        return mSegment;
+    }
+
+    public String getSuffix(int level) {
+        // We don't need lock because mSegment and mParent are final.
+        Path p = this;
+        while (level-- != 0) {
+            p = p.mParent;
+        }
+        return p.mSegment;
+    }
+
+    // Below are for testing/debugging only
+    static void clearAll() {
+        synchronized (Path.class) {
+            sRoot = new Path(null, "");
+        }
+    }
+
+    static void dumpAll() {
+        dumpAll(sRoot, "", "");
+    }
+
+    static void dumpAll(Path p, String prefix1, String prefix2) {
+        synchronized (Path.class) {
+            MediaObject obj = p.getObject();
+            Log.d(TAG, prefix1 + p.mSegment + ":"
+                    + (obj == null ? "null" : obj.getClass().getSimpleName()));
+            if (p.mChildren != null) {
+                ArrayList<String> childrenKeys = p.mChildren.keys();
+                int i = 0, n = childrenKeys.size();
+                for (String key : childrenKeys) {
+                    Path child = p.mChildren.get(key);
+                    if (child == null) {
+                        ++i;
+                        continue;
+                    }
+                    Log.d(TAG, prefix2 + "|");
+                    if (++i < n) {
+                        dumpAll(child, prefix2 + "+-- ", prefix2 + "|   ");
+                    } else {
+                        dumpAll(child, prefix2 + "+-- ", prefix2 + "    ");
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/PathMatcher.java b/src/com/android/gallery3d/data/PathMatcher.java
new file mode 100644
index 0000000..9c6b840
--- /dev/null
+++ b/src/com/android/gallery3d/data/PathMatcher.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class PathMatcher {
+    public static final int NOT_FOUND = -1;
+
+    private ArrayList<String> mVariables = new ArrayList<String>();
+    private Node mRoot = new Node();
+
+    public PathMatcher() {
+        mRoot = new Node();
+    }
+
+    public void add(String pattern, int kind) {
+        String[] segments = Path.split(pattern);
+        Node current = mRoot;
+        for (int i = 0; i < segments.length; i++) {
+            current = current.addChild(segments[i]);
+        }
+        current.setKind(kind);
+    }
+
+    public int match(Path path) {
+        String[] segments = path.split();
+        mVariables.clear();
+        Node current = mRoot;
+        for (int i = 0; i < segments.length; i++) {
+            Node next = current.getChild(segments[i]);
+            if (next == null) {
+                next = current.getChild("*");
+                if (next != null) {
+                    mVariables.add(segments[i]);
+                } else {
+                    return NOT_FOUND;
+                }
+            }
+            current = next;
+        }
+        return current.getKind();
+    }
+
+    public String getVar(int index) {
+        return mVariables.get(index);
+    }
+
+    public int getIntVar(int index) {
+        return Integer.parseInt(mVariables.get(index));
+    }
+
+    public long getLongVar(int index) {
+        return Long.parseLong(mVariables.get(index));
+    }
+
+    private static class Node {
+        private HashMap<String, Node> mMap;
+        private int mKind = NOT_FOUND;
+
+        Node addChild(String segment) {
+            if (mMap == null) {
+                mMap = new HashMap<String, Node>();
+            } else {
+                Node node = mMap.get(segment);
+                if (node != null) return node;
+            }
+
+            Node n = new Node();
+            mMap.put(segment, n);
+            return n;
+        }
+
+        Node getChild(String segment) {
+            if (mMap == null) return null;
+            return mMap.get(segment);
+        }
+
+        void setKind(int kind) {
+            mKind = kind;
+        }
+
+        int getKind() {
+            return mKind;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/SizeClustering.java b/src/com/android/gallery3d/data/SizeClustering.java
new file mode 100644
index 0000000..7e24b33
--- /dev/null
+++ b/src/com/android/gallery3d/data/SizeClustering.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import java.util.ArrayList;
+
+public class SizeClustering extends Clustering {
+    private static final String TAG = "SizeClustering";
+
+    private Context mContext;
+    private ArrayList<Path>[] mClusters;
+    private String[] mNames;
+    private long mMinSizes[];
+
+    private static final long MEGA_BYTES = 1024L*1024;
+    private static final long GIGA_BYTES = 1024L*1024*1024;
+
+    private static final long[] SIZE_LEVELS = {
+        0,
+        1 * MEGA_BYTES,
+        10 * MEGA_BYTES,
+        100 * MEGA_BYTES,
+        1 * GIGA_BYTES,
+        2 * GIGA_BYTES,
+        4 * GIGA_BYTES,
+    };
+
+    public SizeClustering(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public void run(MediaSet baseSet) {
+        final ArrayList<Path>[] group =
+                (ArrayList<Path>[]) new ArrayList[SIZE_LEVELS.length];
+        baseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                // Find the cluster this item belongs to.
+                long size = item.getSize();
+                int i;
+                for (i = 0; i < SIZE_LEVELS.length - 1; i++) {
+                    if (size < SIZE_LEVELS[i + 1]) {
+                        break;
+                    }
+                }
+
+                ArrayList<Path> list = group[i];
+                if (list == null) {
+                    list = new ArrayList<Path>();
+                    group[i] = list;
+                }
+                list.add(item.getPath());
+            }
+        });
+
+        int count = 0;
+        for (int i = 0; i < group.length; i++) {
+            if (group[i] != null) {
+                count++;
+            }
+        }
+
+        mClusters = (ArrayList<Path>[]) new ArrayList[count];
+        mNames = new String[count];
+        mMinSizes = new long[count];
+
+        Resources res = mContext.getResources();
+        int k = 0;
+        // Go through group in the reverse order, so the group with the largest
+        // size will show first.
+        for (int i = group.length - 1; i >= 0; i--) {
+            if (group[i] == null) continue;
+
+            mClusters[k] = group[i];
+            if (i == 0) {
+                mNames[k] = String.format(
+                        res.getString(R.string.size_below), getSizeString(i + 1));
+            } else if (i == group.length - 1) {
+                mNames[k] = String.format(
+                        res.getString(R.string.size_above), getSizeString(i));
+            } else {
+                String minSize = getSizeString(i);
+                String maxSize = getSizeString(i + 1);
+                mNames[k] = String.format(
+                        res.getString(R.string.size_between), minSize, maxSize);
+            }
+            mMinSizes[k] = SIZE_LEVELS[i];
+            k++;
+        }
+    }
+
+    private String getSizeString(int index) {
+        long bytes = SIZE_LEVELS[index];
+        if (bytes >= GIGA_BYTES) {
+            return (bytes / GIGA_BYTES) + "GB";
+        } else {
+            return (bytes / MEGA_BYTES) + "MB";
+        }
+    }
+
+    @Override
+    public int getNumberOfClusters() {
+        return mClusters.length;
+    }
+
+    @Override
+    public ArrayList<Path> getCluster(int index) {
+        return mClusters[index];
+    }
+
+    @Override
+    public String getClusterName(int index) {
+        return mNames[index];
+    }
+
+    public long getMinSize(int index) {
+        return mMinSizes[index];
+    }
+}
diff --git a/src/com/android/gallery3d/data/TagClustering.java b/src/com/android/gallery3d/data/TagClustering.java
new file mode 100644
index 0000000..c873051
--- /dev/null
+++ b/src/com/android/gallery3d/data/TagClustering.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.R;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class TagClustering extends Clustering {
+    @SuppressWarnings("unused")
+    private static final String TAG = "TagClustering";
+
+    private ArrayList<ArrayList<Path>> mClusters;
+    private String[] mNames;
+    private String mUntaggedString;
+
+    public TagClustering(Context context) {
+        mUntaggedString = context.getResources().getString(R.string.untagged);
+    }
+
+    @Override
+    public void run(MediaSet baseSet) {
+        final TreeMap<String, ArrayList<Path>> map =
+                new TreeMap<String, ArrayList<Path>>();
+        final ArrayList<Path> untagged = new ArrayList<Path>();
+
+        baseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                Path path = item.getPath();
+
+                String[] tags = item.getTags();
+                if (tags == null || tags.length == 0) {
+                    untagged.add(path);
+                    return;
+                }
+                for (int j = 0; j < tags.length; j++) {
+                    String key = tags[j];
+                    ArrayList<Path> list = map.get(key);
+                    if (list == null) {
+                        list = new ArrayList<Path>();
+                        map.put(key, list);
+                    }
+                    list.add(path);
+                }
+            }
+        });
+
+        int m = map.size();
+        mClusters = new ArrayList<ArrayList<Path>>();
+        mNames = new String[m + ((untagged.size() > 0) ? 1 : 0)];
+        int i = 0;
+        for (Map.Entry<String, ArrayList<Path>> entry : map.entrySet()) {
+            mNames[i++] = entry.getKey();
+            mClusters.add(entry.getValue());
+        }
+        if (untagged.size() > 0) {
+            mNames[i++] = mUntaggedString;
+            mClusters.add(untagged);
+        }
+    }
+
+    @Override
+    public int getNumberOfClusters() {
+        return mClusters.size();
+    }
+
+    @Override
+    public ArrayList<Path> getCluster(int index) {
+        return mClusters.get(index);
+    }
+
+    @Override
+    public String getClusterName(int index) {
+        return mNames[index];
+    }
+}
diff --git a/src/com/android/gallery3d/data/TimeClustering.java b/src/com/android/gallery3d/data/TimeClustering.java
new file mode 100644
index 0000000..1ccf14c
--- /dev/null
+++ b/src/com/android/gallery3d/data/TimeClustering.java
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.Context;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class TimeClustering extends Clustering {
+    private static final String TAG = "TimeClustering";
+
+    // If 2 items are greater than 25 miles apart, they will be in different
+    // clusters.
+    private static final int GEOGRAPHIC_DISTANCE_CUTOFF_IN_MILES = 20;
+
+    // Do not want to split based on anything under 1 min.
+    private static final long MIN_CLUSTER_SPLIT_TIME_IN_MS = 60000L;
+
+    // Disregard a cluster split time of anything over 2 hours.
+    private static final long MAX_CLUSTER_SPLIT_TIME_IN_MS = 7200000L;
+
+    // Try and get around 9 clusters (best-effort for the common case).
+    private static final int NUM_CLUSTERS_TARGETED = 9;
+
+    // Try and merge 2 clusters if they are both smaller than min cluster size.
+    // The min cluster size can range from 8 to 15.
+    private static final int MIN_MIN_CLUSTER_SIZE = 8;
+    private static final int MAX_MIN_CLUSTER_SIZE = 15;
+
+    // Try and split a cluster if it is bigger than max cluster size.
+    // The max cluster size can range from 20 to 50.
+    private static final int MIN_MAX_CLUSTER_SIZE = 20;
+    private static final int MAX_MAX_CLUSTER_SIZE = 50;
+
+    // Initially put 2 items in the same cluster as long as they are within
+    // 3 cluster frequencies of each other.
+    private static int CLUSTER_SPLIT_MULTIPLIER = 3;
+
+    // The minimum change factor in the time between items to consider a
+    // partition.
+    // Example: (Item 3 - Item 2) / (Item 2 - Item 1).
+    private static final int MIN_PARTITION_CHANGE_FACTOR = 2;
+
+    // Make the cluster split time of a large cluster half that of a regular
+    // cluster.
+    private static final int PARTITION_CLUSTER_SPLIT_TIME_FACTOR = 2;
+
+    private Context mContext;
+    private ArrayList<Cluster> mClusters;
+    private String[] mNames;
+    private Cluster mCurrCluster;
+
+    private long mClusterSplitTime =
+            (MIN_CLUSTER_SPLIT_TIME_IN_MS + MAX_CLUSTER_SPLIT_TIME_IN_MS) / 2;
+    private long mLargeClusterSplitTime =
+            mClusterSplitTime / PARTITION_CLUSTER_SPLIT_TIME_FACTOR;
+    private int mMinClusterSize = (MIN_MIN_CLUSTER_SIZE + MAX_MIN_CLUSTER_SIZE) / 2;
+    private int mMaxClusterSize = (MIN_MAX_CLUSTER_SIZE + MAX_MAX_CLUSTER_SIZE) / 2;
+
+
+    private static final Comparator<SmallItem> sDateComparator =
+            new DateComparator();
+
+    private static class DateComparator implements Comparator<SmallItem> {
+        public int compare(SmallItem item1, SmallItem item2) {
+            return -Utils.compare(item1.dateInMs, item2.dateInMs);
+        }
+    }
+
+    public TimeClustering(Context context) {
+        mContext = context;
+        mClusters = new ArrayList<Cluster>();
+        mCurrCluster = new Cluster();
+    }
+
+    @Override
+    public void run(MediaSet baseSet) {
+        final int total = baseSet.getTotalMediaItemCount();
+        final SmallItem[] buf = new SmallItem[total];
+        final double[] latLng = new double[2];
+
+        baseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
+            public void consume(int index, MediaItem item) {
+                if (index < 0 || index >= total) return;
+                SmallItem s = new SmallItem();
+                s.path = item.getPath();
+                s.dateInMs = item.getDateInMs();
+                item.getLatLong(latLng);
+                s.lat = latLng[0];
+                s.lng = latLng[1];
+                buf[index] = s;
+            }
+        });
+
+        ArrayList<SmallItem> items = new ArrayList<SmallItem>(total);
+        for (int i = 0; i < total; i++) {
+            if (buf[i] != null) {
+                items.add(buf[i]);
+            }
+        }
+
+        Collections.sort(items, sDateComparator);
+
+        int n = items.size();
+        long minTime = 0;
+        long maxTime = 0;
+        for (int i = 0; i < n; i++) {
+            long t = items.get(i).dateInMs;
+            if (t == 0) continue;
+            if (minTime == 0) {
+                minTime = maxTime = t;
+            } else {
+                minTime = Math.min(minTime, t);
+                maxTime = Math.max(maxTime, t);
+            }
+        }
+
+        setTimeRange(maxTime - minTime, n);
+
+        for (int i = 0; i < n; i++) {
+            compute(items.get(i));
+        }
+
+        compute(null);
+
+        int m = mClusters.size();
+        mNames = new String[m];
+        for (int i = 0; i < m; i++) {
+            mNames[i] = mClusters.get(i).generateCaption(mContext);
+        }
+    }
+
+    @Override
+    public int getNumberOfClusters() {
+        return mClusters.size();
+    }
+
+    @Override
+    public ArrayList<Path> getCluster(int index) {
+        ArrayList<SmallItem> items = mClusters.get(index).getItems();
+        ArrayList<Path> result = new ArrayList<Path>(items.size());
+        for (int i = 0, n = items.size(); i < n; i++) {
+            result.add(items.get(i).path);
+        }
+        return result;
+    }
+
+    @Override
+    public String getClusterName(int index) {
+        return mNames[index];
+    }
+
+    private void setTimeRange(long timeRange, int numItems) {
+        if (numItems != 0) {
+            int meanItemsPerCluster = numItems / NUM_CLUSTERS_TARGETED;
+            // Heuristic to get min and max cluster size - half and double the
+            // desired items per cluster.
+            mMinClusterSize = meanItemsPerCluster / 2;
+            mMaxClusterSize = meanItemsPerCluster * 2;
+            mClusterSplitTime = timeRange / numItems * CLUSTER_SPLIT_MULTIPLIER;
+        }
+        mClusterSplitTime = Utils.clamp(mClusterSplitTime, MIN_CLUSTER_SPLIT_TIME_IN_MS, MAX_CLUSTER_SPLIT_TIME_IN_MS);
+        mLargeClusterSplitTime = mClusterSplitTime / PARTITION_CLUSTER_SPLIT_TIME_FACTOR;
+        mMinClusterSize = Utils.clamp(mMinClusterSize, MIN_MIN_CLUSTER_SIZE, MAX_MIN_CLUSTER_SIZE);
+        mMaxClusterSize = Utils.clamp(mMaxClusterSize, MIN_MAX_CLUSTER_SIZE, MAX_MAX_CLUSTER_SIZE);
+    }
+
+    private void compute(SmallItem currentItem) {
+        if (currentItem != null) {
+            int numClusters = mClusters.size();
+            int numCurrClusterItems = mCurrCluster.size();
+            boolean geographicallySeparateItem = false;
+            boolean itemAddedToCurrentCluster = false;
+
+            // Determine if this item should go in the current cluster or be the
+            // start of a new cluster.
+            if (numCurrClusterItems == 0) {
+                mCurrCluster.addItem(currentItem);
+            } else {
+                SmallItem prevItem = mCurrCluster.getLastItem();
+                if (isGeographicallySeparated(prevItem, currentItem)) {
+                    mClusters.add(mCurrCluster);
+                    geographicallySeparateItem = true;
+                } else if (numCurrClusterItems > mMaxClusterSize) {
+                    splitAndAddCurrentCluster();
+                } else if (timeDistance(prevItem, currentItem) < mClusterSplitTime) {
+                    mCurrCluster.addItem(currentItem);
+                    itemAddedToCurrentCluster = true;
+                } else if (numClusters > 0 && numCurrClusterItems < mMinClusterSize
+                        && !mCurrCluster.mGeographicallySeparatedFromPrevCluster) {
+                    mergeAndAddCurrentCluster();
+                } else {
+                    mClusters.add(mCurrCluster);
+                }
+
+                // Creating a new cluster and adding the current item to it.
+                if (!itemAddedToCurrentCluster) {
+                    mCurrCluster = new Cluster();
+                    if (geographicallySeparateItem) {
+                        mCurrCluster.mGeographicallySeparatedFromPrevCluster = true;
+                    }
+                    mCurrCluster.addItem(currentItem);
+                }
+            }
+        } else {
+            if (mCurrCluster.size() > 0) {
+                int numClusters = mClusters.size();
+                int numCurrClusterItems = mCurrCluster.size();
+
+                // The last cluster may potentially be too big or too small.
+                if (numCurrClusterItems > mMaxClusterSize) {
+                    splitAndAddCurrentCluster();
+                } else if (numClusters > 0 && numCurrClusterItems < mMinClusterSize
+                        && !mCurrCluster.mGeographicallySeparatedFromPrevCluster) {
+                    mergeAndAddCurrentCluster();
+                } else {
+                    mClusters.add(mCurrCluster);
+                }
+                mCurrCluster = new Cluster();
+            }
+        }
+    }
+
+    private void splitAndAddCurrentCluster() {
+        ArrayList<SmallItem> currClusterItems = mCurrCluster.getItems();
+        int numCurrClusterItems = mCurrCluster.size();
+        int secondPartitionStartIndex = getPartitionIndexForCurrentCluster();
+        if (secondPartitionStartIndex != -1) {
+            Cluster partitionedCluster = new Cluster();
+            for (int j = 0; j < secondPartitionStartIndex; j++) {
+                partitionedCluster.addItem(currClusterItems.get(j));
+            }
+            mClusters.add(partitionedCluster);
+            partitionedCluster = new Cluster();
+            for (int j = secondPartitionStartIndex; j < numCurrClusterItems; j++) {
+                partitionedCluster.addItem(currClusterItems.get(j));
+            }
+            mClusters.add(partitionedCluster);
+        } else {
+            mClusters.add(mCurrCluster);
+        }
+    }
+
+    private int getPartitionIndexForCurrentCluster() {
+        int partitionIndex = -1;
+        float largestChange = MIN_PARTITION_CHANGE_FACTOR;
+        ArrayList<SmallItem> currClusterItems = mCurrCluster.getItems();
+        int numCurrClusterItems = mCurrCluster.size();
+        int minClusterSize = mMinClusterSize;
+
+        // Could be slightly more efficient here but this code seems cleaner.
+        if (numCurrClusterItems > minClusterSize + 1) {
+            for (int i = minClusterSize; i < numCurrClusterItems - minClusterSize; i++) {
+                SmallItem prevItem = currClusterItems.get(i - 1);
+                SmallItem currItem = currClusterItems.get(i);
+                SmallItem nextItem = currClusterItems.get(i + 1);
+
+                long timeNext = nextItem.dateInMs;
+                long timeCurr = currItem.dateInMs;
+                long timePrev = prevItem.dateInMs;
+
+                if (timeNext == 0 || timeCurr == 0 || timePrev == 0) continue;
+
+                long diff1 = Math.abs(timeNext - timeCurr);
+                long diff2 = Math.abs(timeCurr - timePrev);
+
+                float change = Math.max(diff1 / (diff2 + 0.01f), diff2 / (diff1 + 0.01f));
+                if (change > largestChange) {
+                    if (timeDistance(currItem, prevItem) > mLargeClusterSplitTime) {
+                        partitionIndex = i;
+                        largestChange = change;
+                    } else if (timeDistance(nextItem, currItem) > mLargeClusterSplitTime) {
+                        partitionIndex = i + 1;
+                        largestChange = change;
+                    }
+                }
+            }
+        }
+        return partitionIndex;
+    }
+
+    private void mergeAndAddCurrentCluster() {
+        int numClusters = mClusters.size();
+        Cluster prevCluster = mClusters.get(numClusters - 1);
+        ArrayList<SmallItem> currClusterItems = mCurrCluster.getItems();
+        int numCurrClusterItems = mCurrCluster.size();
+        if (prevCluster.size() < mMinClusterSize) {
+            for (int i = 0; i < numCurrClusterItems; i++) {
+                prevCluster.addItem(currClusterItems.get(i));
+            }
+            mClusters.set(numClusters - 1, prevCluster);
+        } else {
+            mClusters.add(mCurrCluster);
+        }
+    }
+
+    // Returns true if a, b are sufficiently geographically separated.
+    private static boolean isGeographicallySeparated(SmallItem itemA, SmallItem itemB) {
+        if (!GalleryUtils.isValidLocation(itemA.lat, itemA.lng)
+                || !GalleryUtils.isValidLocation(itemB.lat, itemB.lng)) {
+            return false;
+        }
+
+        double distance = GalleryUtils.fastDistanceMeters(
+            Math.toRadians(itemA.lat),
+            Math.toRadians(itemA.lng),
+            Math.toRadians(itemB.lat),
+            Math.toRadians(itemB.lng));
+        return (GalleryUtils.toMile(distance) > GEOGRAPHIC_DISTANCE_CUTOFF_IN_MILES);
+    }
+
+    // Returns the time interval between the two items in milliseconds.
+    private static long timeDistance(SmallItem a, SmallItem b) {
+        return Math.abs(a.dateInMs - b.dateInMs);
+    }
+}
+
+class SmallItem {
+    Path path;
+    long dateInMs;
+    double lat, lng;
+}
+
+class Cluster {
+    @SuppressWarnings("unused")
+    private static final String TAG = "Cluster";
+    private static final String MMDDYY_FORMAT = "MMddyy";
+
+    // This is for TimeClustering only.
+    public boolean mGeographicallySeparatedFromPrevCluster = false;
+
+    private ArrayList<SmallItem> mItems = new ArrayList<SmallItem>();
+
+    public Cluster() {
+    }
+
+    public void addItem(SmallItem item) {
+        mItems.add(item);
+    }
+
+    public int size() {
+        return mItems.size();
+    }
+
+    public SmallItem getLastItem() {
+        int n = mItems.size();
+        return (n == 0) ? null : mItems.get(n - 1);
+    }
+
+    public ArrayList<SmallItem> getItems() {
+        return mItems;
+    }
+
+    public String generateCaption(Context context) {
+        int n = mItems.size();
+        long minTimestamp = 0;
+        long maxTimestamp = 0;
+
+        for (int i = 0; i < n; i++) {
+            long t = mItems.get(i).dateInMs;
+            if (t == 0) continue;
+            if (minTimestamp == 0) {
+                minTimestamp = maxTimestamp = t;
+            } else {
+                minTimestamp = Math.min(minTimestamp, t);
+                maxTimestamp = Math.max(maxTimestamp, t);
+            }
+        }
+        if (minTimestamp == 0) return "";
+
+        String caption;
+        String minDay = DateFormat.format(MMDDYY_FORMAT, minTimestamp)
+                .toString();
+        String maxDay = DateFormat.format(MMDDYY_FORMAT, maxTimestamp)
+                .toString();
+
+        if (minDay.substring(4).equals(maxDay.substring(4))) {
+            // The items are from the same year - show at least as
+            // much granularity as abbrev_all allows.
+            caption = DateUtils.formatDateRange(context, minTimestamp,
+                    maxTimestamp, DateUtils.FORMAT_ABBREV_ALL);
+
+            // Get a more granular date range string if the min and
+            // max timestamp are on the same day and from the
+            // current year.
+            if (minDay.equals(maxDay)) {
+                int flags = DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_SHOW_DATE;
+                // Contains the year only if the date does not
+                // correspond to the current year.
+                String dateRangeWithOptionalYear = DateUtils.formatDateTime(
+                        context, minTimestamp, flags);
+                String dateRangeWithYear = DateUtils.formatDateTime(
+                        context, minTimestamp, flags | DateUtils.FORMAT_SHOW_YEAR);
+                if (!dateRangeWithOptionalYear.equals(dateRangeWithYear)) {
+                    // This means both dates are from the same year
+                    // - show the time.
+                    // Not enough room to display the time range.
+                    // Pick the mid-point.
+                    long midTimestamp = (minTimestamp + maxTimestamp) / 2;
+                    caption = DateUtils.formatDateRange(context, midTimestamp,
+                            midTimestamp, DateUtils.FORMAT_SHOW_TIME | flags);
+                }
+            }
+        } else {
+            // The items are not from the same year - only show
+            // month and year.
+            int flags = DateUtils.FORMAT_NO_MONTH_DAY
+                    | DateUtils.FORMAT_ABBREV_MONTH | DateUtils.FORMAT_SHOW_DATE;
+            caption = DateUtils.formatDateRange(context, minTimestamp,
+                    maxTimestamp, flags);
+        }
+
+        return caption;
+    }
+}
diff --git a/src/com/android/gallery3d/data/UriImage.java b/src/com/android/gallery3d/data/UriImage.java
new file mode 100644
index 0000000..3a7ed7c
--- /dev/null
+++ b/src/com/android/gallery3d/data/UriImage.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.ContentResolver;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory.Options;
+import android.graphics.BitmapRegionDecoder;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.webkit.MimeTypeMap;
+
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.net.URL;
+
+public class UriImage extends MediaItem {
+    private static final String TAG = "UriImage";
+
+    private static final int STATE_INIT = 0;
+    private static final int STATE_DOWNLOADING = 1;
+    private static final int STATE_DOWNLOADED = 2;
+    private static final int STATE_ERROR = -1;
+
+    private final Uri mUri;
+    private final String mContentType;
+
+    private DownloadCache.Entry mCacheEntry;
+    private ParcelFileDescriptor mFileDescriptor;
+    private int mState = STATE_INIT;
+    private int mWidth;
+    private int mHeight;
+
+    private GalleryApp mApplication;
+
+    public UriImage(GalleryApp application, Path path, Uri uri) {
+        super(path, nextVersionNumber());
+        mUri = uri;
+        mApplication = Utils.checkNotNull(application);
+        mContentType = getMimeType(uri);
+    }
+
+    private String getMimeType(Uri uri) {
+        if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
+            String extension =
+                    MimeTypeMap.getFileExtensionFromUrl(uri.toString());
+            String type = MimeTypeMap.getSingleton()
+                    .getMimeTypeFromExtension(extension);
+            if (type != null) return type;
+        }
+        return mApplication.getContentResolver().getType(uri);
+    }
+
+    @Override
+    public Job<Bitmap> requestImage(int type) {
+        return new BitmapJob(type);
+    }
+
+    @Override
+    public Job<BitmapRegionDecoder> requestLargeImage() {
+        return new RegionDecoderJob();
+    }
+
+    private void openFileOrDownloadTempFile(JobContext jc) {
+        int state = openOrDownloadInner(jc);
+        synchronized (this) {
+            mState = state;
+            if (mState != STATE_DOWNLOADED) {
+                if (mFileDescriptor != null) {
+                    Utils.closeSilently(mFileDescriptor);
+                    mFileDescriptor = null;
+                }
+            }
+            notifyAll();
+        }
+    }
+
+    private int openOrDownloadInner(JobContext jc) {
+        String scheme = mUri.getScheme();
+        if (ContentResolver.SCHEME_CONTENT.equals(scheme)
+                || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)
+                || ContentResolver.SCHEME_FILE.equals(scheme)) {
+            try {
+                mFileDescriptor = mApplication.getContentResolver()
+                        .openFileDescriptor(mUri, "r");
+                if (jc.isCancelled()) return STATE_INIT;
+                return STATE_DOWNLOADED;
+            } catch (FileNotFoundException e) {
+                Log.w(TAG, "fail to open: " + mUri, e);
+                return STATE_ERROR;
+            }
+        } else {
+            try {
+                URL url = new URI(mUri.toString()).toURL();
+                mCacheEntry = mApplication.getDownloadCache().download(jc, url);
+                if (jc.isCancelled()) return STATE_INIT;
+                if (mCacheEntry == null) {
+                    Log.w(TAG, "download failed " + url);
+                    return STATE_ERROR;
+                }
+                mFileDescriptor = ParcelFileDescriptor.open(
+                        mCacheEntry.cacheFile, ParcelFileDescriptor.MODE_READ_ONLY);
+                return STATE_DOWNLOADED;
+            } catch (Throwable t) {
+                Log.w(TAG, "download error", t);
+                return STATE_ERROR;
+            }
+        }
+    }
+
+    private boolean prepareInputFile(JobContext jc) {
+        jc.setCancelListener(new CancelListener() {
+            public void onCancel() {
+                synchronized (this) {
+                    notifyAll();
+                }
+            }
+        });
+
+        while (true) {
+            synchronized (this) {
+                if (jc.isCancelled()) return false;
+                if (mState == STATE_INIT) {
+                    mState = STATE_DOWNLOADING;
+                    // Then leave the synchronized block and continue.
+                } else if (mState == STATE_ERROR) {
+                    return false;
+                } else if (mState == STATE_DOWNLOADED) {
+                    return true;
+                } else /* if (mState == STATE_DOWNLOADING) */ {
+                    try {
+                        wait();
+                    } catch (InterruptedException ex) {
+                        // ignored.
+                    }
+                    continue;
+                }
+            }
+            // This is only reached for STATE_INIT->STATE_DOWNLOADING
+            openFileOrDownloadTempFile(jc);
+        }
+    }
+
+    private class RegionDecoderJob implements Job<BitmapRegionDecoder> {
+        public BitmapRegionDecoder run(JobContext jc) {
+            if (!prepareInputFile(jc)) return null;
+            BitmapRegionDecoder decoder = DecodeUtils.requestCreateBitmapRegionDecoder(
+                    jc, mFileDescriptor.getFileDescriptor(), false);
+            mWidth = decoder.getWidth();
+            mHeight = decoder.getHeight();
+            return decoder;
+        }
+    }
+
+    private class BitmapJob implements Job<Bitmap> {
+        private int mType;
+
+        protected BitmapJob(int type) {
+            mType = type;
+        }
+
+        public Bitmap run(JobContext jc) {
+            if (!prepareInputFile(jc)) return null;
+            int targetSize = LocalImage.getTargetSize(mType);
+            Options options = new Options();
+            options.inPreferredConfig = Config.ARGB_8888;
+            Bitmap bitmap = DecodeUtils.requestDecode(jc,
+                    mFileDescriptor.getFileDescriptor(), options, targetSize);
+            if (jc.isCancelled() || bitmap == null) {
+                return null;
+            }
+
+            if (mType == MediaItem.TYPE_MICROTHUMBNAIL) {
+                bitmap = BitmapUtils.resizeDownAndCropCenter(bitmap,
+                        targetSize, true);
+            } else {
+                bitmap = BitmapUtils.resizeDownBySideLength(bitmap,
+                        targetSize, true);
+            }
+
+            return bitmap;
+        }
+    }
+
+    @Override
+    public int getSupportedOperations() {
+        int supported = SUPPORT_EDIT | SUPPORT_SETAS;
+        if (isSharable()) supported |= SUPPORT_SHARE;
+        if (BitmapUtils.isSupportedByRegionDecoder(mContentType)) {
+            supported |= SUPPORT_FULL_IMAGE;
+        }
+        return supported;
+    }
+
+    private boolean isSharable() {
+        // We cannot grant read permission to the receiver since we put
+        // the data URI in EXTRA_STREAM instead of the data part of an intent
+        // And there are issues in MediaUploader and Bluetooth file sender to
+        // share a general image data. So, we only share for local file.
+        return ContentResolver.SCHEME_FILE.equals(mUri.getScheme());
+    }
+
+    @Override
+    public int getMediaType() {
+        return MEDIA_TYPE_IMAGE;
+    }
+
+    @Override
+    public Uri getContentUri() {
+        return mUri;
+    }
+
+    @Override
+    public MediaDetails getDetails() {
+        MediaDetails details = super.getDetails();
+        if (mWidth != 0 && mHeight != 0) {
+            details.addDetail(MediaDetails.INDEX_WIDTH, mWidth);
+            details.addDetail(MediaDetails.INDEX_HEIGHT, mHeight);
+        }
+        details.addDetail(MediaDetails.INDEX_MIMETYPE, mContentType);
+        if (ContentResolver.SCHEME_FILE.equals(mUri.getScheme())) {
+            String filePath = mUri.getPath();
+            details.addDetail(MediaDetails.INDEX_PATH, filePath);
+            MediaDetails.extractExifInfo(details, filePath);
+        }
+        return details;
+    }
+
+    @Override
+    public String getMimeType() {
+        return mContentType;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mFileDescriptor != null) {
+                Utils.closeSilently(mFileDescriptor);
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/data/UriSource.java b/src/com/android/gallery3d/data/UriSource.java
new file mode 100644
index 0000000..ac62b93
--- /dev/null
+++ b/src/com/android/gallery3d/data/UriSource.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.data;
+
+import com.android.gallery3d.app.GalleryApp;
+
+import android.net.Uri;
+
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+
+class UriSource extends MediaSource {
+    @SuppressWarnings("unused")
+    private static final String TAG = "UriSource";
+
+    private GalleryApp mApplication;
+
+    public UriSource(GalleryApp context) {
+        super("uri");
+        mApplication = context;
+    }
+
+    @Override
+    public MediaObject createMediaObject(Path path) {
+        String segment[] = path.split();
+        if (segment.length != 2) {
+            throw new RuntimeException("bad path: " + path);
+        }
+
+        String decoded = URLDecoder.decode(segment[1]);
+        return new UriImage(mApplication, path, Uri.parse(decoded));
+    }
+
+    @Override
+    public Path findPathByUri(Uri uri) {
+        String type = mApplication.getContentResolver().getType(uri);
+        // Assume the type is image if the type cannot be resolved
+        // This could happen for "http" URI.
+        if (type == null || type.startsWith("image/")) {
+            return Path.fromString("/uri/" + URLEncoder.encode(uri.toString()));
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/gallery3d/provider/GalleryProvider.java b/src/com/android/gallery3d/provider/GalleryProvider.java
new file mode 100644
index 0000000..f5f0f1b
--- /dev/null
+++ b/src/com/android/gallery3d/provider/GalleryProvider.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.provider;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.DownloadCache;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MtpImage;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.picasasource.PicasaSource;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.provider.MediaStore.Images.ImageColumns;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class GalleryProvider extends ContentProvider {
+    private static final String TAG = "GalleryProvider";
+
+    public static final String AUTHORITY = "com.android.gallery3d.provider";
+    public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
+
+    private DataManager mDataManager;
+    private DownloadCache mDownloadCache;
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    // TODO: consider concurrent access
+    @Override
+    public String getType(Uri uri) {
+        long token = Binder.clearCallingIdentity();
+        try {
+            Path path = Path.fromString(uri.getPath());
+            MediaItem item = (MediaItem) mDataManager.getMediaObject(path);
+            return item != null ? item.getMimeType() : null;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean onCreate() {
+        GalleryApp app = (GalleryApp) getContext().getApplicationContext();
+        mDataManager = app.getDataManager();
+        return true;
+    }
+
+    private DownloadCache getDownloadCache() {
+        if (mDownloadCache == null) {
+            GalleryApp app = (GalleryApp) getContext().getApplicationContext();
+            mDownloadCache = app.getDownloadCache();
+        }
+        return mDownloadCache;
+    }
+
+    // TODO: consider concurrent access
+    @Override
+    public Cursor query(Uri uri, String[] projection,
+            String selection, String[] selectionArgs, String sortOrder) {
+        long token = Binder.clearCallingIdentity();
+        try {
+            Path path = Path.fromString(uri.getPath());
+            MediaObject object = mDataManager.getMediaObject(path);
+            if (object == null) {
+                Log.w(TAG, "cannot find: " + uri);
+                return null;
+            }
+            if (PicasaSource.isPicasaImage(object)) {
+                return queryPicasaItem(object,
+                        projection, selection, selectionArgs, sortOrder);
+            } else if (object instanceof MtpImage) {
+                return queryMtpItem((MtpImage) object,
+                        projection, selection, selectionArgs, sortOrder);
+            } else {
+                    return null;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private Cursor queryMtpItem(MtpImage image, String[] projection,
+            String selection, String[] selectionArgs, String sortOrder) {
+        Object[] columnValues = new Object[projection.length];
+        for (int i = 0, n = projection.length; i < n; ++i) {
+            String column = projection[i];
+            if (ImageColumns.DISPLAY_NAME.equals(column)) {
+                columnValues[i] = image.getName();
+            } else if (ImageColumns.SIZE.equals(column)){
+                columnValues[i] = image.getSize();
+            } else if (ImageColumns.MIME_TYPE.equals(column)) {
+                columnValues[i] = image.getMimeType();
+            } else if (ImageColumns.DATE_TAKEN.equals(column)) {
+                columnValues[i] = image.getDateInMs();
+            } else {
+                Log.w(TAG, "unsupported column: " + column);
+            }
+        }
+        MatrixCursor cursor = new MatrixCursor(projection);
+        cursor.addRow(columnValues);
+        return cursor;
+    }
+
+    private Cursor queryPicasaItem(MediaObject image, String[] projection,
+            String selection, String[] selectionArgs, String sortOrder) {
+        Object[] columnValues = new Object[projection.length];
+        double latitude = PicasaSource.getLatitude(image);
+        double longitude = PicasaSource.getLongitude(image);
+        boolean isValidLatlong = GalleryUtils.isValidLocation(latitude, longitude);
+
+        for (int i = 0, n = projection.length; i < n; ++i) {
+            String column = projection[i];
+            if (ImageColumns.DISPLAY_NAME.equals(column)) {
+                columnValues[i] = PicasaSource.getImageTitle(image);
+            } else if (ImageColumns.SIZE.equals(column)){
+                columnValues[i] = PicasaSource.getImageSize(image);
+            } else if (ImageColumns.MIME_TYPE.equals(column)) {
+                columnValues[i] = PicasaSource.getContentType(image);
+            } else if (ImageColumns.DATE_TAKEN.equals(column)) {
+                columnValues[i] = PicasaSource.getDateTaken(image);
+            } else if (ImageColumns.LATITUDE.equals(column)) {
+                columnValues[i] = isValidLatlong ? latitude : null;
+            } else if (ImageColumns.LONGITUDE.equals(column)) {
+                columnValues[i] = isValidLatlong ? longitude : null;
+            } else if (ImageColumns.ORIENTATION.equals(column)) {
+                columnValues[i] = PicasaSource.getRotation(image);
+            } else {
+                Log.w(TAG, "unsupported column: " + column);
+            }
+        }
+        MatrixCursor cursor = new MatrixCursor(projection);
+        cursor.addRow(columnValues);
+        return cursor;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode)
+            throws FileNotFoundException {
+        long token = Binder.clearCallingIdentity();
+        try {
+            if (mode.contains("w")) {
+                throw new FileNotFoundException("cannot open file for write");
+            }
+            Path path = Path.fromString(uri.getPath());
+            MediaObject object = mDataManager.getMediaObject(path);
+            if (object == null) {
+                throw new FileNotFoundException(uri.toString());
+            }
+            if (PicasaSource.isPicasaImage(object)) {
+                return PicasaSource.openFile(getContext(), object, mode);
+            } else if (object instanceof MtpImage) {
+                return openPipeHelper(uri, null, null, null,
+                        new MtpPipeDataWriter((MtpImage) object));
+            } else {
+                throw new FileNotFoundException("unspported type: " + object);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    private final class MtpPipeDataWriter implements PipeDataWriter<Object> {
+        private final MtpImage mImage;
+
+        private MtpPipeDataWriter(MtpImage image) {
+            mImage = image;
+        }
+
+        @Override
+        public void writeDataToPipe(ParcelFileDescriptor output,
+                Uri uri, String mimeType, Bundle opts, Object args) {
+            OutputStream os = null;
+            try {
+                os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+                os.write(mImage.getImageData());
+            } catch (IOException e) {
+                Log.w(TAG, "fail to download: " + uri, e);
+            } finally {
+                Utils.closeSilently(os);
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/AbstractDisplayItem.java b/src/com/android/gallery3d/ui/AbstractDisplayItem.java
new file mode 100644
index 0000000..aad3919
--- /dev/null
+++ b/src/com/android/gallery3d/ui/AbstractDisplayItem.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.data.MediaItem;
+
+import android.graphics.Bitmap;
+
+public abstract class AbstractDisplayItem extends DisplayItem {
+
+    private static final String TAG = "AbstractDisplayItem";
+
+    private static final int STATE_INVALID = 0x01;
+    private static final int STATE_VALID = 0x02;
+    private static final int STATE_UPDATING = 0x04;
+    private static final int STATE_CANCELING = 0x08;
+    private static final int STATE_ERROR = 0x10;
+
+    private int mState = STATE_INVALID;
+    private boolean mImageRequested = false;
+    private boolean mRecycling = false;
+    private Bitmap mBitmap;
+
+    protected final MediaItem mMediaItem;
+    private int mRotation;
+
+    public AbstractDisplayItem(MediaItem item) {
+        mMediaItem = item;
+        if (item == null) mState = STATE_ERROR;
+        if (item != null) mRotation = mMediaItem.getRotation();
+    }
+
+    protected void updateImage(Bitmap bitmap, boolean isCancelled) {
+        if (mRecycling) {
+            return;
+        }
+
+        if (isCancelled && bitmap == null) {
+            mState = STATE_INVALID;
+            if (mImageRequested) {
+                // request image again.
+                requestImage();
+            }
+            return;
+        }
+
+        mBitmap = bitmap;
+        mState = bitmap == null ? STATE_ERROR : STATE_VALID ;
+        onBitmapAvailable(mBitmap);
+    }
+
+    @Override
+    public int getRotation() {
+        return mRotation;
+    }
+
+    @Override
+    public long getIdentity() {
+        return mMediaItem != null
+                ? System.identityHashCode(mMediaItem.getPath())
+                : System.identityHashCode(this);
+    }
+
+    public void requestImage() {
+        mImageRequested = true;
+        if (mState == STATE_INVALID) {
+            mState = STATE_UPDATING;
+            startLoadBitmap();
+        }
+    }
+
+    public void cancelImageRequest() {
+        mImageRequested = false;
+        if (mState == STATE_UPDATING) {
+            mState = STATE_CANCELING;
+            cancelLoadBitmap();
+        }
+    }
+
+    private boolean inState(int states) {
+        return (mState & states) != 0;
+    }
+
+    public void recycle() {
+        if (!inState(STATE_UPDATING | STATE_CANCELING)) {
+            if (mBitmap != null) mBitmap = null;
+        } else {
+            mRecycling = true;
+            cancelImageRequest();
+        }
+    }
+
+    public boolean isRequestInProgress() {
+        return mImageRequested && inState(STATE_UPDATING | STATE_CANCELING);
+    }
+
+    abstract protected void startLoadBitmap();
+    abstract protected void cancelLoadBitmap();
+    abstract protected void onBitmapAvailable(Bitmap bitmap);
+}
diff --git a/src/com/android/gallery3d/ui/ActionModeHandler.java b/src/com/android/gallery3d/ui/ActionModeHandler.java
new file mode 100644
index 0000000..6c81a3f
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ActionModeHandler.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryActionBar;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.CustomMenu.DropDownMenu;
+import com.android.gallery3d.ui.MenuExecutor.ProgressListener;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.view.ActionMode;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.PopupMenu.OnMenuItemClickListener;
+import android.widget.ShareActionProvider;
+
+import java.util.ArrayList;
+
+public class ActionModeHandler implements ActionMode.Callback {
+    private static final String TAG = "ActionModeHandler";
+    private static final int SUPPORT_MULTIPLE_MASK = MediaObject.SUPPORT_DELETE
+            | MediaObject.SUPPORT_ROTATE | MediaObject.SUPPORT_SHARE
+            | MediaObject.SUPPORT_CACHE | MediaObject.SUPPORT_IMPORT;
+
+    public interface ActionModeListener {
+        public boolean onActionItemClicked(MenuItem item);
+    }
+
+    private final GalleryActivity mActivity;
+    private final MenuExecutor mMenuExecutor;
+    private final SelectionManager mSelectionManager;
+    private Menu mMenu;
+    private DropDownMenu mSelectionMenu;
+    private ActionModeListener mListener;
+    private Future<?> mMenuTask;
+    private Handler mMainHandler;
+    private ShareActionProvider mShareActionProvider;
+
+    public ActionModeHandler(
+            GalleryActivity activity, SelectionManager selectionManager) {
+        mActivity = Utils.checkNotNull(activity);
+        mSelectionManager = Utils.checkNotNull(selectionManager);
+        mMenuExecutor = new MenuExecutor(activity, selectionManager);
+        mMainHandler = new Handler(activity.getMainLooper());
+    }
+
+    public ActionMode startActionMode() {
+        Activity a = (Activity) mActivity;
+        final ActionMode actionMode = a.startActionMode(this);
+        CustomMenu customMenu = new CustomMenu(a);
+        View customView = LayoutInflater.from(a).inflate(
+                R.layout.action_mode, null);
+        actionMode.setCustomView(customView);
+        mSelectionMenu = customMenu.addDropDownMenu(
+                (Button) customView.findViewById(R.id.selection_menu),
+                R.menu.selection);
+        customMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
+            public boolean onMenuItemClick(MenuItem item) {
+                return onActionItemClicked(actionMode, item);
+            }
+        });
+        return actionMode;
+    }
+
+    public void setTitle(String title) {
+        mSelectionMenu.setTitle(title);
+    }
+
+    public void setActionModeListener(ActionModeListener listener) {
+        mListener = listener;
+    }
+
+    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+        boolean result;
+        if (mListener != null) {
+            result = mListener.onActionItemClicked(item);
+            if (result) {
+                mSelectionManager.leaveSelectionMode();
+                return result;
+            }
+        }
+        ProgressListener listener = null;
+        if (item.getItemId() == R.id.action_import) {
+            listener = new ImportCompleteListener(mActivity);
+        }
+        result = mMenuExecutor.onMenuClicked(item, listener);
+        if (item.getItemId() == R.id.action_select_all) {
+            updateSupportedOperation();
+
+            // For clients who call SelectionManager.selectAll() directly, we need to ensure the
+            // menu status is consistent with selection manager.
+            item = mSelectionMenu.findItem(R.id.action_select_all);
+            if (item != null) {
+                if (mSelectionManager.inSelectAllMode()) {
+                    item.setChecked(true);
+                    item.setTitle(R.string.deselect_all);
+                } else {
+                    item.setChecked(false);
+                    item.setTitle(R.string.select_all);
+                }
+            }
+        }
+        return result;
+    }
+
+    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+        MenuInflater inflater = mode.getMenuInflater();
+        inflater.inflate(R.menu.operation, menu);
+
+        mShareActionProvider = GalleryActionBar.initializeShareActionProvider(menu);
+
+        mMenu = menu;
+        return true;
+    }
+
+    public void onDestroyActionMode(ActionMode mode) {
+        mSelectionManager.leaveSelectionMode();
+    }
+
+    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+        return true;
+    }
+
+    private void updateMenuOptionsAndSharingIntent(JobContext jc) {
+        ArrayList<Path> paths = mSelectionManager.getSelected(true);
+        if (paths.size() == 0) return;
+
+        int operation = MediaObject.SUPPORT_ALL;
+        DataManager manager = mActivity.getDataManager();
+        final ArrayList<Uri> uris = new ArrayList<Uri>();
+        int type = 0;
+        for (Path path : paths) {
+            if (jc.isCancelled()) return;
+            int support = manager.getSupportedOperations(path);
+            type |= manager.getMediaType(path);
+            operation &= support;
+            if ((support & MediaObject.SUPPORT_SHARE) != 0) {
+                uris.add(manager.getContentUri(path));
+            }
+        }
+        final Intent intent = new Intent();
+        final String mimeType = MenuExecutor.getMimeType(type);
+
+        if (paths.size() == 1) {
+            if (!GalleryUtils.isEditorAvailable((Context) mActivity, mimeType)) {
+                operation &= ~MediaObject.SUPPORT_EDIT;
+            }
+        } else {
+            operation &= SUPPORT_MULTIPLE_MASK;
+        }
+
+
+        Log.v(TAG, "Sharing intent MIME type=" + mimeType + ", uri size = "+ uris.size());
+        if (uris.size() > 1) {
+            intent.setAction(Intent.ACTION_SEND_MULTIPLE).setType(mimeType);
+            intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
+        } else {
+            intent.setAction(Intent.ACTION_SEND).setType(mimeType);
+            intent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
+        }
+        intent.setType(mimeType);
+
+        final int supportedOperation = operation;
+
+        mMainHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mMenuTask = null;
+                MenuExecutor.updateMenuOperation(mMenu, supportedOperation);
+
+                if (mShareActionProvider != null) {
+                    Log.v(TAG, "Sharing intent is ready: action = " + intent.getAction());
+                    mShareActionProvider.setShareIntent(intent);
+                }
+            }
+        });
+    }
+
+    public void updateSupportedOperation(Path path, boolean selected) {
+        // TODO: We need to improve the performance
+        updateSupportedOperation();
+    }
+
+    public void updateSupportedOperation() {
+        if (mMenuTask != null) {
+            mMenuTask.cancel();
+        }
+
+        // Disable share action until share intent is in good shape
+        if (mShareActionProvider != null) {
+            Log.v(TAG, "Disable sharing until intent is ready");
+            mShareActionProvider.setShareIntent(null);
+        }
+
+        // Generate sharing intent and update supported operations in the background
+        mMenuTask = mActivity.getThreadPool().submit(new Job<Void>() {
+            public Void run(JobContext jc) {
+                updateMenuOptionsAndSharingIntent(jc);
+                return null;
+            }
+        });
+    }
+
+    public void pause() {
+        if (mMenuTask != null) {
+            mMenuTask.cancel();
+            mMenuTask = null;
+        }
+        mMenuExecutor.pause();
+    }
+
+    public void resume() {
+        updateSupportedOperation();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/AdaptiveBackground.java b/src/com/android/gallery3d/ui/AdaptiveBackground.java
new file mode 100644
index 0000000..42cb2cc
--- /dev/null
+++ b/src/com/android/gallery3d/ui/AdaptiveBackground.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.LightingColorFilter;
+import android.graphics.Paint;
+
+import com.android.gallery3d.anim.FloatAnimation;
+
+public class AdaptiveBackground extends GLView {
+
+    private static final int BACKGROUND_WIDTH = 128;
+    private static final int BACKGROUND_HEIGHT = 64;
+    private static final int FILTERED_COLOR = 0xffaaaaaa;
+    private static final int ANIMATION_DURATION = 500;
+
+    private BasicTexture mOldBackground;
+    private BasicTexture mBackground;
+
+    private final Paint mPaint;
+    private Bitmap mPendingBitmap;
+    private final FloatAnimation mAnimation =
+            new FloatAnimation(0, 1, ANIMATION_DURATION);
+
+    public AdaptiveBackground() {
+        Paint paint = new Paint();
+        paint.setFilterBitmap(true);
+        paint.setColorFilter(new LightingColorFilter(FILTERED_COLOR, 0));
+        mPaint = paint;
+    }
+
+    public Bitmap getAdaptiveBitmap(Bitmap bitmap) {
+        Bitmap target = Bitmap.createBitmap(
+                BACKGROUND_WIDTH, BACKGROUND_HEIGHT, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(target);
+        int width = bitmap.getWidth();
+        int height = bitmap.getHeight();
+        int left = 0;
+        int top = 0;
+        if (width * BACKGROUND_HEIGHT > height * BACKGROUND_WIDTH) {
+            float scale = (float) BACKGROUND_HEIGHT / height;
+            canvas.scale(scale, scale);
+            left = (BACKGROUND_WIDTH - (int) (width * scale + 0.5)) / 2;
+        } else {
+            float scale = (float) BACKGROUND_WIDTH / width;
+            canvas.scale(scale, scale);
+            top = (BACKGROUND_HEIGHT - (int) (height * scale + 0.5)) / 2;
+        }
+        canvas.drawBitmap(bitmap, left, top, mPaint);
+        BoxBlurFilter.apply(target,
+                BoxBlurFilter.MODE_REPEAT, BoxBlurFilter.MODE_CLAMP);
+        return target;
+    }
+
+    private void startTransition(Bitmap bitmap) {
+        BitmapTexture texture = new BitmapTexture(bitmap);
+        if (mBackground == null) {
+            mBackground = texture;
+        } else {
+            if (mOldBackground != null) mOldBackground.recycle();
+            mOldBackground = mBackground;
+            mBackground = texture;
+            mAnimation.start();
+        }
+        invalidate();
+    }
+
+    public void setImage(Bitmap bitmap) {
+        if (mAnimation.isActive()) {
+            mPendingBitmap = bitmap;
+        } else {
+            startTransition(bitmap);
+        }
+    }
+
+    public void setScrollPosition(int position) {
+        if (mScrollX == position) return;
+        mScrollX = position;
+        invalidate();
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        if (mBackground == null) return;
+
+        int height = getHeight();
+        float scale = (float) height / BACKGROUND_HEIGHT;
+        int width = (int) (BACKGROUND_WIDTH * scale + 0.5f);
+        int scroll = mScrollX;
+        int start = (scroll / width) * width;
+
+        if (mOldBackground == null) {
+            for (int i = start, n = scroll + getWidth(); i < n; i += width) {
+                mBackground.draw(canvas, i - scroll, 0, width, height);
+            }
+        } else {
+            boolean moreAnimation =
+                    mAnimation.calculate(canvas.currentAnimationTimeMillis());
+            float ratio = mAnimation.get();
+            for (int i = start, n = scroll + getWidth(); i < n; i += width) {
+                canvas.drawMixed(mOldBackground,
+                        mBackground, ratio, i - scroll, 0, width, height);
+            }
+            if (moreAnimation) {
+                invalidate();
+            } else if (mPendingBitmap != null) {
+                startTransition(mPendingBitmap);
+                mPendingBitmap = null;
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
new file mode 100644
index 0000000..92d8b41
--- /dev/null
+++ b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.AlbumSetView.AlbumSetItem;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.MediaSetUtils;
+import com.android.gallery3d.util.ThreadPool;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.os.Message;
+
+public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener {
+    private static final String TAG = "GallerySlidingWindow";
+    private static final int MSG_LOAD_BITMAP_DONE = 0;
+
+    public static interface Listener {
+        public void onSizeChanged(int size);
+        public void onContentInvalidated();
+        public void onWindowContentChanged(
+                int slot, AlbumSetItem old, AlbumSetItem update);
+    }
+
+    private final AlbumSetView.Model mSource;
+    private int mSize;
+    private int mLabelWidth;
+    private int mDisplayItemSize;
+    private int mLabelFontSize;
+
+    private int mContentStart = 0;
+    private int mContentEnd = 0;
+
+    private int mActiveStart = 0;
+    private int mActiveEnd = 0;
+
+    private Listener mListener;
+
+    private final MyAlbumSetItem mData[];
+    private SelectionDrawer mSelectionDrawer;
+    private final ColorTexture mWaitLoadingTexture;
+
+    private SynchronizedHandler mHandler;
+    private ThreadPool mThreadPool;
+
+    private int mActiveRequestCount = 0;
+    private String mLoadingLabel;
+    private boolean mIsActive = false;
+
+    private static class MyAlbumSetItem extends AlbumSetItem {
+        public Path setPath;
+        public int sourceType;
+        public int cacheFlag;
+        public int cacheStatus;
+    }
+
+    public AlbumSetSlidingWindow(GalleryActivity activity, int labelWidth,
+            int displayItemSize, int labelFontSize, SelectionDrawer drawer,
+            AlbumSetView.Model source, int cacheSize) {
+        source.setModelListener(this);
+        mLabelWidth = labelWidth;
+        mDisplayItemSize = displayItemSize;
+        mLabelFontSize = labelFontSize;
+        mLoadingLabel = activity.getAndroidContext().getString(R.string.loading);
+        mSource = source;
+        mSelectionDrawer = drawer;
+        mData = new MyAlbumSetItem[cacheSize];
+        mSize = source.size();
+
+        mWaitLoadingTexture = new ColorTexture(Color.TRANSPARENT);
+        mWaitLoadingTexture.setSize(1, 1);
+
+        mHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                Utils.assertTrue(message.what == MSG_LOAD_BITMAP_DONE);
+                ((GalleryDisplayItem) message.obj).onLoadBitmapDone();
+            }
+        };
+
+        mThreadPool = activity.getThreadPool();
+    }
+
+    public void setSelectionDrawer(SelectionDrawer drawer) {
+        mSelectionDrawer = drawer;
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    public AlbumSetItem get(int slotIndex) {
+        Utils.assertTrue(isActiveSlot(slotIndex),
+                "invalid slot: %s outsides (%s, %s)",
+                slotIndex, mActiveStart, mActiveEnd);
+        return mData[slotIndex % mData.length];
+    }
+
+    public int size() {
+        return mSize;
+    }
+
+    public boolean isActiveSlot(int slotIndex) {
+        return slotIndex >= mActiveStart && slotIndex < mActiveEnd;
+    }
+
+    private void setContentWindow(int contentStart, int contentEnd) {
+        if (contentStart == mContentStart && contentEnd == mContentEnd) return;
+
+        if (contentStart >= mContentEnd || mContentStart >= contentEnd) {
+            for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+                freeSlotContent(i);
+            }
+            mSource.setActiveWindow(contentStart, contentEnd);
+            for (int i = contentStart; i < contentEnd; ++i) {
+                prepareSlotContent(i);
+            }
+        } else {
+            for (int i = mContentStart; i < contentStart; ++i) {
+                freeSlotContent(i);
+            }
+            for (int i = contentEnd, n = mContentEnd; i < n; ++i) {
+                freeSlotContent(i);
+            }
+            mSource.setActiveWindow(contentStart, contentEnd);
+            for (int i = contentStart, n = mContentStart; i < n; ++i) {
+                prepareSlotContent(i);
+            }
+            for (int i = mContentEnd; i < contentEnd; ++i) {
+                prepareSlotContent(i);
+            }
+        }
+
+        mContentStart = contentStart;
+        mContentEnd = contentEnd;
+    }
+
+    public void setActiveWindow(int start, int end) {
+        Utils.assertTrue(
+                start <= end && end - start <= mData.length && end <= mSize,
+                "start = %s, end = %s, length = %s, size = %s",
+                start, end, mData.length, mSize);
+
+        AlbumSetItem data[] = mData;
+
+        mActiveStart = start;
+        mActiveEnd = end;
+
+        // If no data is visible, keep the cache content
+        if (start == end) return;
+
+        int contentStart = Utils.clamp((start + end) / 2 - data.length / 2,
+                0, Math.max(0, mSize - data.length));
+        int contentEnd = Math.min(contentStart + data.length, mSize);
+        setContentWindow(contentStart, contentEnd);
+        if (mIsActive) updateAllImageRequests();
+    }
+
+    // We would like to request non active slots in the following order:
+    // Order:    8 6 4 2                   1 3 5 7
+    //         |---------|---------------|---------|
+    //                   |<-  active  ->|
+    //         |<-------- cached range ----------->|
+    private void requestNonactiveImages() {
+        int range = Math.max(
+                mContentEnd - mActiveEnd, mActiveStart - mContentStart);
+        for (int i = 0 ;i < range; ++i) {
+            requestImagesInSlot(mActiveEnd + i);
+            requestImagesInSlot(mActiveStart - 1 - i);
+        }
+    }
+
+    private void cancelNonactiveImages() {
+        int range = Math.max(
+                mContentEnd - mActiveEnd, mActiveStart - mContentStart);
+        for (int i = 0 ;i < range; ++i) {
+            cancelImagesInSlot(mActiveEnd + i);
+            cancelImagesInSlot(mActiveStart - 1 - i);
+        }
+    }
+
+    private void requestImagesInSlot(int slotIndex) {
+        if (slotIndex < mContentStart || slotIndex >= mContentEnd) return;
+        AlbumSetItem items = mData[slotIndex % mData.length];
+        for (DisplayItem item : items.covers) {
+            ((GalleryDisplayItem) item).requestImage();
+        }
+    }
+
+    private void cancelImagesInSlot(int slotIndex) {
+        if (slotIndex < mContentStart || slotIndex >= mContentEnd) return;
+        AlbumSetItem items = mData[slotIndex % mData.length];
+        for (DisplayItem item : items.covers) {
+            ((GalleryDisplayItem) item).cancelImageRequest();
+        }
+    }
+
+    private void freeSlotContent(int slotIndex) {
+        AlbumSetItem data[] = mData;
+        int index = slotIndex % data.length;
+        AlbumSetItem original = data[index];
+        if (original != null) {
+            data[index] = null;
+            for (DisplayItem item : original.covers) {
+                ((GalleryDisplayItem) item).recycle();
+            }
+        }
+    }
+
+    private long getMediaSetDataVersion(MediaSet set) {
+        return set == null
+                ? MediaSet.INVALID_DATA_VERSION
+                : set.getDataVersion();
+    }
+
+    private void prepareSlotContent(int slotIndex) {
+        MediaSet set = mSource.getMediaSet(slotIndex);
+
+        MyAlbumSetItem item = new MyAlbumSetItem();
+        MediaItem[] coverItems = mSource.getCoverItems(slotIndex);
+        item.covers = new GalleryDisplayItem[coverItems.length];
+        item.sourceType = identifySourceType(set);
+        item.cacheFlag = identifyCacheFlag(set);
+        item.cacheStatus = identifyCacheStatus(set);
+        item.setPath = set == null ? null : set.getPath();
+
+        for (int i = 0; i < coverItems.length; ++i) {
+            item.covers[i] = new GalleryDisplayItem(slotIndex, i, coverItems[i]);
+        }
+        item.labelItem = new LabelDisplayItem(slotIndex);
+        item.setDataVersion = getMediaSetDataVersion(set);
+        mData[slotIndex % mData.length] = item;
+    }
+
+    private boolean isCoverItemsChanged(int slotIndex) {
+        AlbumSetItem original = mData[slotIndex % mData.length];
+        if (original == null) return true;
+        MediaItem[] coverItems = mSource.getCoverItems(slotIndex);
+
+        if (original.covers.length != coverItems.length) return true;
+        for (int i = 0, n = coverItems.length; i < n; ++i) {
+            GalleryDisplayItem g = (GalleryDisplayItem) original.covers[i];
+            if (g.mDataVersion != coverItems[i].getDataVersion()) return true;
+        }
+        return false;
+    }
+
+    private void updateSlotContent(final int slotIndex) {
+
+        MyAlbumSetItem data[] = mData;
+        int pos = slotIndex % data.length;
+        MyAlbumSetItem original = data[pos];
+
+        if (!isCoverItemsChanged(slotIndex)) {
+            MediaSet set = mSource.getMediaSet(slotIndex);
+            original.sourceType = identifySourceType(set);
+            original.cacheFlag = identifyCacheFlag(set);
+            original.cacheStatus = identifyCacheStatus(set);
+            original.setPath = set == null ? null : set.getPath();
+            ((LabelDisplayItem) original.labelItem).updateContent();
+            if (mListener != null) mListener.onContentInvalidated();
+            return;
+        }
+
+        prepareSlotContent(slotIndex);
+        AlbumSetItem update = data[pos];
+
+        if (mListener != null && isActiveSlot(slotIndex)) {
+            mListener.onWindowContentChanged(slotIndex, original, update);
+        }
+        if (original != null) {
+            for (DisplayItem item : original.covers) {
+                ((GalleryDisplayItem) item).recycle();
+            }
+        }
+    }
+
+    private void notifySlotChanged(int slotIndex) {
+        // If the updated content is not cached, ignore it
+        if (slotIndex < mContentStart || slotIndex >= mContentEnd) {
+            Log.w(TAG, String.format(
+                    "invalid update: %s is outside (%s, %s)",
+                    slotIndex, mContentStart, mContentEnd) );
+            return;
+        }
+        updateSlotContent(slotIndex);
+        boolean isActiveSlot = isActiveSlot(slotIndex);
+        if (mActiveRequestCount == 0 || isActiveSlot) {
+            for (DisplayItem item : mData[slotIndex % mData.length].covers) {
+                GalleryDisplayItem galleryItem = (GalleryDisplayItem) item;
+                galleryItem.requestImage();
+                if (isActiveSlot && galleryItem.isRequestInProgress()) {
+                    ++mActiveRequestCount;
+                }
+            }
+        }
+    }
+
+    private void updateAllImageRequests() {
+        mActiveRequestCount = 0;
+        for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) {
+            for (DisplayItem item : mData[i % mData.length].covers) {
+                GalleryDisplayItem coverItem = (GalleryDisplayItem) item;
+                coverItem.requestImage();
+                if (coverItem.isRequestInProgress()) ++mActiveRequestCount;
+            }
+        }
+        if (mActiveRequestCount == 0) {
+            requestNonactiveImages();
+        } else {
+            cancelNonactiveImages();
+        }
+    }
+
+    private class GalleryDisplayItem extends AbstractDisplayItem
+            implements FutureListener<Bitmap> {
+        private Future<Bitmap> mFuture;
+        private final int mSlotIndex;
+        private final int mCoverIndex;
+        private final int mMediaType;
+        private Texture mContent;
+        private final long mDataVersion;
+
+        public GalleryDisplayItem(int slotIndex, int coverIndex, MediaItem item) {
+            super(item);
+            mSlotIndex = slotIndex;
+            mCoverIndex = coverIndex;
+            mMediaType = item.getMediaType();
+            mDataVersion = item.getDataVersion();
+            updateContent(mWaitLoadingTexture);
+        }
+
+        @Override
+        protected void onBitmapAvailable(Bitmap bitmap) {
+            if (isActiveSlot(mSlotIndex)) {
+                --mActiveRequestCount;
+                if (mActiveRequestCount == 0) requestNonactiveImages();
+            }
+            if (bitmap != null) {
+                BitmapTexture texture = new BitmapTexture(bitmap);
+                texture.setThrottled(true);
+                updateContent(texture);
+                if (mListener != null) mListener.onContentInvalidated();
+            }
+        }
+
+        private void updateContent(Texture content) {
+            mContent = content;
+
+            int width = content.getWidth();
+            int height = content.getHeight();
+
+            float scale = (float) mDisplayItemSize / Math.max(width, height);
+
+            width = (int) Math.floor(width * scale);
+            height = (int) Math.floor(height * scale);
+
+            setSize(width, height);
+        }
+
+        @Override
+        public boolean render(GLCanvas canvas, int pass) {
+            int sourceType = SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED;
+            int cacheFlag = MediaSet.CACHE_FLAG_NO;
+            int cacheStatus = MediaSet.CACHE_STATUS_NOT_CACHED;
+            MyAlbumSetItem set = mData[mSlotIndex % mData.length];
+            Path path = set.setPath;
+            if (mCoverIndex == 0) {
+                sourceType = set.sourceType;
+                cacheFlag = set.cacheFlag;
+                cacheStatus = set.cacheStatus;
+            }
+
+            mSelectionDrawer.draw(canvas, mContent, mWidth, mHeight,
+                    getRotation(), path, mCoverIndex, sourceType, mMediaType,
+                    cacheFlag == MediaSet.CACHE_FLAG_FULL,
+                    (cacheFlag == MediaSet.CACHE_FLAG_FULL)
+                    && (cacheStatus != MediaSet.CACHE_STATUS_CACHED_FULL));
+            return false;
+        }
+
+        @Override
+        public void startLoadBitmap() {
+            mFuture = mThreadPool.submit(mMediaItem.requestImage(
+                    MediaItem.TYPE_MICROTHUMBNAIL), this);
+        }
+
+        @Override
+        public void cancelLoadBitmap() {
+            mFuture.cancel();
+        }
+
+        @Override
+        public void onFutureDone(Future<Bitmap> future) {
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_LOAD_BITMAP_DONE, this));
+        }
+
+        private void onLoadBitmapDone() {
+            Future<Bitmap> future = mFuture;
+            mFuture = null;
+            updateImage(future.get(), future.isCancelled());
+        }
+
+        @Override
+        public String toString() {
+            return String.format("GalleryDisplayItem(%s, %s)", mSlotIndex, mCoverIndex);
+        }
+    }
+
+    private static int identifySourceType(MediaSet set) {
+        if (set == null) {
+            return SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED;
+        }
+
+        Path path = set.getPath();
+        if (MediaSetUtils.isCameraSource(path)) {
+            return SelectionDrawer.DATASOURCE_TYPE_CAMERA;
+        }
+
+        int type = SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED;
+        String prefix = path.getPrefix();
+
+        if (prefix.equals("picasa")) {
+            type = SelectionDrawer.DATASOURCE_TYPE_PICASA;
+        } else if (prefix.equals("local") || prefix.equals("merge")) {
+            type = SelectionDrawer.DATASOURCE_TYPE_LOCAL;
+        } else if (prefix.equals("mtp")) {
+            type = SelectionDrawer.DATASOURCE_TYPE_MTP;
+        }
+
+        return type;
+    }
+
+    private static int identifyCacheFlag(MediaSet set) {
+        if (set == null || (set.getSupportedOperations()
+                & MediaSet.SUPPORT_CACHE) == 0) {
+            return MediaSet.CACHE_FLAG_NO;
+        }
+
+        return set.getCacheFlag();
+    }
+
+    private static int identifyCacheStatus(MediaSet set) {
+        if (set == null || (set.getSupportedOperations()
+                & MediaSet.SUPPORT_CACHE) == 0) {
+            return MediaSet.CACHE_STATUS_NOT_CACHED;
+        }
+
+        return set.getCacheStatus();
+    }
+
+    private class LabelDisplayItem extends DisplayItem {
+        private static final int FONT_COLOR = Color.WHITE;
+
+        private StringTexture mTexture;
+        private String mLabel;
+        private String mPostfix;
+        private final int mSlotIndex;
+
+        public LabelDisplayItem(int slotIndex) {
+            mSlotIndex = slotIndex;
+            updateContent();
+        }
+
+        public boolean updateContent() {
+            String label = mLoadingLabel;
+            String postfix = null;
+            MediaSet set = mSource.getMediaSet(mSlotIndex);
+            if (set != null) {
+                label = Utils.ensureNotNull(set.getName());
+                postfix = " (" + set.getTotalMediaItemCount() + ")";
+            }
+            if (Utils.equals(label, mLabel)
+                    && Utils.equals(postfix, mPostfix)) return false;
+            mTexture = StringTexture.newInstance(
+                    label, postfix, mLabelFontSize, FONT_COLOR, mLabelWidth, true);
+            setSize(mTexture.getWidth(), mTexture.getHeight());
+            return true;
+        }
+
+        @Override
+        public boolean render(GLCanvas canvas, int pass) {
+            mTexture.draw(canvas, -mWidth / 2, -mHeight / 2);
+            return false;
+        }
+
+        @Override
+        public long getIdentity() {
+            return System.identityHashCode(this);
+        }
+    }
+
+    public void onSizeChanged(int size) {
+        if (mSize != size) {
+            mSize = size;
+            if (mListener != null && mIsActive) mListener.onSizeChanged(mSize);
+        }
+    }
+
+    public void onWindowContentChanged(int index) {
+        if (!mIsActive) {
+            // paused, ignore slot changed event
+            return;
+        }
+        notifySlotChanged(index);
+    }
+
+    public void pause() {
+        mIsActive = false;
+        for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+            freeSlotContent(i);
+        }
+    }
+
+    public void resume() {
+        mIsActive = true;
+        for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+            prepareSlotContent(i);
+        }
+        updateAllImageRequests();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/AlbumSetView.java b/src/com/android/gallery3d/ui/AlbumSetView.java
new file mode 100644
index 0000000..ef066b3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/AlbumSetView.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.ui.PositionRepository.Position;
+
+import android.graphics.Rect;
+
+import java.util.Random;
+
+public class AlbumSetView extends SlotView {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AlbumSetView";
+    private static final int CACHE_SIZE = 32;
+    private static final float PHOTO_DISTANCE = 35f;
+
+    private int mVisibleStart;
+    private int mVisibleEnd;
+
+    private Random mRandom = new Random();
+    private long mSeed = mRandom.nextLong();
+
+    private AlbumSetSlidingWindow mDataWindow;
+    private final GalleryActivity mActivity;
+    private final int mSlotWidth;
+    private final int mDisplayItemSize;
+    private final int mLabelFontSize;
+    private final int mLabelOffsetY;
+    private final int mLabelMargin;
+
+    private SelectionDrawer mSelectionDrawer;
+
+    public static interface Model {
+        public MediaItem[] getCoverItems(int index);
+        public MediaSet getMediaSet(int index);
+        public int size();
+        public void setActiveWindow(int start, int end);
+        public void setModelListener(ModelListener listener);
+    }
+
+    public static interface ModelListener {
+        public void onWindowContentChanged(int index);
+        public void onSizeChanged(int size);
+    }
+
+    public static class AlbumSetItem {
+        public DisplayItem[] covers;
+        public DisplayItem labelItem;
+        public long setDataVersion;
+    }
+
+    public AlbumSetView(GalleryActivity activity, SelectionDrawer drawer,
+            int slotWidth, int slotHeight, int displayItemSize,
+            int labelFontSize, int labelOffsetY, int labelMargin) {
+        super(activity.getAndroidContext());
+        mActivity = activity;
+        setSelectionDrawer(drawer);
+        setSlotSize(slotWidth, slotHeight);
+        mSlotWidth = slotWidth;
+        mDisplayItemSize = displayItemSize;
+        mLabelFontSize = labelFontSize;
+        mLabelOffsetY = labelOffsetY;
+        mLabelMargin = labelMargin;
+    }
+
+    public void setSelectionDrawer(SelectionDrawer drawer) {
+        mSelectionDrawer = drawer;
+        if (mDataWindow != null) {
+            mDataWindow.setSelectionDrawer(drawer);
+        }
+    }
+
+    public void setModel(AlbumSetView.Model model) {
+        if (mDataWindow != null) {
+            mDataWindow.setListener(null);
+            setSlotCount(0);
+            mDataWindow = null;
+        }
+        if (model != null) {
+            mDataWindow = new AlbumSetSlidingWindow(mActivity,
+                    mSlotWidth - mLabelMargin * 2, mDisplayItemSize, mLabelFontSize,
+                    mSelectionDrawer, model, CACHE_SIZE);
+            mDataWindow.setListener(new MyCacheListener());
+            setSlotCount(mDataWindow.size());
+            updateVisibleRange(getVisibleStart(), getVisibleEnd());
+        }
+    }
+
+    private void putSlotContent(int slotIndex, AlbumSetItem entry) {
+        // Get displayItems from mItemsetMap or create them from MediaSet.
+        Utils.assertTrue(entry != null);
+        Rect rect = getSlotRect(slotIndex);
+
+        DisplayItem[] items = entry.covers;
+        mRandom.setSeed(slotIndex ^ mSeed);
+
+        int x = (rect.left + rect.right) / 2;
+        int y = (rect.top + rect.bottom) / 2;
+
+        Position basePosition = new Position(x, y, 0);
+
+        // Put the cover items in reverse order, so that the first item is on
+        // top of the rest.
+        int labelY = y + mLabelOffsetY - entry.labelItem.getHeight() / 2;
+        Position position = new Position(x, labelY, 0f);
+        putDisplayItem(position, position, entry.labelItem);
+
+        for (int i = 0, n = items.length; i < n; ++i) {
+            DisplayItem item = items[i];
+            float dx = 0;
+            float dy = 0;
+            float dz = 0f;
+            float theta = 0;
+            if (i != 0) {
+                dz = i * PHOTO_DISTANCE;
+            }
+            position = new Position(x + dx, y + dy, dz);
+            position.theta = theta;
+            putDisplayItem(position, basePosition, item);
+        }
+
+    }
+
+    private void freeSlotContent(int index, AlbumSetItem entry) {
+        if (entry == null) return;
+        for (DisplayItem item : entry.covers) {
+            removeDisplayItem(item);
+        }
+        removeDisplayItem(entry.labelItem);
+    }
+
+    public int size() {
+        return mDataWindow.size();
+    }
+
+    @Override
+    public void onLayoutChanged(int width, int height) {
+        updateVisibleRange(0, 0);
+        updateVisibleRange(getVisibleStart(), getVisibleEnd());
+    }
+
+    @Override
+    public void onScrollPositionChanged(int position) {
+        super.onScrollPositionChanged(position);
+        updateVisibleRange(getVisibleStart(), getVisibleEnd());
+    }
+
+    private void updateVisibleRange(int start, int end) {
+        if (start == mVisibleStart && end == mVisibleEnd) {
+            // we need to set the mDataWindow active range in any case.
+            mDataWindow.setActiveWindow(start, end);
+            return;
+        }
+        if (start >= mVisibleEnd || mVisibleStart >= end) {
+            for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
+                freeSlotContent(i, mDataWindow.get(i));
+            }
+            mDataWindow.setActiveWindow(start, end);
+            for (int i = start; i < end; ++i) {
+                putSlotContent(i, mDataWindow.get(i));
+            }
+        } else {
+            for (int i = mVisibleStart; i < start; ++i) {
+                freeSlotContent(i, mDataWindow.get(i));
+            }
+            for (int i = end, n = mVisibleEnd; i < n; ++i) {
+                freeSlotContent(i, mDataWindow.get(i));
+            }
+            mDataWindow.setActiveWindow(start, end);
+            for (int i = start, n = mVisibleStart; i < n; ++i) {
+                putSlotContent(i, mDataWindow.get(i));
+            }
+            for (int i = mVisibleEnd; i < end; ++i) {
+                putSlotContent(i, mDataWindow.get(i));
+            }
+        }
+        mVisibleStart = start;
+        mVisibleEnd = end;
+
+        invalidate();
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        mSelectionDrawer.prepareDrawing();
+        super.render(canvas);
+    }
+
+    private class MyCacheListener implements AlbumSetSlidingWindow.Listener {
+
+        public void onSizeChanged(int size) {
+            // If the layout parameters are changed, we need reput all items.
+            if (setSlotCount(size)) updateVisibleRange(0, 0);
+            updateVisibleRange(getVisibleStart(), getVisibleEnd());
+            invalidate();
+        }
+
+        public void onWindowContentChanged(int slot, AlbumSetItem old, AlbumSetItem update) {
+            freeSlotContent(slot, old);
+            putSlotContent(slot, update);
+            invalidate();
+        }
+
+        public void onContentInvalidated() {
+            invalidate();
+        }
+    }
+
+    public void pause() {
+        for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
+            freeSlotContent(i, mDataWindow.get(i));
+        }
+        mDataWindow.pause();
+    }
+
+    public void resume() {
+        mDataWindow.resume();
+        for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
+            putSlotContent(i, mDataWindow.get(i));
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java
new file mode 100644
index 0000000..9e44bd1
--- /dev/null
+++ b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.LruCache;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.ThreadPool;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.os.Message;
+
+public class AlbumSlidingWindow implements AlbumView.ModelListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AlbumSlidingWindow";
+
+    private static final int MSG_LOAD_BITMAP_DONE = 0;
+    private static final int MSG_UPDATE_SLOT = 1;
+    private static final int MIN_THUMB_SIZE = 100;
+
+    public static interface Listener {
+        public void onSizeChanged(int size);
+        public void onContentInvalidated();
+        public void onWindowContentChanged(
+                int slot, DisplayItem old, DisplayItem update);
+    }
+
+    private final AlbumView.Model mSource;
+    private int mSize;
+
+    private int mContentStart = 0;
+    private int mContentEnd = 0;
+
+    private int mActiveStart = 0;
+    private int mActiveEnd = 0;
+
+    private Listener mListener;
+    private int mFocusIndex = -1;
+
+    private final AlbumDisplayItem mData[];
+    private final ColorTexture mWaitLoadingTexture;
+    private SelectionDrawer mSelectionDrawer;
+
+    private SynchronizedHandler mHandler;
+    private ThreadPool mThreadPool;
+    private int mSlotWidth, mSlotHeight;
+
+    private int mActiveRequestCount = 0;
+    private boolean mIsActive = false;
+
+    private int mDisplayItemSize;  // 0: disabled
+    private LruCache<Path, Bitmap> mImageCache = new LruCache<Path, Bitmap>(1000);
+
+    public AlbumSlidingWindow(GalleryActivity activity,
+            AlbumView.Model source, int cacheSize,
+            int slotWidth, int slotHeight, int displayItemSize) {
+        source.setModelListener(this);
+        mSource = source;
+        mData = new AlbumDisplayItem[cacheSize];
+        mSize = source.size();
+        mSlotWidth = slotWidth;
+        mSlotHeight = slotHeight;
+        mDisplayItemSize = displayItemSize;
+
+        mWaitLoadingTexture = new ColorTexture(Color.TRANSPARENT);
+        mWaitLoadingTexture.setSize(1, 1);
+
+        mHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_LOAD_BITMAP_DONE: {
+                        ((AlbumDisplayItem) message.obj).onLoadBitmapDone();
+                        break;
+                    }
+                    case MSG_UPDATE_SLOT: {
+                        updateSlotContent(message.arg1);
+                        break;
+                    }
+                }
+            }
+        };
+
+        mThreadPool = activity.getThreadPool();
+    }
+
+    public void setSelectionDrawer(SelectionDrawer drawer) {
+        mSelectionDrawer = drawer;
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    public void setFocusIndex(int slotIndex) {
+        mFocusIndex = slotIndex;
+    }
+
+    public DisplayItem get(int slotIndex) {
+        Utils.assertTrue(isActiveSlot(slotIndex),
+                "invalid slot: %s outsides (%s, %s)",
+                slotIndex, mActiveStart, mActiveEnd);
+        return mData[slotIndex % mData.length];
+    }
+
+    public int size() {
+        return mSize;
+    }
+
+    public boolean isActiveSlot(int slotIndex) {
+        return slotIndex >= mActiveStart && slotIndex < mActiveEnd;
+    }
+
+    private void setContentWindow(int contentStart, int contentEnd) {
+        if (contentStart == mContentStart && contentEnd == mContentEnd) return;
+
+        if (!mIsActive) {
+            mContentStart = contentStart;
+            mContentEnd = contentEnd;
+            mSource.setActiveWindow(contentStart, contentEnd);
+            return;
+        }
+
+        if (contentStart >= mContentEnd || mContentStart >= contentEnd) {
+            for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+                freeSlotContent(i);
+            }
+            mSource.setActiveWindow(contentStart, contentEnd);
+            for (int i = contentStart; i < contentEnd; ++i) {
+                prepareSlotContent(i);
+            }
+        } else {
+            for (int i = mContentStart; i < contentStart; ++i) {
+                freeSlotContent(i);
+            }
+            for (int i = contentEnd, n = mContentEnd; i < n; ++i) {
+                freeSlotContent(i);
+            }
+            mSource.setActiveWindow(contentStart, contentEnd);
+            for (int i = contentStart, n = mContentStart; i < n; ++i) {
+                prepareSlotContent(i);
+            }
+            for (int i = mContentEnd; i < contentEnd; ++i) {
+                prepareSlotContent(i);
+            }
+        }
+
+        mContentStart = contentStart;
+        mContentEnd = contentEnd;
+    }
+
+    public void setActiveWindow(int start, int end) {
+        Utils.assertTrue(start <= end
+                && end - start <= mData.length && end <= mSize,
+                "%s, %s, %s, %s", start, end, mData.length, mSize);
+        DisplayItem data[] = mData;
+
+        mActiveStart = start;
+        mActiveEnd = end;
+
+        // If no data is visible, keep the cache content
+        if (start == end) return;
+
+        int contentStart = Utils.clamp((start + end) / 2 - data.length / 2,
+                0, Math.max(0, mSize - data.length));
+        int contentEnd = Math.min(contentStart + data.length, mSize);
+        setContentWindow(contentStart, contentEnd);
+        if (mIsActive) updateAllImageRequests();
+    }
+
+    // We would like to request non active slots in the following order:
+    // Order:    8 6 4 2                   1 3 5 7
+    //         |---------|---------------|---------|
+    //                   |<-  active  ->|
+    //         |<-------- cached range ----------->|
+    private void requestNonactiveImages() {
+        int range = Math.max(
+                (mContentEnd - mActiveEnd), (mActiveStart - mContentStart));
+        for (int i = 0 ;i < range; ++i) {
+            requestSlotImage(mActiveEnd + i, false);
+            requestSlotImage(mActiveStart - 1 - i, false);
+        }
+    }
+
+    private void requestSlotImage(int slotIndex, boolean isActive) {
+        if (slotIndex < mContentStart || slotIndex >= mContentEnd) return;
+        AlbumDisplayItem item = mData[slotIndex % mData.length];
+        item.requestImage();
+    }
+
+    private void cancelNonactiveImages() {
+        int range = Math.max(
+                (mContentEnd - mActiveEnd), (mActiveStart - mContentStart));
+        for (int i = 0 ;i < range; ++i) {
+            cancelSlotImage(mActiveEnd + i, false);
+            cancelSlotImage(mActiveStart - 1 - i, false);
+        }
+    }
+
+    private void cancelSlotImage(int slotIndex, boolean isActive) {
+        if (slotIndex < mContentStart || slotIndex >= mContentEnd) return;
+        AlbumDisplayItem item = mData[slotIndex % mData.length];
+        item.cancelImageRequest();
+    }
+
+    private void freeSlotContent(int slotIndex) {
+        AlbumDisplayItem data[] = mData;
+        int index = slotIndex % data.length;
+        AlbumDisplayItem original = data[index];
+        if (original != null) {
+            original.recycle();
+            data[index] = null;
+        }
+    }
+
+    private void prepareSlotContent(final int slotIndex) {
+        mData[slotIndex % mData.length] = new AlbumDisplayItem(
+                slotIndex, mSource.get(slotIndex));
+    }
+
+    private void updateSlotContent(final int slotIndex) {
+        MediaItem item = mSource.get(slotIndex);
+        AlbumDisplayItem data[] = mData;
+        int index = slotIndex % data.length;
+        AlbumDisplayItem original = data[index];
+        AlbumDisplayItem update = new AlbumDisplayItem(slotIndex, item);
+        data[index] = update;
+        boolean isActive = isActiveSlot(slotIndex);
+        if (mListener != null && isActive) {
+            mListener.onWindowContentChanged(slotIndex, original, update);
+        }
+        if (original != null) {
+            if (isActive && original.isRequestInProgress()) {
+                --mActiveRequestCount;
+            }
+            original.recycle();
+        }
+        if (isActive) {
+            if (mActiveRequestCount == 0) cancelNonactiveImages();
+            ++mActiveRequestCount;
+            update.requestImage();
+        } else {
+            if (mActiveRequestCount == 0) update.requestImage();
+        }
+    }
+
+    private void updateAllImageRequests() {
+        mActiveRequestCount = 0;
+        AlbumDisplayItem data[] = mData;
+        for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) {
+            AlbumDisplayItem item = data[i % data.length];
+            item.requestImage();
+            if (item.isRequestInProgress()) ++mActiveRequestCount;
+        }
+        if (mActiveRequestCount == 0) {
+            requestNonactiveImages();
+        } else {
+            cancelNonactiveImages();
+        }
+    }
+
+    private class AlbumDisplayItem extends AbstractDisplayItem
+            implements FutureListener<Bitmap>, Job<Bitmap> {
+        private Future<Bitmap> mFuture;
+        private final int mSlotIndex;
+        private final int mMediaType;
+        private Texture mContent;
+
+        public AlbumDisplayItem(int slotIndex, MediaItem item) {
+            super(item);
+            mMediaType = (item == null)
+                    ? MediaItem.MEDIA_TYPE_UNKNOWN
+                    : item.getMediaType();
+            mSlotIndex = slotIndex;
+            updateContent(mWaitLoadingTexture);
+        }
+
+        @Override
+        protected void onBitmapAvailable(Bitmap bitmap) {
+            boolean isActiveSlot = isActiveSlot(mSlotIndex);
+            if (isActiveSlot) {
+                --mActiveRequestCount;
+                if (mActiveRequestCount == 0) requestNonactiveImages();
+            }
+            if (bitmap != null) {
+                BitmapTexture texture = new BitmapTexture(bitmap);
+                texture.setThrottled(true);
+                updateContent(texture);
+                if (mListener != null && isActiveSlot) {
+                    mListener.onContentInvalidated();
+                }
+            }
+        }
+
+        private void updateContent(Texture content) {
+            mContent = content;
+
+            int width = mContent.getWidth();
+            int height = mContent.getHeight();
+
+            float scalex = mDisplayItemSize / (float) width;
+            float scaley = mDisplayItemSize / (float) height;
+            float scale = Math.min(scalex, scaley);
+
+            width = (int) Math.floor(width * scale);
+            height = (int) Math.floor(height * scale);
+
+            setSize(width, height);
+        }
+
+        @Override
+        public boolean render(GLCanvas canvas, int pass) {
+            if (pass == 0) {
+                Path path = null;
+                if (mMediaItem != null) path = mMediaItem.getPath();
+                mSelectionDrawer.draw(canvas, mContent, mWidth, mHeight,
+                        getRotation(), path, mMediaType);
+                return (mFocusIndex == mSlotIndex);
+            } else if (pass == 1) {
+                mSelectionDrawer.drawFocus(canvas, mWidth, mHeight);
+            }
+            return false;
+        }
+
+        @Override
+        public void startLoadBitmap() {
+            if (mDisplayItemSize < MIN_THUMB_SIZE) {
+                Path path = mMediaItem.getPath();
+                if (mImageCache.containsKey(path)) {
+                    Bitmap bitmap = mImageCache.get(path);
+                    updateImage(bitmap, false);
+                    return;
+                }
+                mFuture = mThreadPool.submit(this, this);
+            } else {
+                mFuture = mThreadPool.submit(mMediaItem.requestImage(
+                        MediaItem.TYPE_MICROTHUMBNAIL), this);
+            }
+        }
+
+        // This gets the bitmap and scale it down.
+        public Bitmap run(JobContext jc) {
+            Job<Bitmap> job = mMediaItem.requestImage(
+                    MediaItem.TYPE_MICROTHUMBNAIL);
+            Bitmap bitmap = job.run(jc);
+            if (bitmap != null) {
+                bitmap = BitmapUtils.resizeDownBySideLength(
+                        bitmap, mDisplayItemSize, true);
+            }
+            return bitmap;
+        }
+
+        @Override
+        public void cancelLoadBitmap() {
+            if (mFuture != null) {
+                mFuture.cancel();
+            }
+        }
+
+        @Override
+        public void onFutureDone(Future<Bitmap> bitmap) {
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_LOAD_BITMAP_DONE, this));
+        }
+
+        private void onLoadBitmapDone() {
+            Future<Bitmap> future = mFuture;
+            mFuture = null;
+            Bitmap bitmap = future.get();
+            boolean isCancelled = future.isCancelled();
+            if (mDisplayItemSize < MIN_THUMB_SIZE && (bitmap != null || !isCancelled)) {
+                Path path = mMediaItem.getPath();
+                mImageCache.put(path, bitmap);
+            }
+            updateImage(bitmap, isCancelled);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("AlbumDisplayItem[%s]", mSlotIndex);
+        }
+    }
+
+    public void onSizeChanged(int size) {
+        if (mSize != size) {
+            mSize = size;
+            if (mListener != null) mListener.onSizeChanged(mSize);
+        }
+    }
+
+    public void onWindowContentChanged(int index) {
+        if (index >= mContentStart && index < mContentEnd && mIsActive) {
+            updateSlotContent(index);
+        }
+    }
+
+    public void resume() {
+        mIsActive = true;
+        for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+            prepareSlotContent(i);
+        }
+        updateAllImageRequests();
+    }
+
+    public void pause() {
+        mIsActive = false;
+        for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
+            freeSlotContent(i);
+        }
+        mImageCache.clear();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/AlbumView.java b/src/com/android/gallery3d/ui/AlbumView.java
new file mode 100644
index 0000000..417611a
--- /dev/null
+++ b/src/com/android/gallery3d/ui/AlbumView.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.ui.PositionRepository.Position;
+
+import android.graphics.Rect;
+
+public class AlbumView extends SlotView {
+    @SuppressWarnings("unused")
+    private static final String TAG = "AlbumView";
+    private static final int CACHE_SIZE = 64;
+
+    private int mVisibleStart = 0;
+    private int mVisibleEnd = 0;
+
+    private AlbumSlidingWindow mDataWindow;
+    private final GalleryActivity mActivity;
+    private SelectionDrawer mSelectionDrawer;
+    private int mSlotWidth, mSlotHeight;
+    private int mDisplayItemSize;
+
+    private boolean mIsActive = false;
+
+    public static interface Model {
+        public int size();
+        public MediaItem get(int index);
+        public void setActiveWindow(int start, int end);
+        public void setModelListener(ModelListener listener);
+    }
+
+    public static interface ModelListener {
+        public void onWindowContentChanged(int index);
+        public void onSizeChanged(int size);
+    }
+
+    public AlbumView(GalleryActivity activity,
+            int slotWidth, int slotHeight, int displayItemSize) {
+        super(activity.getAndroidContext());
+        mSlotWidth = slotWidth;
+        mSlotHeight = slotHeight;
+        mDisplayItemSize = displayItemSize;
+        setSlotSize(slotWidth, slotHeight);
+        mActivity = activity;
+    }
+
+    public void setSelectionDrawer(SelectionDrawer drawer) {
+        mSelectionDrawer = drawer;
+        if (mDataWindow != null) mDataWindow.setSelectionDrawer(drawer);
+    }
+
+    public void setModel(Model model) {
+        if (mDataWindow != null) {
+            mDataWindow.setListener(null);
+            setSlotCount(0);
+            mDataWindow = null;
+        }
+        if (model != null) {
+            mDataWindow = new AlbumSlidingWindow(
+                    mActivity, model, CACHE_SIZE,
+                    mSlotWidth, mSlotHeight, mDisplayItemSize);
+            mDataWindow.setSelectionDrawer(mSelectionDrawer);
+            mDataWindow.setListener(new MyDataModelListener());
+            setSlotCount(model.size());
+            updateVisibleRange(getVisibleStart(), getVisibleEnd());
+        }
+    }
+
+    public void setFocusIndex(int slotIndex) {
+        if (mDataWindow != null) {
+            mDataWindow.setFocusIndex(slotIndex);
+        }
+    }
+
+    private void putSlotContent(int slotIndex, DisplayItem item) {
+        Rect rect = getSlotRect(slotIndex);
+        Position position = new Position(
+                (rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 0);
+        putDisplayItem(position, position, item);
+    }
+
+    private void updateVisibleRange(int start, int end) {
+        if (start == mVisibleStart && end == mVisibleEnd) {
+            // we need to set the mDataWindow active range in any case.
+            mDataWindow.setActiveWindow(start, end);
+            return;
+        }
+
+        if (!mIsActive) {
+            mVisibleStart = start;
+            mVisibleEnd = end;
+            mDataWindow.setActiveWindow(start, end);
+            return;
+        }
+
+        if (start >= mVisibleEnd || mVisibleStart >= end) {
+            for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
+                DisplayItem item = mDataWindow.get(i);
+                if (item != null) removeDisplayItem(item);
+            }
+            mDataWindow.setActiveWindow(start, end);
+            for (int i = start; i < end; ++i) {
+                putSlotContent(i, mDataWindow.get(i));
+            }
+        } else {
+            for (int i = mVisibleStart; i < start; ++i) {
+                DisplayItem item = mDataWindow.get(i);
+                if (item != null) removeDisplayItem(item);
+            }
+            for (int i = end, n = mVisibleEnd; i < n; ++i) {
+                DisplayItem item = mDataWindow.get(i);
+                if (item != null) removeDisplayItem(item);
+            }
+            mDataWindow.setActiveWindow(start, end);
+            for (int i = start, n = mVisibleStart; i < n; ++i) {
+                putSlotContent(i, mDataWindow.get(i));
+            }
+            for (int i = mVisibleEnd; i < end; ++i) {
+                putSlotContent(i, mDataWindow.get(i));
+            }
+        }
+
+        mVisibleStart = start;
+        mVisibleEnd = end;
+    }
+
+    @Override
+    protected void onLayoutChanged(int width, int height) {
+        // Reput all the items
+        updateVisibleRange(0, 0);
+        updateVisibleRange(getVisibleStart(), getVisibleEnd());
+    }
+
+    @Override
+    protected void onScrollPositionChanged(int position) {
+        super.onScrollPositionChanged(position);
+        updateVisibleRange(getVisibleStart(), getVisibleEnd());
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        mSelectionDrawer.prepareDrawing();
+        super.render(canvas);
+    }
+
+    private class MyDataModelListener implements AlbumSlidingWindow.Listener {
+
+        public void onContentInvalidated() {
+            invalidate();
+        }
+
+        public void onSizeChanged(int size) {
+            // If the layout parameters are changed, we need reput all items.
+            if (setSlotCount(size)) updateVisibleRange(0, 0);
+            updateVisibleRange(getVisibleStart(), getVisibleEnd());
+            invalidate();
+        }
+
+        public void onWindowContentChanged(
+                int slotIndex, DisplayItem old, DisplayItem update) {
+            removeDisplayItem(old);
+            putSlotContent(slotIndex, update);
+        }
+    }
+
+    public void resume() {
+        mIsActive = true;
+        mDataWindow.resume();
+        for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
+            putSlotContent(i, mDataWindow.get(i));
+        }
+    }
+
+    public void pause() {
+        mIsActive = false;
+        for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
+            removeDisplayItem(mDataWindow.get(i));
+        }
+        mDataWindow.pause();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/BasicTexture.java b/src/com/android/gallery3d/ui/BasicTexture.java
new file mode 100644
index 0000000..e930063
--- /dev/null
+++ b/src/com/android/gallery3d/ui/BasicTexture.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import java.lang.ref.WeakReference;
+import java.util.WeakHashMap;
+
+// BasicTexture is a Texture corresponds to a real GL texture.
+// The state of a BasicTexture indicates whether its data is loaded to GL memory.
+// If a BasicTexture is loaded into GL memory, it has a GL texture id.
+abstract class BasicTexture implements Texture {
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "BasicTexture";
+    protected static final int UNSPECIFIED = -1;
+
+    protected static final int STATE_UNLOADED = 0;
+    protected static final int STATE_LOADED = 1;
+    protected static final int STATE_ERROR = -1;
+
+    protected int mId;
+    protected int mState;
+
+    protected int mWidth = UNSPECIFIED;
+    protected int mHeight = UNSPECIFIED;
+
+    private int mTextureWidth;
+    private int mTextureHeight;
+
+    protected WeakReference<GLCanvas> mCanvasRef = null;
+    private static WeakHashMap<BasicTexture, Object> sAllTextures
+            = new WeakHashMap<BasicTexture, Object>();
+    private static ThreadLocal sInFinalizer = new ThreadLocal();
+
+    protected BasicTexture(GLCanvas canvas, int id, int state) {
+        setAssociatedCanvas(canvas);
+        mId = id;
+        mState = state;
+        synchronized (sAllTextures) {
+            sAllTextures.put(this, null);
+        }
+    }
+
+    protected BasicTexture() {
+        this(null, 0, STATE_UNLOADED);
+    }
+
+    protected void setAssociatedCanvas(GLCanvas canvas) {
+        mCanvasRef = canvas == null
+                ? null
+                : new WeakReference<GLCanvas>(canvas);
+    }
+
+    /**
+     * Sets the content size of this texture. In OpenGL, the actual texture
+     * size must be of power of 2, the size of the content may be smaller.
+     */
+    protected void setSize(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        mTextureWidth = Utils.nextPowerOf2(width);
+        mTextureHeight = Utils.nextPowerOf2(height);
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+
+    // Returns the width rounded to the next power of 2.
+    public int getTextureWidth() {
+        return mTextureWidth;
+    }
+
+    // Returns the height rounded to the next power of 2.
+    public int getTextureHeight() {
+        return mTextureHeight;
+    }
+
+    public void draw(GLCanvas canvas, int x, int y) {
+        canvas.drawTexture(this, x, y, getWidth(), getHeight());
+    }
+
+    public void draw(GLCanvas canvas, int x, int y, int w, int h) {
+        canvas.drawTexture(this, x, y, w, h);
+    }
+
+    // onBind is called before GLCanvas binds this texture.
+    // It should make sure the data is uploaded to GL memory.
+    abstract protected boolean onBind(GLCanvas canvas);
+
+    public boolean isLoaded(GLCanvas canvas) {
+        return mState == STATE_LOADED && mCanvasRef.get() == canvas;
+    }
+
+    // recycle() is called when the texture will never be used again,
+    // so it can free all resources.
+    public void recycle() {
+        freeResource();
+    }
+
+    // yield() is called when the texture will not be used temporarily,
+    // so it can free some resources.
+    // The default implementation unloads the texture from GL memory, so
+    // the subclass should make sure it can reload the texture to GL memory
+    // later, or it will have to override this method.
+    public void yield() {
+        freeResource();
+    }
+
+    private void freeResource() {
+        GLCanvas canvas = mCanvasRef == null ? null : mCanvasRef.get();
+        if (canvas != null && isLoaded(canvas)) {
+            canvas.unloadTexture(this);
+        }
+        mState = BasicTexture.STATE_UNLOADED;
+        setAssociatedCanvas(null);
+    }
+
+    @Override
+    protected void finalize() {
+        sInFinalizer.set(BasicTexture.class);
+        recycle();
+        sInFinalizer.set(null);
+    }
+
+    // This is for deciding if we can call Bitmap's recycle().
+    // We cannot call Bitmap's recycle() in finalizer because at that point
+    // the finalizer of Bitmap may already be called so recycle() will crash.
+    public static boolean inFinalizer() {
+        return sInFinalizer.get() != null;
+    }
+
+    public static void yieldAllTextures() {
+        synchronized (sAllTextures) {
+            for (BasicTexture t : sAllTextures.keySet()) {
+                t.yield();
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/BitmapTexture.java b/src/com/android/gallery3d/ui/BitmapTexture.java
new file mode 100644
index 0000000..046bda9
--- /dev/null
+++ b/src/com/android/gallery3d/ui/BitmapTexture.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import android.graphics.Bitmap;
+
+// BitmapTexture is a texture whose content is specified by a fixed Bitmap.
+//
+// The texture does not own the Bitmap. The user should make sure the Bitmap
+// is valid during the texture's lifetime. When the texture is recycled, it
+// does not free the Bitmap.
+public class BitmapTexture extends UploadedTexture {
+    protected Bitmap mContentBitmap;
+
+    public BitmapTexture(Bitmap bitmap) {
+        Utils.assertTrue(bitmap != null && !bitmap.isRecycled());
+        mContentBitmap = bitmap;
+    }
+
+    @Override
+    protected void onFreeBitmap(Bitmap bitmap) {
+        // Do nothing.
+    }
+
+    @Override
+    protected Bitmap onGetBitmap() {
+        return mContentBitmap;
+    }
+
+    public Bitmap getBitmap() {
+        return mContentBitmap;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/BitmapTileProvider.java b/src/com/android/gallery3d/ui/BitmapTileProvider.java
new file mode 100644
index 0000000..a47337f
--- /dev/null
+++ b/src/com/android/gallery3d/ui/BitmapTileProvider.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.BitmapUtils;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Bitmap.Config;
+
+import java.util.ArrayList;
+
+public class BitmapTileProvider implements TileImageView.Model {
+    private final Bitmap mBackup;
+    private final Bitmap[] mMipmaps;
+    private final Config mConfig;
+    private final int mImageWidth;
+    private final int mImageHeight;
+
+    private boolean mRecycled = false;
+
+    public BitmapTileProvider(Bitmap bitmap, int maxBackupSize) {
+        mImageWidth = bitmap.getWidth();
+        mImageHeight = bitmap.getHeight();
+        ArrayList<Bitmap> list = new ArrayList<Bitmap>();
+        list.add(bitmap);
+        while (bitmap.getWidth() > maxBackupSize
+                || bitmap.getHeight() > maxBackupSize) {
+            bitmap = BitmapUtils.resizeBitmapByScale(bitmap, 0.5f, false);
+            list.add(bitmap);
+        }
+
+        mBackup = list.remove(list.size() - 1);
+        mMipmaps = list.toArray(new Bitmap[list.size()]);
+        mConfig = Config.ARGB_8888;
+    }
+
+    public Bitmap getBackupImage() {
+        return mBackup;
+    }
+
+    public int getImageHeight() {
+        return mImageHeight;
+    }
+
+    public int getImageWidth() {
+        return mImageWidth;
+    }
+
+    public int getLevelCount() {
+        return mMipmaps.length;
+    }
+
+    public Bitmap getTile(int level, int x, int y, int tileSize) {
+        Bitmap result = Bitmap.createBitmap(tileSize, tileSize, mConfig);
+        Canvas canvas = new Canvas(result);
+        canvas.drawBitmap(mMipmaps[level], -(x >> level), -(y >> level), null);
+        return result;
+    }
+
+    public void recycle() {
+        if (mRecycled) return;
+        mRecycled = true;
+        for (Bitmap bitmap : mMipmaps) {
+            BitmapUtils.recycleSilently(bitmap);
+        }
+        BitmapUtils.recycleSilently(mBackup);
+    }
+
+    public int getRotation() {
+        return 0;
+    }
+
+    public boolean isFailedToLoad() {
+        return false;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/BoxBlurFilter.java b/src/com/android/gallery3d/ui/BoxBlurFilter.java
new file mode 100644
index 0000000..0497a61
--- /dev/null
+++ b/src/com/android/gallery3d/ui/BoxBlurFilter.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Bitmap;
+
+
+public class BoxBlurFilter {
+    private static final int RED_MASK = 0xff0000;
+    private static final int RED_MASK_SHIFT = 16;
+    private static final int GREEN_MASK = 0x00ff00;
+    private static final int GREEN_MASK_SHIFT = 8;
+    private static final int BLUE_MASK = 0x0000ff;
+    private static final int RADIUS = 4;
+    private static final int KERNEL_SIZE = RADIUS * 2 + 1;
+    private static final int NUM_COLORS = 256;
+    private static final int[] KERNEL_NORM = new int[KERNEL_SIZE * NUM_COLORS];
+
+    public static final int MODE_REPEAT = 1;
+    public static final int MODE_CLAMP = 2;
+
+    static {
+        int index = 0;
+        // Build a lookup table from summed to normalized kernel values.
+        // The formula: KERNAL_NORM[value] = value / KERNEL_SIZE
+        for (int i = 0; i < NUM_COLORS; ++i) {
+            for (int j = 0; j < KERNEL_SIZE; ++j) {
+                KERNEL_NORM[index++] = i;
+            }
+        }
+    }
+
+    private BoxBlurFilter() {
+    }
+
+    private static int sample(int x, int width, int mode) {
+        if (x >= 0 && x < width) return x;
+        return mode == MODE_REPEAT
+                ? x < 0 ? x + width : x - width
+                : x < 0 ? 0 : width - 1;
+    }
+
+    public static void apply(
+            Bitmap bitmap, int horizontalMode, int verticalMode) {
+
+        int width = bitmap.getWidth();
+        int height = bitmap.getHeight();
+        int data[] = new int[width * height];
+        bitmap.getPixels(data, 0, width, 0, 0, width, height);
+        int temp[] = new int[width * height];
+        applyOneDimension(data, temp, width, height, horizontalMode);
+        applyOneDimension(temp, data, height, width, verticalMode);
+        bitmap.setPixels(data, 0, width, 0, 0, width, height);
+    }
+
+    private static void applyOneDimension(
+            int[] in, int[] out, int width, int height, int mode) {
+        for (int y = 0, read = 0; y < height; ++y, read += width) {
+            // Evaluate the kernel for the first pixel in the row.
+            int red = 0;
+            int green = 0;
+            int blue = 0;
+            for (int i = -RADIUS; i <= RADIUS; ++i) {
+                int argb = in[read + sample(i, width, mode)];
+                red += (argb & RED_MASK) >> RED_MASK_SHIFT;
+                green += (argb & GREEN_MASK) >> GREEN_MASK_SHIFT;
+                blue += argb & BLUE_MASK;
+            }
+            for (int x = 0, write = y; x < width; ++x, write += height) {
+                // Output the current pixel.
+                out[write] = 0xFF000000
+                        | (KERNEL_NORM[red] << RED_MASK_SHIFT)
+                        | (KERNEL_NORM[green] << GREEN_MASK_SHIFT)
+                        | KERNEL_NORM[blue];
+
+                // Slide to the next pixel, adding the new rightmost pixel and
+                // subtracting the former leftmost.
+                int prev = in[read + sample(x - RADIUS, width, mode)];
+                int next = in[read + sample(x + RADIUS + 1, width, mode)];
+                red += ((next & RED_MASK) - (prev & RED_MASK)) >> RED_MASK_SHIFT;
+                green += ((next & GREEN_MASK) - (prev & GREEN_MASK)) >> GREEN_MASK_SHIFT;
+                blue += (next & BLUE_MASK) - (prev & BLUE_MASK);
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/CacheBarView.java b/src/com/android/gallery3d/ui/CacheBarView.java
new file mode 100644
index 0000000..40f84d8
--- /dev/null
+++ b/src/com/android/gallery3d/ui/CacheBarView.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Message;
+import android.os.StatFs;
+import android.text.format.Formatter;
+import android.view.View.MeasureSpec;
+
+import java.io.File;
+
+public class CacheBarView extends GLView implements TextButton.OnClickedListener {
+    private static final String TAG = "CacheBarView";
+    private static final int FONT_COLOR = 0xffffffff;
+    private static final int MSG_REFRESH_STORAGE = 1;
+    private static final int PIN_SIZE = 36;
+
+    public interface Listener {
+        void onDoneClicked();
+    }
+
+    private GalleryActivity mActivity;
+    private Context mContext;
+
+    private StorageInfo mStorageInfo;
+    private long mUserChangeDelta;
+    private Future<StorageInfo> mStorageInfoFuture;
+    private Handler mHandler;
+
+    private int mTotalHeight;
+    private int mPinLeftMargin;
+    private int mPinRightMargin;
+    private int mButtonRightMargin;
+
+    private NinePatchTexture mBackground;
+    private GLView mLeftPin;            // The pin icon.
+    private GLView mLeftLabel;          // "Make available offline"
+    private ProgressBar mStorageBar;
+    private Label mStorageLabel;        // "27.26 GB free"
+    private TextButton mDoneButton;     // "Done"
+
+    private Listener mListener;
+
+    public CacheBarView(GalleryActivity activity, int resBackground, int height,
+            int pinLeftMargin, int pinRightMargin, int buttonRightMargin,
+            int fontSize) {
+        mActivity = activity;
+        mContext = activity.getAndroidContext();
+
+        mPinLeftMargin = pinLeftMargin;
+        mPinRightMargin = pinRightMargin;
+        mButtonRightMargin = buttonRightMargin;
+
+        mBackground = new NinePatchTexture(mContext, resBackground);
+        Rect paddings = mBackground.getPaddings();
+
+        // The total height of the strip that includes the bar containing Pin,
+        // Label, DoneButton, ..., ect. and the extended fading bar.
+        mTotalHeight = height + paddings.top;
+
+        mLeftPin = new Icon(mContext, R.drawable.ic_manage_pin, PIN_SIZE, PIN_SIZE);
+        mLeftLabel = new Label(mContext, R.string.make_available_offline,
+                fontSize, FONT_COLOR);
+        addComponent(mLeftPin);
+        addComponent(mLeftLabel);
+
+        mDoneButton = new TextButton(mContext, R.string.done);
+        mDoneButton.setOnClickListener(this);
+        NinePatchTexture normal = new NinePatchTexture(
+                mContext, R.drawable.btn_default_normal_holo_dark);
+        NinePatchTexture pressed = new NinePatchTexture(
+                mContext, R.drawable.btn_default_pressed_holo_dark);
+        mDoneButton.setNormalBackground(normal);
+        mDoneButton.setPressedBackground(pressed);
+        addComponent(mDoneButton);
+
+        // Initially the progress bar and label are invisible.
+        // It will be made visible after we have the storage information.
+        mStorageBar = new ProgressBar(mContext,
+                R.drawable.progress_primary_holo_dark,
+                R.drawable.progress_secondary_holo_dark,
+                R.drawable.progress_bg_holo_dark);
+        mStorageLabel = new Label(mContext, "", 14, Color.WHITE);
+        addComponent(mStorageBar);
+        addComponent(mStorageLabel);
+        mStorageBar.setVisibility(GLView.INVISIBLE);
+        mStorageLabel.setVisibility(GLView.INVISIBLE);
+
+        mHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message msg) {
+                switch(msg.what) {
+                    case MSG_REFRESH_STORAGE:
+                        mStorageInfo = (StorageInfo) msg.obj;
+                        refreshStorageInfo();
+                        break;
+                }
+            }
+        };
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    // Called by mDoneButton
+    public void onClicked(GLView source) {
+        if (mListener != null) {
+            mListener.onDoneClicked();
+        }
+    }
+
+    @Override
+    protected void onLayout(
+            boolean changed, int left, int top, int right, int bottom) {
+        // The size of mStorageLabel can change, so we need to layout
+        // even if the size of CacheBarView does not change.
+        int w = right - left;
+        int h = bottom - top;
+
+        mLeftPin.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+        int pinH = mLeftPin.getMeasuredHeight();
+        int pinW = mLeftPin.getMeasuredWidth();
+        int pinT = (h - pinH) / 2;
+        int pinL = mPinLeftMargin;
+        mLeftPin.layout(pinL, pinT, pinL + pinW, pinT + pinH);
+
+        mLeftLabel.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+        int labelH = mLeftLabel.getMeasuredHeight();
+        int labelW = mLeftLabel.getMeasuredWidth();
+        int labelT = (h - labelH) / 2;
+        int labelL = pinL + pinW + mPinRightMargin;
+        mLeftLabel.layout(labelL, labelT, labelL + labelW, labelT + labelH);
+
+        mDoneButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+        int doneH = mDoneButton.getMeasuredHeight();
+        int doneW = mDoneButton.getMeasuredWidth();
+        int doneT = (h - doneH) / 2;
+        int doneR = w - mButtonRightMargin;
+        mDoneButton.layout(doneR - doneW, doneT, doneR, doneT + doneH);
+
+        int centerX = w / 2;
+        int centerY = h / 2;
+
+        int capBarH = 20;
+        int capBarW = 200;
+        int capBarT = centerY - capBarH / 2;
+        int capBarL = centerX - capBarW / 2;
+        mStorageBar.layout(capBarL, capBarT, capBarL + capBarW,
+                capBarT + capBarH);
+
+        mStorageLabel.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+        int capLabelH = mStorageLabel.getMeasuredHeight();
+        int capLabelW = mStorageLabel.getMeasuredWidth();
+        int capLabelT = centerY - capLabelH / 2;
+        int capLabelL = centerX + capBarW / 2 + 8;
+        mStorageLabel.layout(capLabelL , capLabelT, capLabelL + capLabelW,
+                capLabelT + capLabelH);
+    }
+
+    public void refreshStorageInfo() {
+        long used = mStorageInfo.usedBytes;
+        long total = mStorageInfo.totalBytes;
+        long cached = mStorageInfo.usedCacheBytes;
+        long target = mStorageInfo.targetCacheBytes;
+
+        double primary = (double) used / total;
+        double secondary =
+                (double) (used - cached + target + mUserChangeDelta) / total;
+
+        mStorageBar.setProgress((int) (primary * 10000));
+        mStorageBar.setSecondaryProgress((int) (secondary * 10000));
+
+        long freeBytes = mStorageInfo.totalBytes - mStorageInfo.usedBytes;
+        String sizeString = Formatter.formatFileSize(mContext, freeBytes);
+        String label = mContext.getString(R.string.free_space_format, sizeString);
+        mStorageLabel.setText(label);
+        mStorageBar.setVisibility(GLView.VISIBLE);
+        mStorageLabel.setVisibility(GLView.VISIBLE);
+        requestLayout(); // because the size of the label may have changed.
+    }
+
+    public void increaseTargetCacheSize(long delta) {
+        mUserChangeDelta += delta;
+        refreshStorageInfo();
+    }
+
+    @Override
+    protected void renderBackground(GLCanvas canvas) {
+        Rect paddings = mBackground.getPaddings();
+        mBackground.draw(canvas, 0, -paddings.top, getWidth(), mTotalHeight);
+    }
+
+    public void resume() {
+        mStorageInfoFuture = mActivity.getThreadPool().submit(
+            new StorageInfoJob(),
+            new FutureListener<StorageInfo>() {
+                    public void onFutureDone(Future<StorageInfo> future) {
+                        mStorageInfoFuture = null;
+                        if (!future.isCancelled()) {
+                            mHandler.sendMessage(mHandler.obtainMessage(
+                                    MSG_REFRESH_STORAGE, future.get()));
+                        }
+                    }
+                });
+    }
+
+    public void pause() {
+        if (mStorageInfoFuture != null) {
+            mStorageInfoFuture.cancel();
+            mStorageInfoFuture = null;
+        }
+        mStorageBar.setVisibility(GLView.INVISIBLE);
+        mStorageLabel.setVisibility(GLView.INVISIBLE);
+    }
+
+    public static class StorageInfo {
+        long totalBytes;      // number of bytes the storage has.
+        long usedBytes;       // number of bytes already used.
+        long usedCacheBytes;  // number of bytes used for the cache (should be less
+                              // then usedBytes).
+        long targetCacheBytes;// number of bytes used for the cache
+                              // if all pending downloads (and removals) are completed.
+    }
+
+    private class StorageInfoJob implements Job<StorageInfo> {
+        public StorageInfo run(JobContext jc) {
+            File cacheDir = mContext.getExternalCacheDir();
+            if (cacheDir == null) {
+                cacheDir = mContext.getCacheDir();
+            }
+            String path = cacheDir.getAbsolutePath();
+            StatFs stat = new StatFs(path);
+            long blockSize = stat.getBlockSize();
+            long availableBlocks = stat.getAvailableBlocks();
+            long totalBlocks = stat.getBlockCount();
+            StorageInfo si = new StorageInfo();
+            si.totalBytes = blockSize * totalBlocks;
+            si.usedBytes = blockSize * (totalBlocks - availableBlocks);
+            si.usedCacheBytes = mActivity.getDataManager().getTotalUsedCacheSize();
+            si.targetCacheBytes = mActivity.getDataManager().getTotalTargetCacheSize();
+            return si;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/CanvasTexture.java b/src/com/android/gallery3d/ui/CanvasTexture.java
new file mode 100644
index 0000000..679a4bc
--- /dev/null
+++ b/src/com/android/gallery3d/ui/CanvasTexture.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Bitmap.Config;
+
+// CanvasTexture is a texture whose content is the drawing on a Canvas.
+// The subclasses should override onDraw() to draw on the bitmap.
+// By default CanvasTexture is not opaque.
+abstract class CanvasTexture extends UploadedTexture {
+    protected Canvas mCanvas;
+    private final Config mConfig;
+
+    public CanvasTexture(int width, int height) {
+        mConfig = Config.ARGB_8888;
+        setSize(width, height);
+        setOpaque(false);
+    }
+
+    @Override
+    protected Bitmap onGetBitmap() {
+        Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, mConfig);
+        mCanvas = new Canvas(bitmap);
+        onDraw(mCanvas, bitmap);
+        return bitmap;
+    }
+
+    @Override
+    protected void onFreeBitmap(Bitmap bitmap) {
+        if (!inFinalizer()) {
+            bitmap.recycle();
+        }
+    }
+
+    abstract protected void onDraw(Canvas canvas, Bitmap backing);
+}
diff --git a/src/com/android/gallery3d/ui/ColorTexture.java b/src/com/android/gallery3d/ui/ColorTexture.java
new file mode 100644
index 0000000..24e8914
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ColorTexture.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+// ColorTexture is a texture which fills the rectangle with the specified color.
+public class ColorTexture implements Texture {
+
+    private final int mColor;
+    private int mWidth;
+    private int mHeight;
+
+    public ColorTexture(int color) {
+        mColor = color;
+        mWidth = 1;
+        mHeight = 1;
+    }
+
+    public void draw(GLCanvas canvas, int x, int y) {
+        draw(canvas, x, y, mWidth, mHeight);
+    }
+
+    public void draw(GLCanvas canvas, int x, int y, int w, int h) {
+        canvas.fillRect(x, y, w, h, mColor);
+    }
+
+    public boolean isOpaque() {
+        return Utils.isOpaque(mColor);
+    }
+
+    public void setSize(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+    }
+
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/Config.java b/src/com/android/gallery3d/ui/Config.java
new file mode 100644
index 0000000..5c5b621
--- /dev/null
+++ b/src/com/android/gallery3d/ui/Config.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+interface DetailsWindowConfig {
+    public static final int FONT_SIZE = 18;
+    public static final int PREFERRED_WIDTH = 400;
+    public static final int LEFT_RIGHT_EXTRA_PADDING = 9;
+    public static final int TOP_BOTTOM_EXTRA_PADDING = 9;
+    public static final int LINE_SPACING = 5;
+    public static final int FIRST_LINE_SPACING = 18;
+}
+
+interface TextButtonConfig {
+    public static final int HORIZONTAL_PADDINGS = 16;
+    public static final int VERTICAL_PADDINGS = 5;
+}
diff --git a/src/com/android/gallery3d/ui/CropView.java b/src/com/android/gallery3d/ui/CropView.java
new file mode 100644
index 0000000..9c59c9a
--- /dev/null
+++ b/src/com/android/gallery3d/ui/CropView.java
@@ -0,0 +1,801 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.anim.Animation;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.media.FaceDetector;
+import android.os.Handler;
+import android.os.Message;
+import android.view.MotionEvent;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import javax.microedition.khronos.opengles.GL11;
+
+/**
+ * The activity can crop specific region of interest from an image.
+ */
+public class CropView extends GLView {
+    private static final String TAG = "CropView";
+
+    private static final int FACE_PIXEL_COUNT = 120000; // around 400x300
+
+    private static final int COLOR_OUTLINE = 0xFF008AFF;
+    private static final int COLOR_FACE_OUTLINE = 0xFF000000;
+
+    private static final float OUTLINE_WIDTH = 3f;
+
+    private static final int SIZE_UNKNOWN = -1;
+    private static final int TOUCH_TOLERANCE = 30;
+
+    private static final float MIN_SELECTION_LENGTH = 16f;
+    public static final float UNSPECIFIED = -1f;
+
+    private static final int MAX_FACE_COUNT = 3;
+    private static final float FACE_EYE_RATIO = 2f;
+
+    private static final int ANIMATION_DURATION = 1250;
+
+    private static final int MOVE_LEFT = 1;
+    private static final int MOVE_TOP = 2;
+    private static final int MOVE_RIGHT = 4;
+    private static final int MOVE_BOTTOM = 8;
+    private static final int MOVE_BLOCK = 16;
+
+    private static final float MAX_SELECTION_RATIO = 0.8f;
+    private static final float MIN_SELECTION_RATIO = 0.4f;
+    private static final float SELECTION_RATIO = 0.60f;
+    private static final int ANIMATION_TRIGGER = 64;
+
+    private static final int MSG_UPDATE_FACES = 1;
+
+    private float mAspectRatio = UNSPECIFIED;
+    private float mSpotlightRatioX = 0;
+    private float mSpotlightRatioY = 0;
+
+    private Handler mMainHandler;
+
+    private FaceHighlightView mFaceDetectionView;
+    private HighlightRectangle mHighlightRectangle;
+    private TileImageView mImageView;
+    private AnimationController mAnimation = new AnimationController();
+
+    private int mImageWidth = SIZE_UNKNOWN;
+    private int mImageHeight = SIZE_UNKNOWN;
+
+    private GalleryActivity mActivity;
+
+    private GLPaint mPaint = new GLPaint();
+    private GLPaint mFacePaint = new GLPaint();
+
+    private int mImageRotation;
+
+    public CropView(GalleryActivity activity) {
+        mActivity = activity;
+        mImageView = new TileImageView(activity);
+        mFaceDetectionView = new FaceHighlightView();
+        mHighlightRectangle = new HighlightRectangle();
+
+        addComponent(mImageView);
+        addComponent(mFaceDetectionView);
+        addComponent(mHighlightRectangle);
+
+        mHighlightRectangle.setVisibility(GLView.INVISIBLE);
+
+        mPaint.setColor(COLOR_OUTLINE);
+        mPaint.setLineWidth(OUTLINE_WIDTH);
+
+        mFacePaint.setColor(COLOR_FACE_OUTLINE);
+        mFacePaint.setLineWidth(OUTLINE_WIDTH);
+
+        mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                Utils.assertTrue(message.what == MSG_UPDATE_FACES);
+                ((DetectFaceTask) message.obj).updateFaces();
+            }
+        };
+    }
+
+    public void setAspectRatio(float ratio) {
+        mAspectRatio = ratio;
+    }
+
+    public void setSpotlightRatio(float ratioX, float ratioY) {
+        mSpotlightRatioX = ratioX;
+        mSpotlightRatioY = ratioY;
+    }
+
+    @Override
+    public void onLayout(boolean changed, int l, int t, int r, int b) {
+        int width = r - l;
+        int height = b - t;
+
+        mFaceDetectionView.layout(0, 0, width, height);
+        mHighlightRectangle.layout(0, 0, width, height);
+        mImageView.layout(0, 0, width, height);
+        if (mImageHeight != SIZE_UNKNOWN) {
+            mAnimation.initialize();
+            if (mHighlightRectangle.getVisibility() == GLView.VISIBLE) {
+                mAnimation.parkNow(
+                        mHighlightRectangle.mHighlightRect);
+            }
+        }
+    }
+
+    private boolean setImageViewPosition(int centerX, int centerY, float scale) {
+        int inverseX = mImageWidth - centerX;
+        int inverseY = mImageHeight - centerY;
+        TileImageView t = mImageView;
+        int rotation = mImageRotation;
+        switch (rotation) {
+            case 0: return t.setPosition(centerX, centerY, scale, 0);
+            case 90: return t.setPosition(centerY, inverseX, scale, 90);
+            case 180: return t.setPosition(inverseX, inverseY, scale, 180);
+            case 270: return t.setPosition(inverseY, centerX, scale, 270);
+            default: throw new IllegalArgumentException(String.valueOf(rotation));
+        }
+    }
+
+    @Override
+    public void render(GLCanvas canvas) {
+        AnimationController a = mAnimation;
+        if (a.calculate(canvas.currentAnimationTimeMillis())) invalidate();
+        setImageViewPosition(a.getCenterX(), a.getCenterY(), a.getScale());
+        super.render(canvas);
+    }
+
+    @Override
+    public void renderBackground(GLCanvas canvas) {
+        canvas.clearBuffer();
+    }
+
+    public RectF getCropRectangle() {
+        if (mHighlightRectangle.getVisibility() == GLView.INVISIBLE) return null;
+        RectF rect = mHighlightRectangle.mHighlightRect;
+        RectF result = new RectF(rect.left * mImageWidth, rect.top * mImageHeight,
+                rect.right * mImageWidth, rect.bottom * mImageHeight);
+        return result;
+    }
+
+    public int getImageWidth() {
+        return mImageWidth;
+    }
+
+    public int getImageHeight() {
+        return mImageHeight;
+    }
+
+    private class FaceHighlightView extends GLView {
+        private static final int INDEX_NONE = -1;
+        private ArrayList<RectF> mFaces = new ArrayList<RectF>();
+        private RectF mRect = new RectF();
+        private int mPressedFaceIndex = INDEX_NONE;
+
+        public void addFace(RectF faceRect) {
+            mFaces.add(faceRect);
+            invalidate();
+        }
+
+        private void renderFace(GLCanvas canvas, RectF face, boolean pressed) {
+            GL11 gl = canvas.getGLInstance();
+            if (pressed) {
+                gl.glEnable(GL11.GL_STENCIL_TEST);
+                gl.glClear(GL11.GL_STENCIL_BUFFER_BIT);
+                gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
+                gl.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
+            }
+
+            RectF r = mAnimation.mapRect(face, mRect);
+            canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
+            canvas.drawRect(r.left, r.top, r.width(), r.height(), mFacePaint);
+
+            if (pressed) {
+                gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
+            }
+        }
+
+        @Override
+        protected void renderBackground(GLCanvas canvas) {
+            ArrayList<RectF> faces = mFaces;
+            for (int i = 0, n = faces.size(); i < n; ++i) {
+                renderFace(canvas, faces.get(i), i == mPressedFaceIndex);
+            }
+
+            GL11 gl = canvas.getGLInstance();
+            if (mPressedFaceIndex != INDEX_NONE) {
+                gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
+                canvas.fillRect(0, 0, getWidth(), getHeight(), 0x66000000);
+                gl.glDisable(GL11.GL_STENCIL_TEST);
+            }
+        }
+
+        private void setPressedFace(int index) {
+            if (mPressedFaceIndex == index) return;
+            mPressedFaceIndex = index;
+            invalidate();
+        }
+
+        private int getFaceIndexByPosition(float x, float y) {
+            ArrayList<RectF> faces = mFaces;
+            for (int i = 0, n = faces.size(); i < n; ++i) {
+                RectF r = mAnimation.mapRect(faces.get(i), mRect);
+                if (r.contains(x, y)) return i;
+            }
+            return INDEX_NONE;
+        }
+
+        @Override
+        protected boolean onTouch(MotionEvent event) {
+            float x = event.getX();
+            float y = event.getY();
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                case MotionEvent.ACTION_MOVE: {
+                    setPressedFace(getFaceIndexByPosition(x, y));
+                    break;
+                }
+                case MotionEvent.ACTION_CANCEL:
+                case MotionEvent.ACTION_UP: {
+                    int index = mPressedFaceIndex;
+                    setPressedFace(INDEX_NONE);
+                    if (index != INDEX_NONE) {
+                        mHighlightRectangle.setRectangle(mFaces.get(index));
+                        mHighlightRectangle.setVisibility(GLView.VISIBLE);
+                        setVisibility(GLView.INVISIBLE);
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    private class AnimationController extends Animation {
+        private int mCurrentX;
+        private int mCurrentY;
+        private float mCurrentScale;
+        private int mStartX;
+        private int mStartY;
+        private float mStartScale;
+        private int mTargetX;
+        private int mTargetY;
+        private float mTargetScale;
+
+        public AnimationController() {
+            setDuration(ANIMATION_DURATION);
+            setInterpolator(new DecelerateInterpolator(4));
+        }
+
+        public void initialize() {
+            mCurrentX = mImageWidth / 2;
+            mCurrentY = mImageHeight / 2;
+            mCurrentScale = Math.min(2, Math.min(
+                    (float) getWidth() / mImageWidth,
+                    (float) getHeight() / mImageHeight));
+        }
+
+        public void startParkingAnimation(RectF highlight) {
+            RectF r = mAnimation.mapRect(highlight, new RectF());
+            int width = getWidth();
+            int height = getHeight();
+
+            float wr = r.width() / width;
+            float hr = r.height() / height;
+            final int d = ANIMATION_TRIGGER;
+            if (wr >= MIN_SELECTION_RATIO && wr < MAX_SELECTION_RATIO
+                    && hr >= MIN_SELECTION_RATIO && hr < MAX_SELECTION_RATIO
+                    && r.left >= d && r.right < width - d
+                    && r.top >= d && r.bottom < height - d) return;
+
+            mStartX = mCurrentX;
+            mStartY = mCurrentY;
+            mStartScale = mCurrentScale;
+            calculateTarget(highlight);
+            start();
+        }
+
+        public void parkNow(RectF highlight) {
+            calculateTarget(highlight);
+            forceStop();
+            mStartX = mCurrentX = mTargetX;
+            mStartY = mCurrentY = mTargetY;
+            mStartScale = mCurrentScale = mTargetScale;
+        }
+
+        public void inverseMapPoint(PointF point) {
+            float s = mCurrentScale;
+            point.x = Utils.clamp(((point.x - getWidth() * 0.5f) / s
+                    + mCurrentX) / mImageWidth, 0, 1);
+            point.y = Utils.clamp(((point.y - getHeight() * 0.5f) / s
+                    + mCurrentY) / mImageHeight, 0, 1);
+        }
+
+        public RectF mapRect(RectF input, RectF output) {
+            float offsetX = getWidth() * 0.5f;
+            float offsetY = getHeight() * 0.5f;
+            int x = mCurrentX;
+            int y = mCurrentY;
+            float s = mCurrentScale;
+            output.set(
+                    offsetX + (input.left * mImageWidth - x) * s,
+                    offsetY + (input.top * mImageHeight - y) * s,
+                    offsetX + (input.right * mImageWidth - x) * s,
+                    offsetY + (input.bottom * mImageHeight - y) * s);
+            return output;
+        }
+
+        @Override
+        protected void onCalculate(float progress) {
+            mCurrentX = Math.round(mStartX + (mTargetX - mStartX) * progress);
+            mCurrentY = Math.round(mStartY + (mTargetY - mStartY) * progress);
+            mCurrentScale = mStartScale + (mTargetScale - mStartScale) * progress;
+
+            if (mCurrentX == mTargetX && mCurrentY == mTargetY
+                    && mCurrentScale == mTargetScale) forceStop();
+        }
+
+        public int getCenterX() {
+            return mCurrentX;
+        }
+
+        public int getCenterY() {
+            return mCurrentY;
+        }
+
+        public float getScale() {
+            return mCurrentScale;
+        }
+
+        private void calculateTarget(RectF highlight) {
+            float width = getWidth();
+            float height = getHeight();
+
+            if (mImageWidth != SIZE_UNKNOWN) {
+                float minScale = Math.min(width / mImageWidth, height / mImageHeight);
+                float scale = Utils.clamp(SELECTION_RATIO * Math.min(
+                        width / (highlight.width() * mImageWidth),
+                        height / (highlight.height() * mImageHeight)), minScale, 2f);
+                int centerX = Math.round(
+                        mImageWidth * (highlight.left + highlight.right) * 0.5f);
+                int centerY = Math.round(
+                        mImageHeight * (highlight.top + highlight.bottom) * 0.5f);
+
+                if (Math.round(mImageWidth * scale) > width) {
+                    int limitX = Math.round(width * 0.5f / scale);
+                    centerX = Math.round(
+                            (highlight.left + highlight.right) * mImageWidth / 2);
+                    centerX = Utils.clamp(centerX, limitX, mImageWidth - limitX);
+                } else {
+                    centerX = mImageWidth / 2;
+                }
+                if (Math.round(mImageHeight * scale) > height) {
+                    int limitY = Math.round(height * 0.5f / scale);
+                    centerY = Math.round(
+                            (highlight.top + highlight.bottom) * mImageHeight / 2);
+                    centerY = Utils.clamp(centerY, limitY, mImageHeight - limitY);
+                } else {
+                    centerY = mImageHeight / 2;
+                }
+                mTargetX = centerX;
+                mTargetY = centerY;
+                mTargetScale = scale;
+            }
+        }
+
+    }
+
+    private class HighlightRectangle extends GLView {
+        private RectF mHighlightRect = new RectF(0.25f, 0.25f, 0.75f, 0.75f);
+        private RectF mTempRect = new RectF();
+        private PointF mTempPoint = new PointF();
+
+        private ResourceTexture mArrowX;
+        private ResourceTexture mArrowY;
+
+        private int mMovingEdges = 0;
+        private float mReferenceX;
+        private float mReferenceY;
+
+        public HighlightRectangle() {
+            mArrowX = new ResourceTexture(mActivity.getAndroidContext(),
+                    R.drawable.camera_crop_width_holo);
+            mArrowY = new ResourceTexture(mActivity.getAndroidContext(),
+                    R.drawable.camera_crop_height_holo);
+        }
+
+        public void setInitRectangle() {
+            float targetRatio = mAspectRatio == UNSPECIFIED
+                    ? 1f
+                    : mAspectRatio * mImageHeight / mImageWidth;
+            float w = SELECTION_RATIO / 2f;
+            float h = SELECTION_RATIO / 2f;
+            if (targetRatio > 1) {
+                h = w / targetRatio;
+            } else {
+                w = h * targetRatio;
+            }
+            mHighlightRect.set(0.5f - w, 0.5f - h, 0.5f + w, 0.5f + h);
+        }
+
+        public void setRectangle(RectF faceRect) {
+            mHighlightRect.set(faceRect);
+            mAnimation.startParkingAnimation(faceRect);
+            invalidate();
+        }
+
+        private void moveEdges(MotionEvent event) {
+            float scale = mAnimation.getScale();
+            float dx = (event.getX() - mReferenceX) / scale / mImageWidth;
+            float dy = (event.getY() - mReferenceY) / scale / mImageHeight;
+            mReferenceX = event.getX();
+            mReferenceY = event.getY();
+            RectF r = mHighlightRect;
+
+            if ((mMovingEdges & MOVE_BLOCK) != 0) {
+                dx = Utils.clamp(dx, -r.left,  1 - r.right);
+                dy = Utils.clamp(dy, -r.top , 1 - r.bottom);
+                r.top += dy;
+                r.bottom += dy;
+                r.left += dx;
+                r.right += dx;
+            } else {
+                PointF point = mTempPoint;
+                point.set(mReferenceX, mReferenceY);
+                mAnimation.inverseMapPoint(point);
+                float left = r.left + MIN_SELECTION_LENGTH / mImageWidth;
+                float right = r.right - MIN_SELECTION_LENGTH / mImageWidth;
+                float top = r.top + MIN_SELECTION_LENGTH / mImageHeight;
+                float bottom = r.bottom - MIN_SELECTION_LENGTH / mImageHeight;
+                if ((mMovingEdges & MOVE_RIGHT) != 0) {
+                    r.right = Utils.clamp(point.x, left, 1f);
+                }
+                if ((mMovingEdges & MOVE_LEFT) != 0) {
+                    r.left = Utils.clamp(point.x, 0, right);
+                }
+                if ((mMovingEdges & MOVE_TOP) != 0) {
+                    r.top = Utils.clamp(point.y, 0, bottom);
+                }
+                if ((mMovingEdges & MOVE_BOTTOM) != 0) {
+                    r.bottom = Utils.clamp(point.y, top, 1f);
+                }
+                if (mAspectRatio != UNSPECIFIED) {
+                    float targetRatio = mAspectRatio * mImageHeight / mImageWidth;
+                    if (r.width() / r.height() > targetRatio) {
+                        float height = r.width() / targetRatio;
+                        if ((mMovingEdges & MOVE_BOTTOM) != 0) {
+                            r.bottom = Utils.clamp(r.top + height, top, 1f);
+                        } else {
+                            r.top = Utils.clamp(r.bottom - height, 0, bottom);
+                        }
+                    } else {
+                        float width = r.height() * targetRatio;
+                        if ((mMovingEdges & MOVE_LEFT) != 0) {
+                            r.left = Utils.clamp(r.right - width, 0, right);
+                        } else {
+                            r.right = Utils.clamp(r.left + width, left, 1f);
+                        }
+                    }
+                    if (r.width() / r.height() > targetRatio) {
+                        float width = r.height() * targetRatio;
+                        if ((mMovingEdges & MOVE_LEFT) != 0) {
+                            r.left = Utils.clamp(r.right - width, 0, right);
+                        } else {
+                            r.right = Utils.clamp(r.left + width, left, 1f);
+                        }
+                    } else {
+                        float height = r.width() / targetRatio;
+                        if ((mMovingEdges & MOVE_BOTTOM) != 0) {
+                            r.bottom = Utils.clamp(r.top + height, top, 1f);
+                        } else {
+                            r.top = Utils.clamp(r.bottom - height, 0, bottom);
+                        }
+                    }
+                }
+            }
+            invalidate();
+        }
+
+        private void setMovingEdges(MotionEvent event) {
+            RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
+            float x = event.getX();
+            float y = event.getY();
+
+            if (x > r.left + TOUCH_TOLERANCE && x < r.right - TOUCH_TOLERANCE
+                    && y > r.top + TOUCH_TOLERANCE && y < r.bottom - TOUCH_TOLERANCE) {
+                mMovingEdges = MOVE_BLOCK;
+                return;
+            }
+
+            boolean inVerticalRange = (r.top - TOUCH_TOLERANCE) <= y
+                    && y <= (r.bottom + TOUCH_TOLERANCE);
+            boolean inHorizontalRange = (r.left - TOUCH_TOLERANCE) <= x
+                    && x <= (r.right + TOUCH_TOLERANCE);
+
+            if (inVerticalRange) {
+                boolean left = Math.abs(x - r.left) <= TOUCH_TOLERANCE;
+                boolean right = Math.abs(x - r.right) <= TOUCH_TOLERANCE;
+                if (left && right) {
+                    left = Math.abs(x - r.left) < Math.abs(x - r.right);
+                    right = !left;
+                }
+                if (left) mMovingEdges |= MOVE_LEFT;
+                if (right) mMovingEdges |= MOVE_RIGHT;
+                if (mAspectRatio != UNSPECIFIED && inHorizontalRange) {
+                    mMovingEdges |= (y >
+                            (r.top + r.bottom) / 2) ? MOVE_BOTTOM : MOVE_TOP;
+                }
+            }
+            if (inHorizontalRange) {
+                boolean top = Math.abs(y - r.top) <= TOUCH_TOLERANCE;
+                boolean bottom = Math.abs(y - r.bottom) <= TOUCH_TOLERANCE;
+                if (top && bottom) {
+                    top = Math.abs(y - r.top) < Math.abs(y - r.bottom);
+                    bottom = !top;
+                }
+                if (top) mMovingEdges |= MOVE_TOP;
+                if (bottom) mMovingEdges |= MOVE_BOTTOM;
+                if (mAspectRatio != UNSPECIFIED && inVerticalRange) {
+                    mMovingEdges |= (x >
+                            (r.left + r.right) / 2) ? MOVE_RIGHT : MOVE_LEFT;
+                }
+            }
+        }
+
+        @Override
+        protected boolean onTouch(MotionEvent event) {
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN: {
+                    mReferenceX = event.getX();
+                    mReferenceY = event.getY();
+                    setMovingEdges(event);
+                    invalidate();
+                    return true;
+                }
+                case MotionEvent.ACTION_MOVE:
+                    moveEdges(event);
+                    break;
+                case MotionEvent.ACTION_CANCEL:
+                case MotionEvent.ACTION_UP: {
+                    mMovingEdges = 0;
+                    mAnimation.startParkingAnimation(mHighlightRect);
+                    invalidate();
+                    return true;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        protected void renderBackground(GLCanvas canvas) {
+            RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
+            drawHighlightRectangle(canvas, r);
+
+            float centerY = (r.top + r.bottom) / 2;
+            float centerX = (r.left + r.right) / 2;
+            if ((mMovingEdges & (MOVE_RIGHT | MOVE_BLOCK)) != 0) {
+                mArrowX.draw(canvas,
+                        Math.round(r.right - mArrowX.getWidth() / 2),
+                        Math.round(centerY - mArrowX.getHeight() / 2));
+            }
+            if ((mMovingEdges & (MOVE_LEFT | MOVE_BLOCK)) != 0) {
+                mArrowX.draw(canvas,
+                        Math.round(r.left - mArrowX.getWidth() / 2),
+                        Math.round(centerY - mArrowX.getHeight() / 2));
+            }
+            if ((mMovingEdges & (MOVE_TOP | MOVE_BLOCK)) != 0) {
+                mArrowY.draw(canvas,
+                        Math.round(centerX - mArrowY.getWidth() / 2),
+                        Math.round(r.top - mArrowY.getHeight() / 2));
+            }
+            if ((mMovingEdges & (MOVE_BOTTOM | MOVE_BLOCK)) != 0) {
+                mArrowY.draw(canvas,
+                        Math.round(centerX - mArrowY.getWidth() / 2),
+                        Math.round(r.bottom - mArrowY.getHeight() / 2));
+            }
+        }
+
+        private void drawHighlightRectangle(GLCanvas canvas, RectF r) {
+            GL11 gl = canvas.getGLInstance();
+            gl.glLineWidth(3.0f);
+            gl.glEnable(GL11.GL_LINE_SMOOTH);
+
+            gl.glEnable(GL11.GL_STENCIL_TEST);
+            gl.glClear(GL11.GL_STENCIL_BUFFER_BIT);
+            gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
+            gl.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
+
+            if (mSpotlightRatioX == 0 || mSpotlightRatioY == 0) {
+                canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
+                canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);
+            } else {
+                float sx = r.width() * mSpotlightRatioX;
+                float sy = r.height() * mSpotlightRatioY;
+                float cx = r.centerX();
+                float cy = r.centerY();
+
+                canvas.fillRect(cx - sx / 2, cy - sy / 2, sx, sy, Color.TRANSPARENT);
+                canvas.drawRect(cx - sx / 2, cy - sy / 2, sx, sy, mPaint);
+                canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);
+
+                gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
+                gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
+
+                canvas.drawRect(cx - sy / 2, cy - sx / 2, sy, sx, mPaint);
+                canvas.fillRect(cx - sy / 2, cy - sx / 2, sy, sx, Color.TRANSPARENT);
+                canvas.fillRect(r.left, r.top, r.width(), r.height(), 0x80000000);
+            }
+
+            gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
+            gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
+
+            canvas.fillRect(0, 0, getWidth(), getHeight(), 0xA0000000);
+
+            gl.glDisable(GL11.GL_STENCIL_TEST);
+        }
+    }
+
+    private class DetectFaceTask extends Thread {
+        private final FaceDetector.Face[] mFaces = new FaceDetector.Face[MAX_FACE_COUNT];
+        private final Bitmap mFaceBitmap;
+        private int mFaceCount;
+
+        public DetectFaceTask(Bitmap bitmap) {
+            mFaceBitmap = bitmap;
+            setName("face-detect");
+        }
+
+        @Override
+        public void run() {
+            Bitmap bitmap = mFaceBitmap;
+            FaceDetector detector = new FaceDetector(
+                    bitmap.getWidth(), bitmap.getHeight(), MAX_FACE_COUNT);
+            mFaceCount = detector.findFaces(bitmap, mFaces);
+            mMainHandler.sendMessage(
+                    mMainHandler.obtainMessage(MSG_UPDATE_FACES, this));
+        }
+
+        private RectF getFaceRect(FaceDetector.Face face) {
+            PointF point = new PointF();
+            face.getMidPoint(point);
+
+            int width = mFaceBitmap.getWidth();
+            int height = mFaceBitmap.getHeight();
+            float rx = face.eyesDistance() * FACE_EYE_RATIO;
+            float ry = rx;
+            float aspect = mAspectRatio;
+            if (aspect != UNSPECIFIED) {
+                if (aspect > 1) {
+                    rx = ry * aspect;
+                } else {
+                    ry = rx / aspect;
+                }
+            }
+
+            RectF r = new RectF(
+                    point.x - rx, point.y - ry, point.x + rx, point.y + ry);
+            r.intersect(0, 0, width, height);
+
+            if (aspect != UNSPECIFIED) {
+                if (r.width() / r.height() > aspect) {
+                    float w = r.height() * aspect;
+                    r.left = (r.left + r.right - w) * 0.5f;
+                    r.right = r.left + w;
+                } else {
+                    float h = r.width() / aspect;
+                    r.top =  (r.top + r.bottom - h) * 0.5f;
+                    r.bottom = r.top + h;
+                }
+            }
+
+            r.left /= width;
+            r.right /= width;
+            r.top /= height;
+            r.bottom /= height;
+            return r;
+        }
+
+        public void updateFaces() {
+            if (mFaceCount > 1) {
+                for (int i = 0, n = mFaceCount; i < n; ++i) {
+                    mFaceDetectionView.addFace(getFaceRect(mFaces[i]));
+                }
+                mFaceDetectionView.setVisibility(GLView.VISIBLE);
+                Toast.makeText(mActivity.getAndroidContext(),
+                        R.string.multiface_crop_help, Toast.LENGTH_SHORT).show();
+            } else if (mFaceCount == 1) {
+                mFaceDetectionView.setVisibility(GLView.INVISIBLE);
+                mHighlightRectangle.setRectangle(getFaceRect(mFaces[0]));
+                mHighlightRectangle.setVisibility(GLView.VISIBLE);
+            } else /*mFaceCount == 0*/ {
+                mHighlightRectangle.setInitRectangle();
+                mHighlightRectangle.setVisibility(GLView.VISIBLE);
+            }
+        }
+    }
+
+    public void setDataModel(TileImageView.Model dataModel, int rotation) {
+        if (((rotation / 90) & 0x01) != 0) {
+            mImageWidth = dataModel.getImageHeight();
+            mImageHeight = dataModel.getImageWidth();
+        } else {
+            mImageWidth = dataModel.getImageWidth();
+            mImageHeight = dataModel.getImageHeight();
+        }
+
+        mImageRotation = rotation;
+
+        mImageView.setModel(dataModel);
+        mAnimation.initialize();
+    }
+
+    public void detectFaces(Bitmap bitmap) {
+        int rotation = mImageRotation;
+        int width = bitmap.getWidth();
+        int height = bitmap.getHeight();
+        float scale = (float) Math.sqrt(
+                (double) FACE_PIXEL_COUNT / (width * height));
+
+        // faceBitmap is a correctly rotated bitmap, as viewed by a user.
+        Bitmap faceBitmap;
+        if (((rotation / 90) & 1) == 0) {
+            int w = (Math.round(width * scale) & ~1); // must be even
+            int h = Math.round(height * scale);
+            faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
+            Canvas canvas = new Canvas(faceBitmap);
+            canvas.rotate(rotation, w / 2, h / 2);
+            canvas.scale((float) w / width, (float) h / height);
+            canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
+        } else {
+            int w = (Math.round(height * scale) & ~1); // must be even
+            int h = Math.round(width * scale);
+            faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
+            Canvas canvas = new Canvas(faceBitmap);
+            canvas.translate(w / 2, h / 2);
+            canvas.rotate(rotation);
+            canvas.translate(-h / 2, -w / 2);
+            canvas.scale((float) w / height, (float) h / width);
+            canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
+        }
+        new DetectFaceTask(faceBitmap).start();
+    }
+
+    public void initializeHighlightRectangle() {
+        mHighlightRectangle.setInitRectangle();
+        mHighlightRectangle.setVisibility(GLView.VISIBLE);
+    }
+
+    public void resume() {
+        mImageView.prepareTextures();
+    }
+
+    public void pause() {
+        mImageView.freeTextures();
+    }
+}
+
diff --git a/src/com/android/gallery3d/ui/CustomMenu.java b/src/com/android/gallery3d/ui/CustomMenu.java
new file mode 100644
index 0000000..de2367e
--- /dev/null
+++ b/src/com/android/gallery3d/ui/CustomMenu.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+
+import android.app.ActionBar;
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.PopupMenu;
+import android.widget.PopupMenu.OnMenuItemClickListener;
+
+import java.util.ArrayList;
+
+public class CustomMenu implements OnMenuItemClickListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "FilterMenu";
+
+    public static class DropDownMenu {
+        private Button mButton;
+        private PopupMenu mPopupMenu;
+        private Menu mMenu;
+
+        public DropDownMenu(Context context, Button button, int menuId,
+                OnMenuItemClickListener listener) {
+            mButton = button;
+            mButton.setBackgroundDrawable(context.getResources().getDrawable(
+                    R.drawable.dropdown_normal_holo_dark));
+            mPopupMenu = new PopupMenu(context, mButton);
+            mMenu = mPopupMenu.getMenu();
+            mPopupMenu.getMenuInflater().inflate(menuId, mMenu);
+            mPopupMenu.setOnMenuItemClickListener(listener);
+            mButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    mPopupMenu.show();
+                }
+            });
+        }
+
+        public MenuItem findItem(int id) {
+            return mMenu.findItem(id);
+        }
+
+        public void setTitle(CharSequence title) {
+            mButton.setText(title);
+        }
+    }
+
+
+
+    private Context mContext;
+    private ArrayList<DropDownMenu> mMenus;
+    private OnMenuItemClickListener mListener;
+
+    public CustomMenu(Context context) {
+        mContext = context;
+        mMenus = new ArrayList<DropDownMenu>();
+    }
+
+    public DropDownMenu addDropDownMenu(Button button, int menuId) {
+        DropDownMenu menu = new DropDownMenu(mContext, button, menuId, this);
+        mMenus.add(menu);
+        return menu;
+    }
+
+    public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
+        mListener = listener;
+    }
+
+    public MenuItem findMenuItem(int id) {
+        MenuItem item = null;
+        for (DropDownMenu menu : mMenus) {
+            item = menu.findItem(id);
+            if (item != null) return item;
+        }
+        return item;
+    }
+
+    public void setMenuItemAppliedEnabled(int id, boolean applied, boolean enabled,
+            boolean updateTitle) {
+        MenuItem item = null;
+        for (DropDownMenu menu : mMenus) {
+            item = menu.findItem(id);
+            if (item != null) {
+                item.setCheckable(true);
+                item.setChecked(applied);
+                item.setEnabled(enabled);
+                if (updateTitle) {
+                    menu.setTitle(item.getTitle());
+                }
+            }
+        }
+    }
+
+    public void setMenuItemVisibility(int id, boolean visibility) {
+        MenuItem item = findMenuItem(id);
+        if (item != null) {
+            item.setVisible(visibility);
+        }
+    }
+
+    public boolean onMenuItemClick(MenuItem item) {
+        if (mListener != null) {
+            return mListener.onMenuItemClick(item);
+        }
+        return false;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/DetailsWindow.java b/src/com/android/gallery3d/ui/DetailsWindow.java
new file mode 100644
index 0000000..03e2169
--- /dev/null
+++ b/src/com/android/gallery3d/ui/DetailsWindow.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import static com.android.gallery3d.ui.DetailsWindowConfig.FONT_SIZE;
+import static com.android.gallery3d.ui.DetailsWindowConfig.LEFT_RIGHT_EXTRA_PADDING;
+import static com.android.gallery3d.ui.DetailsWindowConfig.LINE_SPACING;
+import static com.android.gallery3d.ui.DetailsWindowConfig.PREFERRED_WIDTH;
+import static com.android.gallery3d.ui.DetailsWindowConfig.TOP_BOTTOM_EXTRA_PADDING;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.MediaDetails;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.ReverseGeocoder;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.location.Address;
+import android.os.Handler;
+import android.os.Message;
+import android.text.format.Formatter;
+import android.view.MotionEvent;
+import android.view.View.MeasureSpec;
+
+import java.util.ArrayList;
+import java.util.Map.Entry;
+
+// TODO: Add scroll bar to this window.
+public class DetailsWindow extends GLView {
+    @SuppressWarnings("unused")
+    private static final String TAG = "DetailsWindow";
+    private static final int MSG_REFRESH_LOCATION = 1;
+    private static final int FONT_COLOR = Color.WHITE;
+    private static final int CLOSE_BUTTON_SIZE = 32;
+
+    private GalleryActivity mContext;
+    protected Texture mBackground;
+    private StringTexture mTitle;
+    private MyDataModel mModel;
+    private MediaDetails mDetails;
+    private DetailsSource mSource;
+    private int mIndex;
+    private int mLocationIndex;
+    private Future<Address> mAddressLookupJob;
+    private Handler mHandler;
+    private Icon mCloseButton;
+    private int mMaxDetailLength;
+    private CloseListener mListener;
+
+    private ScrollView mScrollView;
+    private DetailsPanel mDetailPanel = new DetailsPanel();
+
+    public interface DetailsSource {
+        public int size();
+        public int findIndex(int indexHint);
+        public MediaDetails getDetails();
+    }
+
+    public interface CloseListener {
+        public void onClose();
+    }
+
+    public DetailsWindow(GalleryActivity activity, DetailsSource source) {
+        mContext = activity;
+        mSource = source;
+        mHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message msg) {
+                switch(msg.what) {
+                    case MSG_REFRESH_LOCATION:
+                        mModel.updateLocation((Address) msg.obj);
+                        invalidate();
+                        break;
+                }
+            }
+        };
+        Context context = activity.getAndroidContext();
+        ResourceTexture icon = new ResourceTexture(context, R.drawable.ic_menu_cancel_holo_light);
+        setBackground(new NinePatchTexture(context, R.drawable.popup_full_dark));
+
+        mCloseButton = new Icon(context, icon, CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE) {
+            @Override
+            protected boolean onTouch(MotionEvent event) {
+                switch (event.getActionMasked()) {
+                    case MotionEvent.ACTION_UP:
+                        if (mListener != null) mListener.onClose();
+                }
+                return true;
+            }
+        };
+        mScrollView = new ScrollView(context);
+        mScrollView.addComponent(mDetailPanel);
+
+        super.addComponent(mScrollView);
+        super.addComponent(mCloseButton);
+
+        reloadDetails(0);
+    }
+
+    public void setCloseListener(CloseListener listener) {
+        mListener = listener;
+    }
+
+    public void setBackground(Texture background) {
+        if (background == mBackground) return;
+        mBackground = background;
+        if (background != null && background instanceof NinePatchTexture) {
+            Rect p = ((NinePatchTexture) mBackground).getPaddings();
+            p.left += LEFT_RIGHT_EXTRA_PADDING;
+            p.right += LEFT_RIGHT_EXTRA_PADDING;
+            p.top += TOP_BOTTOM_EXTRA_PADDING;
+            p.bottom += TOP_BOTTOM_EXTRA_PADDING;
+            setPaddings(p);
+        } else {
+            setPaddings(0, 0, 0, 0);
+        }
+        Rect p = getPaddings();
+        mMaxDetailLength = PREFERRED_WIDTH - p.left - p.right;
+        invalidate();
+    }
+
+    public void setTitle(String title) {
+        mTitle = StringTexture.newInstance(title, FONT_SIZE, FONT_COLOR);
+    }
+
+    @Override
+    protected void renderBackground(GLCanvas canvas) {
+        if (mBackground == null) return;
+        int width = getWidth();
+        int height = getHeight();
+
+        //TODO: change alpha in the background image.
+        canvas.save(GLCanvas.SAVE_FLAG_ALPHA);
+        canvas.setAlpha(0.7f);
+        mBackground.draw(canvas, 0, 0, width, height);
+        canvas.restore();
+
+        Rect p = getPaddings();
+        if (mTitle != null) mTitle.draw(canvas, p.left, p.top);
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        int height = MeasureSpec.getSize(heightSpec);
+        MeasureHelper.getInstance(this)
+                .setPreferredContentSize(PREFERRED_WIDTH, height)
+                .measure(widthSpec, heightSpec);
+    }
+
+    @Override
+    protected void onLayout(boolean sizeChange, int l, int t, int r, int b) {
+        mCloseButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+        int bWidth = mCloseButton.getMeasuredWidth();
+        int bHeight = mCloseButton.getMeasuredHeight();
+        int width = getWidth();
+        int height = getHeight();
+
+        Rect p = getPaddings();
+        mCloseButton.layout(width - p.right - bWidth, p.top,
+                width - p.right, p.top + bHeight);
+        mScrollView.layout(p.left, p.top + bHeight, width - p.right,
+                height - p.bottom);
+    }
+
+    public void show() {
+        setVisibility(GLView.VISIBLE);
+        requestLayout();
+    }
+
+    public void hide() {
+        setVisibility(GLView.INVISIBLE);
+        requestLayout();
+    }
+
+    public void pause() {
+        Future<Address> lookupJob = mAddressLookupJob;
+        if (lookupJob != null) {
+            lookupJob.cancel();
+            lookupJob.waitDone();
+        }
+    }
+
+    public void reloadDetails(int indexHint) {
+        int index = mSource.findIndex(indexHint);
+        if (index == -1) return;
+        MediaDetails details = mSource.getDetails();
+        if (details != null) {
+            if (mIndex == index && mDetails == details) return;
+            mIndex = index;
+            mDetails = details;
+            setDetails(details);
+        }
+        mDetailPanel.requestLayout();
+    }
+
+    private void setDetails(MediaDetails details) {
+        mModel = new MyDataModel(details);
+        invalidate();
+    }
+
+    private class AddressLookupJob implements Job<Address> {
+        double[] mLatlng;
+        protected AddressLookupJob(double[] latlng) {
+            mLatlng = latlng;
+        }
+
+        public Address run(JobContext jc) {
+            ReverseGeocoder geocoder = new ReverseGeocoder(mContext.getAndroidContext());
+            return geocoder.lookupAddress(mLatlng[0], mLatlng[1], true);
+        }
+    }
+
+    private class MyDataModel {
+        ArrayList<Texture> mItems;
+
+        public MyDataModel(MediaDetails details) {
+            Context context = mContext.getAndroidContext();
+            mLocationIndex = -1;
+            mItems = new ArrayList<Texture>(details.size());
+            setTitle(String.format(context.getString(R.string.sequence_in_set),
+                    mIndex + 1, mSource.size()));
+            setDetails(context, details);
+        }
+
+        private void setDetails(Context context, MediaDetails details) {
+            for (Entry<Integer, Object> detail : details) {
+                String value;
+                switch (detail.getKey()) {
+                    case MediaDetails.INDEX_LOCATION: {
+                        value = getLocationText((double[]) detail.getValue());
+                        break;
+                    }
+                    case MediaDetails.INDEX_SIZE: {
+                        value = Formatter.formatFileSize(
+                                context, (Long) detail.getValue());
+                        break;
+                    }
+                    case MediaDetails.INDEX_WHITE_BALANCE: {
+                        value = "1".equals(detail.getValue())
+                                ? context.getString(R.string.manual)
+                                : context.getString(R.string.auto);
+                        break;
+                    }
+                    case MediaDetails.INDEX_FLASH: {
+                        MediaDetails.FlashState flash =
+                                (MediaDetails.FlashState) detail.getValue();
+                        // TODO: camera doesn't fill in the complete values, show more information
+                        // when it is fixed.
+                        if (flash.isFlashFired()) {
+                            value = context.getString(R.string.flash_on);
+                        } else {
+                            value = context.getString(R.string.flash_off);
+                        }
+                        break;
+                    }
+                    case MediaDetails.INDEX_EXPOSURE_TIME: {
+                        value = (String) detail.getValue();
+                        double time = Double.valueOf(value);
+                        if (time < 1.0f) {
+                            value = String.format("1/%d", (int) (0.5f + 1 / time));
+                        } else {
+                            int integer = (int) time;
+                            time -= integer;
+                            value = String.valueOf(integer) + "''";
+                            if (time > 0.0001) {
+                                value += String.format(" 1/%d", (int) (0.5f + 1 / time));
+                            }
+                        }
+                        break;
+                    }
+                    default: {
+                        Object valueObj = detail.getValue();
+                        // This shouldn't happen, log its key to help us diagnose the problem.
+                        Utils.assertTrue(valueObj != null, "%s's value is Null",
+                                getName(context, detail.getKey()));
+                        value = valueObj.toString();
+                    }
+                }
+                int key = detail.getKey();
+                if (details.hasUnit(key)) {
+                    value = String.format("%s : %s %s", getName(context, key), value,
+                            context.getString(details.getUnit(key)));
+                } else {
+                    value = String.format("%s : %s", getName(context, key), value);
+                }
+                Texture label = MultiLineTexture.newInstance(
+                        value, mMaxDetailLength, FONT_SIZE, FONT_COLOR);
+                mItems.add(label);
+            }
+        }
+
+        private String getLocationText(double[] latlng) {
+            String text = String.format("(%f, %f)", latlng[0], latlng[1]);
+            mAddressLookupJob = mContext.getThreadPool().submit(
+                    new AddressLookupJob(latlng),
+                    new FutureListener<Address>() {
+                        public void onFutureDone(Future<Address> future) {
+                            mAddressLookupJob = null;
+                            if (!future.isCancelled()) {
+                                mHandler.sendMessage(mHandler.obtainMessage(
+                                        MSG_REFRESH_LOCATION, future.get()));
+                            }
+                        }
+                    });
+            mLocationIndex = mItems.size();
+            return text;
+        }
+
+        public void updateLocation(Address address) {
+            int index = mLocationIndex;
+            if (address != null && index >=0 && index < mItems.size()) {
+                Context context = mContext.getAndroidContext();
+                String parts[] = {
+                    address.getAdminArea(),
+                    address.getSubAdminArea(),
+                    address.getLocality(),
+                    address.getSubLocality(),
+                    address.getThoroughfare(),
+                    address.getSubThoroughfare(),
+                    address.getPremises(),
+                    address.getPostalCode(),
+                    address.getCountryName()
+                };
+
+                String addressText = "";
+                for (int i = 0; i < parts.length; i++) {
+                    if (parts[i] == null || parts[i].isEmpty()) continue;
+                    if (!addressText.isEmpty()) {
+                        addressText += ", ";
+                    }
+                    addressText += parts[i];
+                }
+                String text = String.format("%s : %s", getName(context,
+                        MediaDetails.INDEX_LOCATION), addressText);
+                mItems.set(index, MultiLineTexture.newInstance(
+                        text, mMaxDetailLength, FONT_SIZE, FONT_COLOR));
+            }
+        }
+
+        public Texture getView(int index) {
+            return mItems.get(index);
+        }
+
+        public int size() {
+            return mItems.size();
+        }
+    }
+
+    private static String getName(Context context, int key) {
+        switch (key) {
+            case MediaDetails.INDEX_TITLE:
+                return context.getString(R.string.title);
+            case MediaDetails.INDEX_DESCRIPTION:
+                return context.getString(R.string.description);
+            case MediaDetails.INDEX_DATETIME:
+                return context.getString(R.string.time);
+            case MediaDetails.INDEX_LOCATION:
+                return context.getString(R.string.location);
+            case MediaDetails.INDEX_PATH:
+                return context.getString(R.string.path);
+            case MediaDetails.INDEX_WIDTH:
+                return context.getString(R.string.width);
+            case MediaDetails.INDEX_HEIGHT:
+                return context.getString(R.string.height);
+            case MediaDetails.INDEX_ORIENTATION:
+                return context.getString(R.string.orientation);
+            case MediaDetails.INDEX_DURATION:
+                return context.getString(R.string.duration);
+            case MediaDetails.INDEX_MIMETYPE:
+                return context.getString(R.string.mimetype);
+            case MediaDetails.INDEX_SIZE:
+                return context.getString(R.string.file_size);
+            case MediaDetails.INDEX_MAKE:
+                return context.getString(R.string.maker);
+            case MediaDetails.INDEX_MODEL:
+                return context.getString(R.string.model);
+            case MediaDetails.INDEX_FLASH:
+                return context.getString(R.string.flash);
+            case MediaDetails.INDEX_APERTURE:
+                return context.getString(R.string.aperture);
+            case MediaDetails.INDEX_FOCAL_LENGTH:
+                return context.getString(R.string.focal_length);
+            case MediaDetails.INDEX_WHITE_BALANCE:
+                return context.getString(R.string.white_balance);
+            case MediaDetails.INDEX_EXPOSURE_TIME:
+                return context.getString(R.string.exposure_time);
+            case MediaDetails.INDEX_ISO:
+                return context.getString(R.string.iso);
+            default:
+                return "Unknown key" + key;
+        }
+    }
+
+    private class DetailsPanel extends GLView {
+
+        @Override
+        public void onMeasure(int widthSpec, int heightSpec) {
+            if (mTitle == null || mModel == null) {
+                MeasureHelper.getInstance(this)
+                        .setPreferredContentSize(PREFERRED_WIDTH, 0)
+                        .measure(widthSpec, heightSpec);
+                return;
+            }
+
+            int h = getPaddings().top + LINE_SPACING;
+            for (int i = 0, n = mModel.size(); i < n; ++i) {
+                h += mModel.getView(i).getHeight() + LINE_SPACING;
+            }
+
+            MeasureHelper.getInstance(this)
+                    .setPreferredContentSize(PREFERRED_WIDTH, h)
+                    .measure(widthSpec, heightSpec);
+        }
+
+        @Override
+        protected void render(GLCanvas canvas) {
+            super.render(canvas);
+
+            if (mTitle == null || mModel == null) {
+                return;
+            }
+            Rect p = getPaddings();
+            int x = p.left, y = p.top + LINE_SPACING;
+            for (int i = 0, n = mModel.size(); i < n ; i++) {
+                Texture t = mModel.getView(i);
+                t.draw(canvas, x, y);
+                y += t.getHeight() + LINE_SPACING;
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/DisplayItem.java b/src/com/android/gallery3d/ui/DisplayItem.java
new file mode 100644
index 0000000..3038232
--- /dev/null
+++ b/src/com/android/gallery3d/ui/DisplayItem.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+public abstract class DisplayItem {
+
+    protected int mWidth;
+    protected int mHeight;
+
+    protected void setSize(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+    }
+
+    // returns true if more pass is needed
+    public abstract boolean render(GLCanvas canvas, int pass);
+
+    public abstract long getIdentity();
+
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+
+    public int getRotation() {
+        return 0;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/DownUpDetector.java b/src/com/android/gallery3d/ui/DownUpDetector.java
new file mode 100644
index 0000000..19db772
--- /dev/null
+++ b/src/com/android/gallery3d/ui/DownUpDetector.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.view.MotionEvent;
+
+public class DownUpDetector {
+    public interface DownUpListener {
+        void onDown(MotionEvent e);
+        void onUp(MotionEvent e);
+    }
+
+    private boolean mStillDown;
+    private DownUpListener mListener;
+
+    public DownUpDetector(DownUpListener listener) {
+        mListener = listener;
+    }
+
+    private void setState(boolean down, MotionEvent e) {
+        if (down == mStillDown) return;
+        mStillDown = down;
+        if (down) {
+            mListener.onDown(e);
+        } else {
+            mListener.onUp(e);
+        }
+    }
+
+    public void onTouchEvent(MotionEvent ev) {
+        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
+        case MotionEvent.ACTION_DOWN:
+            setState(true, ev);
+            break;
+
+        case MotionEvent.ACTION_UP:
+        case MotionEvent.ACTION_CANCEL:
+        case MotionEvent.ACTION_POINTER_DOWN:  // Multitouch event - abort.
+            setState(false, ev);
+            break;
+        }
+    }
+
+    public boolean isDown() {
+        return mStillDown;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/DrawableTexture.java b/src/com/android/gallery3d/ui/DrawableTexture.java
new file mode 100644
index 0000000..5c3964d
--- /dev/null
+++ b/src/com/android/gallery3d/ui/DrawableTexture.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+
+// DrawableTexture is a texture whose content is from a Drawable.
+public class DrawableTexture extends CanvasTexture {
+
+    private final Drawable mDrawable;
+
+    public DrawableTexture(Drawable drawable, int width, int height) {
+        super(width, height);
+        mDrawable = drawable;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas, Bitmap backing) {
+        mDrawable.setBounds(0, 0, mWidth, mHeight);
+        mDrawable.draw(canvas);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/FilmStripView.java b/src/com/android/gallery3d/ui/FilmStripView.java
new file mode 100644
index 0000000..8d28f2c
--- /dev/null
+++ b/src/com/android/gallery3d/ui/FilmStripView.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.anim.AlphaAnimation;
+import com.android.gallery3d.anim.CanvasAnimation;
+import com.android.gallery3d.app.AlbumDataAdapter;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.data.MediaSet;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.View.MeasureSpec;
+
+public class FilmStripView extends GLView implements SlotView.Listener,
+        ScrollBarView.Listener, UserInteractionListener {
+    @SuppressWarnings("unused")
+    private static final String TAG = "FilmStripView";
+
+    private static final int HIDE_ANIMATION_DURATION = 300;  // 0.3 sec
+
+    public interface Listener {
+        void onSlotSelected(int slotIndex);
+    }
+
+    private int mTopMargin, mMidMargin, mBottomMargin;
+    private int mContentSize, mBarSize, mGripSize;
+    private AlbumView mAlbumView;
+    private ScrollBarView mScrollBarView;
+    private AlbumDataAdapter mAlbumDataAdapter;
+    private StripDrawer mStripDrawer;
+    private Listener mListener;
+    private UserInteractionListener mUIListener;
+    private boolean mFilmStripVisible;
+    private CanvasAnimation mFilmStripAnimation;
+    private NinePatchTexture mBackgroundTexture;
+
+    // The layout of FileStripView is
+    // topMargin
+    //             ----+----+
+    //            /    +----+--\
+    // contentSize     |    |   thumbSize
+    //            \    +----+--/
+    //             ----+----+
+    // midMargin
+    //             ----+----+
+    //            /    +----+--\
+    //     barSize     |    |   gripSize
+    //            \    +----+--/
+    //             ----+----+
+    // bottomMargin
+    public FilmStripView(GalleryActivity activity, MediaSet mediaSet,
+            int topMargin, int midMargin, int bottomMargin, int contentSize,
+            int thumbSize, int barSize, int gripSize, int gripWidth) {
+        mTopMargin = topMargin;
+        mMidMargin = midMargin;
+        mBottomMargin = bottomMargin;
+        mContentSize = contentSize;
+        mBarSize = barSize;
+        mGripSize = gripSize;
+
+        mStripDrawer = new StripDrawer((Context) activity);
+        mAlbumView = new AlbumView(activity, thumbSize, thumbSize, thumbSize);
+        mAlbumView.setOverscrollEffect(SlotView.OVERSCROLL_SYSTEM);
+        mAlbumView.setSelectionDrawer(mStripDrawer);
+        mAlbumView.setListener(this);
+        mAlbumView.setUserInteractionListener(this);
+        mAlbumDataAdapter = new AlbumDataAdapter(activity, mediaSet);
+        addComponent(mAlbumView);
+        mScrollBarView = new ScrollBarView(activity.getAndroidContext(),
+                mGripSize, gripWidth);
+        mScrollBarView.setListener(this);
+        addComponent(mScrollBarView);
+
+        mAlbumView.setModel(mAlbumDataAdapter);
+        mBackgroundTexture = new NinePatchTexture(activity.getAndroidContext(),
+                R.drawable.navstrip_translucent);
+        mFilmStripVisible = true;
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    public void setUserInteractionListener(UserInteractionListener listener) {
+        mUIListener = listener;
+    }
+
+    private void setFilmStripVisible(boolean visible) {
+        if (mFilmStripVisible == visible) return;
+        mFilmStripVisible = visible;
+        if (!visible) {
+            mFilmStripAnimation = new AlphaAnimation(1, 0);
+            mFilmStripAnimation.setDuration(HIDE_ANIMATION_DURATION);
+            mFilmStripAnimation.start();
+        } else {
+            mFilmStripAnimation = null;
+        }
+        invalidate();
+    }
+
+    public void show() {
+        setFilmStripVisible(true);
+    }
+
+    public void hide() {
+        setFilmStripVisible(false);
+    }
+
+    @Override
+    protected void onVisibilityChanged(int visibility) {
+        super.onVisibilityChanged(visibility);
+        if (visibility == GLView.VISIBLE) {
+            onUserInteraction();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        int height = mTopMargin + mContentSize + mMidMargin + mBarSize + mBottomMargin;
+        MeasureHelper.getInstance(this)
+                .setPreferredContentSize(MeasureSpec.getSize(widthSpec), height)
+                .measure(widthSpec, heightSpec);
+    }
+
+    @Override
+    protected void onLayout(
+            boolean changed, int left, int top, int right, int bottom) {
+        if (!changed) return;
+        mAlbumView.layout(0, mTopMargin, right - left, mTopMargin + mContentSize);
+        int barStart = mTopMargin + mContentSize + mMidMargin;
+        mScrollBarView.layout(0, barStart, right - left, barStart + mBarSize);
+        int width = right - left;
+        int height = bottom - top;
+    }
+
+    @Override
+    protected boolean onTouch(MotionEvent event) {
+        // consume all touch events on the "gray area", so they don't go to
+        // the photo view below. (otherwise you can scroll the picture through
+        // it).
+        return true;
+    }
+
+    @Override
+    protected boolean dispatchTouchEvent(MotionEvent event) {
+        if (!mFilmStripVisible && mFilmStripAnimation == null) {
+            return false;
+        }
+
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+                onUserInteractionBegin();
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                onUserInteractionEnd();
+                break;
+        }
+
+        return super.dispatchTouchEvent(event);
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        CanvasAnimation anim = mFilmStripAnimation;
+        if (anim == null && !mFilmStripVisible) return;
+
+        boolean needRestore = false;
+        if (anim != null) {
+            needRestore = true;
+            canvas.save(anim.getCanvasSaveFlags());
+            long now = canvas.currentAnimationTimeMillis();
+            boolean more = anim.calculate(now);
+            anim.apply(canvas);
+            if (more) {
+                invalidate();
+            } else {
+                mFilmStripAnimation = null;
+            }
+        }
+
+        mBackgroundTexture.draw(canvas, 0, 0, getWidth(), getHeight());
+        super.render(canvas);
+
+        if (needRestore) {
+            canvas.restore();
+        }
+    }
+
+    // Called by AlbumView
+    public void onSingleTapUp(int slotIndex) {
+        mAlbumView.setFocusIndex(slotIndex);
+        mListener.onSlotSelected(slotIndex);
+    }
+
+    // Called by AlbumView
+    public void onLongTap(int slotIndex) {
+        onSingleTapUp(slotIndex);
+    }
+
+    // Called by AlbumView
+    public void onUserInteractionBegin() {
+        mUIListener.onUserInteractionBegin();
+    }
+
+    // Called by AlbumView
+    public void onUserInteractionEnd() {
+        mUIListener.onUserInteractionEnd();
+    }
+
+    // Called by AlbumView
+    public void onUserInteraction() {
+        mUIListener.onUserInteraction();
+    }
+
+    // Called by AlbumView
+    public void onScrollPositionChanged(int position, int total) {
+        mScrollBarView.setContentPosition(position, total);
+    }
+
+    // Called by ScrollBarView
+    public void onScrollBarPositionChanged(int position) {
+        mAlbumView.setScrollPosition(position);
+    }
+
+    public void setFocusIndex(int slotIndex) {
+        mAlbumView.setFocusIndex(slotIndex);
+        mAlbumView.makeSlotVisible(slotIndex);
+    }
+
+    public void setStartIndex(int slotIndex) {
+        mAlbumView.setStartIndex(slotIndex);
+    }
+
+    public void pause() {
+        mAlbumView.pause();
+        mAlbumDataAdapter.pause();
+    }
+
+    public void resume() {
+        mAlbumView.resume();
+        mAlbumDataAdapter.resume();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/GLCanvas.java b/src/com/android/gallery3d/ui/GLCanvas.java
new file mode 100644
index 0000000..88c02f3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GLCanvas.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.RectF;
+
+import javax.microedition.khronos.opengles.GL11;
+
+//
+// GLCanvas gives a convenient interface to draw using OpenGL.
+//
+// When a rectangle is specified in this interface, it means the region
+// [x, x+width) * [y, y+height)
+//
+public interface GLCanvas {
+    // Tells GLCanvas the size of the underlying GL surface. This should be
+    // called before first drawing and when the size of GL surface is changed.
+    // This is called by GLRoot and should not be called by the clients
+    // who only want to draw on the GLCanvas. Both width and height must be
+    // nonnegative.
+    public void setSize(int width, int height);
+
+    // Clear the drawing buffers. This should only be used by GLRoot.
+    public void clearBuffer();
+
+    // This is the time value used to calculate the animation in the current
+    // frame. The "set" function should only called by GLRoot, and the
+    // "time" parameter must be nonnegative.
+    public void setCurrentAnimationTimeMillis(long time);
+    public long currentAnimationTimeMillis();
+
+    public void setBlendEnabled(boolean enabled);
+
+    // Sets and gets the current alpha, alpha must be in [0, 1].
+    public void setAlpha(float alpha);
+    public float getAlpha();
+
+    // (current alpha) = (current alpha) * alpha
+    public void multiplyAlpha(float alpha);
+
+    // Change the current transform matrix.
+    public void translate(float x, float y, float z);
+    public void scale(float sx, float sy, float sz);
+    public void rotate(float angle, float x, float y, float z);
+    public void multiplyMatrix(float[] mMatrix, int offset);
+
+    // Modifies the current clip with the specified rectangle.
+    // (current clip) = (current clip) intersect (specified rectangle).
+    // Returns true if the result clip is non-empty.
+    public boolean clipRect(int left, int top, int right, int bottom);
+
+    // Pushes the configuration state (matrix, alpha, and clip) onto
+    // a private stack.
+    public int save();
+
+    // Same as save(), but only save those specified in saveFlags.
+    public int save(int saveFlags);
+
+    public static final int SAVE_FLAG_ALL = 0xFFFFFFFF;
+    public static final int SAVE_FLAG_CLIP = 0x01;
+    public static final int SAVE_FLAG_ALPHA = 0x02;
+    public static final int SAVE_FLAG_MATRIX = 0x04;
+
+    // Pops from the top of the stack as current configuration state (matrix,
+    // alpha, and clip). This call balances a previous call to save(), and is
+    // used to remove all modifications to the configuration state since the
+    // last save call.
+    public void restore();
+
+    // Draws a line using the specified paint from (x1, y1) to (x2, y2).
+    // (Both end points are included).
+    public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint);
+
+    // Draws a rectangle using the specified paint from (x1, y1) to (x2, y2).
+    // (Both end points are included).
+    public void drawRect(float x1, float y1, float x2, float y2, GLPaint paint);
+
+    // Fills the specified rectangle with the specified color.
+    public void fillRect(float x, float y, float width, float height, int color);
+
+    // Draws a texture to the specified rectangle.
+    public void drawTexture(
+            BasicTexture texture, int x, int y, int width, int height);
+    public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
+            int uvBuffer, int indexBuffer, int indexCount);
+
+    // Draws a texture to the specified rectangle. The "alpha" parameter
+    // overrides the current drawing alpha value.
+    public void drawTexture(BasicTexture texture,
+            int x, int y, int width, int height, float alpha);
+
+    // Draws a the source rectangle part of the texture to the target rectangle.
+    public void drawTexture(BasicTexture texture, RectF source, RectF target);
+
+    // Draw two textures to the specified rectangle. The actual texture used is
+    // from * (1 - ratio) + to * ratio
+    // The two textures must have the same size.
+    public void drawMixed(BasicTexture from, BasicTexture to,
+            float ratio, int x, int y, int w, int h);
+
+    public void drawMixed(BasicTexture from, int toColor,
+            float ratio, int x, int y, int w, int h);
+
+    // Return a texture copied from the specified rectangle.
+    public BasicTexture copyTexture(int x, int y, int width, int height);
+
+    // Gets the underlying GL instance. This is used only when direct access to
+    // GL is needed.
+    public GL11 getGLInstance();
+
+    // Unloads the specified texture from the canvas. The resource allocated
+    // to draw the texture will be released. The specified texture will return
+    // to the unloaded state. This function should be called only from
+    // BasicTexture or its descendant
+    public boolean unloadTexture(BasicTexture texture);
+
+    // Delete the specified buffer object, similar to unloadTexture.
+    public void deleteBuffer(int bufferId);
+
+    // Delete the textures and buffers in GL side. This function should only be
+    // called in the GL thread.
+    public void deleteRecycledResources();
+
+}
diff --git a/src/com/android/gallery3d/ui/GLCanvasImpl.java b/src/com/android/gallery3d/ui/GLCanvasImpl.java
new file mode 100644
index 0000000..387743f
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GLCanvasImpl.java
@@ -0,0 +1,913 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.IntArray;
+
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.opengl.GLU;
+import android.opengl.Matrix;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.Stack;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+public class GLCanvasImpl implements GLCanvas {
+    @SuppressWarnings("unused")
+    private static final String TAG = "GLCanvasImp";
+
+    private static final float OPAQUE_ALPHA = 0.95f;
+
+    private static final int OFFSET_FILL_RECT = 0;
+    private static final int OFFSET_DRAW_LINE = 4;
+    private static final int OFFSET_DRAW_RECT = 6;
+    private static final float[] BOX_COORDINATES = {
+            0, 0, 1, 0, 0, 1, 1, 1,  // used for filling a rectangle
+            0, 0, 1, 1,              // used for drawing a line
+            0, 0, 0, 1, 1, 1, 1, 0}; // used for drawing the outline of a rectangle
+
+    private final GL11 mGL;
+
+    private final float mMatrixValues[] = new float[16];
+    private final float mTextureMatrixValues[] = new float[16];
+
+    // mapPoints needs 10 input and output numbers.
+    private final float mMapPointsBuffer[] = new float[10];
+
+    private final float mTextureColor[] = new float[4];
+
+    private int mBoxCoords;
+
+    private final GLState mGLState;
+
+    private long mAnimationTime;
+
+    private float mAlpha;
+    private final Rect mClipRect = new Rect();
+    private final Stack<ConfigState> mRestoreStack =
+            new Stack<ConfigState>();
+    private ConfigState mRecycledRestoreAction;
+
+    private final RectF mDrawTextureSourceRect = new RectF();
+    private final RectF mDrawTextureTargetRect = new RectF();
+    private final float[] mTempMatrix = new float[32];
+    private final IntArray mUnboundTextures = new IntArray();
+    private final IntArray mDeleteBuffers = new IntArray();
+    private int mHeight;
+    private boolean mBlendEnabled = true;
+
+    // Drawing statistics
+    int mCountDrawLine;
+    int mCountFillRect;
+    int mCountDrawMesh;
+    int mCountTextureRect;
+    int mCountTextureOES;
+
+    GLCanvasImpl(GL11 gl) {
+        mGL = gl;
+        mGLState = new GLState(gl);
+        initialize();
+    }
+
+    public void setSize(int width, int height) {
+        Utils.assertTrue(width >= 0 && height >= 0);
+        mHeight = height;
+
+        GL11 gl = mGL;
+        gl.glViewport(0, 0, width, height);
+        gl.glMatrixMode(GL11.GL_PROJECTION);
+        gl.glLoadIdentity();
+        GLU.gluOrtho2D(gl, 0, width, 0, height);
+
+        gl.glMatrixMode(GL11.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        float matrix[] = mMatrixValues;
+
+        Matrix.setIdentityM(matrix, 0);
+        Matrix.translateM(matrix, 0, 0, mHeight, 0);
+        Matrix.scaleM(matrix, 0, 1, -1, 1);
+
+        mClipRect.set(0, 0, width, height);
+        gl.glScissor(0, 0, width, height);
+    }
+
+    public long currentAnimationTimeMillis() {
+        return mAnimationTime;
+    }
+
+    public void setAlpha(float alpha) {
+        Utils.assertTrue(alpha >= 0 && alpha <= 1);
+        mAlpha = alpha;
+    }
+
+    public void multiplyAlpha(float alpha) {
+        Utils.assertTrue(alpha >= 0 && alpha <= 1);
+        mAlpha *= alpha;
+    }
+
+    public float getAlpha() {
+        return mAlpha;
+    }
+
+    private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
+        return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
+    }
+
+    private void initialize() {
+        GL11 gl = mGL;
+
+        // First create an nio buffer, then create a VBO from it.
+        int size = BOX_COORDINATES.length * Float.SIZE / Byte.SIZE;
+        FloatBuffer xyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
+        xyBuffer.put(BOX_COORDINATES, 0, BOX_COORDINATES.length).position(0);
+
+        int[] name = new int[1];
+        gl.glGenBuffers(1, name, 0);
+        mBoxCoords = name[0];
+
+        gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);
+        gl.glBufferData(GL11.GL_ARRAY_BUFFER,
+                xyBuffer.capacity() * (Float.SIZE / Byte.SIZE),
+                xyBuffer, GL11.GL_STATIC_DRAW);
+
+        gl.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
+        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
+
+        // Enable the texture coordinate array for Texture 1
+        gl.glClientActiveTexture(GL11.GL_TEXTURE1);
+        gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
+        gl.glClientActiveTexture(GL11.GL_TEXTURE0);
+        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+        // mMatrixValues will be initialized in setSize()
+        mAlpha = 1.0f;
+    }
+
+    public void drawRect(float x, float y, float width, float height, GLPaint paint) {
+        GL11 gl = mGL;
+
+        mGLState.setColorMode(paint.getColor(), mAlpha);
+        mGLState.setLineWidth(paint.getLineWidth());
+        mGLState.setLineSmooth(paint.getAntiAlias());
+
+        saveTransform();
+        translate(x, y, 0);
+        scale(width, height, 1);
+
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        gl.glDrawArrays(GL11.GL_LINE_LOOP, OFFSET_DRAW_RECT, 4);
+
+        restoreTransform();
+        mCountDrawLine++;
+    }
+
+    public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) {
+        GL11 gl = mGL;
+
+        mGLState.setColorMode(paint.getColor(), mAlpha);
+        mGLState.setLineWidth(paint.getLineWidth());
+        mGLState.setLineSmooth(paint.getAntiAlias());
+
+        saveTransform();
+        translate(x1, y1, 0);
+        scale(x2 - x1, y2 - y1, 1);
+
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        gl.glDrawArrays(GL11.GL_LINE_STRIP, OFFSET_DRAW_LINE, 2);
+
+        restoreTransform();
+        mCountDrawLine++;
+    }
+
+    public void fillRect(float x, float y, float width, float height, int color) {
+        mGLState.setColorMode(color, mAlpha);
+        GL11 gl = mGL;
+
+        saveTransform();
+        translate(x, y, 0);
+        scale(width, height, 1);
+
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4);
+
+        restoreTransform();
+        mCountFillRect++;
+    }
+
+    public void translate(float x, float y, float z) {
+        Matrix.translateM(mMatrixValues, 0, x, y, z);
+    }
+
+    public void scale(float sx, float sy, float sz) {
+        Matrix.scaleM(mMatrixValues, 0, sx, sy, sz);
+    }
+
+    public void rotate(float angle, float x, float y, float z) {
+        float[] temp = mTempMatrix;
+        Matrix.setRotateM(temp, 0, angle, x, y, z);
+        Matrix.multiplyMM(temp, 16, mMatrixValues, 0, temp, 0);
+        System.arraycopy(temp, 16, mMatrixValues, 0, 16);
+    }
+
+    public void multiplyMatrix(float matrix[], int offset) {
+        float[] temp = mTempMatrix;
+        Matrix.multiplyMM(temp, 0, mMatrixValues , 0, matrix, 0);
+        System.arraycopy(temp, 0, mMatrixValues, 0, 16);
+    }
+
+    private void textureRect(float x, float y, float width, float height) {
+        GL11 gl = mGL;
+
+        saveTransform();
+        translate(x, y, 0);
+        scale(width, height, 1);
+
+        gl.glLoadMatrixf(mMatrixValues, 0);
+        gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4);
+
+        restoreTransform();
+        mCountTextureRect++;
+    }
+
+    public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
+            int uvBuffer, int indexBuffer, int indexCount) {
+        float alpha = mAlpha;
+        if (!bindTexture(tex)) return;
+
+        mGLState.setBlendEnabled(mBlendEnabled
+                && (!tex.isOpaque() || alpha < OPAQUE_ALPHA));
+        mGLState.setTextureAlpha(alpha);
+
+        // Reset the texture matrix. We will set our own texture coordinates
+        // below.
+        setTextureCoords(0, 0, 1, 1);
+
+        saveTransform();
+        translate(x, y, 0);
+
+        mGL.glLoadMatrixf(mMatrixValues, 0);
+
+        mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, xyBuffer);
+        mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
+
+        mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, uvBuffer);
+        mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
+
+        mGL.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
+        mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP,
+                indexCount, GL11.GL_UNSIGNED_BYTE, 0);
+
+        mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);
+        mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
+        mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
+
+        restoreTransform();
+        mCountDrawMesh++;
+    }
+
+    private float[] mapPoints(float matrix[], int x1, int y1, int x2, int y2) {
+        float[] point = mMapPointsBuffer;
+        int srcOffset = 6;
+        point[srcOffset] = x1;
+        point[srcOffset + 1] = y1;
+        point[srcOffset + 2] = 0;
+        point[srcOffset + 3] = 1;
+
+        int resultOffset = 0;
+        Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
+        point[resultOffset] /= point[resultOffset + 3];
+        point[resultOffset + 1] /= point[resultOffset + 3];
+
+        // map the second point
+        point[srcOffset] = x2;
+        point[srcOffset + 1] = y2;
+        resultOffset = 2;
+        Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset);
+        point[resultOffset] /= point[resultOffset + 3];
+        point[resultOffset + 1] /= point[resultOffset + 3];
+
+        return point;
+    }
+
+    public boolean clipRect(int left, int top, int right, int bottom) {
+        float point[] = mapPoints(mMatrixValues, left, top, right, bottom);
+
+        // mMatrix could be a rotation matrix. In this case, we need to find
+        // the boundaries after rotation. (only handle 90 * n degrees)
+        if (point[0] > point[2]) {
+            left = (int) point[2];
+            right = (int) point[0];
+        } else {
+            left = (int) point[0];
+            right = (int) point[2];
+        }
+        if (point[1] > point[3]) {
+            top = (int) point[3];
+            bottom = (int) point[1];
+        } else {
+            top = (int) point[1];
+            bottom = (int) point[3];
+        }
+        Rect clip = mClipRect;
+
+        boolean intersect = clip.intersect(left, top, right, bottom);
+        if (!intersect) clip.set(0, 0, 0, 0);
+        mGL.glScissor(clip.left, clip.top, clip.width(), clip.height());
+        return intersect;
+    }
+
+    private void drawBoundTexture(
+            BasicTexture texture, int x, int y, int width, int height) {
+        // Test whether it has been rotated or flipped, if so, glDrawTexiOES
+        // won't work
+        if (isMatrixRotatedOrFlipped(mMatrixValues)) {
+            setTextureCoords(0, 0,
+                    (float) texture.getWidth() / texture.getTextureWidth(),
+                    (float) texture.getHeight() / texture.getTextureHeight());
+            textureRect(x, y, width, height);
+        } else {
+            // draw the rect from bottom-left to top-right
+            float points[] = mapPoints(
+                    mMatrixValues, x, y + height, x + width, y);
+            x = Math.round(points[0]);
+            y = Math.round(points[1]);
+            width = Math.round(points[2]) - x;
+            height = Math.round(points[3]) - y;
+            if (width > 0 && height > 0) {
+                ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height);
+                mCountTextureOES++;
+            }
+        }
+    }
+
+    public void drawTexture(
+            BasicTexture texture, int x, int y, int width, int height) {
+        drawTexture(texture, x, y, width, height, mAlpha);
+    }
+
+    public void setBlendEnabled(boolean enabled) {
+        mBlendEnabled = enabled;
+    }
+
+    public void drawTexture(BasicTexture texture,
+            int x, int y, int width, int height, float alpha) {
+        if (width <= 0 || height <= 0) return;
+
+        mGLState.setBlendEnabled(mBlendEnabled
+                && (!texture.isOpaque() || alpha < OPAQUE_ALPHA));
+        if (!bindTexture(texture)) return;
+        mGLState.setTextureAlpha(alpha);
+        drawBoundTexture(texture, x, y, width, height);
+    }
+
+    public void drawTexture(BasicTexture texture, RectF source, RectF target) {
+        if (target.width() <= 0 || target.height() <= 0) return;
+
+        // Copy the input to avoid changing it.
+        mDrawTextureSourceRect.set(source);
+        mDrawTextureTargetRect.set(target);
+        source = mDrawTextureSourceRect;
+        target = mDrawTextureTargetRect;
+
+        mGLState.setBlendEnabled(mBlendEnabled
+                && (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA));
+        if (!bindTexture(texture)) return;
+        convertCoordinate(source, target, texture);
+        setTextureCoords(source);
+        mGLState.setTextureAlpha(mAlpha);
+        textureRect(target.left, target.top, target.width(), target.height());
+    }
+
+    // This function changes the source coordinate to the texture coordinates.
+    // It also clips the source and target coordinates if it is beyond the
+    // bound of the texture.
+    private void convertCoordinate(RectF source, RectF target,
+            BasicTexture texture) {
+
+        int width = texture.getWidth();
+        int height = texture.getHeight();
+        int texWidth = texture.getTextureWidth();
+        int texHeight = texture.getTextureHeight();
+        // Convert to texture coordinates
+        source.left /= texWidth;
+        source.right /= texWidth;
+        source.top /= texHeight;
+        source.bottom /= texHeight;
+
+        // Clip if the rendering range is beyond the bound of the texture.
+        float xBound = (float) width / texWidth;
+        if (source.right > xBound) {
+            target.right = target.left + target.width() *
+                    (xBound - source.left) / source.width();
+            source.right = xBound;
+        }
+        float yBound = (float) height / texHeight;
+        if (source.bottom > yBound) {
+            target.bottom = target.top + target.height() *
+                    (yBound - source.top) / source.height();
+            source.bottom = yBound;
+        }
+    }
+
+    public void drawMixed(BasicTexture from,
+            int toColor, float ratio, int x, int y, int w, int h) {
+        drawMixed(from, toColor, ratio, x, y, w, h, mAlpha);
+    }
+
+    public void drawMixed(BasicTexture from, BasicTexture to,
+            float ratio, int x, int y, int w, int h) {
+        drawMixed(from, to, ratio, x, y, w, h, mAlpha);
+    }
+
+    private boolean bindTexture(BasicTexture texture) {
+        if (!texture.onBind(this)) return false;
+        mGLState.setTexture2DEnabled(true);
+        mGL.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
+        return true;
+    }
+
+    private void setTextureColor(float r, float g, float b, float alpha) {
+        float[] color = mTextureColor;
+        color[0] = r;
+        color[1] = g;
+        color[2] = b;
+        color[3] = alpha;
+    }
+
+    private void drawMixed(BasicTexture from, int toColor,
+            float ratio, int x, int y, int width, int height, float alpha) {
+
+        if (ratio <= 0) {
+            drawTexture(from, x, y, width, height, alpha);
+            return;
+        } else if (ratio >= 1) {
+            fillRect(x, y, width, height, toColor);
+            return;
+        }
+
+        mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
+                || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));
+
+        final GL11 gl = mGL;
+        if (!bindTexture(from)) return;
+
+        //
+        // The formula we want:
+        //     alpha * ((1 - ratio) * from + ratio * to)
+        // The formula that GL supports is in the form of:
+        //     combo * (modulate * from) + (1 - combo) * to
+        //
+        // So, we have combo = 1 - alpha * ratio
+        //     and     modulate = alpha * (1f - ratio) / combo
+        //
+        float comboRatio = 1 - alpha * ratio;
+
+        // handle the case that (1 - comboRatio) == 0
+        if (alpha < OPAQUE_ALPHA) {
+            mGLState.setTextureAlpha(alpha * (1f - ratio) / comboRatio);
+        } else {
+            mGLState.setTextureAlpha(1f);
+        }
+
+        // Interpolate the RGB and alpha values between both textures.
+        mGLState.setTexEnvMode(GL11.GL_COMBINE);
+        // Specify the interpolation factor via the alpha component of
+        // GL_TEXTURE_ENV_COLORs.
+        // RGB component are get from toColor and will used as SRC1
+        float colorAlpha = (float) (toColor >>> 24) / (0xff * 0xff);
+        setTextureColor(((toColor >>> 16) & 0xff) * colorAlpha,
+                ((toColor >>> 8) & 0xff) * colorAlpha,
+                (toColor & 0xff) * colorAlpha, comboRatio);
+        gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
+
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_RGB, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_ALPHA, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_ALPHA, GL11.GL_SRC_ALPHA);
+
+        // Wire up the interpolation factor for RGB.
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);
+
+        // Wire up the interpolation factor for alpha.
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
+
+        drawBoundTexture(from, x, y, width, height);
+        mGLState.setTexEnvMode(GL11.GL_REPLACE);
+    }
+
+    private void drawMixed(BasicTexture from, BasicTexture to,
+            float ratio, int x, int y, int width, int height, float alpha) {
+
+        if (ratio <= 0) {
+            drawTexture(from, x, y, width, height, alpha);
+            return;
+        } else if (ratio >= 1) {
+            drawTexture(to, x, y, width, height, alpha);
+            return;
+        }
+
+        // In the current implementation the two textures must have the
+        // same size.
+        Utils.assertTrue(from.getWidth() == to.getWidth()
+                && from.getHeight() == to.getHeight());
+
+        mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
+                || !to.isOpaque() || alpha < OPAQUE_ALPHA));
+
+        final GL11 gl = mGL;
+        if (!bindTexture(from)) return;
+
+        //
+        // The formula we want:
+        //     alpha * ((1 - ratio) * from + ratio * to)
+        // The formula that GL supports is in the form of:
+        //     combo * (modulate * from) + (1 - combo) * to
+        //
+        // So, we have combo = 1 - alpha * ratio
+        //     and     modulate = alpha * (1f - ratio) / combo
+        //
+        float comboRatio = 1 - alpha * ratio;
+
+        // handle the case that (1 - comboRatio) == 0
+        if (alpha < OPAQUE_ALPHA) {
+            mGLState.setTextureAlpha(alpha * (1f - ratio) / comboRatio);
+        } else {
+            mGLState.setTextureAlpha(1f);
+        }
+
+        gl.glActiveTexture(GL11.GL_TEXTURE1);
+        if (!bindTexture(to)) {
+            // Disable TEXTURE1.
+            gl.glDisable(GL11.GL_TEXTURE_2D);
+            // Switch back to the default texture unit.
+            gl.glActiveTexture(GL11.GL_TEXTURE0);
+            return;
+        }
+        gl.glEnable(GL11.GL_TEXTURE_2D);
+
+        // Interpolate the RGB and alpha values between both textures.
+        mGLState.setTexEnvMode(GL11.GL_COMBINE);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE);
+
+        // Specify the interpolation factor via the alpha component of
+        // GL_TEXTURE_ENV_COLORs.
+        // We don't use the RGB color, so just give them 0s.
+        setTextureColor(0, 0, 0, comboRatio);
+        gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
+
+        // Wire up the interpolation factor for RGB.
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);
+
+        // Wire up the interpolation factor for alpha.
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
+        gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
+
+        // Draw the combined texture.
+        drawBoundTexture(to, x, y, width, height);
+
+        // Disable TEXTURE1.
+        gl.glDisable(GL11.GL_TEXTURE_2D);
+        // Switch back to the default texture unit.
+        gl.glActiveTexture(GL11.GL_TEXTURE0);
+    }
+
+    // TODO: the code only work for 2D should get fixed for 3D or removed
+    private static final int MSKEW_X = 4;
+    private static final int MSKEW_Y = 1;
+    private static final int MSCALE_X = 0;
+    private static final int MSCALE_Y = 5;
+
+    private static boolean isMatrixRotatedOrFlipped(float matrix[]) {
+        final float eps = 1e-5f;
+        return Math.abs(matrix[MSKEW_X]) > eps
+                || Math.abs(matrix[MSKEW_Y]) > eps
+                || matrix[MSCALE_X] < -eps
+                || matrix[MSCALE_Y] > eps;
+    }
+
+    public BasicTexture copyTexture(int x, int y, int width, int height) {
+
+        if (isMatrixRotatedOrFlipped(mMatrixValues)) {
+            throw new IllegalArgumentException("cannot support rotated matrix");
+        }
+        float points[] = mapPoints(mMatrixValues, x, y + height, x + width, y);
+        x = (int) points[0];
+        y = (int) points[1];
+        width = (int) points[2] - x;
+        height = (int) points[3] - y;
+
+        GL11 gl = mGL;
+
+        RawTexture texture = RawTexture.newInstance(this);
+        gl.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
+        texture.setSize(width, height);
+
+        int[] cropRect = {0,  0, width, height};
+        gl.glTexParameteriv(GL11.GL_TEXTURE_2D,
+                GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0);
+        gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+                GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
+        gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+                GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
+        gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+                GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
+        gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+                GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
+        gl.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0,
+                GL11.GL_RGB, x, y, texture.getTextureWidth(),
+                texture.getTextureHeight(), 0);
+
+        return texture;
+    }
+
+    private static class GLState {
+
+        private final GL11 mGL;
+
+        private int mTexEnvMode = GL11.GL_REPLACE;
+        private float mTextureAlpha = 1.0f;
+        private boolean mTexture2DEnabled = true;
+        private boolean mBlendEnabled = true;
+        private float mLineWidth = 1.0f;
+        private boolean mLineSmooth = false;
+
+        public GLState(GL11 gl) {
+            mGL = gl;
+
+            // Disable unused state
+            gl.glDisable(GL11.GL_LIGHTING);
+
+            // Enable used features
+            gl.glEnable(GL11.GL_DITHER);
+            gl.glEnable(GL11.GL_SCISSOR_TEST);
+
+            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+            gl.glEnable(GL11.GL_TEXTURE_2D);
+
+            gl.glTexEnvf(GL11.GL_TEXTURE_ENV,
+                    GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
+
+            // Set the background color
+            gl.glClearColor(0f, 0f, 0f, 0f);
+            gl.glClearStencil(0);
+
+            gl.glEnable(GL11.GL_BLEND);
+            gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+            // We use 565 or 8888 format, so set the alignment to 2 bytes/pixel.
+            gl.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 2);
+        }
+
+        public void setTexEnvMode(int mode) {
+            if (mTexEnvMode == mode) return;
+            mTexEnvMode = mode;
+            mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode);
+        }
+
+        public void setLineWidth(float width) {
+            if (mLineWidth == width) return;
+            mLineWidth = width;
+            mGL.glLineWidth(width);
+        }
+
+        public void setLineSmooth(boolean enabled) {
+            if (mLineSmooth == enabled) return;
+            mLineSmooth = enabled;
+            if (enabled) {
+                mGL.glEnable(GL11.GL_LINE_SMOOTH);
+            } else {
+                mGL.glDisable(GL11.GL_LINE_SMOOTH);
+            }
+        }
+
+        public void setTextureAlpha(float alpha) {
+            if (mTextureAlpha == alpha) return;
+            mTextureAlpha = alpha;
+            if (alpha >= OPAQUE_ALPHA) {
+                // The alpha is need for those texture without alpha channel
+                mGL.glColor4f(1, 1, 1, 1);
+                setTexEnvMode(GL11.GL_REPLACE);
+            } else {
+                mGL.glColor4f(alpha, alpha, alpha, alpha);
+                setTexEnvMode(GL11.GL_MODULATE);
+            }
+        }
+
+        public void setColorMode(int color, float alpha) {
+            setBlendEnabled(!Utils.isOpaque(color) || alpha < OPAQUE_ALPHA);
+
+            // Set mTextureAlpha to an invalid value, so that it will reset
+            // again in setTextureAlpha(float) later.
+            mTextureAlpha = -1.0f;
+
+            setTexture2DEnabled(false);
+
+            float prealpha = (color >>> 24) * alpha * 65535f / 255f / 255f;
+            mGL.glColor4x(
+                    Math.round(((color >> 16) & 0xFF) * prealpha),
+                    Math.round(((color >> 8) & 0xFF) * prealpha),
+                    Math.round((color & 0xFF) * prealpha),
+                    Math.round(255 * prealpha));
+        }
+
+        public void setTexture2DEnabled(boolean enabled) {
+            if (mTexture2DEnabled == enabled) return;
+            mTexture2DEnabled = enabled;
+            if (enabled) {
+                mGL.glEnable(GL11.GL_TEXTURE_2D);
+            } else {
+                mGL.glDisable(GL11.GL_TEXTURE_2D);
+            }
+        }
+
+        public void setBlendEnabled(boolean enabled) {
+            if (mBlendEnabled == enabled) return;
+            mBlendEnabled = enabled;
+            if (enabled) {
+                mGL.glEnable(GL11.GL_BLEND);
+            } else {
+                mGL.glDisable(GL11.GL_BLEND);
+            }
+        }
+    }
+
+    public GL11 getGLInstance() {
+        return mGL;
+    }
+
+    public void setCurrentAnimationTimeMillis(long time) {
+        Utils.assertTrue(time >= 0);
+        mAnimationTime = time;
+    }
+
+    public void clearBuffer() {
+        mGL.glClear(GL10.GL_COLOR_BUFFER_BIT);
+    }
+
+    private void setTextureCoords(RectF source) {
+        setTextureCoords(source.left, source.top, source.right, source.bottom);
+    }
+
+    private void setTextureCoords(float left, float top,
+            float right, float bottom) {
+        mGL.glMatrixMode(GL11.GL_TEXTURE);
+        mTextureMatrixValues[0] = right - left;
+        mTextureMatrixValues[5] = bottom - top;
+        mTextureMatrixValues[10] = 1;
+        mTextureMatrixValues[12] = left;
+        mTextureMatrixValues[13] = top;
+        mTextureMatrixValues[15] = 1;
+        mGL.glLoadMatrixf(mTextureMatrixValues, 0);
+        mGL.glMatrixMode(GL11.GL_MODELVIEW);
+    }
+
+    // unloadTexture and deleteBuffer can be called from the finalizer thread,
+    // so we synchronized on the mUnboundTextures object.
+    public boolean unloadTexture(BasicTexture t) {
+        synchronized (mUnboundTextures) {
+            if (!t.isLoaded(this)) return false;
+            mUnboundTextures.add(t.mId);
+            return true;
+        }
+    }
+
+    public void deleteBuffer(int bufferId) {
+        synchronized (mUnboundTextures) {
+            mDeleteBuffers.add(bufferId);
+        }
+    }
+
+    public void deleteRecycledResources() {
+        synchronized (mUnboundTextures) {
+            IntArray ids = mUnboundTextures;
+            if (ids.size() > 0) {
+                mGL.glDeleteTextures(ids.size(), ids.getInternalArray(), 0);
+                ids.clear();
+            }
+
+            ids = mDeleteBuffers;
+            if (ids.size() > 0) {
+                mGL.glDeleteBuffers(ids.size(), ids.getInternalArray(), 0);
+                ids.clear();
+            }
+        }
+    }
+
+    public int save() {
+        return save(SAVE_FLAG_ALL);
+    }
+
+    public int save(int saveFlags) {
+        ConfigState config = obtainRestoreConfig();
+
+        if ((saveFlags & SAVE_FLAG_ALPHA) != 0) {
+            config.mAlpha = mAlpha;
+        } else {
+            config.mAlpha = -1;
+        }
+
+        if ((saveFlags & SAVE_FLAG_CLIP) != 0) {
+            config.mRect.set(mClipRect);
+        } else {
+            config.mRect.left = Integer.MAX_VALUE;
+        }
+
+        if ((saveFlags & SAVE_FLAG_MATRIX) != 0) {
+            System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16);
+        } else {
+            config.mMatrix[0] = Float.NEGATIVE_INFINITY;
+        }
+
+        mRestoreStack.push(config);
+        return mRestoreStack.size() - 1;
+    }
+
+    public void restore() {
+        if (mRestoreStack.isEmpty()) throw new IllegalStateException();
+        ConfigState config = mRestoreStack.pop();
+        config.restore(this);
+        freeRestoreConfig(config);
+    }
+
+    private void freeRestoreConfig(ConfigState action) {
+        action.mNextFree = mRecycledRestoreAction;
+        mRecycledRestoreAction = action;
+    }
+
+    private ConfigState obtainRestoreConfig() {
+        if (mRecycledRestoreAction != null) {
+            ConfigState result = mRecycledRestoreAction;
+            mRecycledRestoreAction = result.mNextFree;
+            return result;
+        }
+        return new ConfigState();
+    }
+
+    private static class ConfigState {
+        float mAlpha;
+        Rect mRect = new Rect();
+        float mMatrix[] = new float[16];
+        ConfigState mNextFree;
+
+        public void restore(GLCanvasImpl canvas) {
+            if (mAlpha >= 0) canvas.setAlpha(mAlpha);
+            if (mRect.left != Integer.MAX_VALUE) {
+                Rect rect = mRect;
+                canvas.mClipRect.set(rect);
+                canvas.mGL.glScissor(
+                        rect.left, rect.top, rect.width(), rect.height());
+            }
+            if (mMatrix[0] != Float.NEGATIVE_INFINITY) {
+                System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16);
+            }
+        }
+    }
+
+    public void dumpStatisticsAndClear() {
+        String line = String.format(
+                "MESH:%d, TEX_OES:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d",
+                mCountDrawMesh, mCountTextureRect, mCountTextureOES,
+                mCountFillRect, mCountDrawLine);
+        mCountDrawMesh = 0;
+        mCountTextureRect = 0;
+        mCountTextureOES = 0;
+        mCountFillRect = 0;
+        mCountDrawLine = 0;
+        Log.d(TAG, line);
+    }
+
+    private void saveTransform() {
+        System.arraycopy(mMatrixValues, 0, mTempMatrix, 0, 16);
+    }
+
+    private void restoreTransform() {
+        System.arraycopy(mTempMatrix, 0, mMatrixValues, 0, 16);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/GLPaint.java b/src/com/android/gallery3d/ui/GLPaint.java
new file mode 100644
index 0000000..9f7b6f1
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GLPaint.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+
+public class GLPaint {
+    public static final int FLAG_ANTI_ALIAS = 0x01;
+
+    private int mFlags = 0;
+    private float mLineWidth = 1f;
+    private int mColor = 0;
+
+    public int getFlags() {
+        return mFlags;
+    }
+
+    public void setFlags(int flags) {
+        mFlags = flags;
+    }
+
+    public void setColor(int color) {
+        mColor = color;
+    }
+
+    public int getColor() {
+        return mColor;
+    }
+
+    public void setLineWidth(float width) {
+        Utils.assertTrue(width >= 0);
+        mLineWidth = width;
+    }
+
+    public float getLineWidth() {
+        return mLineWidth;
+    }
+
+    public void setAntiAlias(boolean enabled) {
+        if (enabled) {
+            mFlags |= FLAG_ANTI_ALIAS;
+        } else {
+            mFlags &= ~FLAG_ANTI_ALIAS;
+        }
+    }
+
+    public boolean getAntiAlias(){
+        return (mFlags & FLAG_ANTI_ALIAS) != 0;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/GLRoot.java b/src/com/android/gallery3d/ui/GLRoot.java
new file mode 100644
index 0000000..24e5794
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GLRoot.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.anim.CanvasAnimation;
+
+public interface GLRoot {
+
+    public static interface OnGLIdleListener {
+        public boolean onGLIdle(GLRoot root, GLCanvas canvas);
+    }
+
+    public void addOnGLIdleListener(OnGLIdleListener listener);
+    public void registerLaunchedAnimation(CanvasAnimation animation);
+    public void requestRender();
+    public void requestLayoutContentPane();
+    public boolean hasStencil();
+
+    public void lockRenderThread();
+    public void unlockRenderThread();
+
+    public void setContentPane(GLView content);
+}
diff --git a/src/com/android/gallery3d/ui/GLRootView.java b/src/com/android/gallery3d/ui/GLRootView.java
new file mode 100644
index 0000000..e03adf1
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GLRootView.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.anim.CanvasAnimation;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.opengl.GLSurfaceView;
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+
+// The root component of all <code>GLView</code>s. The rendering is done in GL
+// thread while the event handling is done in the main thread.  To synchronize
+// the two threads, the entry points of this package need to synchronize on the
+// <code>GLRootView</code> instance unless it can be proved that the rendering
+// thread won't access the same thing as the method. The entry points include:
+// (1) The public methods of HeadUpDisplay
+// (2) The public methods of CameraHeadUpDisplay
+// (3) The overridden methods in GLRootView.
+public class GLRootView extends GLSurfaceView
+        implements GLSurfaceView.Renderer, GLRoot {
+    private static final String TAG = "GLRootView";
+
+    private static final boolean DEBUG_FPS = false;
+    private int mFrameCount = 0;
+    private long mFrameCountingStart = 0;
+
+    private static final boolean DEBUG_INVALIDATE = false;
+    private int mInvalidateColor = 0;
+
+    private static final boolean DEBUG_DRAWING_STAT = false;
+
+    private static final int FLAG_INITIALIZED = 1;
+    private static final int FLAG_NEED_LAYOUT = 2;
+
+    private GL11 mGL;
+    private GLCanvasImpl mCanvas;
+
+    private GLView mContentView;
+    private DisplayMetrics mDisplayMetrics;
+
+    private int mFlags = FLAG_NEED_LAYOUT;
+    private volatile boolean mRenderRequested = false;
+
+    private Rect mClipRect = new Rect();
+    private int mClipRetryCount = 0;
+
+    private final GalleryEGLConfigChooser mEglConfigChooser =
+            new GalleryEGLConfigChooser();
+
+    private final ArrayList<CanvasAnimation> mAnimations =
+            new ArrayList<CanvasAnimation>();
+
+    private final LinkedList<OnGLIdleListener> mIdleListeners =
+            new LinkedList<OnGLIdleListener>();
+
+    private final IdleRunner mIdleRunner = new IdleRunner();
+
+    private final ReentrantLock mRenderLock = new ReentrantLock();
+
+    private static final int TARGET_FRAME_TIME = 33;
+    private long mLastDrawFinishTime;
+    private boolean mInDownState = false;
+
+    public GLRootView(Context context) {
+        this(context, null);
+    }
+
+    public GLRootView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mFlags |= FLAG_INITIALIZED;
+        setBackgroundDrawable(null);
+        setEGLConfigChooser(mEglConfigChooser);
+        setRenderer(this);
+        getHolder().setFormat(PixelFormat.RGB_565);
+
+        // Uncomment this to enable gl error check.
+        //setDebugFlags(DEBUG_CHECK_GL_ERROR);
+    }
+
+    public GalleryEGLConfigChooser getEGLConfigChooser() {
+        return mEglConfigChooser;
+    }
+
+    @Override
+    public boolean hasStencil() {
+        return getEGLConfigChooser().getStencilBits() > 0;
+    }
+
+    @Override
+    public void registerLaunchedAnimation(CanvasAnimation animation) {
+        // Register the newly launched animation so that we can set the start
+        // time more precisely. (Usually, it takes much longer for first
+        // rendering, so we set the animation start time as the time we
+        // complete rendering)
+        mAnimations.add(animation);
+    }
+
+    @Override
+    public void addOnGLIdleListener(OnGLIdleListener listener) {
+        synchronized (mIdleListeners) {
+            mIdleListeners.addLast(listener);
+            mIdleRunner.enable();
+        }
+    }
+
+    @Override
+    public void setContentPane(GLView content) {
+        if (mContentView == content) return;
+        if (mContentView != null) {
+            if (mInDownState) {
+                long now = SystemClock.uptimeMillis();
+                MotionEvent cancelEvent = MotionEvent.obtain(
+                        now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0);
+                mContentView.dispatchTouchEvent(cancelEvent);
+                cancelEvent.recycle();
+                mInDownState = false;
+            }
+            mContentView.detachFromRoot();
+            BasicTexture.yieldAllTextures();
+        }
+        mContentView = content;
+        if (content != null) {
+            content.attachToRoot(this);
+            requestLayoutContentPane();
+        }
+    }
+
+    public GLView getContentPane() {
+        return mContentView;
+    }
+
+    @Override
+    public void requestRender() {
+        if (DEBUG_INVALIDATE) {
+            StackTraceElement e = Thread.currentThread().getStackTrace()[4];
+            String caller = e.getFileName() + ":" + e.getLineNumber() + " ";
+            Log.d(TAG, "invalidate: " + caller);
+        }
+        if (mRenderRequested) return;
+        mRenderRequested = true;
+        super.requestRender();
+    }
+
+    @Override
+    public void requestLayoutContentPane() {
+        mRenderLock.lock();
+        try {
+            if (mContentView == null || (mFlags & FLAG_NEED_LAYOUT) != 0) return;
+
+            // "View" system will invoke onLayout() for initialization(bug ?), we
+            // have to ignore it since the GLThread is not ready yet.
+            if ((mFlags & FLAG_INITIALIZED) == 0) return;
+
+            mFlags |= FLAG_NEED_LAYOUT;
+            requestRender();
+        } finally {
+            mRenderLock.unlock();
+        }
+    }
+
+    private void layoutContentPane() {
+        mFlags &= ~FLAG_NEED_LAYOUT;
+        int width = getWidth();
+        int height = getHeight();
+        Log.i(TAG, "layout content pane " + width + "x" + height);
+        if (mContentView != null && width != 0 && height != 0) {
+            mContentView.layout(0, 0, width, height);
+        }
+        // Uncomment this to dump the view hierarchy.
+        //mContentView.dumpTree("");
+    }
+
+    @Override
+    protected void onLayout(
+            boolean changed, int left, int top, int right, int bottom) {
+        if (changed) requestLayoutContentPane();
+    }
+
+    /**
+     * Called when the context is created, possibly after automatic destruction.
+     */
+    // This is a GLSurfaceView.Renderer callback
+    @Override
+    public void onSurfaceCreated(GL10 gl1, EGLConfig config) {
+        GL11 gl = (GL11) gl1;
+        if (mGL != null) {
+            // The GL Object has changed
+            Log.i(TAG, "GLObject has changed from " + mGL + " to " + gl);
+        }
+        mGL = gl;
+        mCanvas = new GLCanvasImpl(gl);
+        if (!DEBUG_FPS) {
+            setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+        } else {
+            setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
+        }
+    }
+
+    /**
+     * Called when the OpenGL surface is recreated without destroying the
+     * context.
+     */
+    // This is a GLSurfaceView.Renderer callback
+    @Override
+    public void onSurfaceChanged(GL10 gl1, int width, int height) {
+        Log.i(TAG, "onSurfaceChanged: " + width + "x" + height
+                + ", gl10: " + gl1.toString());
+        Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
+        GalleryUtils.setRenderThread();
+        GL11 gl = (GL11) gl1;
+        Utils.assertTrue(mGL == gl);
+
+        mCanvas.setSize(width, height);
+
+        mClipRect.set(0, 0, width, height);
+        mClipRetryCount = 2;
+    }
+
+    private void outputFps() {
+        long now = System.nanoTime();
+        if (mFrameCountingStart == 0) {
+            mFrameCountingStart = now;
+        } else if ((now - mFrameCountingStart) > 1000000000) {
+            Log.d(TAG, "fps: " + (double) mFrameCount
+                    * 1000000000 / (now - mFrameCountingStart));
+            mFrameCountingStart = now;
+            mFrameCount = 0;
+        }
+        ++mFrameCount;
+    }
+
+    @Override
+    public void onDrawFrame(GL10 gl) {
+        mRenderLock.lock();
+        try {
+            onDrawFrameLocked(gl);
+        } finally {
+            mRenderLock.unlock();
+        }
+        long end = SystemClock.uptimeMillis();
+
+        if (mLastDrawFinishTime != 0) {
+            long wait = mLastDrawFinishTime + TARGET_FRAME_TIME - end;
+            if (wait > 0) {
+                SystemClock.sleep(wait);
+            }
+        }
+        mLastDrawFinishTime = SystemClock.uptimeMillis();
+    }
+
+    private void onDrawFrameLocked(GL10 gl) {
+        if (DEBUG_FPS) outputFps();
+
+        // release the unbound textures and deleted buffers.
+        mCanvas.deleteRecycledResources();
+
+        // reset texture upload limit
+        UploadedTexture.resetUploadLimit();
+
+        mRenderRequested = false;
+
+        if ((mFlags & FLAG_NEED_LAYOUT) != 0) layoutContentPane();
+
+        // OpenGL seems having a bug causing us not being able to reset the
+        // scissor box in "onSurfaceChanged()". We have to do it in the second
+        // onDrawFrame().
+        if (mClipRetryCount > 0) {
+            --mClipRetryCount;
+            Rect clip = mClipRect;
+            gl.glScissor(clip.left, clip.top, clip.width(), clip.height());
+        }
+
+        mCanvas.setCurrentAnimationTimeMillis(SystemClock.uptimeMillis());
+        if (mContentView != null) {
+           mContentView.render(mCanvas);
+        }
+
+        if (!mAnimations.isEmpty()) {
+            long now = SystemClock.uptimeMillis();
+            for (int i = 0, n = mAnimations.size(); i < n; i++) {
+                mAnimations.get(i).setStartTime(now);
+            }
+            mAnimations.clear();
+        }
+
+        if (UploadedTexture.uploadLimitReached()) {
+            requestRender();
+        }
+
+        synchronized (mIdleListeners) {
+            if (!mRenderRequested && !mIdleListeners.isEmpty()) {
+                mIdleRunner.enable();
+            }
+        }
+
+        if (DEBUG_INVALIDATE) {
+            mCanvas.fillRect(10, 10, 5, 5, mInvalidateColor);
+            mInvalidateColor = ~mInvalidateColor;
+        }
+
+        if (DEBUG_DRAWING_STAT) {
+            mCanvas.dumpStatisticsAndClear();
+        }
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        int action = event.getAction();
+        if (action == MotionEvent.ACTION_CANCEL
+                || action == MotionEvent.ACTION_UP) {
+            mInDownState = false;
+        } else if (!mInDownState && action != MotionEvent.ACTION_DOWN) {
+            return false;
+        }
+        mRenderLock.lock();
+        try {
+            // If this has been detached from root, we don't need to handle event
+            boolean handled = mContentView != null
+                    && mContentView.dispatchTouchEvent(event);
+            if (action == MotionEvent.ACTION_DOWN && handled) {
+                mInDownState = true;
+            }
+            return handled;
+        } finally {
+            mRenderLock.unlock();
+        }
+    }
+
+    public DisplayMetrics getDisplayMetrics() {
+        if (mDisplayMetrics == null) {
+            mDisplayMetrics = new DisplayMetrics();
+            ((Activity) getContext()).getWindowManager()
+                    .getDefaultDisplay().getMetrics(mDisplayMetrics);
+        }
+        return mDisplayMetrics;
+    }
+
+    public GLCanvas getCanvas() {
+        return mCanvas;
+    }
+
+    private class IdleRunner implements Runnable {
+        // true if the idle runner is in the queue
+        private boolean mActive = false;
+
+        @Override
+        public void run() {
+            OnGLIdleListener listener;
+            synchronized (mIdleListeners) {
+                mActive = false;
+                if (mRenderRequested) return;
+                if (mIdleListeners.isEmpty()) return;
+                listener = mIdleListeners.removeFirst();
+            }
+            mRenderLock.lock();
+            try {
+                if (!listener.onGLIdle(GLRootView.this, mCanvas)) return;
+            } finally {
+                mRenderLock.unlock();
+            }
+            synchronized (mIdleListeners) {
+                mIdleListeners.addLast(listener);
+                enable();
+            }
+        }
+
+        public void enable() {
+            // Who gets the flag can add it to the queue
+            if (mActive) return;
+            mActive = true;
+            queueEvent(this);
+        }
+    }
+
+    @Override
+    public void lockRenderThread() {
+        mRenderLock.lock();
+    }
+
+    @Override
+    public void unlockRenderThread() {
+        mRenderLock.unlock();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/GLView.java b/src/com/android/gallery3d/ui/GLView.java
new file mode 100644
index 0000000..c593278
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GLView.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.anim.CanvasAnimation;
+import com.android.gallery3d.common.Utils;
+
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+
+// GLView is a UI component. It can render to a GLCanvas and accept touch
+// events. A GLView may have zero or more child GLView and they form a tree
+// structure. The rendering and event handling will pass through the tree
+// structure.
+//
+// A GLView tree should be attached to a GLRoot before event dispatching and
+// rendering happens. GLView asks GLRoot to re-render or re-layout the
+// GLView hierarchy using requestRender() and requestLayoutContentPane().
+//
+// The render() method is called in a separate thread. Before calling
+// dispatchTouchEvent() and layout(), GLRoot acquires a lock to avoid the
+// rendering thread running at the same time. If there are other entry points
+// from main thread (like a Handler) in your GLView, you need to call
+// lockRendering() if the rendering thread should not run at the same time.
+//
+public class GLView {
+    private static final String TAG = "GLView";
+
+    public static final int VISIBLE = 0;
+    public static final int INVISIBLE = 1;
+
+    private static final int FLAG_INVISIBLE = 1;
+    private static final int FLAG_SET_MEASURED_SIZE = 2;
+    private static final int FLAG_LAYOUT_REQUESTED = 4;
+
+    protected final Rect mBounds = new Rect();
+    protected final Rect mPaddings = new Rect();
+
+    private GLRoot mRoot;
+    protected GLView mParent;
+    private ArrayList<GLView> mComponents;
+    private GLView mMotionTarget;
+
+    private CanvasAnimation mAnimation;
+
+    private int mViewFlags = 0;
+
+    protected int mMeasuredWidth = 0;
+    protected int mMeasuredHeight = 0;
+
+    private int mLastWidthSpec = -1;
+    private int mLastHeightSpec = -1;
+
+    protected int mScrollY = 0;
+    protected int mScrollX = 0;
+    protected int mScrollHeight = 0;
+    protected int mScrollWidth = 0;
+
+    public void startAnimation(CanvasAnimation animation) {
+        GLRoot root = getGLRoot();
+        if (root == null) throw new IllegalStateException();
+
+        mAnimation = animation;
+        mAnimation.start();
+        root.registerLaunchedAnimation(mAnimation);
+        invalidate();
+    }
+
+    // Sets the visiblity of this GLView (either GLView.VISIBLE or
+    // GLView.INVISIBLE).
+    public void setVisibility(int visibility) {
+        if (visibility == getVisibility()) return;
+        if (visibility == VISIBLE) {
+            mViewFlags &= ~FLAG_INVISIBLE;
+        } else {
+            mViewFlags |= FLAG_INVISIBLE;
+        }
+        onVisibilityChanged(visibility);
+        invalidate();
+    }
+
+    // Returns GLView.VISIBLE or GLView.INVISIBLE
+    public int getVisibility() {
+        return (mViewFlags & FLAG_INVISIBLE) == 0 ? VISIBLE : INVISIBLE;
+    }
+
+    // This should only be called on the content pane (the topmost GLView).
+    public void attachToRoot(GLRoot root) {
+        Utils.assertTrue(mParent == null && mRoot == null);
+        onAttachToRoot(root);
+    }
+
+    // This should only be called on the content pane (the topmost GLView).
+    public void detachFromRoot() {
+        Utils.assertTrue(mParent == null && mRoot != null);
+        onDetachFromRoot();
+    }
+
+    // Returns the number of children of the GLView.
+    public int getComponentCount() {
+        return mComponents == null ? 0 : mComponents.size();
+    }
+
+    // Returns the children for the given index.
+    public GLView getComponent(int index) {
+        if (mComponents == null) {
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
+        return mComponents.get(index);
+    }
+
+    // Adds a child to this GLView.
+    public void addComponent(GLView component) {
+        // Make sure the component doesn't have a parent currently.
+        if (component.mParent != null) throw new IllegalStateException();
+
+        // Build parent-child links
+        if (mComponents == null) {
+            mComponents = new ArrayList<GLView>();
+        }
+        mComponents.add(component);
+        component.mParent = this;
+
+        // If this is added after we have a root, tell the component.
+        if (mRoot != null) {
+            component.onAttachToRoot(mRoot);
+        }
+    }
+
+    // Removes a child from this GLView.
+    public boolean removeComponent(GLView component) {
+        if (mComponents == null) return false;
+        if (mComponents.remove(component)) {
+            removeOneComponent(component);
+            return true;
+        }
+        return false;
+    }
+
+    // Removes all children of this GLView.
+    public void removeAllComponents() {
+        for (int i = 0, n = mComponents.size(); i < n; ++i) {
+            removeOneComponent(mComponents.get(i));
+        }
+        mComponents.clear();
+    }
+
+    private void removeOneComponent(GLView component) {
+        if (mMotionTarget == component) {
+            long now = SystemClock.uptimeMillis();
+            MotionEvent cancelEvent = MotionEvent.obtain(
+                    now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0);
+            dispatchTouchEvent(cancelEvent);
+            cancelEvent.recycle();
+        }
+        component.onDetachFromRoot();
+        component.mParent = null;
+    }
+
+    public Rect bounds() {
+        return mBounds;
+    }
+
+    public int getWidth() {
+        return mBounds.right - mBounds.left;
+    }
+
+    public int getHeight() {
+        return mBounds.bottom - mBounds.top;
+    }
+
+    public GLRoot getGLRoot() {
+        return mRoot;
+    }
+
+    // Request re-rendering of the view hierarchy.
+    // This is used for animation or when the contents changed.
+    public void invalidate() {
+        GLRoot root = getGLRoot();
+        if (root != null) root.requestRender();
+    }
+
+    // Request re-layout of the view hierarchy.
+    public void requestLayout() {
+        mViewFlags |= FLAG_LAYOUT_REQUESTED;
+        mLastHeightSpec = -1;
+        mLastWidthSpec = -1;
+        if (mParent != null) {
+            mParent.requestLayout();
+        } else {
+            // Is this a content pane ?
+            GLRoot root = getGLRoot();
+            if (root != null) root.requestLayoutContentPane();
+        }
+    }
+
+    protected void render(GLCanvas canvas) {
+        renderBackground(canvas);
+        for (int i = 0, n = getComponentCount(); i < n; ++i) {
+            renderChild(canvas, getComponent(i));
+        }
+    }
+
+    protected void renderBackground(GLCanvas view) {
+    }
+
+    protected void renderChild(GLCanvas canvas, GLView component) {
+        if (component.getVisibility() != GLView.VISIBLE
+                && component.mAnimation == null) return;
+
+        int xoffset = component.mBounds.left - mScrollX;
+        int yoffset = component.mBounds.top - mScrollY;
+
+        canvas.translate(xoffset, yoffset, 0);
+
+        CanvasAnimation anim = component.mAnimation;
+        if (anim != null) {
+            canvas.save(anim.getCanvasSaveFlags());
+            if (anim.calculate(canvas.currentAnimationTimeMillis())) {
+                invalidate();
+            } else {
+                component.mAnimation = null;
+            }
+            anim.apply(canvas);
+        }
+        component.render(canvas);
+        if (anim != null) canvas.restore();
+        canvas.translate(-xoffset, -yoffset, 0);
+    }
+
+    protected boolean onTouch(MotionEvent event) {
+        return false;
+    }
+
+    protected boolean dispatchTouchEvent(MotionEvent event,
+            int x, int y, GLView component, boolean checkBounds) {
+        Rect rect = component.mBounds;
+        int left = rect.left;
+        int top = rect.top;
+        if (!checkBounds || rect.contains(x, y)) {
+            event.offsetLocation(-left, -top);
+            if (component.dispatchTouchEvent(event)) {
+                event.offsetLocation(left, top);
+                return true;
+            }
+            event.offsetLocation(left, top);
+        }
+        return false;
+    }
+
+    protected boolean dispatchTouchEvent(MotionEvent event) {
+        int x = (int) event.getX();
+        int y = (int) event.getY();
+        int action = event.getAction();
+        if (mMotionTarget != null) {
+            if (action == MotionEvent.ACTION_DOWN) {
+                MotionEvent cancel = MotionEvent.obtain(event);
+                cancel.setAction(MotionEvent.ACTION_CANCEL);
+                dispatchTouchEvent(cancel, x, y, mMotionTarget, false);
+                mMotionTarget = null;
+            } else {
+                dispatchTouchEvent(event, x, y, mMotionTarget, false);
+                if (action == MotionEvent.ACTION_CANCEL
+                        || action == MotionEvent.ACTION_UP) {
+                    mMotionTarget = null;
+                }
+                return true;
+            }
+        }
+        if (action == MotionEvent.ACTION_DOWN) {
+            // in the reverse rendering order
+            for (int i = getComponentCount() - 1; i >= 0; --i) {
+                GLView component = getComponent(i);
+                if (component.getVisibility() != GLView.VISIBLE) continue;
+                if (dispatchTouchEvent(event, x, y, component, true)) {
+                    mMotionTarget = component;
+                    return true;
+                }
+            }
+        }
+        return onTouch(event);
+    }
+
+    public Rect getPaddings() {
+        return mPaddings;
+    }
+
+    public void setPaddings(Rect paddings) {
+        mPaddings.set(paddings);
+    }
+
+    public void setPaddings(int left, int top, int right, int bottom) {
+        mPaddings.set(left, top, right, bottom);
+    }
+
+    public void layout(int left, int top, int right, int bottom) {
+        boolean sizeChanged = setBounds(left, top, right, bottom);
+        if (sizeChanged) {
+            mViewFlags &= ~FLAG_LAYOUT_REQUESTED;
+            onLayout(true, left, top, right, bottom);
+        } else if ((mViewFlags & FLAG_LAYOUT_REQUESTED)!= 0) {
+            mViewFlags &= ~FLAG_LAYOUT_REQUESTED;
+            onLayout(false, left, top, right, bottom);
+        }
+    }
+
+    private boolean setBounds(int left, int top, int right, int bottom) {
+        boolean sizeChanged = (right - left) != (mBounds.right - mBounds.left)
+                || (bottom - top) != (mBounds.bottom - mBounds.top);
+        mBounds.set(left, top, right, bottom);
+        return sizeChanged;
+    }
+
+    public void measure(int widthSpec, int heightSpec) {
+        if (widthSpec == mLastWidthSpec && heightSpec == mLastHeightSpec
+                && (mViewFlags & FLAG_LAYOUT_REQUESTED) == 0) {
+            return;
+        }
+
+        mLastWidthSpec = widthSpec;
+        mLastHeightSpec = heightSpec;
+
+        mViewFlags &= ~FLAG_SET_MEASURED_SIZE;
+        onMeasure(widthSpec, heightSpec);
+        if ((mViewFlags & FLAG_SET_MEASURED_SIZE) == 0) {
+            throw new IllegalStateException(getClass().getName()
+                    + " should call setMeasuredSize() in onMeasure()");
+        }
+    }
+
+    protected void onMeasure(int widthSpec, int heightSpec) {
+    }
+
+    protected void setMeasuredSize(int width, int height) {
+        mViewFlags |= FLAG_SET_MEASURED_SIZE;
+        mMeasuredWidth = width;
+        mMeasuredHeight = height;
+    }
+
+    public int getMeasuredWidth() {
+        return mMeasuredWidth;
+    }
+
+    public int getMeasuredHeight() {
+        return mMeasuredHeight;
+    }
+
+    protected void onLayout(
+            boolean changeSize, int left, int top, int right, int bottom) {
+    }
+
+    /**
+     * Gets the bounds of the given descendant that relative to this view.
+     */
+    public boolean getBoundsOf(GLView descendant, Rect out) {
+        int xoffset = 0;
+        int yoffset = 0;
+        GLView view = descendant;
+        while (view != this) {
+            if (view == null) return false;
+            Rect bounds = view.mBounds;
+            xoffset += bounds.left;
+            yoffset += bounds.top;
+            view = view.mParent;
+        }
+        out.set(xoffset, yoffset, xoffset + descendant.getWidth(),
+                yoffset + descendant.getHeight());
+        return true;
+    }
+
+    protected void onVisibilityChanged(int visibility) {
+        for (int i = 0, n = getComponentCount(); i < n; ++i) {
+            GLView child = getComponent(i);
+            if (child.getVisibility() == GLView.VISIBLE) {
+                child.onVisibilityChanged(visibility);
+            }
+        }
+    }
+
+    protected void onAttachToRoot(GLRoot root) {
+        mRoot = root;
+        for (int i = 0, n = getComponentCount(); i < n; ++i) {
+            getComponent(i).onAttachToRoot(root);
+        }
+    }
+
+    protected void onDetachFromRoot() {
+        for (int i = 0, n = getComponentCount(); i < n; ++i) {
+            getComponent(i).onDetachFromRoot();
+        }
+        mRoot = null;
+    }
+
+    public void lockRendering() {
+        if (mRoot != null) {
+            mRoot.lockRenderThread();
+        }
+    }
+
+    public void unlockRendering() {
+        if (mRoot != null) {
+            mRoot.unlockRenderThread();
+        }
+    }
+
+    // This is for debugging only.
+    // Dump the view hierarchy into log.
+    void dumpTree(String prefix) {
+        Log.d(TAG, prefix + getClass().getSimpleName());
+        for (int i = 0, n = getComponentCount(); i < n; ++i) {
+            getComponent(i).dumpTree(prefix + "....");
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java b/src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java
new file mode 100644
index 0000000..1d50d43
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GalleryEGLConfigChooser.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.gallery3d.ui;
+
+import android.opengl.GLSurfaceView.EGLConfigChooser;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLDisplay;
+
+/*
+ * The code is copied/adapted from
+ * <code>android.opengl.GLSurfaceView.BaseConfigChooser</code>. Here we try to
+ * choose a configuration that support RGBA_8888 format and if possible,
+ * with stencil buffer, but is not required.
+ */
+class GalleryEGLConfigChooser implements EGLConfigChooser {
+
+    private static final String TAG = "GalleryEGLConfigChooser";
+    private int mStencilBits;
+
+    private final int mConfigSpec[] = new int[] {
+            EGL10.EGL_RED_SIZE, 5,
+            EGL10.EGL_GREEN_SIZE, 6,
+            EGL10.EGL_BLUE_SIZE, 5,
+            EGL10.EGL_ALPHA_SIZE, 0,
+            EGL10.EGL_NONE
+    };
+
+    public int getStencilBits() {
+        return mStencilBits;
+    }
+
+    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+        int[] numConfig = new int[1];
+        if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, numConfig)) {
+            throw new RuntimeException("eglChooseConfig failed");
+        }
+
+        if (numConfig[0] <= 0) {
+            throw new RuntimeException("No configs match configSpec");
+        }
+
+        EGLConfig[] configs = new EGLConfig[numConfig[0]];
+        if (!egl.eglChooseConfig(display,
+                mConfigSpec, configs, configs.length, numConfig)) {
+            throw new RuntimeException();
+        }
+
+        return chooseConfig(egl, display, configs);
+    }
+
+    private EGLConfig chooseConfig(
+            EGL10 egl, EGLDisplay display, EGLConfig configs[]) {
+
+        EGLConfig result = null;
+        int minStencil = Integer.MAX_VALUE;
+        int value[] = new int[1];
+
+        // Because we need only one bit of stencil, try to choose a config that
+        // has stencil support but with smallest number of stencil bits. If
+        // none is found, choose any one.
+        for (int i = 0, n = configs.length; i < n; ++i) {
+            if (egl.eglGetConfigAttrib(
+                display, configs[i], EGL10.EGL_RED_SIZE, value)) {
+                // Filter out ARGB 8888 configs.
+                if (value[0] == 8) continue;
+            }
+            if (egl.eglGetConfigAttrib(
+                    display, configs[i], EGL10.EGL_STENCIL_SIZE, value)) {
+                if (value[0] == 0) continue;
+                if (value[0] < minStencil) {
+                    minStencil = value[0];
+                    result = configs[i];
+                }
+            } else {
+                throw new RuntimeException(
+                        "eglGetConfigAttrib error: " + egl.eglGetError());
+            }
+        }
+        if (result == null) result = configs[0];
+        egl.eglGetConfigAttrib(
+                display, result, EGL10.EGL_STENCIL_SIZE, value);
+        mStencilBits = value[0];
+        logConfig(egl, display, result);
+        return result;
+    }
+
+    private static final int[] ATTR_ID = {
+            EGL10.EGL_RED_SIZE,
+            EGL10.EGL_GREEN_SIZE,
+            EGL10.EGL_BLUE_SIZE,
+            EGL10.EGL_ALPHA_SIZE,
+            EGL10.EGL_DEPTH_SIZE,
+            EGL10.EGL_STENCIL_SIZE,
+            EGL10.EGL_CONFIG_ID,
+            EGL10.EGL_CONFIG_CAVEAT
+    };
+
+    private static final String[] ATTR_NAME = {
+        "R", "G", "B", "A", "D", "S", "ID", "CAVEAT"
+    };
+
+    private void logConfig(EGL10 egl, EGLDisplay display, EGLConfig config) {
+        int value[] = new int[1];
+        StringBuilder sb = new StringBuilder();
+        for (int j = 0; j < ATTR_ID.length; j++) {
+            egl.eglGetConfigAttrib(display, config, ATTR_ID[j], value);
+            sb.append(ATTR_NAME[j] + value[0] + " ");
+        }
+        Log.i(TAG, "Config chosen: " + sb.toString());
+    }
+}
diff --git a/src/com/android/gallery3d/ui/GridDrawer.java b/src/com/android/gallery3d/ui/GridDrawer.java
new file mode 100644
index 0000000..54b175c
--- /dev/null
+++ b/src/com/android/gallery3d/ui/GridDrawer.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.Path;
+
+import android.content.Context;
+import android.graphics.Color;
+
+public class GridDrawer extends IconDrawer {
+    private final NinePatchTexture mFrame;
+    private final NinePatchTexture mFrameSelected;
+    private final NinePatchTexture mFrameSelectedTop;
+    private final NinePatchTexture mImportBackground;
+    private Texture mImportLabel;
+    private int mGridWidth;
+    private final SelectionManager mSelectionManager;
+    private final Context mContext;
+    private final int FONT_SIZE = 14;
+    private final int FONT_COLOR = Color.WHITE;
+    private final int IMPORT_LABEL_PADDING = 10;
+    private boolean mSelectionMode;
+
+    public GridDrawer(Context context, SelectionManager selectionManager) {
+        super(context);
+        mContext = context;
+        mFrame = new NinePatchTexture(context, R.drawable.album_frame);
+        mFrameSelected = new NinePatchTexture(context, R.drawable.grid_selected);
+        mFrameSelectedTop = new NinePatchTexture(context, R.drawable.grid_selected_top);
+        mImportBackground = new NinePatchTexture(context, R.drawable.import_translucent);
+        mSelectionManager = selectionManager;
+    }
+
+    @Override
+    public void prepareDrawing() {
+        mSelectionMode = mSelectionManager.inSelectionMode();
+    }
+
+    @Override
+    public void draw(GLCanvas canvas, Texture content, int width, int height,
+            int rotation, Path path, int topIndex, int dataSourceType,
+            int mediaType, boolean wantCache, boolean isCaching) {
+
+        int x = -width / 2;
+        int y = -height / 2;
+
+        drawWithRotationAndGray(canvas, content, x, y, width, height, rotation,
+                topIndex);
+
+        if (((rotation / 90) & 0x01) == 1) {
+            int temp = width;
+            width = height;
+            height = temp;
+            x = -width / 2;
+            y = -height / 2;
+        }
+
+        drawVideoOverlay(canvas, mediaType, x, y, width, height, topIndex);
+
+        NinePatchTexture frame;
+        if (mSelectionMode && mSelectionManager.isItemSelected(path)) {
+            frame = topIndex == 0 ? mFrameSelectedTop : mFrameSelected;
+        } else {
+            frame = mFrame;
+        }
+
+        drawFrame(canvas, frame, x, y, width, height);
+
+        if (topIndex == 0) {
+            ResourceTexture icon = getIcon(dataSourceType);
+            if (icon != null) {
+                IconDimension id = getIconDimension(icon, width, height);
+                if (dataSourceType == DATASOURCE_TYPE_MTP) {
+                    if (mImportLabel == null || mGridWidth != width) {
+                        mGridWidth = width;
+                        mImportLabel = MultiLineTexture.newInstance(
+                                mContext.getString(R.string.click_import),
+                                width - id.width - IMPORT_LABEL_PADDING, FONT_SIZE, FONT_COLOR);
+                    }
+                    int bgHeight = Math.max(id.height, mImportLabel.getHeight());
+                    mImportBackground.setSize(width, bgHeight);
+                    mImportBackground.draw(canvas, x, -y - bgHeight);
+                    mImportLabel.draw(canvas, x + id.width + IMPORT_LABEL_PADDING,
+                            -y - bgHeight + Math.abs(bgHeight - mImportLabel.getHeight()) / 2);
+                }
+                icon.draw(canvas, id.x, id.y, id.width, id.height);
+            }
+        }
+    }
+
+    @Override
+    public void drawFocus(GLCanvas canvas, int width, int height) {
+    }
+}
diff --git a/src/com/android/gallery3d/ui/HighlightDrawer.java b/src/com/android/gallery3d/ui/HighlightDrawer.java
new file mode 100644
index 0000000..9d5868b
--- /dev/null
+++ b/src/com/android/gallery3d/ui/HighlightDrawer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.Path;
+
+import android.content.Context;
+
+public class HighlightDrawer extends IconDrawer {
+    private final NinePatchTexture mFrame;
+    private final NinePatchTexture mFrameSelected;
+    private final NinePatchTexture mFrameSelectedTop;
+    private SelectionManager mSelectionManager;
+    private Path mHighlightItem;
+
+    public HighlightDrawer(Context context) {
+        super(context);
+        mFrame = new NinePatchTexture(context, R.drawable.album_frame);
+        mFrameSelected = new NinePatchTexture(context, R.drawable.grid_selected);
+        mFrameSelectedTop = new NinePatchTexture(context, R.drawable.grid_selected_top);
+    }
+
+    public void setHighlightItem(Path item) {
+        mHighlightItem = item;
+    }
+
+    public void draw(GLCanvas canvas, Texture content, int width, int height,
+            int rotation, Path path, int topIndex, int dataSourceType,
+            int mediaType, boolean wantCache, boolean isCaching) {
+        int x = -width / 2;
+        int y = -height / 2;
+
+        drawWithRotationAndGray(canvas, content, x, y, width, height, rotation,
+                topIndex);
+
+        if (((rotation / 90) & 0x01) == 1) {
+            int temp = width;
+            width = height;
+            height = temp;
+            x = -width / 2;
+            y = -height / 2;
+        }
+
+        drawVideoOverlay(canvas, mediaType, x, y, width, height, topIndex);
+
+        NinePatchTexture frame;
+        if (path == mHighlightItem) {
+            frame = topIndex == 0 ? mFrameSelectedTop : mFrameSelected;
+        } else {
+            frame = mFrame;
+        }
+
+        drawFrame(canvas, frame, x, y, width, height);
+
+        if (topIndex == 0) {
+            drawIcon(canvas, width, height, dataSourceType);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/Icon.java b/src/com/android/gallery3d/ui/Icon.java
new file mode 100644
index 0000000..c710859
--- /dev/null
+++ b/src/com/android/gallery3d/ui/Icon.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.content.Context;
+import android.graphics.Rect;
+
+public class Icon extends GLView {
+    private final BasicTexture mIcon;
+
+    // The width and height requested by the user.
+    private int mReqWidth;
+    private int mReqHeight;
+
+    public Icon(Context context, int iconId, int width, int height) {
+        this(context, new ResourceTexture(context, iconId), width, height);
+    }
+
+    public Icon(Context context, BasicTexture icon, int width, int height) {
+        mIcon = icon;
+        mReqWidth = width;
+        mReqHeight = height;
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        MeasureHelper.getInstance(this)
+                .setPreferredContentSize(mReqWidth, mReqHeight)
+                .measure(widthSpec, heightSpec);
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        Rect p = mPaddings;
+
+        int width = getWidth() - p.left - p.right;
+        int height = getHeight() - p.top - p.bottom;
+
+        // Draw the icon in the center of the space
+        int xoffset = p.left + (width - mReqWidth) / 2;
+        int yoffset = p.top + (height - mReqHeight) / 2;
+
+        mIcon.draw(canvas, xoffset, yoffset, mReqWidth, mReqHeight);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/IconDrawer.java b/src/com/android/gallery3d/ui/IconDrawer.java
new file mode 100644
index 0000000..91732d3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/IconDrawer.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.MediaObject;
+
+import android.content.Context;
+
+public abstract class IconDrawer extends SelectionDrawer {
+    private final String TAG = "IconDrawer";
+    private final ResourceTexture mLocalSetIcon;
+    private final ResourceTexture mCameraIcon;
+    private final ResourceTexture mPicasaIcon;
+    private final ResourceTexture mMtpIcon;
+    private final Texture mVideoOverlay;
+    private final Texture mVideoPlayIcon;
+
+    public static class IconDimension {
+        int x;
+        int y;
+        int width;
+        int height;
+    }
+
+    public IconDrawer(Context context) {
+        mLocalSetIcon = new ResourceTexture(context, R.drawable.ic_album_overlay_folder_holo);
+        mCameraIcon = new ResourceTexture(context, R.drawable.ic_album_overlay_camera_holo);
+        mPicasaIcon = new ResourceTexture(context, R.drawable.ic_album_overlay_picassa_holo);
+        mMtpIcon = new ResourceTexture(context, R.drawable.ic_album_overlay_ptp_holo);
+        mVideoOverlay = new ResourceTexture(context,
+                R.drawable.thumbnail_album_video_overlay_holo);
+        mVideoPlayIcon = new ResourceTexture(context,
+                R.drawable.videooverlay);
+    }
+
+    @Override
+    public void prepareDrawing() {
+    }
+
+    protected IconDimension drawIcon(GLCanvas canvas, int width, int height,
+            int dataSourceType) {
+        ResourceTexture icon = getIcon(dataSourceType);
+
+        if (icon != null) {
+            IconDimension id = getIconDimension(icon, width, height);
+            icon.draw(canvas, id.x, id.y, id.width, id.height);
+            return id;
+        }
+        return null;
+    }
+
+    protected ResourceTexture getIcon(int dataSourceType) {
+        ResourceTexture icon = null;
+        switch (dataSourceType) {
+            case DATASOURCE_TYPE_LOCAL:
+                icon = mLocalSetIcon;
+                break;
+            case DATASOURCE_TYPE_PICASA:
+                icon = mPicasaIcon;
+                break;
+            case DATASOURCE_TYPE_CAMERA:
+                icon = mCameraIcon;
+                break;
+            case DATASOURCE_TYPE_MTP:
+                icon = mMtpIcon;
+                break;
+            default:
+                break;
+        }
+
+        return icon;
+    }
+
+    protected IconDimension getIconDimension(ResourceTexture icon, int width,
+            int height) {
+        IconDimension id = new IconDimension();
+        float scale = 0.25f * width / icon.getWidth();
+        id.width = (int) (scale * icon.getWidth());
+        id.height = (int) (scale * icon.getHeight());
+        id.x = -width / 2;
+        id.y = height / 2 - id.height;
+        return id;
+    }
+
+    protected void drawVideoOverlay(GLCanvas canvas, int mediaType,
+            int x, int y, int width, int height, int topIndex) {
+        if (mediaType != MediaObject.MEDIA_TYPE_VIDEO) return;
+        mVideoOverlay.draw(canvas, x, y, width, height);
+        if (topIndex == 0) {
+            int side = Math.min(width, height) / 6;
+            mVideoPlayIcon.draw(canvas, -side / 2, -side / 2, side, side);
+        }
+    }
+
+    @Override
+    public void drawFocus(GLCanvas canvas, int width, int height) {
+    }
+}
diff --git a/src/com/android/gallery3d/ui/ImportCompleteListener.java b/src/com/android/gallery3d/ui/ImportCompleteListener.java
new file mode 100644
index 0000000..5c52ea1
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ImportCompleteListener.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.AlbumPage;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.util.MediaSetUtils;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.widget.Toast;
+
+public class ImportCompleteListener implements MenuExecutor.ProgressListener {
+    private GalleryActivity mActivity;
+
+    public ImportCompleteListener(GalleryActivity galleryActivity) {
+        mActivity = galleryActivity;
+    }
+
+    public void onProgressComplete(int result) {
+        int message;
+        if (result == MenuExecutor.EXECUTION_RESULT_SUCCESS) {
+            message = R.string.import_complete;
+            goToImportedAlbum();
+        } else {
+            message = R.string.import_fail;
+        }
+        Toast.makeText(mActivity.getAndroidContext(), message, Toast.LENGTH_LONG).show();
+    }
+
+    public void onProgressUpdate(int index) {
+    }
+
+    private void goToImportedAlbum() {
+        String pathOfImportedAlbum = "/local/all/" + MediaSetUtils.IMPORTED_BUCKET_ID;
+        Bundle data = new Bundle();
+        data.putString(AlbumPage.KEY_MEDIA_PATH, pathOfImportedAlbum);
+        mActivity.getStateManager().startState(AlbumPage.class, data);
+    }
+
+}
diff --git a/src/com/android/gallery3d/ui/Label.java b/src/com/android/gallery3d/ui/Label.java
new file mode 100644
index 0000000..6a70a18
--- /dev/null
+++ b/src/com/android/gallery3d/ui/Label.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+
+public class Label extends GLView {
+    private static final String TAG = "Label";
+    public static final int NULL_ID = 0;
+
+    private static final int FONT_SIZE = 18;
+    private static final int FONT_COLOR = Color.WHITE;
+
+    private String mText;
+    private StringTexture mTexture;
+    private int mFontSize, mFontColor;
+
+    public Label(Context context, int stringId,
+            int fontSize, int fontColor) {
+        this(context, context.getString(stringId), fontSize, fontColor);
+    }
+
+    public Label(Context context, int stringId) {
+        this(context, stringId, FONT_SIZE, FONT_COLOR);
+    }
+
+    public Label(Context context, String text) {
+        this(context, text, FONT_SIZE, FONT_COLOR);
+    }
+
+    public Label(Context context, String text, int fontSize, int fontColor) {
+        //TODO: cut the text if it is too long
+        mText = text;
+        mTexture = StringTexture.newInstance(text, fontSize, fontColor);
+        mFontSize = fontSize;
+        mFontColor = fontColor;
+    }
+
+    public void setText(String text) {
+        if (!mText.equals(text)) {
+            mText = text;
+            mTexture = StringTexture.newInstance(text, mFontSize, mFontColor);
+            requestLayout();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        int width = mTexture.getWidth();
+        int height = mTexture.getHeight();
+        MeasureHelper.getInstance(this)
+                .setPreferredContentSize(width, height)
+                .measure(widthSpec, heightSpec);
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        Rect p = mPaddings;
+
+        int width = getWidth() - p.left - p.right;
+        int height = getHeight() - p.top - p.bottom;
+
+        int xoffset = p.left + (width - mTexture.getWidth()) / 2;
+        int yoffset = p.top + (height - mTexture.getHeight()) / 2;
+
+        mTexture.draw(canvas, xoffset, yoffset);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/Log.java b/src/com/android/gallery3d/ui/Log.java
new file mode 100644
index 0000000..32adc98
--- /dev/null
+++ b/src/com/android/gallery3d/ui/Log.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+public class Log {
+    public static int v(String tag, String msg) {
+        return android.util.Log.v(tag, msg);
+    }
+    public static int v(String tag, String msg, Throwable tr) {
+        return android.util.Log.v(tag, msg, tr);
+    }
+    public static int d(String tag, String msg) {
+        return android.util.Log.d(tag, msg);
+    }
+    public static int d(String tag, String msg, Throwable tr) {
+        return android.util.Log.d(tag, msg, tr);
+    }
+    public static int i(String tag, String msg) {
+        return android.util.Log.i(tag, msg);
+    }
+    public static int i(String tag, String msg, Throwable tr) {
+        return android.util.Log.i(tag, msg, tr);
+    }
+    public static int w(String tag, String msg) {
+        return android.util.Log.w(tag, msg);
+    }
+    public static int w(String tag, String msg, Throwable tr) {
+        return android.util.Log.w(tag, msg, tr);
+    }
+    public static int w(String tag, Throwable tr) {
+        return android.util.Log.w(tag, tr);
+    }
+    public static int e(String tag, String msg) {
+        return android.util.Log.e(tag, msg);
+    }
+    public static int e(String tag, String msg, Throwable tr) {
+        return android.util.Log.e(tag, msg, tr);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/ManageCacheDrawer.java b/src/com/android/gallery3d/ui/ManageCacheDrawer.java
new file mode 100644
index 0000000..cf1e39e
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ManageCacheDrawer.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.Path;
+
+import android.content.Context;
+
+public class ManageCacheDrawer extends IconDrawer {
+    private static final int COLOR_CACHING_BACKGROUND = 0x7F000000;
+    private static final int ICON_SIZE = 36;
+    private final NinePatchTexture mFrame;
+    private final ResourceTexture mCheckedItem;
+    private final ResourceTexture mUnCheckedItem;
+    private final SelectionManager mSelectionManager;
+
+    private final ResourceTexture mLocalAlbumIcon;
+    private final StringTexture mCaching;
+
+    public ManageCacheDrawer(Context context, SelectionManager selectionManager) {
+        super(context);
+        mFrame = new NinePatchTexture(context, R.drawable.manage_frame);
+        mCheckedItem = new ResourceTexture(context, R.drawable.btn_make_offline_normal_on_holo_dark);
+        mUnCheckedItem = new ResourceTexture(context, R.drawable.btn_make_offline_normal_off_holo_dark);
+        mLocalAlbumIcon = new ResourceTexture(context, R.drawable.btn_make_offline_disabled_on_holo_dark);
+        String cachingLabel = context.getString(R.string.caching_label);
+        mCaching = StringTexture.newInstance(cachingLabel, 12, 0xffffffff);
+        mSelectionManager = selectionManager;
+    }
+
+    @Override
+    public void prepareDrawing() {
+    }
+
+    private static boolean isLocal(int dataSourceType) {
+        return dataSourceType != DATASOURCE_TYPE_PICASA;
+    }
+
+    @Override
+    public void draw(GLCanvas canvas, Texture content, int width, int height,
+            int rotation, Path path, int topIndex, int dataSourceType,
+            int mediaType, boolean wantCache, boolean isCaching) {
+
+        boolean selected = mSelectionManager.isItemSelected(path);
+        boolean chooseToCache = wantCache ^ selected;
+
+        int x = -width / 2;
+        int y = -height / 2;
+
+        drawWithRotationAndGray(canvas, content, x, y, width, height, rotation,
+                topIndex);
+
+        if (((rotation / 90) & 0x01) == 1) {
+            int temp = width;
+            width = height;
+            height = temp;
+            x = -width / 2;
+            y = -height / 2;
+        }
+
+        drawVideoOverlay(canvas, mediaType, x, y, width, height, topIndex);
+
+        drawFrame(canvas, mFrame, x, y, width, height);
+
+        if (topIndex == 0) {
+            drawIcon(canvas, width, height, dataSourceType);
+        }
+
+        if (topIndex == 0) {
+            ResourceTexture icon = null;
+            if (isLocal(dataSourceType)) {
+                icon = mLocalAlbumIcon;
+            } else if (chooseToCache) {
+                icon = mCheckedItem;
+            } else {
+                icon = mUnCheckedItem;
+            }
+
+            int w = ICON_SIZE;
+            int h = ICON_SIZE;
+            x = width / 2 - w / 2;
+            y = -height / 2 - h / 2;
+
+            icon.draw(canvas, x, y, w, h);
+
+            if (isCaching) {
+                int textWidth = mCaching.getWidth();
+                int textHeight = mCaching.getHeight();
+                x = -textWidth / 2;
+                y = height / 2 - textHeight;
+
+                // Leave a few pixels of margin in the background rect.
+                float sideMargin = Utils.clamp(textWidth * 0.1f, 2.0f,
+                        6.0f);
+                float clearance = Utils.clamp(textHeight * 0.1f, 2.0f,
+                        6.0f);
+
+                // Overlay the "Caching" wording at the bottom-center of the content.
+                canvas.fillRect(x - sideMargin, y - clearance,
+                        textWidth + sideMargin * 2, textHeight + clearance,
+                        COLOR_CACHING_BACKGROUND);
+                mCaching.draw(canvas, x, y);
+            }
+        }
+    }
+
+    @Override
+    public void drawFocus(GLCanvas canvas, int width, int height) {
+    }
+}
diff --git a/src/com/android/gallery3d/ui/MeasureHelper.java b/src/com/android/gallery3d/ui/MeasureHelper.java
new file mode 100644
index 0000000..f65dc10
--- /dev/null
+++ b/src/com/android/gallery3d/ui/MeasureHelper.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Rect;
+import android.view.View.MeasureSpec;
+
+class MeasureHelper {
+
+    private static MeasureHelper sInstance = new MeasureHelper(null);
+
+    private GLView mComponent;
+    private int mPreferredWidth;
+    private int mPreferredHeight;
+
+    private MeasureHelper(GLView component) {
+        mComponent = component;
+    }
+
+    public static MeasureHelper getInstance(GLView component) {
+        sInstance.mComponent = component;
+        return sInstance;
+    }
+
+    public MeasureHelper setPreferredContentSize(int width, int height) {
+        mPreferredWidth = width;
+        mPreferredHeight = height;
+        return this;
+    }
+
+    public void measure(int widthSpec, int heightSpec) {
+        Rect p = mComponent.getPaddings();
+        setMeasuredSize(
+                getLength(widthSpec, mPreferredWidth + p.left + p.right),
+                getLength(heightSpec, mPreferredHeight + p.top + p.bottom));
+    }
+
+    private static int getLength(int measureSpec, int prefered) {
+        int specLength = MeasureSpec.getSize(measureSpec);
+        switch(MeasureSpec.getMode(measureSpec)) {
+            case MeasureSpec.EXACTLY: return specLength;
+            case MeasureSpec.AT_MOST: return Math.min(prefered, specLength);
+            default: return prefered;
+        }
+    }
+
+    protected void setMeasuredSize(int width, int height) {
+        mComponent.setMeasuredSize(width, height);
+    }
+
+}
diff --git a/src/com/android/gallery3d/ui/MenuExecutor.java b/src/com/android/gallery3d/ui/MenuExecutor.java
new file mode 100644
index 0000000..710ddc4
--- /dev/null
+++ b/src/com/android/gallery3d/ui/MenuExecutor.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.CropImage;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.GalleryUtils;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+public class MenuExecutor {
+    @SuppressWarnings("unused")
+    private static final String TAG = "MenuExecutor";
+
+    private static final int MSG_TASK_COMPLETE = 1;
+    private static final int MSG_TASK_UPDATE = 2;
+    private static final int MSG_DO_SHARE = 3;
+
+    public static final int EXECUTION_RESULT_SUCCESS = 1;
+    public static final int EXECUTION_RESULT_FAIL = 2;
+    public static final int EXECUTION_RESULT_CANCEL = 3;
+
+    private ProgressDialog mDialog;
+    private Future<?> mTask;
+
+    private final GalleryActivity mActivity;
+    private final SelectionManager mSelectionManager;
+    private final Handler mHandler;
+
+    private static ProgressDialog showProgressDialog(
+            Context context, int titleId, int progressMax) {
+        ProgressDialog dialog = new ProgressDialog(context);
+        dialog.setTitle(titleId);
+        dialog.setMax(progressMax);
+        dialog.setCancelable(false);
+        dialog.setIndeterminate(false);
+        if (progressMax > 1) {
+            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+        }
+        dialog.show();
+        return dialog;
+    }
+
+    public interface ProgressListener {
+        public void onProgressUpdate(int index);
+        public void onProgressComplete(int result);
+    }
+
+    public MenuExecutor(
+            GalleryActivity activity, SelectionManager selectionManager) {
+        mActivity = Utils.checkNotNull(activity);
+        mSelectionManager = Utils.checkNotNull(selectionManager);
+        mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_TASK_COMPLETE: {
+                        if (mDialog != null) {
+                            mDialog.dismiss();
+                            mDialog = null;
+                            mTask = null;
+                        }
+                        if (message.obj != null) {
+                            ProgressListener listener = (ProgressListener) message.obj;
+                            listener.onProgressComplete(message.arg1);
+                        }
+                        mSelectionManager.leaveSelectionMode();
+                        break;
+                    }
+                    case MSG_TASK_UPDATE: {
+                        if (mDialog != null) mDialog.setProgress(message.arg1);
+                        if (message.obj != null) {
+                            ProgressListener listener = (ProgressListener) message.obj;
+                            listener.onProgressUpdate(message.arg1);
+                        }
+                        break;
+                    }
+                    case MSG_DO_SHARE: {
+                        ((Activity) mActivity).startActivity((Intent) message.obj);
+                        break;
+                    }
+                }
+            }
+        };
+    }
+
+    public void pause() {
+        if (mTask != null) {
+            mTask.cancel();
+            mTask.waitDone();
+            mDialog.dismiss();
+            mDialog = null;
+            mTask = null;
+        }
+    }
+
+    private void onProgressUpdate(int index, ProgressListener listener) {
+        mHandler.sendMessage(
+                mHandler.obtainMessage(MSG_TASK_UPDATE, index, 0, listener));
+    }
+
+    private void onProgressComplete(int result, ProgressListener listener) {
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_TASK_COMPLETE, result, 0, listener));
+    }
+
+    private int getShareType(SelectionManager selectionManager) {
+        ArrayList<Path> items = selectionManager.getSelected(false);
+        int type = 0;
+        DataManager dataManager = mActivity.getDataManager();
+        for (Path id : items) {
+            type |= dataManager.getMediaType(id);
+        }
+        return type;
+    }
+
+    private void onShareItemClicked(final SelectionManager selectionManager,
+            final String mimeType, final ComponentName component) {
+        Utils.assertTrue(mDialog == null);
+        final ArrayList<Path> items = selectionManager.getSelected(true);
+        mDialog = showProgressDialog((Activity) mActivity,
+                R.string.loading_image, items.size());
+
+        mTask = mActivity.getThreadPool().submit(new Job<Void>() {
+            @Override
+            public Void run(JobContext jc) {
+                DataManager manager = mActivity.getDataManager();
+                ArrayList<Uri> uris = new ArrayList<Uri>(items.size());
+                int index = 0;
+                for (Path path : items) {
+                    if ((manager.getSupportedOperations(path)
+                            & MediaObject.SUPPORT_SHARE) != 0) {
+                        uris.add(manager.getContentUri(path));
+                    }
+                    onProgressUpdate(++index, null);
+                }
+                if (jc.isCancelled()) return null;
+                Intent intent = new Intent()
+                        .setComponent(component).setType(mimeType);
+                if (uris.isEmpty()) {
+                    return null;
+                } else if (uris.size() == 1) {
+                    intent.setAction(Intent.ACTION_SEND);
+                    intent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
+                } else {
+                    intent.setAction(Intent.ACTION_SEND_MULTIPLE);
+                    intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
+                }
+                onProgressComplete(EXECUTION_RESULT_SUCCESS, null);
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_DO_SHARE, intent));
+                return null;
+            }
+        }, null);
+    }
+
+    private static void setMenuItemVisibility(
+            Menu menu, int id, boolean visibility) {
+        MenuItem item = menu.findItem(id);
+        if (item != null) item.setVisible(visibility);
+    }
+
+    public static void updateMenuOperation(Menu menu, int supported) {
+        boolean supportDelete = (supported & MediaObject.SUPPORT_DELETE) != 0;
+        boolean supportRotate = (supported & MediaObject.SUPPORT_ROTATE) != 0;
+        boolean supportCrop = (supported & MediaObject.SUPPORT_CROP) != 0;
+        boolean supportShare = (supported & MediaObject.SUPPORT_SHARE) != 0;
+        boolean supportSetAs = (supported & MediaObject.SUPPORT_SETAS) != 0;
+        boolean supportShowOnMap = (supported & MediaObject.SUPPORT_SHOW_ON_MAP) != 0;
+        boolean supportCache = (supported & MediaObject.SUPPORT_CACHE) != 0;
+        boolean supportEdit = (supported & MediaObject.SUPPORT_EDIT) != 0;
+        boolean supportInfo = (supported & MediaObject.SUPPORT_INFO) != 0;
+        boolean supportImport = (supported & MediaObject.SUPPORT_IMPORT) != 0;
+
+        setMenuItemVisibility(menu, R.id.action_delete, supportDelete);
+        setMenuItemVisibility(menu, R.id.action_rotate_ccw, supportRotate);
+        setMenuItemVisibility(menu, R.id.action_rotate_cw, supportRotate);
+        setMenuItemVisibility(menu, R.id.action_crop, supportCrop);
+        setMenuItemVisibility(menu, R.id.action_share, supportShare);
+        setMenuItemVisibility(menu, R.id.action_setas, supportSetAs);
+        setMenuItemVisibility(menu, R.id.action_show_on_map, supportShowOnMap);
+        setMenuItemVisibility(menu, R.id.action_edit, supportEdit);
+        setMenuItemVisibility(menu, R.id.action_details, supportInfo);
+        setMenuItemVisibility(menu, R.id.action_import, supportImport);
+    }
+
+    private Path getSingleSelectedPath() {
+        ArrayList<Path> ids = mSelectionManager.getSelected(true);
+        Utils.assertTrue(ids.size() == 1);
+        return ids.get(0);
+    }
+
+    public boolean onMenuClicked(MenuItem menuItem, ProgressListener listener) {
+        int title;
+        DataManager manager = mActivity.getDataManager();
+        int action = menuItem.getItemId();
+        switch (action) {
+            case R.id.action_select_all:
+                if (mSelectionManager.inSelectAllMode()) {
+                    mSelectionManager.deSelectAll();
+                } else {
+                    mSelectionManager.selectAll();
+                }
+                return true;
+            case R.id.action_crop: {
+                Path path = getSingleSelectedPath();
+                String mimeType = getMimeType(manager.getMediaType(path));
+                Intent intent = new Intent(CropImage.ACTION_CROP)
+                        .setDataAndType(manager.getContentUri(path), mimeType);
+                ((Activity) mActivity).startActivity(intent);
+                return true;
+            }
+            case R.id.action_setas: {
+                Path path = getSingleSelectedPath();
+                int type = manager.getMediaType(path);
+                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
+                String mimeType = getMimeType(type);
+                intent.setDataAndType(manager.getContentUri(path), mimeType);
+                intent.putExtra("mimeType", mimeType);
+                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                Activity activity = (Activity) mActivity;
+                activity.startActivity(Intent.createChooser(
+                        intent, activity.getString(R.string.set_as)));
+                return true;
+            }
+            case R.id.action_confirm_delete:
+                title = R.string.delete;
+                break;
+            case R.id.action_rotate_cw:
+                title = R.string.rotate_right;
+                break;
+            case R.id.action_rotate_ccw:
+                title = R.string.rotate_left;
+                break;
+            case R.id.action_show_on_map:
+                title = R.string.show_on_map;
+                break;
+            case R.id.action_edit:
+                title = R.string.edit;
+                break;
+            case R.id.action_import:
+                title = R.string.Import;
+                break;
+            default:
+                return false;
+        }
+        startAction(action, title, listener);
+        return true;
+    }
+
+    public void startAction(int action, int title, ProgressListener listener) {
+        ArrayList<Path> ids = mSelectionManager.getSelected(false);
+        Utils.assertTrue(mDialog == null);
+
+        Activity activity = (Activity) mActivity;
+        mDialog = showProgressDialog(activity, title, ids.size());
+        MediaOperation operation = new MediaOperation(action, ids, listener);
+        mTask = mActivity.getThreadPool().submit(operation, null);
+    }
+
+    public static String getMimeType(int type) {
+        switch (type) {
+            case MediaObject.MEDIA_TYPE_IMAGE :
+                return "image/*";
+            case MediaObject.MEDIA_TYPE_VIDEO :
+                return "video/*";
+            default: return "*/*";
+        }
+    }
+
+    private boolean execute(
+            DataManager manager, JobContext jc, int cmd, Path path) {
+        boolean result = true;
+        switch (cmd) {
+            case R.id.action_confirm_delete:
+                manager.delete(path);
+                break;
+            case R.id.action_rotate_cw:
+                manager.rotate(path, 90);
+                break;
+            case R.id.action_rotate_ccw:
+                manager.rotate(path, -90);
+                break;
+            case R.id.action_toggle_full_caching: {
+                MediaObject obj = manager.getMediaObject(path);
+                int cacheFlag = obj.getCacheFlag();
+                if (cacheFlag == MediaObject.CACHE_FLAG_FULL) {
+                    cacheFlag = MediaObject.CACHE_FLAG_SCREENNAIL;
+                } else {
+                    cacheFlag = MediaObject.CACHE_FLAG_FULL;
+                }
+                obj.cache(cacheFlag);
+                break;
+            }
+            case R.id.action_show_on_map: {
+                MediaItem item = (MediaItem) manager.getMediaObject(path);
+                double latlng[] = new double[2];
+                item.getLatLong(latlng);
+                if (GalleryUtils.isValidLocation(latlng[0], latlng[1])) {
+                    GalleryUtils.showOnMap((Context) mActivity, latlng[0], latlng[1]);
+                }
+                break;
+            }
+            case R.id.action_import: {
+                MediaObject obj = manager.getMediaObject(path);
+                result = obj.Import();
+                break;
+            }
+            case R.id.action_edit: {
+                Activity activity = (Activity) mActivity;
+                MediaItem item = (MediaItem) manager.getMediaObject(path);
+                try {
+                    activity.startActivity(Intent.createChooser(
+                            new Intent(Intent.ACTION_EDIT)
+                                    .setData(item.getContentUri())
+                                    .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION),
+                            null));
+                } catch (Throwable t) {
+                    Log.w(TAG, "failed to start edit activity: ", t);
+                    Toast.makeText(activity,
+                            activity.getString(R.string.activity_not_found),
+                            Toast.LENGTH_SHORT).show();
+                }
+                break;
+            }
+            default:
+                throw new AssertionError();
+        }
+        return result;
+    }
+
+    private class MediaOperation implements Job<Void> {
+        private final ArrayList<Path> mItems;
+        private final int mOperation;
+        private final ProgressListener mListener;
+
+        public MediaOperation(int operation, ArrayList<Path> items, ProgressListener listener) {
+            mOperation = operation;
+            mItems = items;
+            mListener = listener;
+        }
+
+        public Void run(JobContext jc) {
+            int index = 0;
+            DataManager manager = mActivity.getDataManager();
+            int result = EXECUTION_RESULT_SUCCESS;
+            for (Path id : mItems) {
+                if (jc.isCancelled()) {
+                    result = EXECUTION_RESULT_CANCEL;
+                    break;
+                }
+                try {
+                    if (!execute(manager, jc, mOperation, id)) result = EXECUTION_RESULT_FAIL;
+                } catch (Throwable th) {
+                    Log.e(TAG, "failed to execute operation " + mOperation
+                            + " for " + id, th);
+                }
+                onProgressUpdate(index++, mListener);
+            }
+            onProgressComplete(result, mListener);
+            return null;
+        }
+    }
+}
+
diff --git a/src/com/android/gallery3d/ui/MultiLineTexture.java b/src/com/android/gallery3d/ui/MultiLineTexture.java
new file mode 100644
index 0000000..be62d59
--- /dev/null
+++ b/src/com/android/gallery3d/ui/MultiLineTexture.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.text.Layout;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+
+// MultiLineTexture is a texture shows the content of a specified String.
+//
+// To create a MultiLineTexture, use the newInstance() method and specify
+// the String, the font size, and the color.
+class MultiLineTexture extends CanvasTexture {
+    private final Layout mLayout;
+
+    private MultiLineTexture(Layout layout) {
+        super(layout.getWidth(), layout.getHeight());
+        mLayout = layout;
+    }
+
+    public static MultiLineTexture newInstance(
+            String text, int maxWidth, float textSize, int color) {
+        TextPaint paint = StringTexture.getDefaultPaint(textSize, color);
+        Layout layout = new StaticLayout(text, 0, text.length(), paint,
+                maxWidth, Layout.Alignment.ALIGN_NORMAL, 1, 0, true, null, 0);
+
+        return new MultiLineTexture(layout);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas, Bitmap backing) {
+        mLayout.draw(canvas);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/NinePatchChunk.java b/src/com/android/gallery3d/ui/NinePatchChunk.java
new file mode 100644
index 0000000..61bf22c
--- /dev/null
+++ b/src/com/android/gallery3d/ui/NinePatchChunk.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Rect;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+// See "frameworks/base/include/utils/ResourceTypes.h" for the format of
+// NinePatch chunk.
+class NinePatchChunk {
+
+    public static final int NO_COLOR = 0x00000001;
+    public static final int TRANSPARENT_COLOR = 0x00000000;
+
+    public Rect mPaddings = new Rect();
+
+    public int mDivX[];
+    public int mDivY[];
+    public int mColor[];
+
+    private static void readIntArray(int[] data, ByteBuffer buffer) {
+        for (int i = 0, n = data.length; i < n; ++i) {
+            data[i] = buffer.getInt();
+        }
+    }
+
+    private static void checkDivCount(int length) {
+        if (length == 0 || (length & 0x01) != 0) {
+            throw new RuntimeException("invalid nine-patch: " + length);
+        }
+    }
+
+    public static NinePatchChunk deserialize(byte[] data) {
+        ByteBuffer byteBuffer =
+                ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
+
+        byte wasSerialized = byteBuffer.get();
+        if (wasSerialized == 0) return null;
+
+        NinePatchChunk chunk = new NinePatchChunk();
+        chunk.mDivX = new int[byteBuffer.get()];
+        chunk.mDivY = new int[byteBuffer.get()];
+        chunk.mColor = new int[byteBuffer.get()];
+
+        checkDivCount(chunk.mDivX.length);
+        checkDivCount(chunk.mDivY.length);
+
+        // skip 8 bytes
+        byteBuffer.getInt();
+        byteBuffer.getInt();
+
+        chunk.mPaddings.left = byteBuffer.getInt();
+        chunk.mPaddings.right = byteBuffer.getInt();
+        chunk.mPaddings.top = byteBuffer.getInt();
+        chunk.mPaddings.bottom = byteBuffer.getInt();
+
+        // skip 4 bytes
+        byteBuffer.getInt();
+
+        readIntArray(chunk.mDivX, byteBuffer);
+        readIntArray(chunk.mDivY, byteBuffer);
+        readIntArray(chunk.mColor, byteBuffer);
+
+        return chunk;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/ui/NinePatchTexture.java b/src/com/android/gallery3d/ui/NinePatchTexture.java
new file mode 100644
index 0000000..15b057a
--- /dev/null
+++ b/src/com/android/gallery3d/ui/NinePatchTexture.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Rect;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.microedition.khronos.opengles.GL11;
+
+// NinePatchTexture is a texture backed by a NinePatch resource.
+//
+// getPaddings() returns paddings specified in the NinePatch.
+// getNinePatchChunk() returns the layout data specified in the NinePatch.
+//
+public class NinePatchTexture extends ResourceTexture {
+    @SuppressWarnings("unused")
+    private static final String TAG = "NinePatchTexture";
+    private NinePatchChunk mChunk;
+    private MyCacheMap<Long, NinePatchInstance> mInstanceCache =
+            new MyCacheMap<Long, NinePatchInstance>();
+
+    public NinePatchTexture(Context context, int resId) {
+        super(context, resId);
+    }
+
+    @Override
+    protected Bitmap onGetBitmap() {
+        if (mBitmap != null) return mBitmap;
+
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        Bitmap bitmap = BitmapFactory.decodeResource(
+                mContext.getResources(), mResId, options);
+        mBitmap = bitmap;
+        setSize(bitmap.getWidth(), bitmap.getHeight());
+        byte[] chunkData = bitmap.getNinePatchChunk();
+        mChunk = chunkData == null
+                ? null
+                : NinePatchChunk.deserialize(bitmap.getNinePatchChunk());
+        if (mChunk == null) {
+            throw new RuntimeException("invalid nine-patch image: " + mResId);
+        }
+        return bitmap;
+    }
+
+    public Rect getPaddings() {
+        // get the paddings from nine patch
+        if (mChunk == null) onGetBitmap();
+        return mChunk.mPaddings;
+    }
+
+    public NinePatchChunk getNinePatchChunk() {
+        if (mChunk == null) onGetBitmap();
+        return mChunk;
+    }
+
+    private static class MyCacheMap<K, V> extends LinkedHashMap<K, V> {
+        private int CACHE_SIZE = 16;
+        private V mJustRemoved;
+
+        public MyCacheMap() {
+            super(4, 0.75f, true);
+        }
+
+        @Override
+        protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+            if (size() > CACHE_SIZE) {
+                mJustRemoved = eldest.getValue();
+                return true;
+            }
+            return false;
+        }
+
+        public V getJustRemoved() {
+            V result = mJustRemoved;
+            mJustRemoved = null;
+            return result;
+        }
+    }
+
+    private NinePatchInstance findInstance(GLCanvas canvas, int w, int h) {
+        long key = w;
+        key = (key << 32) | h;
+        NinePatchInstance instance = mInstanceCache.get(key);
+
+        if (instance == null) {
+            instance = new NinePatchInstance(this, w, h);
+            mInstanceCache.put(key, instance);
+            NinePatchInstance removed = mInstanceCache.getJustRemoved();
+            if (removed != null) {
+                removed.recycle(canvas);
+            }
+        }
+
+        return instance;
+    }
+
+    @Override
+    public void draw(GLCanvas canvas, int x, int y, int w, int h) {
+        if (!isLoaded(canvas)) {
+            mInstanceCache.clear();
+        }
+
+        if (w != 0 && h != 0) {
+            findInstance(canvas, w, h).draw(canvas, this, x, y);
+        }
+    }
+
+    @Override
+    public void recycle() {
+        super.recycle();
+        GLCanvas canvas = mCanvasRef == null ? null : mCanvasRef.get();
+        if (canvas == null) return;
+        for (NinePatchInstance instance : mInstanceCache.values()) {
+            instance.recycle(canvas);
+        }
+        mInstanceCache.clear();
+    }
+}
+
+// This keeps data for a specialization of NinePatchTexture with the size
+// (width, height). We pre-compute the coordinates for efficiency.
+class NinePatchInstance {
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "NinePatchInstance";
+
+    // We need 16 vertices for a normal nine-patch image (the 4x4 vertices)
+    private static final int VERTEX_BUFFER_SIZE = 16 * 2;
+
+    // We need 22 indices for a normal nine-patch image, plus 2 for each
+    // transparent region. Current there are at most 1 transparent region.
+    private static final int INDEX_BUFFER_SIZE = 22 + 2;
+
+    private FloatBuffer mXyBuffer;
+    private FloatBuffer mUvBuffer;
+    private ByteBuffer mIndexBuffer;
+
+    // Names for buffer names: xy, uv, index.
+    private int[] mBufferNames;
+
+    private int mIdxCount;
+
+    public NinePatchInstance(NinePatchTexture tex, int width, int height) {
+        NinePatchChunk chunk = tex.getNinePatchChunk();
+
+        if (width <= 0 || height <= 0) {
+            throw new RuntimeException("invalid dimension");
+        }
+
+        // The code should be easily extended to handle the general cases by
+        // allocating more space for buffers. But let's just handle the only
+        // use case.
+        if (chunk.mDivX.length != 2 || chunk.mDivY.length != 2) {
+            throw new RuntimeException("unsupported nine patch");
+        }
+
+        float divX[] = new float[4];
+        float divY[] = new float[4];
+        float divU[] = new float[4];
+        float divV[] = new float[4];
+
+        int nx = stretch(divX, divU, chunk.mDivX, tex.getWidth(), width);
+        int ny = stretch(divY, divV, chunk.mDivY, tex.getHeight(), height);
+
+        prepareVertexData(divX, divY, divU, divV, nx, ny, chunk.mColor);
+    }
+
+    /**
+     * Stretches the texture according to the nine-patch rules. It will
+     * linearly distribute the strechy parts defined in the nine-patch chunk to
+     * the target area.
+     *
+     * <pre>
+     *                      source
+     *          /--------------^---------------\
+     *         u0    u1       u2  u3     u4   u5
+     * div ---> |fffff|ssssssss|fff|ssssss|ffff| ---> u
+     *          |    div0    div1 div2   div3  |
+     *          |     |       /   /      /    /
+     *          |     |      /   /     /    /
+     *          |     |     /   /    /    /
+     *          |fffff|ssss|fff|sss|ffff| ---> x
+     *         x0    x1   x2  x3  x4   x5
+     *          \----------v------------/
+     *                  target
+     *
+     * f: fixed segment
+     * s: stretchy segment
+     * </pre>
+     *
+     * @param div the stretch parts defined in nine-patch chunk
+     * @param source the length of the texture
+     * @param target the length on the drawing plan
+     * @param u output, the positions of these dividers in the texture
+     *        coordinate
+     * @param x output, the corresponding position of these dividers on the
+     *        drawing plan
+     * @return the number of these dividers.
+     */
+    private static int stretch(
+            float x[], float u[], int div[], int source, int target) {
+        int textureSize = Utils.nextPowerOf2(source);
+        float textureBound = (float) source / textureSize;
+
+        float stretch = 0;
+        for (int i = 0, n = div.length; i < n; i += 2) {
+            stretch += div[i + 1] - div[i];
+        }
+
+        float remaining = target - source + stretch;
+
+        float lastX = 0;
+        float lastU = 0;
+
+        x[0] = 0;
+        u[0] = 0;
+        for (int i = 0, n = div.length; i < n; i += 2) {
+            // Make the stretchy segment a little smaller to prevent sampling
+            // on neighboring fixed segments.
+            // fixed segment
+            x[i + 1] = lastX + (div[i] - lastU) + 0.5f;
+            u[i + 1] = Math.min((div[i] + 0.5f) / textureSize, textureBound);
+
+            // stretchy segment
+            float partU = div[i + 1] - div[i];
+            float partX = remaining * partU / stretch;
+            remaining -= partX;
+            stretch -= partU;
+
+            lastX = x[i + 1] + partX;
+            lastU = div[i + 1];
+            x[i + 2] = lastX - 0.5f;
+            u[i + 2] = Math.min((lastU - 0.5f)/ textureSize, textureBound);
+        }
+        // the last fixed segment
+        x[div.length + 1] = target;
+        u[div.length + 1] = textureBound;
+
+        // remove segments with length 0.
+        int last = 0;
+        for (int i = 1, n = div.length + 2; i < n; ++i) {
+            if ((x[i] - x[last]) < 1f) continue;
+            x[++last] = x[i];
+            u[last] = u[i];
+        }
+        return last + 1;
+    }
+
+    private void prepareVertexData(float x[], float y[], float u[], float v[],
+            int nx, int ny, int[] color) {
+        /*
+         * Given a 3x3 nine-patch image, the vertex order is defined as the
+         * following graph:
+         *
+         * (0) (1) (2) (3)
+         *  |  /|  /|  /|
+         *  | / | / | / |
+         * (4) (5) (6) (7)
+         *  | \ | \ | \ |
+         *  |  \|  \|  \|
+         * (8) (9) (A) (B)
+         *  |  /|  /|  /|
+         *  | / | / | / |
+         * (C) (D) (E) (F)
+         *
+         * And we draw the triangle strip in the following index order:
+         *
+         * index: 04152637B6A5948C9DAEBF
+         */
+        int pntCount = 0;
+        float xy[] = new float[VERTEX_BUFFER_SIZE];
+        float uv[] = new float[VERTEX_BUFFER_SIZE];
+        for (int j = 0; j < ny; ++j) {
+            for (int i = 0; i < nx; ++i) {
+                int xIndex = (pntCount++) << 1;
+                int yIndex = xIndex + 1;
+                xy[xIndex] = x[i];
+                xy[yIndex] = y[j];
+                uv[xIndex] = u[i];
+                uv[yIndex] = v[j];
+            }
+        }
+
+        int idxCount = 1;
+        boolean isForward = false;
+        byte index[] = new byte[INDEX_BUFFER_SIZE];
+        for (int row = 0; row < ny - 1; row++) {
+            --idxCount;
+            isForward = !isForward;
+
+            int start, end, inc;
+            if (isForward) {
+                start = 0;
+                end = nx;
+                inc = 1;
+            } else {
+                start = nx - 1;
+                end = -1;
+                inc = -1;
+            }
+
+            for (int col = start; col != end; col += inc) {
+                int k = row * nx + col;
+                if (col != start) {
+                    int colorIdx = row * (nx - 1) + col;
+                    if (isForward) colorIdx--;
+                    if (color[colorIdx] == NinePatchChunk.TRANSPARENT_COLOR) {
+                        index[idxCount] = index[idxCount - 1];
+                        ++idxCount;
+                        index[idxCount++] = (byte) k;
+                    }
+                }
+
+                index[idxCount++] = (byte) k;
+                index[idxCount++] = (byte) (k + nx);
+            }
+        }
+
+        mIdxCount = idxCount;
+
+        int size = (pntCount * 2) * (Float.SIZE / Byte.SIZE);
+        mXyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
+        mUvBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
+        mIndexBuffer = allocateDirectNativeOrderBuffer(mIdxCount);
+
+        mXyBuffer.put(xy, 0, pntCount * 2).position(0);
+        mUvBuffer.put(uv, 0, pntCount * 2).position(0);
+        mIndexBuffer.put(index, 0, idxCount).position(0);
+    }
+
+    private static ByteBuffer allocateDirectNativeOrderBuffer(int size) {
+        return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
+    }
+
+    private void prepareBuffers(GLCanvas canvas) {
+        mBufferNames = new int[3];
+        GL11 gl = canvas.getGLInstance();
+        gl.glGenBuffers(3, mBufferNames, 0);
+
+        gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBufferNames[0]);
+        gl.glBufferData(GL11.GL_ARRAY_BUFFER,
+                mXyBuffer.capacity() * (Float.SIZE / Byte.SIZE),
+                mXyBuffer, GL11.GL_STATIC_DRAW);
+
+        gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBufferNames[1]);
+        gl.glBufferData(GL11.GL_ARRAY_BUFFER,
+                mUvBuffer.capacity() * (Float.SIZE / Byte.SIZE),
+                mUvBuffer, GL11.GL_STATIC_DRAW);
+
+        gl.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mBufferNames[2]);
+        gl.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER,
+                mIndexBuffer.capacity(),
+                mIndexBuffer, GL11.GL_STATIC_DRAW);
+
+        // These buffers are never used again.
+        mXyBuffer = null;
+        mUvBuffer = null;
+        mIndexBuffer = null;
+    }
+
+    public void draw(GLCanvas canvas, NinePatchTexture tex, int x, int y) {
+        if (mBufferNames == null) {
+            prepareBuffers(canvas);
+        }
+        canvas.drawMesh(tex, x, y, mBufferNames[0], mBufferNames[1],
+                mBufferNames[2], mIdxCount);
+    }
+
+    public void recycle(GLCanvas canvas) {
+        if (mBufferNames != null) {
+            canvas.deleteBuffer(mBufferNames[0]);
+            canvas.deleteBuffer(mBufferNames[1]);
+            canvas.deleteBuffer(mBufferNames[2]);
+            mBufferNames = null;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/OnSelectedListener.java b/src/com/android/gallery3d/ui/OnSelectedListener.java
new file mode 100644
index 0000000..2cc5809
--- /dev/null
+++ b/src/com/android/gallery3d/ui/OnSelectedListener.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+public interface OnSelectedListener {
+    public void onSelected(GLView source);
+}
diff --git a/src/com/android/gallery3d/ui/Paper.java b/src/com/android/gallery3d/ui/Paper.java
new file mode 100644
index 0000000..641fc2c
--- /dev/null
+++ b/src/com/android/gallery3d/ui/Paper.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.ui.PositionRepository.Position;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.opengl.Matrix;
+
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+// This class does the overscroll effect.
+class Paper {
+    private static final String TAG = "Paper";
+    private static final int ROTATE_FACTOR = 4;
+    private OverscrollAnimation mAnimationLeft = new OverscrollAnimation();
+    private OverscrollAnimation mAnimationRight = new OverscrollAnimation();
+    private int mWidth, mHeight;
+    private float[] mMatrix = new float[16];
+
+    public void overScroll(float distance) {
+        if (distance < 0) {
+            mAnimationLeft.scroll(-distance);
+        } else {
+            mAnimationRight.scroll(distance);
+        }
+    }
+
+    public boolean advanceAnimation(long currentTimeMillis) {
+        return mAnimationLeft.advanceAnimation(currentTimeMillis)
+            | mAnimationRight.advanceAnimation(currentTimeMillis);
+    }
+
+    public void setSize(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+    }
+
+    public float[] getTransform(Position target, Position base,
+            float scrollX, float scrollY) {
+        float left = mAnimationLeft.getValue();
+        float right = mAnimationRight.getValue();
+        float screenX = target.x - scrollX;
+        float t = ((mWidth - screenX) * left - screenX * right) / (mWidth * mWidth);
+        // compress t to the range (-1, 1) by the function
+        // f(t) = (1 / (1 + e^-t) - 0.5) * 2
+        // then multiply by 90 to make the range (-45, 45)
+        float degrees =
+                (1 / (1 + (float) Math.exp(-t * ROTATE_FACTOR)) - 0.5f) * 2 * -45;
+        Matrix.setIdentityM(mMatrix, 0);
+        Matrix.translateM(mMatrix, 0, mMatrix, 0, base.x, base.y, base.z);
+        Matrix.rotateM(mMatrix, 0, degrees, 0, 1, 0);
+        Matrix.translateM(mMatrix, 0, mMatrix, 0,
+                target.x - base.x, target.y - base.y, target.z - base.z);
+        return mMatrix;
+    }
+}
+
+class OverscrollAnimation {
+    private static final String TAG = "OverscrollAnimation";
+    private static final long START_ANIMATION = -1;
+    private static final long NO_ANIMATION = -2;
+    private static final long ANIMATION_DURATION = 500;
+
+    private long mAnimationStartTime = NO_ANIMATION;
+    private float mVelocity;
+    private float mCurrentValue;
+
+    public void scroll(float distance) {
+        mAnimationStartTime = START_ANIMATION;
+        mCurrentValue += distance;
+    }
+
+    public boolean advanceAnimation(long currentTimeMillis) {
+        if (mAnimationStartTime == NO_ANIMATION) return false;
+        if (mAnimationStartTime == START_ANIMATION) {
+            mAnimationStartTime = currentTimeMillis;
+            return true;
+        }
+
+        long deltaTime = currentTimeMillis - mAnimationStartTime;
+        float t = deltaTime / 100f;
+        mCurrentValue *= Math.pow(0.5f, t);
+        mAnimationStartTime = currentTimeMillis;
+
+        if (mCurrentValue < 1) {
+            mAnimationStartTime = NO_ANIMATION;
+            mCurrentValue = 0;
+            return false;
+        }
+        return true;
+    }
+
+    public float getValue() {
+        return mCurrentValue;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java
new file mode 100644
index 0000000..aba572b
--- /dev/null
+++ b/src/com/android/gallery3d/ui/PhotoView.java
@@ -0,0 +1,1191 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.ui.PositionRepository.Position;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.RectF;
+import android.os.Message;
+import android.os.SystemClock;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+
+public class PhotoView extends GLView {
+    @SuppressWarnings("unused")
+    private static final String TAG = "PhotoView";
+
+    public static final int INVALID_SIZE = -1;
+
+    private static final int MSG_TRANSITION_COMPLETE = 1;
+    private static final int MSG_SHOW_LOADING = 2;
+
+    private static final long DELAY_SHOW_LOADING = 250; // 250ms;
+
+    private static final int TRANS_NONE = 0;
+    private static final int TRANS_SWITCH_NEXT = 3;
+    private static final int TRANS_SWITCH_PREVIOUS = 4;
+
+    public static final int TRANS_SLIDE_IN_RIGHT = 1;
+    public static final int TRANS_SLIDE_IN_LEFT = 2;
+    public static final int TRANS_OPEN_ANIMATION = 5;
+
+    private static final int LOADING_INIT = 0;
+    private static final int LOADING_TIMEOUT = 1;
+    private static final int LOADING_COMPLETE = 2;
+    private static final int LOADING_FAIL = 3;
+
+    private static final int ENTRY_PREVIOUS = 0;
+    private static final int ENTRY_NEXT = 1;
+
+    private static final int IMAGE_GAP = 96;
+    private static final int SWITCH_THRESHOLD = 256;
+    private static final float SWIPE_THRESHOLD = 300f;
+
+    private static final float DEFAULT_TEXT_SIZE = 20;
+
+    // We try to scale up the image to fill the screen. But in order not to
+    // scale too much for small icons, we limit the max up-scaling factor here.
+    private static final float SCALE_LIMIT = 4;
+
+    public interface PhotoTapListener {
+        public void onSingleTapUp(int x, int y);
+    }
+
+    // the previous/next image entries
+    private final ScreenNailEntry mScreenNails[] = new ScreenNailEntry[2];
+
+    private final ScaleGestureDetector mScaleDetector;
+    private final GestureDetector mGestureDetector;
+    private final DownUpDetector mDownUpDetector;
+
+    private PhotoTapListener mPhotoTapListener;
+
+    private final PositionController mPositionController;
+
+    private Model mModel;
+    private StringTexture mLoadingText;
+    private StringTexture mNoThumbnailText;
+    private int mTransitionMode = TRANS_NONE;
+    private final TileImageView mTileView;
+    private Texture mVideoPlayIcon;
+
+    private boolean mShowVideoPlayIcon;
+    private ProgressSpinner mLoadingSpinner;
+
+    private SynchronizedHandler mHandler;
+
+    private int mLoadingState = LOADING_COMPLETE;
+
+    private RectF mTempRect = new RectF();
+    private float[] mTempPoints = new float[8];
+
+    private int mImageRotation;
+
+    private Path mOpenedItemPath;
+    private GalleryActivity mActivity;
+
+    public PhotoView(GalleryActivity activity) {
+        mActivity = activity;
+        mTileView = new TileImageView(activity);
+        addComponent(mTileView);
+        Context context = activity.getAndroidContext();
+        mLoadingSpinner = new ProgressSpinner(context);
+        mLoadingText = StringTexture.newInstance(
+                context.getString(R.string.loading),
+                DEFAULT_TEXT_SIZE, Color.WHITE);
+        mNoThumbnailText = StringTexture.newInstance(
+                context.getString(R.string.no_thumbnail),
+                DEFAULT_TEXT_SIZE, Color.WHITE);
+
+        mHandler = new SynchronizedHandler(activity.getGLRoot()) {
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_TRANSITION_COMPLETE: {
+                        onTransitionComplete();
+                        break;
+                    }
+                    case MSG_SHOW_LOADING: {
+                        if (mLoadingState == LOADING_INIT) {
+                            // We don't need the opening animation
+                            mOpenedItemPath = null;
+
+                            mLoadingSpinner.startAnimation();
+                            mLoadingState = LOADING_TIMEOUT;
+                            invalidate();
+                        }
+                        break;
+                    }
+                    default: throw new AssertionError(message.what);
+                }
+            }
+        };
+
+        mGestureDetector = new GestureDetector(context,
+                new MyGestureListener(), null, true /* ignoreMultitouch */);
+        mScaleDetector = new ScaleGestureDetector(context, new MyScaleListener());
+        mDownUpDetector = new DownUpDetector(new MyDownUpListener());
+
+        for (int i = 0, n = mScreenNails.length; i < n; ++i) {
+            mScreenNails[i] = new ScreenNailEntry();
+        }
+
+        mPositionController = new PositionController(this);
+        mVideoPlayIcon = new ResourceTexture(context, R.drawable.ic_control_play);
+    }
+
+
+    public void setModel(Model model) {
+        if (mModel == model) return;
+        mModel = model;
+        mTileView.setModel(model);
+        if (model != null) notifyOnNewImage();
+    }
+
+    public void setPhotoTapListener(PhotoTapListener listener) {
+        mPhotoTapListener = listener;
+    }
+
+    private boolean setTileViewPosition(int centerX, int centerY, float scale) {
+        int inverseX = mPositionController.mImageW - centerX;
+        int inverseY = mPositionController.mImageH - centerY;
+        TileImageView t = mTileView;
+        int rotation = mImageRotation;
+        switch (rotation) {
+            case 0: return t.setPosition(centerX, centerY, scale, 0);
+            case 90: return t.setPosition(centerY, inverseX, scale, 90);
+            case 180: return t.setPosition(inverseX, inverseY, scale, 180);
+            case 270: return t.setPosition(inverseY, centerX, scale, 270);
+            default: throw new IllegalArgumentException(String.valueOf(rotation));
+        }
+    }
+
+    public void setPosition(int centerX, int centerY, float scale) {
+        if (setTileViewPosition(centerX, centerY, scale)) {
+            layoutScreenNails();
+        }
+    }
+
+    private void updateScreenNailEntry(int which, ImageData data) {
+        if (mTransitionMode == TRANS_SWITCH_NEXT
+                || mTransitionMode == TRANS_SWITCH_PREVIOUS) {
+            // ignore screen nail updating during switching
+            return;
+        }
+        ScreenNailEntry entry = mScreenNails[which];
+        if (data == null) {
+            entry.set(false, null, 0);
+        } else {
+            entry.set(true, data.bitmap, data.rotation);
+        }
+    }
+
+    // -1 previous, 0 current, 1 next
+    public void notifyImageInvalidated(int which) {
+        switch (which) {
+            case -1: {
+                updateScreenNailEntry(
+                        ENTRY_PREVIOUS, mModel.getPreviousImage());
+                layoutScreenNails();
+                invalidate();
+                break;
+            }
+            case 1: {
+                updateScreenNailEntry(ENTRY_NEXT, mModel.getNextImage());
+                layoutScreenNails();
+                invalidate();
+                break;
+            }
+            case 0: {
+                // mImageWidth and mImageHeight will get updated
+                mTileView.notifyModelInvalidated();
+
+                mImageRotation = mModel.getImageRotation();
+                if (((mImageRotation / 90) & 1) == 0) {
+                    mPositionController.setImageSize(
+                            mTileView.mImageWidth, mTileView.mImageHeight);
+                } else {
+                    mPositionController.setImageSize(
+                            mTileView.mImageHeight, mTileView.mImageWidth);
+                }
+                updateLoadingState();
+                break;
+            }
+        }
+    }
+
+    private void updateLoadingState() {
+        // Possible transitions of mLoadingState:
+        //        INIT --> TIMEOUT, COMPLETE, FAIL
+        //     TIMEOUT --> COMPLETE, FAIL, INIT
+        //    COMPLETE --> INIT
+        //        FAIL --> INIT
+        if (mModel.getLevelCount() != 0 || mModel.getBackupImage() != null) {
+            mHandler.removeMessages(MSG_SHOW_LOADING);
+            mLoadingState = LOADING_COMPLETE;
+        } else if (mModel.isFailedToLoad()) {
+            mHandler.removeMessages(MSG_SHOW_LOADING);
+            mLoadingState = LOADING_FAIL;
+        } else if (mLoadingState != LOADING_INIT) {
+            mLoadingState = LOADING_INIT;
+            mHandler.removeMessages(MSG_SHOW_LOADING);
+            mHandler.sendEmptyMessageDelayed(
+                    MSG_SHOW_LOADING, DELAY_SHOW_LOADING);
+        }
+    }
+
+    public void notifyModelInvalidated() {
+        if (mModel == null) {
+            updateScreenNailEntry(ENTRY_PREVIOUS, null);
+            updateScreenNailEntry(ENTRY_NEXT, null);
+        } else {
+            updateScreenNailEntry(ENTRY_PREVIOUS, mModel.getPreviousImage());
+            updateScreenNailEntry(ENTRY_NEXT, mModel.getNextImage());
+        }
+        layoutScreenNails();
+
+        if (mModel == null) {
+            mTileView.notifyModelInvalidated();
+            mImageRotation = 0;
+            mPositionController.setImageSize(0, 0);
+            updateLoadingState();
+        } else {
+            notifyImageInvalidated(0);
+        }
+    }
+
+    @Override
+    protected boolean onTouch(MotionEvent event) {
+        mGestureDetector.onTouchEvent(event);
+        mScaleDetector.onTouchEvent(event);
+        mDownUpDetector.onTouchEvent(event);
+        return true;
+    }
+
+    @Override
+    protected void onLayout(
+            boolean changeSize, int left, int top, int right, int bottom) {
+        mTileView.layout(left, top, right, bottom);
+        if (changeSize) {
+            mPositionController.setViewSize(getWidth(), getHeight());
+            for (ScreenNailEntry entry : mScreenNails) {
+                entry.updateDrawingSize();
+            }
+        }
+    }
+
+    private static int gapToSide(int imageWidth, int viewWidth) {
+        return Math.max(0, (viewWidth - imageWidth) / 2);
+    }
+
+    private RectF getImageBounds() {
+        PositionController p = mPositionController;
+        float points[] = mTempPoints;
+
+        /*
+         * (p0,p1)----------(p2,p3)
+         *   |                  |
+         *   |                  |
+         * (p4,p5)----------(p6,p7)
+         */
+        points[0] = points[4] = -p.mCurrentX;
+        points[1] = points[3] = -p.mCurrentY;
+        points[2] = points[6] = p.mImageW - p.mCurrentX;
+        points[5] = points[7] = p.mImageH - p.mCurrentY;
+
+        RectF rect = mTempRect;
+        rect.set(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY,
+                Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
+
+        float scale = p.mCurrentScale;
+        float offsetX = p.mViewW / 2;
+        float offsetY = p.mViewH / 2;
+        for (int i = 0; i < 4; ++i) {
+            float x = points[i + i] * scale + offsetX;
+            float y = points[i + i + 1] * scale + offsetY;
+            if (x < rect.left) rect.left = x;
+            if (x > rect.right) rect.right = x;
+            if (y < rect.top) rect.top = y;
+            if (y > rect.bottom) rect.bottom = y;
+        }
+        return rect;
+    }
+
+
+    /*
+     * Here is how we layout the screen nails
+     *
+     *  previous            current           next
+     *  ___________       ________________     __________
+     * |  _______  |     |   __________   |   |  ______  |
+     * | |       | |     |  |   right->|  |   | |      | |
+     * | |       |<-------->|<--left   |  |   | |      | |
+     * | |_______| |  |  |  |__________|  |   | |______| |
+     * |___________|  |  |________________|   |__________|
+     *                |  <--> gapToSide()
+     *                |
+     * IMAGE_GAP + Max(previous.gapToSide(), current.gapToSide)
+     */
+    private void layoutScreenNails() {
+        int width = getWidth();
+        int height = getHeight();
+
+        // Use the image width in AC, since we may fake the size if the
+        // image is unavailable
+        RectF bounds = getImageBounds();
+        int left = Math.round(bounds.left);
+        int right = Math.round(bounds.right);
+        int gap = gapToSide(right - left, width);
+
+        // layout the previous image
+        ScreenNailEntry entry = mScreenNails[ENTRY_PREVIOUS];
+
+        if (entry.isEnabled()) {
+            entry.layoutRightEdgeAt(left - (
+                    IMAGE_GAP + Math.max(gap, entry.gapToSide())));
+        }
+
+        // layout the next image
+        entry = mScreenNails[ENTRY_NEXT];
+        if (entry.isEnabled()) {
+            entry.layoutLeftEdgeAt(right + (
+                    IMAGE_GAP + Math.max(gap, entry.gapToSide())));
+        }
+    }
+
+    private static class PositionController {
+        private long mAnimationStartTime = NO_ANIMATION;
+        private static final long NO_ANIMATION = -1;
+        private static final long LAST_ANIMATION = -2;
+
+        // Animation time in milliseconds.
+        private static final float ANIM_TIME_SCROLL = 0;
+        private static final float ANIM_TIME_SCALE = 50;
+        private static final float ANIM_TIME_SNAPBACK = 600;
+        private static final float ANIM_TIME_SLIDE = 400;
+        private static final float ANIM_TIME_ZOOM = 300;
+
+        private int mAnimationKind;
+        private final static int ANIM_KIND_SCROLL = 0;
+        private final static int ANIM_KIND_SCALE = 1;
+        private final static int ANIM_KIND_SNAPBACK = 2;
+        private final static int ANIM_KIND_SLIDE = 3;
+        private final static int ANIM_KIND_ZOOM = 4;
+
+        private PhotoView mViewer;
+        private int mImageW, mImageH;
+        private int mViewW, mViewH;
+
+        // The X, Y are the coordinate on bitmap which shows on the center of
+        // the view. We always keep the mCurrent{X,Y,SCALE} sync with the actual
+        // values used currently.
+        private int mCurrentX, mFromX, mToX;
+        private int mCurrentY, mFromY, mToY;
+        private float mCurrentScale, mFromScale, mToScale;
+
+        // The offsets from the center of the view to the user's focus point,
+        // converted to the bitmap domain.
+        private float mPrevOffsetX;
+        private float mPrevOffsetY;
+        private boolean mInScale;
+        private boolean mUseViewSize = true;
+
+        // The limits for position and scale.
+        private float mScaleMin, mScaleMax = 4f;
+
+        PositionController(PhotoView viewer) {
+            mViewer = viewer;
+        }
+
+        public void setImageSize(int width, int height) {
+
+            // If no image available, use view size.
+            if (width == 0 || height == 0) {
+                mUseViewSize = true;
+                mImageW = mViewW;
+                mImageH = mViewH;
+                mCurrentX = mImageW / 2;
+                mCurrentY = mImageH / 2;
+                mCurrentScale = 1;
+                mScaleMin = 1;
+                mViewer.setPosition(mCurrentX, mCurrentY, mCurrentScale);
+                return;
+            }
+
+            mUseViewSize = false;
+
+            float ratio = Math.min(
+                    (float) mImageW / width, (float) mImageH / height);
+
+            mCurrentX = translate(mCurrentX, mImageW, width, ratio);
+            mCurrentY = translate(mCurrentY, mImageH, height, ratio);
+            mCurrentScale = mCurrentScale * ratio;
+
+            mFromX = translate(mFromX, mImageW, width, ratio);
+            mFromY = translate(mFromY, mImageH, height, ratio);
+            mFromScale = mFromScale * ratio;
+
+            mToX = translate(mToX, mImageW, width, ratio);
+            mToY = translate(mToY, mImageH, height, ratio);
+            mToScale = mToScale * ratio;
+
+            mImageW = width;
+            mImageH = height;
+
+            mScaleMin = getMinimalScale(width, height, 0);
+
+            // Scale the new image to fit into the old one
+            if (mViewer.mOpenedItemPath != null) {
+                Position position = PositionRepository
+                        .getInstance(mViewer.mActivity).get(Long.valueOf(
+                        System.identityHashCode(mViewer.mOpenedItemPath)));
+                mViewer.mOpenedItemPath = null;
+                if (position != null) {
+                    float scale = 240f / Math.min(width, height);
+                    mCurrentX = Math.round((mViewW / 2f - position.x) / scale) + mImageW / 2;
+                    mCurrentY = Math.round((mViewH / 2f - position.y) / scale) + mImageH / 2;
+                    mCurrentScale = scale;
+                    mViewer.mTransitionMode = TRANS_OPEN_ANIMATION;
+                    startSnapback();
+                }
+            } else if (mAnimationStartTime == NO_ANIMATION) {
+                mCurrentScale = Utils.clamp(mCurrentScale, mScaleMin, mScaleMax);
+            }
+            mViewer.setPosition(mCurrentX, mCurrentY, mCurrentScale);
+        }
+
+        public void zoomIn(float tapX, float tapY, float targetScale) {
+            if (targetScale > mScaleMax) targetScale = mScaleMax;
+            float scale = mCurrentScale;
+            float tempX = (tapX - mViewW / 2) / mCurrentScale + mCurrentX;
+            float tempY = (tapY - mViewH / 2) / mCurrentScale + mCurrentY;
+
+            // mCurrentX + (mViewW / 2) * (1 / targetScale) < mImageW
+            // mCurrentX - (mViewW / 2) * (1 / targetScale) > 0
+            float min = mViewW / 2.0f / targetScale;
+            float max = mImageW  - mViewW / 2.0f / targetScale;
+            int targetX = (int) Utils.clamp(tempX, min, max);
+
+            min = mViewH / 2.0f / targetScale;
+            max = mImageH  - mViewH / 2.0f / targetScale;
+            int targetY = (int) Utils.clamp(tempY,  min, max);
+
+            // If the width of the image is less then the view, center the image
+            if (mImageW * targetScale < mViewW) targetX = mImageW / 2;
+            if (mImageH * targetScale < mViewH) targetY = mImageH / 2;
+
+            startAnimation(targetX, targetY, targetScale, ANIM_KIND_ZOOM);
+        }
+
+        public void resetToFullView() {
+            startAnimation(mImageW / 2, mImageH / 2, mScaleMin, ANIM_KIND_ZOOM);
+        }
+
+        private float getMinimalScale(int w, int h, int rotation) {
+            return Math.min(SCALE_LIMIT, ((rotation / 90) & 0x01) == 0
+                    ? Math.min((float) mViewW / w, (float) mViewH / h)
+                    : Math.min((float) mViewW / h, (float) mViewH / w));
+        }
+
+        private static int translate(int value, int size, int updateSize, float ratio) {
+            return Math.round(
+                    (value + (updateSize * ratio - size) / 2f) / ratio);
+        }
+
+        public void setViewSize(int viewW, int viewH) {
+            boolean needLayout = mViewW == 0 || mViewH == 0;
+
+            mViewW = viewW;
+            mViewH = viewH;
+
+            if (mUseViewSize) {
+                mImageW = viewW;
+                mImageH = viewH;
+                mCurrentX = mImageW / 2;
+                mCurrentY = mImageH / 2;
+                mCurrentScale = 1;
+                mViewer.setPosition(mCurrentX, mCurrentY, mCurrentScale);
+            } else {
+                boolean wasMinScale = (mCurrentScale == mScaleMin);
+                mScaleMin = Math.min(SCALE_LIMIT, Math.min(
+                        (float) viewW / mImageW, (float) viewH / mImageH));
+                if (needLayout || mCurrentScale < mScaleMin || wasMinScale) {
+                    mCurrentX = mImageW / 2;
+                    mCurrentY = mImageH / 2;
+                    mCurrentScale = mScaleMin;
+                    mViewer.setPosition(mCurrentX, mCurrentY, mCurrentScale);
+                }
+            }
+        }
+
+        public void stopAnimation() {
+            mAnimationStartTime = NO_ANIMATION;
+        }
+
+        public void skipAnimation() {
+            if (mAnimationStartTime == NO_ANIMATION) return;
+            mAnimationStartTime = NO_ANIMATION;
+            mCurrentX = mToX;
+            mCurrentY = mToY;
+            mCurrentScale = mToScale;
+        }
+
+        public void scrollBy(float dx, float dy, int type) {
+            startAnimation(getTargetX() + Math.round(dx / mCurrentScale),
+                    getTargetY() + Math.round(dy / mCurrentScale),
+                    mCurrentScale, type);
+        }
+
+        public void beginScale(float focusX, float focusY) {
+            mInScale = true;
+            mPrevOffsetX = (focusX - mViewW / 2f) / mCurrentScale;
+            mPrevOffsetY = (focusY - mViewH / 2f) / mCurrentScale;
+        }
+
+        public void scaleBy(float s, float focusX, float focusY) {
+
+            // The focus point should keep this position on the ImageView.
+            // So, mCurrentX + mPrevOffsetX = mCurrentX' + offsetX.
+            // mCurrentY + mPrevOffsetY = mCurrentY' + offsetY.
+            float offsetX = (focusX - mViewW / 2f) / mCurrentScale;
+            float offsetY = (focusY - mViewH / 2f) / mCurrentScale;
+
+            startAnimation(getTargetX() - Math.round(offsetX - mPrevOffsetX),
+                           getTargetY() - Math.round(offsetY - mPrevOffsetY),
+                           getTargetScale() * s, ANIM_KIND_SCALE);
+            mPrevOffsetX = offsetX;
+            mPrevOffsetY = offsetY;
+        }
+
+        public void endScale() {
+            mInScale = false;
+            startSnapbackIfNeeded();
+        }
+
+        public void up() {
+            startSnapback();
+        }
+
+        public void startSlideInAnimation(int fromX) {
+            mFromX = Math.round(fromX + (mImageW - mViewW) / 2f);
+            mFromY = Math.round(mImageH / 2f);
+            mCurrentX = mFromX;
+            mCurrentY = mFromY;
+            startAnimation(mImageW / 2, mImageH / 2, mCurrentScale,
+                    ANIM_KIND_SLIDE);
+        }
+
+        public void startHorizontalSlide(int distance) {
+            scrollBy(distance, 0, ANIM_KIND_SLIDE);
+        }
+
+        private void startAnimation(
+                int centerX, int centerY, float scale, int kind) {
+            if (centerX == mCurrentX && centerY == mCurrentY
+                    && scale == mCurrentScale) return;
+
+            mFromX = mCurrentX;
+            mFromY = mCurrentY;
+            mFromScale = mCurrentScale;
+
+            mToX = centerX;
+            mToY = centerY;
+            mToScale = Utils.clamp(scale, 0.6f * mScaleMin, 1.4f * mScaleMax);
+
+            // If the scaled dimension is smaller than the view,
+            // force it to be in the center.
+            if (Math.floor(mImageH * mToScale) <= mViewH) {
+                mToY = mImageH / 2;
+            }
+
+            mAnimationStartTime = SystemClock.uptimeMillis();
+            mAnimationKind = kind;
+            if (advanceAnimation()) mViewer.invalidate();
+        }
+
+        // Returns true if redraw is needed.
+        public boolean advanceAnimation() {
+            if (mAnimationStartTime == NO_ANIMATION) {
+                return false;
+            } else if (mAnimationStartTime == LAST_ANIMATION) {
+                mAnimationStartTime = NO_ANIMATION;
+                if (mViewer.mTransitionMode != TRANS_NONE) {
+                    mViewer.mHandler.sendEmptyMessage(MSG_TRANSITION_COMPLETE);
+                    return false;
+                } else {
+                    return startSnapbackIfNeeded();
+                }
+            }
+
+            float animationTime;
+            if (mAnimationKind == ANIM_KIND_SCROLL) {
+                animationTime = ANIM_TIME_SCROLL;
+            } else if (mAnimationKind == ANIM_KIND_SCALE) {
+                animationTime = ANIM_TIME_SCALE;
+            } else if (mAnimationKind == ANIM_KIND_SLIDE) {
+                animationTime = ANIM_TIME_SLIDE;
+            } else if (mAnimationKind == ANIM_KIND_ZOOM) {
+                animationTime = ANIM_TIME_ZOOM;
+            } else /* if (mAnimationKind == ANIM_KIND_SNAPBACK) */ {
+                animationTime = ANIM_TIME_SNAPBACK;
+            }
+
+            float progress;
+            if (animationTime == 0) {
+                progress = 1;
+            } else {
+                long now = SystemClock.uptimeMillis();
+                progress = (now - mAnimationStartTime) / animationTime;
+            }
+
+            if (progress >= 1) {
+                progress = 1;
+                mCurrentX = mToX;
+                mCurrentY = mToY;
+                mCurrentScale = mToScale;
+                mAnimationStartTime = LAST_ANIMATION;
+            } else {
+                float f = 1 - progress;
+                if (mAnimationKind == ANIM_KIND_SCROLL) {
+                    progress = 1 - f;  // linear
+                } else if (mAnimationKind == ANIM_KIND_SCALE) {
+                    progress = 1 - f * f;  // quadratic
+                } else /* if mAnimationKind is ANIM_KIND_SNAPBACK,
+                            ANIM_KIND_ZOOM or ANIM_KIND_SLIDE */ {
+                    progress = 1 - f * f * f * f * f; // x^5
+                }
+                linearInterpolate(progress);
+            }
+            mViewer.setPosition(mCurrentX, mCurrentY, mCurrentScale);
+            return true;
+        }
+
+        private void linearInterpolate(float progress) {
+            // To linearly interpolate the position, we have to translate the
+            // coordinates. The meaning of the translated point (x, y) is the
+            // coordinates of the center of the bitmap on the view component.
+            float fromX = mViewW / 2f + (mImageW / 2f - mFromX) * mFromScale;
+            float toX = mViewW / 2f + (mImageW / 2f - mToX) * mToScale;
+            float currentX = fromX + progress * (toX - fromX);
+
+            float fromY = mViewH / 2f + (mImageH / 2f - mFromY) * mFromScale;
+            float toY = mViewH / 2f + (mImageH / 2f - mToY) * mToScale;
+            float currentY = fromY + progress * (toY - fromY);
+
+            mCurrentScale = mFromScale + progress * (mToScale - mFromScale);
+            mCurrentX = Math.round(
+                    mImageW / 2f + (mViewW / 2f - currentX) / mCurrentScale);
+            mCurrentY = Math.round(
+                    mImageH / 2f + (mViewH / 2f - currentY) / mCurrentScale);
+        }
+
+        // Returns true if redraw is needed.
+        private boolean startSnapbackIfNeeded() {
+            if (mAnimationStartTime != NO_ANIMATION) return false;
+            if (mInScale) return false;
+            if (mAnimationKind == ANIM_KIND_SCROLL && mViewer.isDown()) {
+                return false;
+            }
+            return startSnapback();
+        }
+
+        public boolean startSnapback() {
+            boolean needAnimation = false;
+            int x = mCurrentX;
+            int y = mCurrentY;
+            float scale = mCurrentScale;
+
+            if (mCurrentScale < mScaleMin || mCurrentScale > mScaleMax) {
+                needAnimation = true;
+                scale = Utils.clamp(mCurrentScale, mScaleMin, mScaleMax);
+            }
+
+            // The number of pixels when the edge is aligned.
+            int left = (int) Math.ceil(mViewW / (2 * scale));
+            int right = mImageW - left;
+            int top = (int) Math.ceil(mViewH / (2 * scale));
+            int bottom = mImageH - top;
+
+            if (mImageW * scale > mViewW) {
+                if (mCurrentX < left) {
+                    needAnimation = true;
+                    x = left;
+                } else if (mCurrentX > right) {
+                    needAnimation = true;
+                    x = right;
+                }
+            } else if (mCurrentX != mImageW / 2) {
+                needAnimation = true;
+                x = mImageW / 2;
+            }
+
+            if (mImageH * scale > mViewH) {
+                if (mCurrentY < top) {
+                    needAnimation = true;
+                    y = top;
+                } else if (mCurrentY > bottom) {
+                    needAnimation = true;
+                    y = bottom;
+                }
+            } else if (mCurrentY != mImageH / 2) {
+                needAnimation = true;
+                y = mImageH / 2;
+            }
+
+            if (needAnimation) {
+                startAnimation(x, y, scale, ANIM_KIND_SNAPBACK);
+            }
+
+            return needAnimation;
+        }
+
+        private float getTargetScale() {
+            if (mAnimationStartTime == NO_ANIMATION
+                    || mAnimationKind == ANIM_KIND_SNAPBACK) return mCurrentScale;
+            return mToScale;
+        }
+
+        private int getTargetX() {
+            if (mAnimationStartTime == NO_ANIMATION
+                    || mAnimationKind == ANIM_KIND_SNAPBACK) return mCurrentX;
+            return mToX;
+        }
+
+        private int getTargetY() {
+            if (mAnimationStartTime == NO_ANIMATION
+                    || mAnimationKind == ANIM_KIND_SNAPBACK) return mCurrentY;
+            return mToY;
+        }
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        PositionController p = mPositionController;
+
+        // Draw the current photo
+        if (mLoadingState == LOADING_COMPLETE) {
+            super.render(canvas);
+        }
+
+        // Draw the previous and the next photo
+        if (mTransitionMode != TRANS_SLIDE_IN_LEFT
+                && mTransitionMode != TRANS_SLIDE_IN_RIGHT
+                && mTransitionMode != TRANS_OPEN_ANIMATION) {
+            ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
+            ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
+
+            if (prevNail.mVisible) prevNail.draw(canvas);
+            if (nextNail.mVisible) nextNail.draw(canvas);
+        }
+
+        // Draw the progress spinner and the text below it
+        //
+        // (x, y) is where we put the center of the spinner.
+        // s is the size of the video play icon, and we use s to layout text
+        // because we want to keep the text at the same place when the video
+        // play icon is shown instead of the spinner.
+        int w = getWidth();
+        int h = getHeight();
+        int x = Math.round(getImageBounds().centerX());
+        int y = h / 2;
+        int s = Math.min(getWidth(), getHeight()) / 6;
+
+        if (mLoadingState == LOADING_TIMEOUT) {
+            StringTexture m = mLoadingText;
+            ProgressSpinner r = mLoadingSpinner;
+            r.draw(canvas, x - r.getWidth() / 2, y - r.getHeight() / 2);
+            m.draw(canvas, x - m.getWidth() / 2, y + s / 2 + 5);
+            invalidate(); // we need to keep the spinner rotating
+        } else if (mLoadingState == LOADING_FAIL) {
+            StringTexture m = mNoThumbnailText;
+            m.draw(canvas, x - m.getWidth() / 2, y + s / 2 + 5);
+        }
+
+        // Draw the video play icon (in the place where the spinner was)
+        if (mShowVideoPlayIcon
+                && mLoadingState != LOADING_INIT
+                && mLoadingState != LOADING_TIMEOUT) {
+            mVideoPlayIcon.draw(canvas, x - s / 2, y - s / 2, s, s);
+        }
+
+        if (mPositionController.advanceAnimation()) invalidate();
+    }
+
+    private void stopCurrentSwipingIfNeeded() {
+        // Enable fast sweeping
+        if (mTransitionMode == TRANS_SWITCH_NEXT) {
+            mTransitionMode = TRANS_NONE;
+            mPositionController.stopAnimation();
+            switchToNextImage();
+        } else if (mTransitionMode == TRANS_SWITCH_PREVIOUS) {
+            mTransitionMode = TRANS_NONE;
+            mPositionController.stopAnimation();
+            switchToPreviousImage();
+        }
+    }
+
+    private static boolean isAlmostEquals(float a, float b) {
+        float diff = a - b;
+        return (diff < 0 ? -diff : diff) < 0.02f;
+    }
+
+    private boolean swipeImages(float velocity) {
+        if (mTransitionMode != TRANS_NONE
+                && mTransitionMode != TRANS_SWITCH_NEXT
+                && mTransitionMode != TRANS_SWITCH_PREVIOUS) return false;
+
+        ScreenNailEntry next = mScreenNails[ENTRY_NEXT];
+        ScreenNailEntry prev = mScreenNails[ENTRY_PREVIOUS];
+
+        int width = getWidth();
+
+        // If the edge of the current photo is visible and the sweeping velocity
+        // exceed the threshold, switch to next / previous image
+        PositionController controller = mPositionController;
+        if (isAlmostEquals(controller.mCurrentScale, controller.mScaleMin)) {
+            if (velocity < -SWIPE_THRESHOLD) {
+                stopCurrentSwipingIfNeeded();
+                if (next.isEnabled()) {
+                    mTransitionMode = TRANS_SWITCH_NEXT;
+                    controller.startHorizontalSlide(next.mOffsetX - width / 2);
+                    return true;
+                }
+                return false;
+            }
+            if (velocity > SWIPE_THRESHOLD) {
+                stopCurrentSwipingIfNeeded();
+                if (prev.isEnabled()) {
+                    mTransitionMode = TRANS_SWITCH_PREVIOUS;
+                    controller.startHorizontalSlide(prev.mOffsetX - width / 2);
+                    return true;
+                }
+                return false;
+            }
+        }
+
+        if (mTransitionMode != TRANS_NONE) return false;
+
+        // Decide whether to swiping to the next/prev image in the zoom-in case
+        RectF bounds = getImageBounds();
+        int left = Math.round(bounds.left);
+        int right = Math.round(bounds.right);
+        int threshold = SWITCH_THRESHOLD + gapToSide(right - left, width);
+
+        // If we have moved the picture a lot, switching.
+        if (next.isEnabled() && threshold < width - right) {
+            mTransitionMode = TRANS_SWITCH_NEXT;
+            controller.startHorizontalSlide(next.mOffsetX - width / 2);
+            return true;
+        }
+        if (prev.isEnabled() && threshold < left) {
+            mTransitionMode = TRANS_SWITCH_PREVIOUS;
+            controller.startHorizontalSlide(prev.mOffsetX - width / 2);
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean mIgnoreUpEvent = false;
+
+    private class MyGestureListener
+            extends GestureDetector.SimpleOnGestureListener {
+        @Override
+        public boolean onScroll(
+                MotionEvent e1, MotionEvent e2, float dx, float dy) {
+            if (mTransitionMode != TRANS_NONE) return true;
+            mPositionController.scrollBy(
+                    dx, dy, PositionController.ANIM_KIND_SCROLL);
+            return true;
+        }
+
+        @Override
+        public boolean onSingleTapUp(MotionEvent e) {
+            if (mPhotoTapListener != null) {
+                mPhotoTapListener.onSingleTapUp((int) e.getX(), (int) e.getY());
+            }
+            return true;
+        }
+
+        @Override
+        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+                float velocityY) {
+            mIgnoreUpEvent = true;
+            if (!swipeImages(velocityX) && mTransitionMode == TRANS_NONE) {
+                mPositionController.up();
+            }
+            return true;
+        }
+
+        @Override
+        public boolean onDoubleTap(MotionEvent e) {
+            if (mTransitionMode != TRANS_NONE) return true;
+            PositionController controller = mPositionController;
+            float scale = controller.mCurrentScale;
+            // onDoubleTap happened on the second ACTION_DOWN.
+            // We need to ignore the next UP event.
+            mIgnoreUpEvent = true;
+            if (scale <= 1.0f || isAlmostEquals(scale, controller.mScaleMin)) {
+                controller.zoomIn(
+                        e.getX(), e.getY(), Math.max(1.5f, scale * 1.5f));
+            } else {
+                controller.resetToFullView();
+            }
+            return true;
+        }
+    }
+
+    private class MyScaleListener
+            extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+
+        @Override
+        public boolean onScale(ScaleGestureDetector detector) {
+            float scale = detector.getScaleFactor();
+            if (Float.isNaN(scale) || Float.isInfinite(scale)
+                    || mTransitionMode != TRANS_NONE) return true;
+            mPositionController.scaleBy(scale,
+                    detector.getFocusX(), detector.getFocusY());
+            return true;
+        }
+
+        @Override
+        public boolean onScaleBegin(ScaleGestureDetector detector) {
+            if (mTransitionMode != TRANS_NONE) return false;
+            mPositionController.beginScale(
+                detector.getFocusX(), detector.getFocusY());
+            return true;
+        }
+
+        @Override
+        public void onScaleEnd(ScaleGestureDetector detector) {
+            mPositionController.endScale();
+            swipeImages(0);
+        }
+    }
+
+    public void notifyOnNewImage() {
+        mPositionController.setImageSize(0, 0);
+    }
+
+    public void startSlideInAnimation(int direction) {
+        PositionController a = mPositionController;
+        a.stopAnimation();
+        switch (direction) {
+            case TRANS_SLIDE_IN_LEFT: {
+                mTransitionMode = TRANS_SLIDE_IN_LEFT;
+                a.startSlideInAnimation(a.mViewW);
+                break;
+            }
+            case TRANS_SLIDE_IN_RIGHT: {
+                mTransitionMode = TRANS_SLIDE_IN_RIGHT;
+                a.startSlideInAnimation(-a.mViewW);
+                break;
+            }
+            default: throw new IllegalArgumentException(String.valueOf(direction));
+        }
+    }
+
+    private class MyDownUpListener implements DownUpDetector.DownUpListener {
+        public void onDown(MotionEvent e) {
+        }
+
+        public void onUp(MotionEvent e) {
+            if (mIgnoreUpEvent) {
+                mIgnoreUpEvent = false;
+                return;
+            }
+            if (!swipeImages(0) && mTransitionMode == TRANS_NONE) {
+                mPositionController.up();
+            }
+        }
+    }
+
+    private void switchToNextImage() {
+        // We update the texture here directly to prevent texture uploading.
+        ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
+        ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
+        mTileView.invalidateTiles();
+        if (prevNail.mTexture != null) prevNail.mTexture.recycle();
+        prevNail.mTexture = mTileView.mBackupImage;
+        mTileView.mBackupImage = nextNail.mTexture;
+        nextNail.mTexture = null;
+        mModel.next();
+    }
+
+    private void switchToPreviousImage() {
+        // We update the texture here directly to prevent texture uploading.
+        ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
+        ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
+        mTileView.invalidateTiles();
+        if (nextNail.mTexture != null) nextNail.mTexture.recycle();
+        nextNail.mTexture = mTileView.mBackupImage;
+        mTileView.mBackupImage = prevNail.mTexture;
+        nextNail.mTexture = null;
+        mModel.previous();
+    }
+
+    private void onTransitionComplete() {
+        int mode = mTransitionMode;
+        mTransitionMode = TRANS_NONE;
+
+        if (mModel == null) return;
+        if (mode == TRANS_SWITCH_NEXT) {
+            switchToNextImage();
+        } else if (mode == TRANS_SWITCH_PREVIOUS) {
+            switchToPreviousImage();
+        }
+    }
+
+    private boolean isDown() {
+        return mDownUpDetector.isDown();
+    }
+
+    public static interface Model extends TileImageView.Model {
+        public void next();
+        public void previous();
+        public int getImageRotation();
+
+        // Return null if the specified image is unavailable.
+        public ImageData getNextImage();
+        public ImageData getPreviousImage();
+    }
+
+    public static class ImageData {
+        public int rotation;
+        public Bitmap bitmap;
+
+        public ImageData(Bitmap bitmap, int rotation) {
+            this.bitmap = bitmap;
+            this.rotation = rotation;
+        }
+    }
+
+    private static int getRotated(int degree, int original, int theother) {
+        return ((degree / 90) & 1) == 0 ? original : theother;
+    }
+
+    private class ScreenNailEntry {
+        private boolean mVisible;
+        private boolean mEnabled;
+
+        private int mRotation;
+        private int mDrawWidth;
+        private int mDrawHeight;
+        private int mOffsetX;
+
+        private BitmapTexture mTexture;
+
+        public void set(boolean enabled, Bitmap bitmap, int rotation) {
+            mEnabled = enabled;
+            mRotation = rotation;
+            if (bitmap == null) {
+                if (mTexture != null) mTexture.recycle();
+                mTexture = null;
+            } else {
+                if (mTexture != null) {
+                    if (mTexture.getBitmap() != bitmap) {
+                        mTexture.recycle();
+                        mTexture = new BitmapTexture(bitmap);
+                    }
+                } else {
+                    mTexture = new BitmapTexture(bitmap);
+                }
+                updateDrawingSize();
+            }
+        }
+
+        public void layoutRightEdgeAt(int x) {
+            mVisible = x > 0;
+            mOffsetX = x - getRotated(
+                    mRotation, mDrawWidth, mDrawHeight) / 2;
+        }
+
+        public void layoutLeftEdgeAt(int x) {
+            mVisible = x < getWidth();
+            mOffsetX = x + getRotated(
+                    mRotation, mDrawWidth, mDrawHeight) / 2;
+        }
+
+        public int gapToSide() {
+            return ((mRotation / 90) & 1) != 0
+                    ? PhotoView.gapToSide(mDrawHeight, getWidth())
+                    : PhotoView.gapToSide(mDrawWidth, getWidth());
+        }
+
+        public void updateDrawingSize() {
+            if (mTexture == null) return;
+
+            int width = mTexture.getWidth();
+            int height = mTexture.getHeight();
+            float s = mPositionController.getMinimalScale(width, height, mRotation);
+            mDrawWidth = Math.round(width * s);
+            mDrawHeight = Math.round(height * s);
+        }
+
+        public boolean isEnabled() {
+            return mEnabled;
+        }
+
+        public void draw(GLCanvas canvas) {
+            int x = mOffsetX;
+            int y = getHeight() / 2;
+
+            if (mTexture != null) {
+                if (mRotation != 0) {
+                    canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+                    canvas.translate(x, y, 0);
+                    canvas.rotate(mRotation, 0, 0, 1); //mRotation
+                    canvas.translate(-x, -y, 0);
+                }
+                mTexture.draw(canvas, x - mDrawWidth / 2, y - mDrawHeight / 2,
+                        mDrawWidth, mDrawHeight);
+                if (mRotation != 0) {
+                    canvas.restore();
+                }
+            }
+        }
+    }
+
+    public void pause() {
+        mPositionController.skipAnimation();
+        mTransitionMode = TRANS_NONE;
+        mTileView.freeTextures();
+        for (ScreenNailEntry entry : mScreenNails) {
+            entry.set(false, null, 0);
+        }
+    }
+
+    public void resume() {
+        mTileView.prepareTextures();
+    }
+
+    public void setOpenedItem(Path itemPath) {
+        mOpenedItemPath = itemPath;
+    }
+
+    public void showVideoPlayIcon(boolean show) {
+        mShowVideoPlayIcon = show;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/PositionProvider.java b/src/com/android/gallery3d/ui/PositionProvider.java
new file mode 100644
index 0000000..930c61e
--- /dev/null
+++ b/src/com/android/gallery3d/ui/PositionProvider.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.ui.PositionRepository.Position;
+
+public interface PositionProvider {
+    public Position getPosition(long identity, Position target);
+}
diff --git a/src/com/android/gallery3d/ui/PositionRepository.java b/src/com/android/gallery3d/ui/PositionRepository.java
new file mode 100644
index 0000000..0b829fa
--- /dev/null
+++ b/src/com/android/gallery3d/ui/PositionRepository.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.common.Utils;
+
+import java.util.HashMap;
+import java.util.WeakHashMap;
+
+public class PositionRepository {
+    private static final WeakHashMap<GalleryActivity, PositionRepository>
+            sMap = new WeakHashMap<GalleryActivity, PositionRepository>();
+
+    public static class Position implements Cloneable {
+        public float x;
+        public float y;
+        public float z;
+        public float theta;
+        public float alpha;
+
+        public Position() {
+        }
+
+        public Position(float x, float y, float z) {
+            this(x, y, z, 0f, 1f);
+        }
+
+        public Position(float x, float y, float z, float ftheta, float alpha) {
+            this.x = x;
+            this.y = y;
+            this.z = z;
+            this.theta = ftheta;
+            this.alpha = alpha;
+        }
+
+        @Override
+        public Position clone() {
+            try {
+                return (Position) super.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new AssertionError(); // we do support clone.
+            }
+        }
+
+        public void set(Position another) {
+            x = another.x;
+            y = another.y;
+            z = another.z;
+            theta = another.theta;
+            alpha = another.alpha;
+        }
+
+        public void set(float x, float y, float z, float ftheta, float alpha) {
+            this.x = x;
+            this.y = y;
+            this.z = z;
+            this.theta = ftheta;
+            this.alpha = alpha;
+        }
+
+        @Override
+        public boolean equals(Object object) {
+            if (!(object instanceof Position)) return false;
+            Position position = (Position) object;
+            return x == position.x && y == position.y && z == position.z
+                    && theta == position.theta
+                    && alpha == position.alpha;
+        }
+
+        public static void interpolate(
+                Position source, Position target, Position output, float progress) {
+            if (progress < 1f) {
+                output.set(
+                        Utils.interpolateScale(source.x, target.x, progress),
+                        Utils.interpolateScale(source.y, target.y, progress),
+                        Utils.interpolateScale(source.z, target.z, progress),
+                        Utils.interpolateAngle(source.theta, target.theta, progress),
+                        Utils.interpolateScale(source.alpha, target.alpha, progress));
+            } else {
+                output.set(target);
+            }
+        }
+    }
+
+    public static PositionRepository getInstance(GalleryActivity activity) {
+        PositionRepository repository = sMap.get(activity);
+        if (repository == null) {
+            repository = new PositionRepository();
+            sMap.put(activity, repository);
+        }
+        return repository;
+    }
+
+    private HashMap<Long, Position> mData = new HashMap<Long, Position>();
+    private int mOffsetX;
+    private int mOffsetY;
+    private Position mTempPosition = new Position();
+
+    public Position get(Long identity) {
+        Position position = mData.get(identity);
+        if (position == null) return null;
+        mTempPosition.set(position);
+        position = mTempPosition;
+        position.x -= mOffsetX;
+        position.y -= mOffsetY;
+        return position;
+    }
+
+    public void setOffset(int offsetX, int offsetY) {
+        mOffsetX = offsetX;
+        mOffsetY = offsetY;
+    }
+
+    public void putPosition(Long identity, Position position) {
+        Position clone = position.clone();
+        clone.x += mOffsetX;
+        clone.y += mOffsetY;
+        mData.put(identity, clone);
+    }
+
+    public void clear() {
+        mData.clear();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/ProgressBar.java b/src/com/android/gallery3d/ui/ProgressBar.java
new file mode 100644
index 0000000..c62fa9a
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ProgressBar.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.content.Context;
+import android.graphics.Rect;
+
+public class ProgressBar extends GLView {
+    private final int MAX_PROGRESS = 10000;
+    private int mProgress;
+    private int mSecondaryProgress;
+    private BasicTexture mProgressTexture;
+    private BasicTexture mSecondaryProgressTexture;
+    private BasicTexture mBackgrondTexture;
+
+
+    public ProgressBar(Context context, int resProgress,
+            int resSecondaryProgress, int resBackground) {
+        mProgressTexture = new NinePatchTexture(context, resProgress);
+        mSecondaryProgressTexture = new NinePatchTexture(
+                context, resSecondaryProgress);
+        mBackgrondTexture = new NinePatchTexture(context, resBackground);
+
+    }
+
+    // The progress value is between 0 (empty) and MAX_PROGRESS (full).
+    public void setProgress(int progress) {
+        mProgress = progress;
+    }
+
+    public void setSecondaryProgress(int progress) {
+        mSecondaryProgress = progress;
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        Rect p = mPaddings;
+
+        int width = getWidth() - p.left - p.right;
+        int height = getHeight() - p.top - p.bottom;
+
+        int primary = width * mProgress / MAX_PROGRESS;
+        int secondary = width * mSecondaryProgress / MAX_PROGRESS;
+        int x = p.left;
+        int y = p.top;
+
+        canvas.drawTexture(mBackgrondTexture, x, y, width, height);
+        canvas.drawTexture(mProgressTexture, x, y, primary, height);
+        canvas.drawTexture(mSecondaryProgressTexture, x, y, secondary, height);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/ProgressSpinner.java b/src/com/android/gallery3d/ui/ProgressSpinner.java
new file mode 100644
index 0000000..e4d6024
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ProgressSpinner.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+
+import android.content.Context;
+
+public class ProgressSpinner {
+    private static float ROTATE_SPEED_OUTER = 1080f / 3500f;
+    private static float ROTATE_SPEED_INNER = -720f / 3500f;
+    private final ResourceTexture mOuter;
+    private final ResourceTexture mInner;
+    private final int mWidth;
+    private final int mHeight;
+
+    private float mInnerDegree = 0f;
+    private float mOuterDegree = 0f;
+    private long mAnimationTimestamp = -1;
+
+    public ProgressSpinner(Context context) {
+        mOuter = new ResourceTexture(context, R.drawable.spinner_76_outer_holo);
+        mInner = new ResourceTexture(context, R.drawable.spinner_76_inner_holo);
+
+        mWidth = Math.max(mOuter.getWidth(), mInner.getWidth());
+        mHeight = Math.max(mOuter.getHeight(), mInner.getHeight());
+    }
+
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+
+    public void startAnimation() {
+        mAnimationTimestamp = -1;
+        mOuterDegree = 0;
+        mInnerDegree = 0;
+    }
+
+    public void draw(GLCanvas canvas, int x, int y) {
+        long now = canvas.currentAnimationTimeMillis();
+        if (mAnimationTimestamp == -1) mAnimationTimestamp = now;
+        mOuterDegree += (now - mAnimationTimestamp) * ROTATE_SPEED_OUTER;
+        mInnerDegree += (now - mAnimationTimestamp) * ROTATE_SPEED_INNER;
+
+        mAnimationTimestamp = now;
+
+        // just preventing overflow
+        if (mOuterDegree > 360) mOuterDegree -= 360f;
+        if (mInnerDegree < 0) mInnerDegree += 360f;
+
+        canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+
+        canvas.translate(x + mWidth / 2, y + mHeight / 2, 0);
+        canvas.rotate(mInnerDegree, 0, 0, 1);
+        mOuter.draw(canvas, -mOuter.getWidth() / 2, -mOuter.getHeight() / 2);
+        canvas.rotate(mOuterDegree - mInnerDegree, 0, 0, 1);
+        mInner.draw(canvas, -mInner.getWidth() / 2, -mInner.getHeight() / 2);
+        canvas.restore();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/RawTexture.java b/src/com/android/gallery3d/ui/RawTexture.java
new file mode 100644
index 0000000..c1be435
--- /dev/null
+++ b/src/com/android/gallery3d/ui/RawTexture.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import javax.microedition.khronos.opengles.GL11;
+
+// RawTexture is used for texture created by glCopyTexImage2D.
+//
+// It will throw RuntimeException in onBind() if used with a different GL
+// context. It is only used internally by copyTexture() in GLCanvas.
+class RawTexture extends BasicTexture {
+
+    private RawTexture(GLCanvas canvas, int id) {
+        super(canvas, id, STATE_LOADED);
+    }
+
+    public static RawTexture newInstance(GLCanvas canvas) {
+        int[] textureId = new int[1];
+        GL11 gl = canvas.getGLInstance();
+        gl.glGenTextures(1, textureId, 0);
+        return new RawTexture(canvas, textureId[0]);
+    }
+
+    @Override
+    protected boolean onBind(GLCanvas canvas) {
+        if (mCanvasRef.get() != canvas) {
+            throw new RuntimeException("cannot bind to different canvas");
+        }
+        return true;
+    }
+
+    public boolean isOpaque() {
+        return true;
+    }
+
+    @Override
+    public void yield() {
+        // we cannot free the texture because we have no backup.
+    }
+}
diff --git a/src/com/android/gallery3d/ui/ResourceTexture.java b/src/com/android/gallery3d/ui/ResourceTexture.java
new file mode 100644
index 0000000..08fb891
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ResourceTexture.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+// ResourceTexture is a texture whose Bitmap is decoded from a resource.
+// By default ResourceTexture is not opaque.
+public class ResourceTexture extends UploadedTexture {
+
+    protected final Context mContext;
+    protected final int mResId;
+
+    public ResourceTexture(Context context, int resId) {
+        mContext = Utils.checkNotNull(context);
+        mResId = resId;
+        setOpaque(false);
+    }
+
+    @Override
+    protected Bitmap onGetBitmap() {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        return BitmapFactory.decodeResource(
+                mContext.getResources(), mResId, options);
+    }
+
+    @Override
+    protected void onFreeBitmap(Bitmap bitmap) {
+        if (!inFinalizer()) {
+            bitmap.recycle();
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/ScrollBarView.java b/src/com/android/gallery3d/ui/ScrollBarView.java
new file mode 100644
index 0000000..7e375c9
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ScrollBarView.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+
+import android.content.Context;
+import android.graphics.Rect;
+
+public class ScrollBarView extends GLView {
+    @SuppressWarnings("unused")
+    private static final String TAG = "ScrollBarView";
+
+    public interface Listener {
+        void onScrollBarPositionChanged(int position);
+    }
+
+    private int mBarHeight;
+
+    private int mGripHeight;
+    private int mGripPosition;  // left side of the grip
+    private int mGripWidth;     // zero if the grip is disabled
+    private int mGivenGripWidth;
+
+    private int mContentPosition;
+    private int mContentTotal;
+
+    private Listener mListener;
+    private NinePatchTexture mScrollBarTexture;
+
+    public ScrollBarView(Context context, int gripHeight, int gripWidth) {
+        mScrollBarTexture = new NinePatchTexture(
+                context, R.drawable.scrollbar_handle_holo_dark);
+        mGripPosition = 0;
+        mGripWidth = 0;
+        mGivenGripWidth = gripWidth;
+        mGripHeight = gripHeight;
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    protected void onLayout(
+            boolean changed, int left, int top, int right, int bottom) {
+        if (!changed) return;
+        mBarHeight = bottom - top;
+    }
+
+    // The content position is between 0 to "total". The current position is
+    // in "position".
+    public void setContentPosition(int position, int total) {
+        if (position == mContentPosition && total == mContentTotal) {
+            return;
+        }
+
+        invalidate();
+
+        mContentPosition = position;
+        mContentTotal = total;
+
+        // If the grip cannot move, don't draw it.
+        if (mContentTotal <= 0) {
+            mGripPosition = 0;
+            mGripWidth = 0;
+            return;
+        }
+
+        // Map from the content range to scroll bar range.
+        //
+        // mContentTotal --> getWidth() - mGripWidth
+        // mContentPosition --> mGripPosition
+        mGripWidth = mGivenGripWidth;
+        float r = (getWidth() - mGripWidth) / (float) mContentTotal;
+        mGripPosition = Math.round(r * mContentPosition);
+    }
+
+    private void notifyContentPositionFromGrip() {
+        if (mContentTotal <= 0) return;
+        float r = (getWidth() - mGripWidth) / (float) mContentTotal;
+        int newContentPosition = Math.round(mGripPosition / r);
+        mListener.onScrollBarPositionChanged(newContentPosition);
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        super.render(canvas);
+        if (mGripWidth == 0) return;
+        Rect b = bounds();
+        int y = (mBarHeight - mGripHeight) / 2;
+        mScrollBarTexture.draw(canvas, mGripPosition, y, mGripWidth, mGripHeight);
+    }
+
+    // The onTouch() handler is disabled because now we don't want the user
+    // to drag the bar (it's an indicator only).
+    /*
+    @Override
+    protected boolean onTouch(MotionEvent event) {
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN: {
+                int x = (int) event.getX();
+                return (x >= mGripPosition && x < mGripPosition + mGripWidth);
+            }
+            case MotionEvent.ACTION_MOVE: {
+                // Adjust x by mGripWidth / 2 so the center of the grip
+                // matches the touch position.
+                int x = (int) event.getX() - mGripWidth / 2;
+                x = Utils.clamp(x, 0, getWidth() - mGripWidth);
+                if (mGripPosition != x) {
+                    mGripPosition = x;
+                    notifyContentPositionFromGrip();
+                    invalidate();
+                }
+                break;
+            }
+        }
+        return true;
+    }
+    */
+}
diff --git a/src/com/android/gallery3d/ui/ScrollView.java b/src/com/android/gallery3d/ui/ScrollView.java
new file mode 100644
index 0000000..f762833
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ScrollView.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.Utils;
+
+import android.content.Context;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View.MeasureSpec;
+
+// The current implementation can only scroll vertically.
+public class ScrollView extends GLView {
+
+    private static final int MIN_SCROLLER_HEIGHT = 20;
+
+    private NinePatchTexture mScroller;
+    private int mScrollLimit = 0;
+    private int mScrollerHeight = MIN_SCROLLER_HEIGHT;
+    private GestureDetector mGestureDetector;
+
+    public ScrollView(Context context) {
+        mScroller = new NinePatchTexture(context, R.drawable.scrollbar_handle_holo_dark);
+        mGestureDetector = new GestureDetector(context, new MyGestureListener());
+    }
+
+    private GLView getContentView() {
+        return getComponentCount() == 0 ? null : getComponent(0);
+    }
+
+    @Override
+    public void onLayout(boolean sizeChange, int l, int t, int r, int b) {
+        GLView content = getContentView();
+        int width = getWidth();
+        int height = getHeight();
+        content.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                MeasureSpec.UNSPECIFIED);
+        int contentHeight = content.getMeasuredHeight();
+        content.layout(0, 0, width, contentHeight);
+        if (height < contentHeight) {
+            mScrollLimit = contentHeight - height;
+            mScrollerHeight = Math.max(MIN_SCROLLER_HEIGHT,
+                    height * height / contentHeight);
+        } else {
+            mScrollLimit = 0;
+        }
+        mScrollY = Utils.clamp(mScrollY, 0, mScrollLimit);
+    }
+
+    @Override
+    public void render(GLCanvas canvas) {
+        GLView content = getContentView();
+        if (content == null) return;
+        int width = getWidth();
+        int height = getHeight();
+
+        canvas.save(GLCanvas.SAVE_FLAG_CLIP);
+        canvas.clipRect(0, 0, width, height);
+        super.render(canvas);
+        if (mScrollLimit > 0) {
+            int x = getWidth() - mScroller.getWidth();
+            int y = (height - mScrollerHeight) * mScrollY / mScrollLimit;
+            mScroller.draw(canvas, x, y, mScroller.getWidth(), mScrollerHeight);
+        }
+        canvas.restore();
+    }
+
+    @Override
+    public boolean onTouch(MotionEvent event) {
+        mGestureDetector.onTouchEvent(event);
+        return true;
+    }
+
+    private class MyGestureListener
+            extends GestureDetector.SimpleOnGestureListener {
+        @Override
+        public boolean onScroll(MotionEvent e1,
+                MotionEvent e2, float distanceX, float distanceY) {
+            mScrollY = Utils.clamp(mScrollY + (int) distanceY, 0, mScrollLimit);
+            invalidate();
+            return true;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/ScrollerHelper.java b/src/com/android/gallery3d/ui/ScrollerHelper.java
new file mode 100644
index 0000000..9f19cec
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ScrollerHelper.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import android.content.Context;
+import android.view.ViewConfiguration;
+import android.widget.OverScroller;
+
+public class ScrollerHelper {
+    private OverScroller mScroller;
+    private int mOverflingDistance;
+    private boolean mOverflingEnabled;
+
+    public ScrollerHelper(Context context) {
+        mScroller = new OverScroller(context);
+        ViewConfiguration configuration = ViewConfiguration.get(context);
+        mOverflingDistance = configuration.getScaledOverflingDistance();
+    }
+
+    public void setOverfling(boolean enabled) {
+        mOverflingEnabled = enabled;
+    }
+
+    /**
+     * Call this when you want to know the new location. The position will be
+     * updated and can be obtained by getPosition(). Returns true if  the
+     * animation is not yet finished.
+     */
+    public boolean advanceAnimation(long currentTimeMillis) {
+        return mScroller.computeScrollOffset();
+    }
+
+    public boolean isFinished() {
+        return mScroller.isFinished();
+    }
+
+    public void forceFinished() {
+        mScroller.forceFinished(true);
+    }
+
+    public int getPosition() {
+        return mScroller.getCurrX();
+    }
+
+    public void setPosition(int position) {
+        mScroller.startScroll(
+                position, 0,    // startX, startY
+                0, 0, 0);       // dx, dy, duration
+
+        // This forces the scroller to reach the final position.
+        mScroller.abortAnimation();
+    }
+
+    public void fling(int velocity, int min, int max) {
+        int currX = getPosition();
+        mScroller.fling(
+                currX, 0,      // startX, startY
+                velocity, 0,   // velocityX, velocityY
+                min, max,      // minX, maxX
+                0, 0,          // minY, maxY
+                mOverflingEnabled ? mOverflingDistance : 0, 0);
+    }
+
+    public boolean startScroll(int distance, int min, int max) {
+        int currPosition = mScroller.getCurrX();
+        int finalPosition = mScroller.getFinalX();
+        int newPosition = Utils.clamp(finalPosition + distance, min, max);
+        if (newPosition != currPosition) {
+            mScroller.startScroll(
+                currPosition, 0,                    // startX, startY
+                newPosition - currPosition, 0, 0);  // dx, dy, duration
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/SelectionDrawer.java b/src/com/android/gallery3d/ui/SelectionDrawer.java
new file mode 100644
index 0000000..2655a22
--- /dev/null
+++ b/src/com/android/gallery3d/ui/SelectionDrawer.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.Path;
+
+import android.graphics.Rect;
+
+/**
+ * Drawer class responsible for drawing selectable frame.
+ */
+public abstract class SelectionDrawer {
+    public static final int DATASOURCE_TYPE_NOT_CATEGORIZED = 0;
+    public static final int DATASOURCE_TYPE_LOCAL = 1;
+    public static final int DATASOURCE_TYPE_PICASA = 2;
+    public static final int DATASOURCE_TYPE_MTP = 3;
+    public static final int DATASOURCE_TYPE_CAMERA = 4;
+
+    public abstract void prepareDrawing();
+    public abstract void draw(GLCanvas canvas, Texture content,
+            int width, int height, int rotation, Path path,
+            int topIndex, int dataSourceType, int mediaType,
+            boolean wantCache, boolean isCaching);
+    public abstract void drawFocus(GLCanvas canvas, int width, int height);
+
+    public void draw(GLCanvas canvas, Texture content, int width, int height,
+            int rotation, Path path, int mediaType) {
+        draw(canvas, content, width, height, rotation, path, 0,
+                DATASOURCE_TYPE_NOT_CATEGORIZED, mediaType,
+                false, false);
+    }
+
+    public static void drawWithRotation(GLCanvas canvas, Texture content,
+            int x, int y, int width, int height, int rotation) {
+        if (rotation != 0) {
+            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+            canvas.rotate(rotation, 0, 0, 1);
+        }
+
+        content.draw(canvas, x, y, width, height);
+
+        if (rotation != 0) {
+            canvas.restore();
+        }
+    }
+
+    public static void drawWithRotationAndGray(GLCanvas canvas, Texture content,
+                int x, int y, int width, int height, int rotation,
+                int topIndex) {
+        if (rotation != 0) {
+            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+            canvas.rotate(rotation, 0, 0, 1);
+        }
+
+        if (topIndex > 0 && (content instanceof BasicTexture)) {
+            float ratio = Utils.clamp(0.3f + 0.2f * topIndex, 0f, 1f);
+            canvas.drawMixed((BasicTexture) content, 0xFF222222, ratio,
+                    x, y, width, height);
+        } else {
+            content.draw(canvas, x, y, width, height);
+        }
+
+        if (rotation != 0) {
+            canvas.restore();
+        }
+    }
+
+    public static void drawFrame(GLCanvas canvas, NinePatchTexture frame,
+            int x, int y, int width, int height) {
+        Rect p = frame.getPaddings();
+        frame.draw(canvas, x - p.left, y - p.top, width + p.left + p.right,
+                 height + p.top + p.bottom);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/SelectionManager.java b/src/com/android/gallery3d/ui/SelectionManager.java
new file mode 100644
index 0000000..b85ca7a
--- /dev/null
+++ b/src/com/android/gallery3d/ui/SelectionManager.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.app.GalleryContext;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+
+import android.content.Context;
+import android.os.Vibrator;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+public class SelectionManager {
+    @SuppressWarnings("unused")
+    private static final String TAG = "SelectionManager";
+
+    public static final int ENTER_SELECTION_MODE = 1;
+    public static final int LEAVE_SELECTION_MODE = 2;
+    public static final int SELECT_ALL_MODE = 3;
+
+    private Set<Path> mClickedSet;
+    private MediaSet mSourceMediaSet;
+    private final Vibrator mVibrator;
+    private SelectionListener mListener;
+    private DataManager mDataManager;
+    private boolean mInverseSelection;
+    private boolean mIsAlbumSet;
+    private boolean mInSelectionMode;
+    private boolean mAutoLeave = true;
+    private int mTotal;
+
+    public interface SelectionListener {
+        public void onSelectionModeChange(int mode);
+        public void onSelectionChange(Path path, boolean selected);
+    }
+
+    public SelectionManager(GalleryContext galleryContext, boolean isAlbumSet) {
+        Context context = galleryContext.getAndroidContext();
+        mDataManager = galleryContext.getDataManager();
+        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+        mClickedSet = new HashSet<Path>();
+        mIsAlbumSet = isAlbumSet;
+        mTotal = -1;
+    }
+
+    // Whether we will leave selection mode automatically once the number of
+    // selected items is down to zero.
+    public void setAutoLeaveSelectionMode(boolean enable) {
+        mAutoLeave = enable;
+    }
+
+    public void setSelectionListener(SelectionListener listener) {
+        mListener = listener;
+    }
+
+    public void selectAll() {
+        enterSelectionMode();
+        mInverseSelection = true;
+        mClickedSet.clear();
+        if (mListener != null) mListener.onSelectionModeChange(SELECT_ALL_MODE);
+    }
+
+    public void deSelectAll() {
+        leaveSelectionMode();
+        mInverseSelection = false;
+        mClickedSet.clear();
+    }
+
+    public boolean inSelectAllMode() {
+        return mInverseSelection;
+    }
+
+    public boolean inSelectionMode() {
+        return mInSelectionMode;
+    }
+
+    public void enterSelectionMode() {
+        if (mInSelectionMode) return;
+
+        mInSelectionMode = true;
+        mVibrator.vibrate(100);
+        if (mListener != null) mListener.onSelectionModeChange(ENTER_SELECTION_MODE);
+    }
+
+    public void leaveSelectionMode() {
+        if (!mInSelectionMode) return;
+
+        mInSelectionMode = false;
+        mInverseSelection = false;
+        mClickedSet.clear();
+        if (mListener != null) mListener.onSelectionModeChange(LEAVE_SELECTION_MODE);
+    }
+
+    public boolean isItemSelected(Path itemId) {
+        return mInverseSelection ^ mClickedSet.contains(itemId);
+    }
+
+    public int getSelectedCount() {
+        int count = mClickedSet.size();
+        if (mInverseSelection) {
+            if (mTotal < 0) {
+                mTotal = mIsAlbumSet
+                        ? mSourceMediaSet.getSubMediaSetCount()
+                        : mSourceMediaSet.getMediaItemCount();
+            }
+            count = mTotal - count;
+        }
+        return count;
+    }
+
+    public void toggle(Path path) {
+        if (mClickedSet.contains(path)) {
+            mClickedSet.remove(path);
+        } else {
+            enterSelectionMode();
+            mClickedSet.add(path);
+        }
+
+        if (mListener != null) mListener.onSelectionChange(path, isItemSelected(path));
+        if (getSelectedCount() == 0 && mAutoLeave) {
+            leaveSelectionMode();
+        }
+    }
+
+    private static void expandMediaSet(ArrayList<Path> items, MediaSet set) {
+        int subCount = set.getSubMediaSetCount();
+        for (int i = 0; i < subCount; i++) {
+            expandMediaSet(items, set.getSubMediaSet(i));
+        }
+        int total = set.getMediaItemCount();
+        int batch = 50;
+        int index = 0;
+
+        while (index < total) {
+            int count = index + batch < total
+                    ? batch
+                    : total - index;
+            ArrayList<MediaItem> list = set.getMediaItem(index, count);
+            for (MediaItem item : list) {
+                items.add(item.getPath());
+            }
+            index += batch;
+        }
+    }
+
+    public ArrayList<Path> getSelected(boolean expandSet) {
+        ArrayList<Path> selected = new ArrayList<Path>();
+        if (mIsAlbumSet) {
+            if (mInverseSelection) {
+                int max = mSourceMediaSet.getSubMediaSetCount();
+                for (int i = 0; i < max; i++) {
+                    MediaSet set = mSourceMediaSet.getSubMediaSet(i);
+                    Path id = set.getPath();
+                    if (!mClickedSet.contains(id)) {
+                        if (expandSet) {
+                            expandMediaSet(selected, set);
+                        } else {
+                            selected.add(id);
+                        }
+                    }
+                }
+            } else {
+                for (Path id : mClickedSet) {
+                    if (expandSet) {
+                        expandMediaSet(selected, mDataManager.getMediaSet(id));
+                    } else {
+                        selected.add(id);
+                    }
+                }
+            }
+        } else {
+            if (mInverseSelection) {
+
+                int total = mSourceMediaSet.getMediaItemCount();
+                int index = 0;
+                while (index < total) {
+                    int count = Math.min(total - index, MediaSet.MEDIAITEM_BATCH_FETCH_COUNT);
+                    ArrayList<MediaItem> list = mSourceMediaSet.getMediaItem(index, count);
+                    for (MediaItem item : list) {
+                        Path id = item.getPath();
+                        if (!mClickedSet.contains(id)) selected.add(id);
+                    }
+                    index += count;
+                }
+            } else {
+                for (Path id : mClickedSet) {
+                    selected.add(id);
+                }
+            }
+        }
+        return selected;
+    }
+
+    public void setSourceMediaSet(MediaSet set) {
+        mSourceMediaSet = set;
+        mTotal = -1;
+    }
+
+    public MediaSet getSourceMediaSet() {
+        return mSourceMediaSet;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/SlideshowView.java b/src/com/android/gallery3d/ui/SlideshowView.java
new file mode 100644
index 0000000..79a6bf0
--- /dev/null
+++ b/src/com/android/gallery3d/ui/SlideshowView.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.anim.CanvasAnimation;
+import com.android.gallery3d.anim.FloatAnimation;
+
+import android.graphics.Bitmap;
+import android.graphics.PointF;
+
+import java.util.Random;
+import javax.microedition.khronos.opengles.GL11;
+
+public class SlideshowView extends GLView {
+    @SuppressWarnings("unused")
+    private static final String TAG = "SlideshowView";
+
+    private static final int SLIDESHOW_DURATION = 3500;
+    private static final int TRANSITION_DURATION = 1000;
+
+    private static final float SCALE_SPEED = 0.20f ;
+    private static final float MOVE_SPEED = SCALE_SPEED;
+
+    private int mCurrentRotation;
+    private BitmapTexture mCurrentTexture;
+    private SlideshowAnimation mCurrentAnimation;
+
+    private int mPrevRotation;
+    private BitmapTexture mPrevTexture;
+    private SlideshowAnimation mPrevAnimation;
+
+    private final FloatAnimation mTransitionAnimation =
+            new FloatAnimation(0, 1, TRANSITION_DURATION);
+
+    private Random mRandom = new Random();
+
+    public void next(Bitmap bitmap, int rotation) {
+
+        mTransitionAnimation.start();
+
+        if (mPrevTexture != null) {
+            mPrevTexture.getBitmap().recycle();
+            mPrevTexture.recycle();
+        }
+
+        mPrevTexture = mCurrentTexture;
+        mPrevAnimation = mCurrentAnimation;
+        mPrevRotation = mCurrentRotation;
+
+        mCurrentRotation = rotation;
+        mCurrentTexture = new BitmapTexture(bitmap);
+        if (((rotation / 90) & 0x01) == 0) {
+            mCurrentAnimation = new SlideshowAnimation(
+                    mCurrentTexture.getWidth(), mCurrentTexture.getHeight(),
+                    mRandom);
+        } else {
+            mCurrentAnimation = new SlideshowAnimation(
+                    mCurrentTexture.getHeight(), mCurrentTexture.getWidth(),
+                    mRandom);
+        }
+        mCurrentAnimation.start();
+
+        invalidate();
+    }
+
+    public void release() {
+        if (mPrevTexture != null) {
+            mPrevTexture.recycle();
+            mPrevTexture = null;
+        }
+        if (mCurrentTexture != null) {
+            mCurrentTexture.recycle();
+            mCurrentTexture = null;
+        }
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        long currentTimeMillis = canvas.currentAnimationTimeMillis();
+        boolean requestRender = mTransitionAnimation.calculate(currentTimeMillis);
+        GL11 gl = canvas.getGLInstance();
+        gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
+        float alpha = mPrevTexture == null ? 1f : mTransitionAnimation.get();
+
+        if (mPrevTexture != null && alpha != 1f) {
+            requestRender |= mPrevAnimation.calculate(currentTimeMillis);
+            canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
+            canvas.setAlpha(1f - alpha);
+            mPrevAnimation.apply(canvas);
+            canvas.rotate(mPrevRotation, 0, 0, 1);
+            mPrevTexture.draw(canvas, -mPrevTexture.getWidth() / 2,
+                    -mPrevTexture.getHeight() / 2);
+            canvas.restore();
+        }
+        if (mCurrentTexture != null) {
+            requestRender |= mCurrentAnimation.calculate(currentTimeMillis);
+            canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
+            canvas.setAlpha(alpha);
+            mCurrentAnimation.apply(canvas);
+            canvas.rotate(mCurrentRotation, 0, 0, 1);
+            mCurrentTexture.draw(canvas, -mCurrentTexture.getWidth() / 2,
+                    -mCurrentTexture.getHeight() / 2);
+            canvas.restore();
+        }
+        if (requestRender) invalidate();
+        gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+    }
+
+    private class SlideshowAnimation extends CanvasAnimation {
+        private final int mWidth;
+        private final int mHeight;
+
+        private final PointF mMovingVector;
+        private float mProgress;
+
+        public SlideshowAnimation(int width, int height, Random random) {
+            mWidth = width;
+            mHeight = height;
+            mMovingVector = new PointF(
+                    MOVE_SPEED * mWidth * (random.nextFloat() - 0.5f),
+                    MOVE_SPEED * mHeight * (random.nextFloat() - 0.5f));
+            setDuration(SLIDESHOW_DURATION);
+        }
+
+        @Override
+        public void apply(GLCanvas canvas) {
+            int viewWidth = getWidth();
+            int viewHeight = getHeight();
+
+            float initScale = Math.min(2f, Math.min((float)
+                    viewWidth / mWidth, (float) viewHeight / mHeight));
+            float scale = initScale * (1 + SCALE_SPEED * mProgress);
+
+            float centerX = viewWidth / 2 + mMovingVector.x * mProgress;
+            float centerY = viewHeight / 2 + mMovingVector.y * mProgress;
+
+            canvas.translate(centerX, centerY, 0);
+            canvas.scale(scale, scale, 0);
+        }
+
+        @Override
+        public int getCanvasSaveFlags() {
+            return GLCanvas.SAVE_FLAG_MATRIX;
+        }
+
+        @Override
+        protected void onCalculate(float progress) {
+            mProgress = progress;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/SlotView.java b/src/com/android/gallery3d/ui/SlotView.java
new file mode 100644
index 0000000..a8ca5f2
--- /dev/null
+++ b/src/com/android/gallery3d/ui/SlotView.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.anim.Animation;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.ui.PositionRepository.Position;
+import com.android.gallery3d.util.LinkedNode;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.animation.DecelerateInterpolator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class SlotView extends GLView {
+    @SuppressWarnings("unused")
+    private static final String TAG = "SlotView";
+
+    private static final boolean WIDE = true;
+
+    private static final int INDEX_NONE = -1;
+
+    public interface Listener {
+        public void onSingleTapUp(int index);
+        public void onLongTap(int index);
+        public void onScrollPositionChanged(int position, int total);
+    }
+
+    public static class SimpleListener implements Listener {
+        public void onSingleTapUp(int index) {}
+        public void onLongTap(int index) {}
+        public void onScrollPositionChanged(int position, int total) {}
+    }
+
+    private final GestureDetector mGestureDetector;
+    private final ScrollerHelper mScroller;
+    private final Paper mPaper = new Paper();
+
+    private Listener mListener;
+    private UserInteractionListener mUIListener;
+
+    // Use linked hash map to keep the rendering order
+    private HashMap<DisplayItem, ItemEntry> mItems =
+            new HashMap<DisplayItem, ItemEntry>();
+
+    public LinkedNode.List<ItemEntry> mItemList = LinkedNode.newList();
+
+    // This is used for multipass rendering
+    private ArrayList<ItemEntry> mCurrentItems = new ArrayList<ItemEntry>();
+    private ArrayList<ItemEntry> mNextItems = new ArrayList<ItemEntry>();
+
+    private boolean mMoreAnimation = false;
+    private MyAnimation mAnimation = null;
+    private final Position mTempPosition = new Position();
+    private final Layout mLayout = new Layout();
+    private PositionProvider mPositions;
+    private int mStartIndex = INDEX_NONE;
+
+    // whether the down action happened while the view is scrolling.
+    private boolean mDownInScrolling;
+    private int mOverscrollEffect = OVERSCROLL_3D;
+
+    public static final int OVERSCROLL_3D = 0;
+    public static final int OVERSCROLL_SYSTEM = 1;
+    public static final int OVERSCROLL_NONE = 2;
+
+    public SlotView(Context context) {
+        mGestureDetector =
+                new GestureDetector(context, new MyGestureListener());
+        mScroller = new ScrollerHelper(context);
+    }
+
+    public void setCenterIndex(int index) {
+        int slotCount = mLayout.mSlotCount;
+        if (index < 0 || index >= slotCount) {
+            return;
+        }
+        Rect rect = mLayout.getSlotRect(index);
+        int position = WIDE
+                ? (rect.left + rect.right - getWidth()) / 2
+                : (rect.top + rect.bottom - getHeight()) / 2;
+        setScrollPosition(position);
+    }
+
+    public void makeSlotVisible(int index) {
+        Rect rect = mLayout.getSlotRect(index);
+        int visibleBegin = WIDE ? mScrollX : mScrollY;
+        int visibleLength = WIDE ? getWidth() : getHeight();
+        int visibleEnd = visibleBegin + visibleLength;
+        int slotBegin = WIDE ? rect.left : rect.top;
+        int slotEnd = WIDE ? rect.right : rect.bottom;
+
+        int position = visibleBegin;
+        if (visibleLength < slotEnd - slotBegin) {
+            position = visibleBegin;
+        } else if (slotBegin < visibleBegin) {
+            position = slotBegin;
+        } else if (slotEnd > visibleEnd) {
+            position = slotEnd - visibleLength;
+        }
+
+        setScrollPosition(position);
+    }
+
+    public void setScrollPosition(int position) {
+        position = Utils.clamp(position, 0, mLayout.getScrollLimit());
+        mScroller.setPosition(position);
+        updateScrollPosition(position, false);
+    }
+
+    public void setSlotSize(int slotWidth, int slotHeight) {
+        mLayout.setSlotSize(slotWidth, slotHeight);
+    }
+
+    @Override
+    public void addComponent(GLView view) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean removeComponent(GLView view) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void onLayout(boolean changeSize, int l, int t, int r, int b) {
+        if (!changeSize) return;
+        mLayout.setSize(r - l, b - t);
+        onLayoutChanged(r - l, b - t);
+        if (mOverscrollEffect == OVERSCROLL_3D) {
+            mPaper.setSize(r - l, b - t);
+        }
+    }
+
+    protected void onLayoutChanged(int width, int height) {
+    }
+
+    public void startTransition(PositionProvider position) {
+        mPositions = position;
+        mAnimation = new MyAnimation();
+        mAnimation.start();
+        if (mItems.size() != 0) invalidate();
+    }
+
+    public void savePositions(PositionRepository repository) {
+        repository.clear();
+        LinkedNode.List<ItemEntry> list = mItemList;
+        ItemEntry entry = list.getFirst();
+        Position position = new Position();
+        while (entry != null) {
+            position.set(entry.target);
+            position.x -= mScrollX;
+            position.y -= mScrollY;
+            repository.putPosition(entry.item.getIdentity(), position);
+            entry = list.nextOf(entry);
+        }
+    }
+
+    private void updateScrollPosition(int position, boolean force) {
+        if (!force && (WIDE ? position == mScrollX : position == mScrollY)) return;
+        if (WIDE) {
+            mScrollX = position;
+        } else {
+            mScrollY = position;
+        }
+        mLayout.setScrollPosition(position);
+        onScrollPositionChanged(position);
+    }
+
+    protected void onScrollPositionChanged(int newPosition) {
+        int limit = mLayout.getScrollLimit();
+        mListener.onScrollPositionChanged(newPosition, limit);
+    }
+
+    public void putDisplayItem(Position target, Position base, DisplayItem item) {
+        ItemEntry entry = new ItemEntry(item, target, base);
+        mItemList.insertLast(entry);
+        mItems.put(item, entry);
+    }
+
+    public void removeDisplayItem(DisplayItem item) {
+        ItemEntry entry = mItems.remove(item);
+        if (entry != null) entry.remove();
+    }
+
+    public Rect getSlotRect(int slotIndex) {
+        return mLayout.getSlotRect(slotIndex);
+    }
+
+    @Override
+    protected boolean onTouch(MotionEvent event) {
+        if (mUIListener != null) mUIListener.onUserInteraction();
+        mGestureDetector.onTouchEvent(event);
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mDownInScrolling = !mScroller.isFinished();
+                mScroller.forceFinished();
+                break;
+        }
+        return true;
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    public void setUserInteractionListener(UserInteractionListener listener) {
+        mUIListener = listener;
+    }
+
+    public void setOverscrollEffect(int kind) {
+        mOverscrollEffect = kind;
+        mScroller.setOverfling(kind == OVERSCROLL_SYSTEM);
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        canvas.save(GLCanvas.SAVE_FLAG_CLIP);
+        canvas.clipRect(0, 0, getWidth(), getHeight());
+        super.render(canvas);
+
+        long currentTimeMillis = canvas.currentAnimationTimeMillis();
+        boolean more = mScroller.advanceAnimation(currentTimeMillis);
+        boolean paperActive = (mOverscrollEffect == OVERSCROLL_3D)
+                && mPaper.advanceAnimation(currentTimeMillis);
+        updateScrollPosition(mScroller.getPosition(), false);
+        float interpolate = 1f;
+        if (mAnimation != null) {
+            more |= mAnimation.calculate(currentTimeMillis);
+            interpolate = mAnimation.value;
+        }
+
+        more |= paperActive;
+
+        if (WIDE) {
+            canvas.translate(-mScrollX, 0, 0);
+        } else {
+            canvas.translate(0, -mScrollY, 0);
+        }
+
+        LinkedNode.List<ItemEntry> list = mItemList;
+        for (ItemEntry entry = list.getLast(); entry != null;) {
+            if (renderItem(canvas, entry, interpolate, 0, paperActive)) {
+                mCurrentItems.add(entry);
+            }
+            entry = list.previousOf(entry);
+        }
+
+        int pass = 1;
+        while (!mCurrentItems.isEmpty()) {
+            for (int i = 0, n = mCurrentItems.size(); i < n; i++) {
+                ItemEntry entry = mCurrentItems.get(i);
+                if (renderItem(canvas, entry, interpolate, pass, paperActive)) {
+                    mNextItems.add(entry);
+                }
+            }
+            mCurrentItems.clear();
+            // swap mNextItems with mCurrentItems
+            ArrayList<ItemEntry> tmp = mNextItems;
+            mNextItems = mCurrentItems;
+            mCurrentItems = tmp;
+            pass += 1;
+        }
+
+        if (WIDE) {
+            canvas.translate(mScrollX, 0, 0);
+        } else {
+            canvas.translate(0, mScrollY, 0);
+        }
+
+        if (more) invalidate();
+        if (mMoreAnimation && !more && mUIListener != null) {
+            mUIListener.onUserInteractionEnd();
+        }
+        mMoreAnimation = more;
+        canvas.restore();
+    }
+
+    private boolean renderItem(GLCanvas canvas, ItemEntry entry,
+            float interpolate, int pass, boolean paperActive) {
+        canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
+        Position position = entry.target;
+        if (mPositions != null) {
+            position = mTempPosition;
+            position.set(entry.target);
+            position.x -= mScrollX;
+            position.y -= mScrollY;
+            Position source = mPositions
+                    .getPosition(entry.item.getIdentity(), position);
+            source.x += mScrollX;
+            source.y += mScrollY;
+            position = mTempPosition;
+            Position.interpolate(
+                    source, entry.target, position, interpolate);
+        }
+        canvas.multiplyAlpha(position.alpha);
+        if (paperActive) {
+            canvas.multiplyMatrix(mPaper.getTransform(
+                    position, entry.base, mScrollX, mScrollY), 0);
+        } else {
+            canvas.translate(position.x, position.y, position.z);
+        }
+        canvas.rotate(position.theta, 0, 0, 1);
+        boolean more = entry.item.render(canvas, pass);
+        canvas.restore();
+        return more;
+    }
+
+    public static class MyAnimation extends Animation {
+        public float value;
+
+        public MyAnimation() {
+            setInterpolator(new DecelerateInterpolator(4));
+            setDuration(1500);
+        }
+
+        @Override
+        protected void onCalculate(float progress) {
+            value = progress;
+        }
+    }
+
+    private static class ItemEntry extends LinkedNode {
+        public DisplayItem item;
+        public Position target;
+        public Position base;
+
+        public ItemEntry(DisplayItem item, Position target, Position base) {
+            this.item = item;
+            this.target = target;
+            this.base = base;
+        }
+    }
+
+    public static class Layout {
+
+        private int mVisibleStart;
+        private int mVisibleEnd;
+
+        private int mSlotCount;
+        private int mSlotWidth;
+        private int mSlotHeight;
+
+        private int mWidth;
+        private int mHeight;
+
+        private int mUnitCount;
+        private int mContentLength;
+        private int mScrollPosition;
+
+        private int mVerticalPadding;
+        private int mHorizontalPadding;
+
+        public void setSlotSize(int slotWidth, int slotHeight) {
+            mSlotWidth = slotWidth;
+            mSlotHeight = slotHeight;
+        }
+
+        public boolean setSlotCount(int slotCount) {
+            mSlotCount = slotCount;
+            int hPadding = mHorizontalPadding;
+            int vPadding = mVerticalPadding;
+            initLayoutParameters();
+            return vPadding != mVerticalPadding || hPadding != mHorizontalPadding;
+        }
+
+        public Rect getSlotRect(int index) {
+            int col, row;
+            if (WIDE) {
+                col = index / mUnitCount;
+                row = index - col * mUnitCount;
+            } else {
+                row = index / mUnitCount;
+                col = index - row * mUnitCount;
+            }
+
+            int x = mHorizontalPadding + col * mSlotWidth;
+            int y = mVerticalPadding + row * mSlotHeight;
+            return new Rect(x, y, x + mSlotWidth, y + mSlotHeight);
+        }
+
+        public int getContentLength() {
+            return mContentLength;
+        }
+
+        // Calculate
+        // (1) mUnitCount: the number of slots we can fit into one column (or row).
+        // (2) mContentLength: the width (or height) we need to display all the
+        //     columns (rows).
+        // (3) padding[]: the vertical and horizontal padding we need in order
+        //     to put the slots towards to the center of the display.
+        //
+        // The "major" direction is the direction the user can scroll. The other
+        // direction is the "minor" direction.
+        //
+        // The comments inside this method are the description when the major
+        // directon is horizontal (X), and the minor directon is vertical (Y).
+        private void initLayoutParameters(
+                int majorLength, int minorLength,  /* The view width and height */
+                int majorUnitSize, int minorUnitSize,  /* The slot width and height */
+                int[] padding) {
+            int unitCount = minorLength / minorUnitSize;
+            if (unitCount == 0) unitCount = 1;
+            mUnitCount = unitCount;
+
+            // We put extra padding above and below the column.
+            int availableUnits = Math.min(mUnitCount, mSlotCount);
+            padding[0] = (minorLength - availableUnits * minorUnitSize) / 2;
+
+            // Then calculate how many columns we need for all slots.
+            int count = ((mSlotCount + mUnitCount - 1) / mUnitCount);
+            mContentLength = count * majorUnitSize;
+
+            // If the content length is less then the screen width, put
+            // extra padding in left and right.
+            padding[1] = Math.max(0, (majorLength - mContentLength) / 2);
+        }
+
+        private void initLayoutParameters() {
+            int[] padding = new int[2];
+            if (WIDE) {
+                initLayoutParameters(mWidth, mHeight, mSlotWidth, mSlotHeight, padding);
+                mVerticalPadding = padding[0];
+                mHorizontalPadding = padding[1];
+            } else {
+                initLayoutParameters(mHeight, mWidth, mSlotHeight, mSlotWidth, padding);
+                mVerticalPadding = padding[1];
+                mHorizontalPadding = padding[0];
+            }
+            updateVisibleSlotRange();
+        }
+
+        public void setSize(int width, int height) {
+            mWidth = width;
+            mHeight = height;
+            initLayoutParameters();
+        }
+
+        private void updateVisibleSlotRange() {
+            int position = mScrollPosition;
+
+            if (WIDE) {
+                int start = Math.max(0, (position / mSlotWidth) * mUnitCount);
+                int end = Math.min(mSlotCount, mUnitCount
+                        * (position + mWidth + mSlotWidth - 1) / mSlotWidth);
+                setVisibleRange(start, end);
+            } else {
+                int start = Math.max(0, mUnitCount * (position / mSlotHeight));
+                int end = Math.min(mSlotCount, mUnitCount
+                        * (position + mHeight + mSlotHeight - 1) / mSlotHeight);
+                setVisibleRange(start, end);
+            }
+        }
+
+        public void setScrollPosition(int position) {
+            if (mScrollPosition == position) return;
+            mScrollPosition = position;
+            updateVisibleSlotRange();
+        }
+
+        private void setVisibleRange(int start, int end) {
+            if (start == mVisibleStart && end == mVisibleEnd) return;
+            if (start < end) {
+                mVisibleStart = start;
+                mVisibleEnd = end;
+            } else {
+                mVisibleStart = mVisibleEnd = 0;
+            }
+        }
+
+        public int getVisibleStart() {
+            return mVisibleStart;
+        }
+
+        public int getVisibleEnd() {
+            return mVisibleEnd;
+        }
+
+        public int getSlotIndexByPosition(float x, float y) {
+            float absoluteX = x + (WIDE ? mScrollPosition : 0);
+            absoluteX -= mHorizontalPadding;
+            int columnIdx = (int) (absoluteX + 0.5) / mSlotWidth;
+            if ((absoluteX - mSlotWidth * columnIdx) < 0
+                    || (!WIDE && columnIdx >= mUnitCount)) {
+                return INDEX_NONE;
+            }
+
+            float absoluteY = y + (WIDE ? 0 : mScrollPosition);
+            absoluteY -= mVerticalPadding;
+            int rowIdx = (int) (absoluteY + 0.5) / mSlotHeight;
+            if (((absoluteY - mSlotHeight * rowIdx) < 0)
+                    || (WIDE && rowIdx >= mUnitCount)) {
+                return INDEX_NONE;
+            }
+            int index = WIDE
+                    ? (columnIdx * mUnitCount + rowIdx)
+                    : (rowIdx * mUnitCount + columnIdx);
+
+            return index >= mSlotCount ? INDEX_NONE : index;
+        }
+
+        public int getScrollLimit() {
+            int limit = WIDE ? mContentLength - mWidth : mContentLength - mHeight;
+            return limit <= 0 ? 0 : limit;
+        }
+    }
+
+    private class MyGestureListener
+            extends GestureDetector.SimpleOnGestureListener {
+
+        @Override
+        public boolean onFling(MotionEvent e1,
+                MotionEvent e2, float velocityX, float velocityY) {
+            int scrollLimit = mLayout.getScrollLimit();
+            if (scrollLimit == 0) return false;
+            float velocity = WIDE ? velocityX : velocityY;
+            mScroller.fling((int) -velocity, 0, scrollLimit);
+            if (mUIListener != null) mUIListener.onUserInteractionBegin();
+            invalidate();
+            return true;
+        }
+
+        @Override
+        public boolean onScroll(MotionEvent e1,
+                MotionEvent e2, float distanceX, float distanceY) {
+            float distance = WIDE ? distanceX : distanceY;
+            boolean canMove = mScroller.startScroll(
+                    Math.round(distance), 0, mLayout.getScrollLimit());
+            if (mOverscrollEffect == OVERSCROLL_3D && !canMove) {
+                mPaper.overScroll(distance);
+            }
+            invalidate();
+            return true;
+        }
+
+        @Override
+        public boolean onSingleTapUp(MotionEvent e) {
+            if (mDownInScrolling) return true;
+            int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
+            if (index != INDEX_NONE) mListener.onSingleTapUp(index);
+            return true;
+        }
+
+        @Override
+        public void onLongPress(MotionEvent e) {
+            if (mDownInScrolling) return;
+            lockRendering();
+            try {
+                int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
+                if (index != INDEX_NONE) mListener.onLongTap(index);
+            } finally {
+                unlockRendering();
+            }
+        }
+    }
+
+    public void setStartIndex(int index) {
+        mStartIndex = index;
+    }
+
+    // Return true if the layout parameters have been changed
+    public boolean setSlotCount(int slotCount) {
+        boolean changed = mLayout.setSlotCount(slotCount);
+
+        // mStartIndex is applied the first time setSlotCount is called.
+        if (mStartIndex != INDEX_NONE) {
+            setCenterIndex(mStartIndex);
+            mStartIndex = INDEX_NONE;
+        }
+        updateScrollPosition(WIDE ? mScrollX : mScrollY, true);
+        return changed;
+    }
+
+    public int getVisibleStart() {
+        return mLayout.getVisibleStart();
+    }
+
+    public int getVisibleEnd() {
+        return mLayout.getVisibleEnd();
+    }
+
+    public int getScrollX() {
+        return mScrollX;
+    }
+
+    public int getScrollY() {
+        return mScrollY;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/StaticBackground.java b/src/com/android/gallery3d/ui/StaticBackground.java
new file mode 100644
index 0000000..08c55c3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/StaticBackground.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.content.Context;
+
+public class StaticBackground extends GLView {
+
+    private Context mContext;
+    private int mLandscapeResource;
+    private int mPortraitResource;
+
+    private BasicTexture mBackground;
+    private boolean mIsLandscape = false;
+
+    public StaticBackground(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    protected void onLayout(boolean changeSize, int l, int t, int r, int b) {
+        setOrientation(getWidth() >= getHeight());
+    }
+
+    private void setOrientation(boolean isLandscape) {
+        if (mIsLandscape == isLandscape) return;
+        mIsLandscape = isLandscape;
+        if (mBackground != null) mBackground.recycle();
+        mBackground = new ResourceTexture(
+                mContext, mIsLandscape ? mLandscapeResource : mPortraitResource);
+        invalidate();
+    }
+
+    public void setImage(int landscapeId, int portraitId) {
+        mLandscapeResource = landscapeId;
+        mPortraitResource = portraitId;
+        if (mBackground != null) mBackground.recycle();
+        mBackground = new ResourceTexture(
+                mContext, mIsLandscape ? landscapeId : portraitId);
+        invalidate();
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        //mBackground.draw(canvas, 0, 0, getWidth(), getHeight());
+        canvas.fillRect(0, 0, getWidth(), getHeight(), 0xFF000000);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/StringTexture.java b/src/com/android/gallery3d/ui/StringTexture.java
new file mode 100644
index 0000000..71ab9b3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/StringTexture.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint.FontMetricsInt;
+import android.graphics.Typeface;
+import android.text.TextPaint;
+import android.text.TextUtils;
+
+// StringTexture is a texture shows the content of a specified String.
+//
+// To create a StringTexture, use the newInstance() method and specify
+// the String, the font size, and the color.
+class StringTexture extends CanvasTexture {
+    private final String mText;
+    private final TextPaint mPaint;
+    private final FontMetricsInt mMetrics;
+
+    private StringTexture(String text, TextPaint paint,
+            FontMetricsInt metrics, int width, int height) {
+        super(width, height);
+        mText = text;
+        mPaint = paint;
+        mMetrics = metrics;
+    }
+
+    public static TextPaint getDefaultPaint(float textSize, int color) {
+        TextPaint paint = new TextPaint();
+        paint.setTextSize(textSize);
+        paint.setAntiAlias(true);
+        paint.setColor(color);
+        paint.setShadowLayer(2f, 0f, 0f, Color.BLACK);
+        return paint;
+    }
+
+    public static StringTexture newInstance(
+            String text, float textSize, int color) {
+        return newInstance(text, getDefaultPaint(textSize, color));
+    }
+
+    public static StringTexture newInstance(
+            String text, String postfix, float textSize, int color,
+            float lengthLimit, boolean isBold) {
+        TextPaint paint = getDefaultPaint(textSize, color);
+        if (isBold) {
+            paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
+        }
+        if (postfix != null) {
+            lengthLimit = Math.max(0,
+                    lengthLimit - paint.measureText(postfix));
+            text = TextUtils.ellipsize(text, paint, lengthLimit,
+                    TextUtils.TruncateAt.END).toString() + postfix;
+        } else {
+            text = TextUtils.ellipsize(
+                    text, paint, lengthLimit, TextUtils.TruncateAt.END).toString();
+        }
+        return newInstance(text, paint);
+    }
+
+    private static StringTexture newInstance(String text, TextPaint paint) {
+        FontMetricsInt metrics = paint.getFontMetricsInt();
+        int width = (int) Math.ceil(paint.measureText(text));
+        int height = metrics.bottom - metrics.top;
+        // The texture size needs to be at least 1x1.
+        if (width <= 0) width = 1;
+        if (height <= 0) height = 1;
+        return new StringTexture(text, paint, metrics, width, height);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas, Bitmap backing) {
+        canvas.translate(0, -mMetrics.ascent);
+        canvas.drawText(mText, 0, 0, mPaint);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/StripDrawer.java b/src/com/android/gallery3d/ui/StripDrawer.java
new file mode 100644
index 0000000..0910612
--- /dev/null
+++ b/src/com/android/gallery3d/ui/StripDrawer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.Path;
+
+import android.content.Context;
+import android.graphics.Rect;
+
+public class StripDrawer extends SelectionDrawer {
+    private NinePatchTexture mFocusBox;
+    private Rect mFocusBoxPadding;
+
+    public StripDrawer(Context context) {
+        mFocusBox = new NinePatchTexture(context, R.drawable.focus_box);
+        mFocusBoxPadding = mFocusBox.getPaddings();
+    }
+
+    @Override
+    public void prepareDrawing() {
+    }
+
+    @Override
+    public void draw(GLCanvas canvas, Texture content, int width, int height,
+            int rotation, Path path, int topIndex, int dataSourceType,
+            int mediaType, boolean wantCache, boolean isCaching) {
+
+        int x = -width / 2;
+        int y = -height / 2;
+
+        drawWithRotation(canvas, content, x, y, width, height, rotation);
+    }
+
+    @Override
+    public void drawFocus(GLCanvas canvas, int width, int height) {
+        int x = -width / 2;
+        int y = -height / 2;
+        Rect p = mFocusBoxPadding;
+        mFocusBox.draw(canvas, x - p.left, y - p.top,
+                width + p.left + p.right, height + p.top + p.bottom);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/SynchronizedHandler.java b/src/com/android/gallery3d/ui/SynchronizedHandler.java
new file mode 100644
index 0000000..bd494a3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/SynchronizedHandler.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import android.os.Handler;
+import android.os.Message;
+
+public class SynchronizedHandler extends Handler {
+
+    private final GLRoot mRoot;
+
+    public SynchronizedHandler(GLRoot root) {
+        mRoot = Utils.checkNotNull(root);
+    }
+
+    @Override
+    public void dispatchMessage(Message message) {
+        mRoot.lockRenderThread();
+        try {
+            super.dispatchMessage(message);
+        } finally {
+            mRoot.unlockRenderThread();
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/TextButton.java b/src/com/android/gallery3d/ui/TextButton.java
new file mode 100644
index 0000000..c6b85bf
--- /dev/null
+++ b/src/com/android/gallery3d/ui/TextButton.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import static com.android.gallery3d.ui.TextButtonConfig.*;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.MotionEvent;
+
+public class TextButton extends Label {
+    private static final String TAG = "TextButton";
+    private boolean mPressed;
+    private Texture mPressedBackground;
+    private Texture mNormalBackground;
+    private OnClickedListener mOnClickListener;
+
+    public interface OnClickedListener {
+        public void onClicked(GLView source);
+    }
+
+    public TextButton(Context context, int label) {
+        super(context, label);
+        setPaddings(HORIZONTAL_PADDINGS, VERTICAL_PADDINGS,
+                HORIZONTAL_PADDINGS, VERTICAL_PADDINGS);
+    }
+
+    public void setOnClickListener(OnClickedListener listener) {
+        mOnClickListener = listener;
+    }
+
+    public void setPressedBackground(Texture texture) {
+        mPressedBackground = texture;
+    }
+
+    public void setNormalBackground(Texture texture) {
+        mNormalBackground = texture;
+    }
+
+    @SuppressWarnings("fallthrough")
+    @Override
+    protected boolean onTouch(MotionEvent event) {
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mPressed = true;
+                invalidate();
+                break;
+            case MotionEvent.ACTION_UP:
+                if (mOnClickListener != null) {
+                    mOnClickListener.onClicked(this);
+                }
+                // fall-through
+            case MotionEvent.ACTION_CANCEL:
+                mPressed = false;
+                invalidate();
+                break;
+        }
+        return true;
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        Texture bg = mPressed ? mPressedBackground : mNormalBackground;
+        if (bg != null) {
+            int width = getWidth();
+            int height = getHeight();
+            if (bg instanceof NinePatchTexture) {
+                Rect p = ((NinePatchTexture) bg).getPaddings();
+                bg.draw(canvas, -p.left, -p.top,
+                        width + p.left + p.right, height + p.top + p.bottom);
+            } else {
+                bg.draw(canvas, 0, 0, width, height);
+            }
+        }
+        super.render(canvas);
+    }
+}
diff --git a/src/com/android/gallery3d/ui/Texture.java b/src/com/android/gallery3d/ui/Texture.java
new file mode 100644
index 0000000..feb7b0a
--- /dev/null
+++ b/src/com/android/gallery3d/ui/Texture.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+// Texture is a rectangular image which can be drawn on GLCanvas.
+// The isOpaque() function gives a hint about whether the texture is opaque,
+// so the drawing can be done faster.
+//
+// This is the current texture hierarchy:
+//
+// Texture
+// -- ColorTexture
+// -- BasicTexture
+//    -- RawTexture
+//    -- UploadedTexture
+//       -- BitmapTexture
+//       -- Tile
+//       -- ResourceTexture
+//          -- NinePatchTexture
+//       -- CanvasTexture
+//          -- DrawableTexture
+//          -- StringTexture
+//
+public interface Texture {
+    public int getWidth();
+    public int getHeight();
+    public void draw(GLCanvas canvas, int x, int y);
+    public void draw(GLCanvas canvas, int x, int y, int w, int h);
+    public boolean isOpaque();
+}
diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java
new file mode 100644
index 0000000..cf06851
--- /dev/null
+++ b/src/com/android/gallery3d/ui/TileImageView.java
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.app.GalleryContext;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.ThreadPool;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class TileImageView extends GLView {
+    public static final int SIZE_UNKNOWN = -1;
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "TileImageView";
+
+    // TILE_SIZE must be 2^N - 2. We put one pixel border in each side of the
+    // texture to avoid seams between tiles.
+    private static final int TILE_SIZE = 254;
+    private static final int TILE_BORDER = 1;
+    private static final int UPLOAD_LIMIT = 1;
+
+    /*
+     *  This is the tile state in the CPU side.
+     *  Life of a Tile:
+     *      ACTIVATED (initial state)
+     *              --> IN_QUEUE - by queueForDecode()
+     *              --> RECYCLED - by recycleTile()
+     *      IN_QUEUE --> DECODING - by decodeTile()
+     *               --> RECYCLED - by recycleTile)
+     *      DECODING --> RECYCLING - by recycleTile()
+     *               --> DECODED  - by decodeTile()
+     *      RECYCLING --> RECYCLED - by decodeTile()
+     *      DECODED --> ACTIVATED - (after the decoded bitmap is uploaded)
+     *      DECODED --> RECYCLED - by recycleTile()
+     *      RECYCLED --> ACTIVATED - by obtainTile()
+     */
+    private static final int STATE_ACTIVATED = 0x01;
+    private static final int STATE_IN_QUEUE = 0x02;
+    private static final int STATE_DECODING = 0x04;
+    private static final int STATE_DECODED = 0x08;
+    private static final int STATE_RECYCLING = 0x10;
+    private static final int STATE_RECYCLED = 0x20;
+
+    private Model mModel;
+    protected BitmapTexture mBackupImage;
+    protected int mLevelCount;  // cache the value of mScaledBitmaps.length
+
+    // The mLevel variable indicates which level of bitmap we should use.
+    // Level 0 means the original full-sized bitmap, and a larger value means
+    // a smaller scaled bitmap (The width and height of each scaled bitmap is
+    // half size of the previous one). If the value is in [0, mLevelCount), we
+    // use the bitmap in mScaledBitmaps[mLevel] for display, otherwise the value
+    // is mLevelCount, and that means we use mBackupTexture for display.
+    private int mLevel = 0;
+
+    // The offsets of the (left, top) of the upper-left tile to the (left, top)
+    // of the view.
+    private int mOffsetX;
+    private int mOffsetY;
+
+    private int mUploadQuota;
+    private boolean mRenderComplete;
+
+    private final RectF mSourceRect = new RectF();
+    private final RectF mTargetRect = new RectF();
+
+    private final HashMap<Long, Tile> mActiveTiles = new HashMap<Long, Tile>();
+
+    // The following three queue is guarded by TileImageView.this
+    private TileQueue mRecycledQueue = new TileQueue();
+    private TileQueue mUploadQueue = new TileQueue();
+    private TileQueue mDecodeQueue = new TileQueue();
+
+    // The width and height of the full-sized bitmap
+    protected int mImageWidth = SIZE_UNKNOWN;
+    protected int mImageHeight = SIZE_UNKNOWN;
+
+    protected int mCenterX;
+    protected int mCenterY;
+    protected float mScale;
+    protected int mRotation;
+
+    // Temp variables to avoid memory allocation
+    private final Rect mTileRange = new Rect();
+    private final Rect mActiveRange[] = {new Rect(), new Rect()};
+
+    private final TileUploader mTileUploader = new TileUploader();
+    private boolean mIsTextureFreed;
+    private Future<Void> mTileDecoder;
+    private ThreadPool mThreadPool;
+    private boolean mBackgroundTileUploaded;
+
+    public static interface Model {
+        public int getLevelCount();
+        public Bitmap getBackupImage();
+        public int getImageWidth();
+        public int getImageHeight();
+
+        // The method would be called in another thread
+        public Bitmap getTile(int level, int x, int y, int tileSize);
+        public boolean isFailedToLoad();
+    }
+
+    public TileImageView(GalleryContext context) {
+        mThreadPool = context.getThreadPool();
+        mTileDecoder = mThreadPool.submit(new TileDecoder());
+    }
+
+    public void setModel(Model model) {
+        mModel = model;
+        if (model != null) notifyModelInvalidated();
+    }
+
+    private void updateBackupTexture(Bitmap backup) {
+        if (backup == null) {
+            if (mBackupImage != null) mBackupImage.recycle();
+            mBackupImage = null;
+        } else {
+            if (mBackupImage != null) {
+                if (mBackupImage.getBitmap() != backup) {
+                    mBackupImage.recycle();
+                    mBackupImage = new BitmapTexture(backup);
+                }
+            } else {
+                mBackupImage = new BitmapTexture(backup);
+            }
+        }
+    }
+
+    public void notifyModelInvalidated() {
+        invalidateTiles();
+        if (mModel == null) {
+            mBackupImage = null;
+            mImageWidth = 0;
+            mImageHeight = 0;
+            mLevelCount = 0;
+        } else {
+            updateBackupTexture(mModel.getBackupImage());
+            mImageWidth = mModel.getImageWidth();
+            mImageHeight = mModel.getImageHeight();
+            mLevelCount = mModel.getLevelCount();
+        }
+        layoutTiles(mCenterX, mCenterY, mScale, mRotation);
+        invalidate();
+    }
+
+    @Override
+    protected void onLayout(
+            boolean changeSize, int left, int top, int right, int bottom) {
+        super.onLayout(changeSize, left, top, right, bottom);
+        if (changeSize) layoutTiles(mCenterX, mCenterY, mScale, mRotation);
+    }
+
+    // Prepare the tiles we want to use for display.
+    //
+    // 1. Decide the tile level we want to use for display.
+    // 2. Decide the tile levels we want to keep as texture (in addition to
+    //    the one we use for display).
+    // 3. Recycle unused tiles.
+    // 4. Activate the tiles we want.
+    private void layoutTiles(int centerX, int centerY, float scale, int rotation) {
+        // The width and height of this view.
+        int width = getWidth();
+        int height = getHeight();
+
+        // The tile levels we want to keep as texture is in the range
+        // [fromLevel, endLevel).
+        int fromLevel;
+        int endLevel;
+
+        // We want to use a texture larger than or equal to the display size.
+        mLevel = Utils.clamp(Utils.floorLog2(1f / scale), 0, mLevelCount);
+
+        // We want to keep one more tile level as texture in addition to what
+        // we use for display. So it can be faster when the scale moves to the
+        // next level. We choose a level closer to the current scale.
+        if (mLevel != mLevelCount) {
+            Rect range = mTileRange;
+            getRange(range, centerX, centerY, mLevel, scale, rotation);
+            mOffsetX = Math.round(width / 2f + (range.left - centerX) * scale);
+            mOffsetY = Math.round(height / 2f + (range.top - centerY) * scale);
+            fromLevel = scale * (1 << mLevel) > 0.75f ? mLevel - 1 : mLevel;
+        } else {
+            // Activate the tiles of the smallest two levels.
+            fromLevel = mLevel - 2;
+            mOffsetX = Math.round(width / 2f - centerX * scale);
+            mOffsetY = Math.round(height / 2f - centerY * scale);
+        }
+
+        fromLevel = Math.max(0, Math.min(fromLevel, mLevelCount - 2));
+        endLevel = Math.min(fromLevel + 2, mLevelCount);
+
+        Rect range[] = mActiveRange;
+        for (int i = fromLevel; i < endLevel; ++i) {
+            getRange(range[i - fromLevel], centerX, centerY, i, rotation);
+        }
+
+        // If rotation is transient, don't update the tile.
+        if (rotation % 90 != 0) return;
+
+        synchronized (this) {
+            mDecodeQueue.clean();
+            mUploadQueue.clean();
+            mBackgroundTileUploaded = false;
+        }
+
+        // Recycle unused tiles: if the level of the active tile is outside the
+        // range [fromLevel, endLevel) or not in the visible range.
+        Iterator<Map.Entry<Long, Tile>>
+                iter = mActiveTiles.entrySet().iterator();
+        while (iter.hasNext()) {
+            Tile tile = iter.next().getValue();
+            int level = tile.mTileLevel;
+            if (level < fromLevel || level >= endLevel
+                    || !range[level - fromLevel].contains(tile.mX, tile.mY)) {
+                iter.remove();
+                recycleTile(tile);
+            }
+        }
+
+        for (int i = fromLevel; i < endLevel; ++i) {
+            int size = TILE_SIZE << i;
+            Rect r = range[i - fromLevel];
+            for (int y = r.top, bottom = r.bottom; y < bottom; y += size) {
+                for (int x = r.left, right = r.right; x < right; x += size) {
+                    activateTile(x, y, i);
+                }
+            }
+        }
+        invalidate();
+    }
+
+    protected synchronized void invalidateTiles() {
+        mDecodeQueue.clean();
+        mUploadQueue.clean();
+        // TODO disable decoder
+        for (Tile tile : mActiveTiles.values()) {
+            recycleTile(tile);
+        }
+        mActiveTiles.clear();
+    }
+
+    private void getRange(Rect out, int cX, int cY, int level, int rotation) {
+        getRange(out, cX, cY, level, 1f / (1 << (level + 1)), rotation);
+    }
+
+    // If the bitmap is scaled by the given factor "scale", return the
+    // rectangle containing visible range. The left-top coordinate returned is
+    // aligned to the tile boundary.
+    //
+    // (cX, cY) is the point on the original bitmap which will be put in the
+    // center of the ImageViewer.
+    private void getRange(Rect out,
+            int cX, int cY, int level, float scale, int rotation) {
+
+        double radians = Math.toRadians(-rotation);
+        double w = getWidth();
+        double h = getHeight();
+
+        double cos = Math.cos(radians);
+        double sin = Math.sin(radians);
+        int width = (int) Math.ceil(Math.max(
+                Math.abs(cos * w - sin * h), Math.abs(cos * w + sin * h)));
+        int height = (int) Math.ceil(Math.max(
+                Math.abs(sin * w + cos * h), Math.abs(sin * w - cos * h)));
+
+        int left = (int) Math.floor(cX - width / (2f * scale));
+        int top = (int) Math.floor(cY - height / (2f * scale));
+        int right = (int) Math.ceil(left + width / scale);
+        int bottom = (int) Math.ceil(top + height / scale);
+
+        // align the rectangle to tile boundary
+        int size = TILE_SIZE << level;
+        left = Math.max(0, size * (left / size));
+        top = Math.max(0, size * (top / size));
+        right = Math.min(mImageWidth, right);
+        bottom = Math.min(mImageHeight, bottom);
+
+        out.set(left, top, right, bottom);
+    }
+
+    public boolean setPosition(int centerX, int centerY, float scale, int rotation) {
+        if (mCenterX == centerX
+                && mCenterY == centerY && mScale == scale) return false;
+        mCenterX = centerX;
+        mCenterY = centerY;
+        mScale = scale;
+        mRotation = rotation;
+        layoutTiles(centerX, centerY, scale, rotation);
+        invalidate();
+        return true;
+    }
+
+    public void freeTextures() {
+        mIsTextureFreed = true;
+
+        if (mTileDecoder != null) {
+            mTileDecoder.cancel();
+            mTileDecoder.get();
+            mTileDecoder = null;
+        }
+
+        for (Tile texture : mActiveTiles.values()) {
+            texture.recycle();
+        }
+        mTileRange.set(0, 0, 0, 0);
+        mActiveTiles.clear();
+
+        synchronized (this) {
+            mUploadQueue.clean();
+            mDecodeQueue.clean();
+            Tile tile = mRecycledQueue.pop();
+            while (tile != null) {
+                tile.recycle();
+                tile = mRecycledQueue.pop();
+            }
+        }
+        updateBackupTexture(null);
+    }
+
+    public void prepareTextures() {
+        if (mTileDecoder == null) {
+            mTileDecoder = mThreadPool.submit(new TileDecoder());
+        }
+        if (mIsTextureFreed) {
+            layoutTiles(mCenterX, mCenterY, mScale, mRotation);
+            mIsTextureFreed = false;
+            updateBackupTexture(mModel.getBackupImage());
+        }
+    }
+
+    @Override
+    protected void render(GLCanvas canvas) {
+        mUploadQuota = UPLOAD_LIMIT;
+        mRenderComplete = true;
+
+        int level = mLevel;
+        int rotation = mRotation;
+
+        if (rotation != 0) {
+            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+            int centerX = getWidth() / 2, centerY = getHeight() / 2;
+            canvas.translate(centerX, centerY, 0);
+            canvas.rotate(rotation, 0, 0, 1);
+            canvas.translate(-centerX, -centerY, 0);
+        }
+        try {
+            if (level != mLevelCount) {
+                int size = (TILE_SIZE << level);
+                float length = size * mScale;
+                Rect r = mTileRange;
+
+                for (int ty = r.top, i = 0; ty < r.bottom; ty += size, i++) {
+                    float y = mOffsetY + i * length;
+                    for (int tx = r.left, j = 0; tx < r.right; tx += size, j++) {
+                        float x = mOffsetX + j * length;
+                        drawTile(canvas, tx, ty, level, x, y, length);
+                    }
+                }
+            } else if (mBackupImage != null) {
+                mBackupImage.draw(canvas, mOffsetX, mOffsetY,
+                        Math.round(mImageWidth * mScale),
+                        Math.round(mImageHeight * mScale));
+            }
+        } finally {
+            if (rotation != 0) canvas.restore();
+        }
+
+        if (mRenderComplete) {
+            if (!mBackgroundTileUploaded) uploadBackgroundTiles(canvas);
+        } else {
+            invalidate();
+        }
+    }
+
+    private void uploadBackgroundTiles(GLCanvas canvas) {
+        mBackgroundTileUploaded = true;
+        for (Tile tile : mActiveTiles.values()) {
+            if (!tile.isContentValid(canvas)) queueForDecode(tile);
+        }
+    }
+
+    void queueForUpload(Tile tile) {
+        synchronized (this) {
+            mUploadQueue.push(tile);
+        }
+        if (mTileUploader.mActive.compareAndSet(false, true)) {
+            getGLRoot().addOnGLIdleListener(mTileUploader);
+        }
+    }
+
+    synchronized void queueForDecode(Tile tile) {
+        if (tile.mTileState == STATE_ACTIVATED) {
+            tile.mTileState = STATE_IN_QUEUE;
+            if (mDecodeQueue.push(tile)) notifyAll();
+        }
+    }
+
+    boolean decodeTile(Tile tile) {
+        synchronized (this) {
+            if (tile.mTileState != STATE_IN_QUEUE) return false;
+            tile.mTileState = STATE_DECODING;
+        }
+        boolean decodeComplete = tile.decode();
+        synchronized (this) {
+            if (tile.mTileState == STATE_RECYCLING) {
+                tile.mTileState = STATE_RECYCLED;
+                tile.mDecodedTile = null;
+                mRecycledQueue.push(tile);
+                return false;
+            }
+            tile.mTileState = STATE_DECODED;
+            return decodeComplete;
+        }
+    }
+
+    private synchronized Tile obtainTile(int x, int y, int level) {
+        Tile tile = mRecycledQueue.pop();
+        if (tile != null) {
+            tile.mTileState = STATE_ACTIVATED;
+            tile.update(x, y, level);
+            return tile;
+        }
+        return new Tile(x, y, level);
+    }
+
+    synchronized void recycleTile(Tile tile) {
+        if (tile.mTileState == STATE_DECODING) {
+            tile.mTileState = STATE_RECYCLING;
+            return;
+        }
+        tile.mTileState = STATE_RECYCLED;
+        tile.mDecodedTile = null;
+        mRecycledQueue.push(tile);
+    }
+
+    private void activateTile(int x, int y, int level) {
+        Long key = makeTileKey(x, y, level);
+        Tile tile = mActiveTiles.get(key);
+        if (tile != null) {
+            if (tile.mTileState == STATE_IN_QUEUE) {
+                tile.mTileState = STATE_ACTIVATED;
+            }
+            return;
+        }
+        tile = obtainTile(x, y, level);
+        mActiveTiles.put(key, tile);
+    }
+
+    private Tile getTile(int x, int y, int level) {
+        return mActiveTiles.get(makeTileKey(x, y, level));
+    }
+
+    private static Long makeTileKey(int x, int y, int level) {
+        long result = x;
+        result = (result << 16) | y;
+        result = (result << 16) | level;
+        return Long.valueOf(result);
+    }
+
+    private class TileUploader implements GLRoot.OnGLIdleListener {
+        AtomicBoolean mActive = new AtomicBoolean(false);
+
+        @Override
+        public boolean onGLIdle(GLRoot root, GLCanvas canvas) {
+            int quota = UPLOAD_LIMIT;
+            Tile tile;
+            while (true) {
+                synchronized (TileImageView.this) {
+                    tile = mUploadQueue.pop();
+                }
+                if (tile == null || quota <= 0) break;
+                if (!tile.isContentValid(canvas)) {
+                    Utils.assertTrue(tile.mTileState == STATE_DECODED);
+                    tile.updateContent(canvas);
+                    --quota;
+                }
+            }
+            mActive.set(tile != null);
+            return tile != null;
+        }
+    }
+
+    // Draw the tile to a square at canvas that locates at (x, y) and
+    // has a side length of length.
+    public void drawTile(GLCanvas canvas,
+            int tx, int ty, int level, float x, float y, float length) {
+        RectF source = mSourceRect;
+        RectF target = mTargetRect;
+        target.set(x, y, x + length, y + length);
+        source.set(0, 0, TILE_SIZE, TILE_SIZE);
+
+        Tile tile = getTile(tx, ty, level);
+        if (tile != null) {
+            if (!tile.isContentValid(canvas)) {
+                if (tile.mTileState == STATE_DECODED) {
+                    if (mUploadQuota > 0) {
+                        --mUploadQuota;
+                        tile.updateContent(canvas);
+                    } else {
+                        mRenderComplete = false;
+                    }
+                } else {
+                    mRenderComplete = false;
+                    queueForDecode(tile);
+                }
+            }
+            if (drawTile(tile, canvas, source, target)) return;
+        }
+        if (mBackupImage != null) {
+            BasicTexture backup = mBackupImage;
+            int size = TILE_SIZE << level;
+            float scaleX = (float) backup.getWidth() / mImageWidth;
+            float scaleY = (float) backup.getHeight() / mImageHeight;
+            source.set(tx * scaleX, ty * scaleY, (tx + size) * scaleX,
+                    (ty + size) * scaleY);
+            canvas.drawTexture(backup, source, target);
+        }
+    }
+
+    // TODO: avoid drawing the unused part of the textures.
+    static boolean drawTile(
+            Tile tile, GLCanvas canvas, RectF source, RectF target) {
+        while (true) {
+            if (tile.isContentValid(canvas)) {
+                // offset source rectangle for the texture border.
+                source.offset(TILE_BORDER, TILE_BORDER);
+                canvas.drawTexture(tile, source, target);
+                return true;
+            }
+
+            // Parent can be divided to four quads and tile is one of the four.
+            Tile parent = tile.getParentTile();
+            if (parent == null) return false;
+            if (tile.mX == parent.mX) {
+                source.left /= 2f;
+                source.right /= 2f;
+            } else {
+                source.left = (TILE_SIZE + source.left) / 2f;
+                source.right = (TILE_SIZE + source.right) / 2f;
+            }
+            if (tile.mY == parent.mY) {
+                source.top /= 2f;
+                source.bottom /= 2f;
+            } else {
+                source.top = (TILE_SIZE + source.top) / 2f;
+                source.bottom = (TILE_SIZE + source.bottom) / 2f;
+            }
+            tile = parent;
+        }
+    }
+
+    private class Tile extends UploadedTexture {
+        int mX;
+        int mY;
+        int mTileLevel;
+        Tile mNext;
+        Bitmap mDecodedTile;
+        volatile int mTileState = STATE_ACTIVATED;
+
+        public Tile(int x, int y, int level) {
+            mX = x;
+            mY = y;
+            mTileLevel = level;
+        }
+
+        @Override
+        protected void onFreeBitmap(Bitmap bitmap) {
+            bitmap.recycle();
+        }
+
+        boolean decode() {
+            // Get a tile from the original image. The tile is down-scaled
+            // by (1 << mTilelevel) from a region in the original image.
+            int tileLength = (TILE_SIZE + 2 * TILE_BORDER);
+            int borderLength = TILE_BORDER << mTileLevel;
+            try {
+                mDecodedTile = mModel.getTile(
+                        mTileLevel, mX - borderLength, mY - borderLength, tileLength);
+                return mDecodedTile != null;
+            } catch (Throwable t) {
+                Log.w(TAG, "fail to decode tile", t);
+                return false;
+            }
+        }
+
+        @Override
+        protected Bitmap onGetBitmap() {
+            Utils.assertTrue(mTileState == STATE_DECODED);
+            Bitmap bitmap = mDecodedTile;
+            mDecodedTile = null;
+            mTileState = STATE_ACTIVATED;
+            return bitmap;
+        }
+
+        public void update(int x, int y, int level) {
+            mX = x;
+            mY = y;
+            mTileLevel = level;
+            invalidateContent();
+        }
+
+        public Tile getParentTile() {
+            if (mTileLevel + 1 == mLevelCount) return null;
+            int size = TILE_SIZE << (mTileLevel + 1);
+            int x = size * (mX / size);
+            int y = size * (mY / size);
+            return getTile(x, y, mTileLevel + 1);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("tile(%s, %s, %s / %s)",
+                    mX / TILE_SIZE, mY / TILE_SIZE, mLevel, mLevelCount);
+        }
+    }
+
+    private static class TileQueue {
+        private Tile mHead;
+
+        public Tile pop() {
+            Tile tile = mHead;
+            if (tile != null) mHead = tile.mNext;
+            return tile;
+        }
+
+        public boolean push(Tile tile) {
+            boolean wasEmpty = mHead == null;
+            tile.mNext = mHead;
+            mHead = tile;
+            return wasEmpty;
+        }
+
+        public void clean() {
+            mHead = null;
+        }
+    }
+
+    private class TileDecoder implements ThreadPool.Job<Void> {
+
+        private CancelListener mNotifier = new CancelListener() {
+            @Override
+            public void onCancel() {
+                synchronized (TileImageView.this) {
+                    TileImageView.this.notifyAll();
+                }
+            }
+        };
+
+        @Override
+        public Void run(JobContext jc) {
+            jc.setMode(ThreadPool.MODE_NONE);
+            jc.setCancelListener(mNotifier);
+            while (!jc.isCancelled()) {
+                Tile tile = null;
+                synchronized(TileImageView.this) {
+                    tile = mDecodeQueue.pop();
+                    if (tile == null && !jc.isCancelled()) {
+                        Utils.waitWithoutInterrupt(TileImageView.this);
+                    }
+                }
+                if (tile == null) continue;
+                if (decodeTile(tile)) queueForUpload(tile);
+            }
+            return null;
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/ui/TileImageViewAdapter.java b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
new file mode 100644
index 0000000..65dea0e
--- /dev/null
+++ b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+
+public class TileImageViewAdapter implements TileImageView.Model {
+    protected BitmapRegionDecoder mRegionDecoder;
+    protected int mImageWidth;
+    protected int mImageHeight;
+    protected Bitmap mBackupImage;
+    protected int mLevelCount;
+    protected boolean mFailedToLoad;
+
+    private final Rect mIntersectRect = new Rect();
+    private final Rect mRegionRect = new Rect();
+
+    public TileImageViewAdapter() {
+    }
+
+    public TileImageViewAdapter(Bitmap backup, BitmapRegionDecoder regionDecoder) {
+        mBackupImage = Utils.checkNotNull(backup);
+        mRegionDecoder = regionDecoder;
+        mImageWidth = regionDecoder.getWidth();
+        mImageHeight = regionDecoder.getHeight();
+        mLevelCount = calculateLevelCount();
+    }
+
+    public synchronized void clear() {
+        mBackupImage = null;
+        mImageWidth = 0;
+        mImageHeight = 0;
+        mLevelCount = 0;
+        mRegionDecoder = null;
+        mFailedToLoad = false;
+    }
+
+    public synchronized void setBackupImage(Bitmap backup, int width, int height) {
+        mBackupImage = Utils.checkNotNull(backup);
+        mImageWidth = width;
+        mImageHeight = height;
+        mRegionDecoder = null;
+        mLevelCount = 0;
+        mFailedToLoad = false;
+    }
+
+    public synchronized void setRegionDecoder(BitmapRegionDecoder decoder) {
+        mRegionDecoder = Utils.checkNotNull(decoder);
+        mImageWidth = decoder.getWidth();
+        mImageHeight = decoder.getHeight();
+        mLevelCount = calculateLevelCount();
+        mFailedToLoad = false;
+    }
+
+    private int calculateLevelCount() {
+        return Math.max(0, Utils.ceilLog2(
+                (float) mImageWidth / mBackupImage.getWidth()));
+    }
+
+    @Override
+    public synchronized Bitmap getTile(int level, int x, int y, int length) {
+        Rect region = mRegionRect;
+        Rect intersectRect = mIntersectRect;
+        region.set(x, y, x + (length << level), y + (length << level));
+        intersectRect.set(0, 0, mImageWidth, mImageHeight);
+
+        // Get the intersected rect of the requested region and the image.
+        Utils.assertTrue(intersectRect.intersect(region));
+
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inPreferredConfig = Config.ARGB_8888;
+        options.inPreferQualityOverSpeed = true;
+        options.inSampleSize =  (1 << level);
+
+        Bitmap bitmap;
+
+        // In CropImage, we may call the decodeRegion() concurrently.
+        synchronized (mRegionDecoder) {
+            bitmap = mRegionDecoder.decodeRegion(intersectRect, options);
+        }
+
+        // The returned region may not match with the targetLength.
+        // If so, we fill black pixels on it.
+        if (intersectRect.equals(region)) return bitmap;
+
+        Bitmap tile = Bitmap.createBitmap(length, length, Config.ARGB_8888);
+        Canvas canvas = new Canvas(tile);
+        canvas.drawBitmap(bitmap,
+                (intersectRect.left - region.left) >> level,
+                (intersectRect.top - region.top) >> level, null);
+        bitmap.recycle();
+        return tile;
+    }
+
+    @Override
+    public Bitmap getBackupImage() {
+        return mBackupImage;
+    }
+
+    @Override
+    public int getImageHeight() {
+        return mImageHeight;
+    }
+
+    @Override
+    public int getImageWidth() {
+        return mImageWidth;
+    }
+
+    @Override
+    public int getLevelCount() {
+        return mLevelCount;
+    }
+
+    public void setFailedToLoad() {
+        mFailedToLoad = true;
+    }
+
+    @Override
+    public boolean isFailedToLoad() {
+        return mFailedToLoad;
+    }
+}
diff --git a/src/com/android/gallery3d/ui/UploadedTexture.java b/src/com/android/gallery3d/ui/UploadedTexture.java
new file mode 100644
index 0000000..b063824
--- /dev/null
+++ b/src/com/android/gallery3d/ui/UploadedTexture.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+import com.android.gallery3d.common.Utils;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.opengl.GLUtils;
+
+import java.util.HashMap;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+// UploadedTextures use a Bitmap for the content of the texture.
+//
+// Subclasses should implement onGetBitmap() to provide the Bitmap and
+// implement onFreeBitmap(mBitmap) which will be called when the Bitmap
+// is not needed anymore.
+//
+// isContentValid() is meaningful only when the isLoaded() returns true.
+// It means whether the content needs to be updated.
+//
+// The user of this class should call recycle() when the texture is not
+// needed anymore.
+//
+// By default an UploadedTexture is opaque (so it can be drawn faster without
+// blending). The user or subclass can override it using setOpaque().
+abstract class UploadedTexture extends BasicTexture {
+
+    // To prevent keeping allocation the borders, we store those used borders here.
+    // Since the length will be power of two, it won't use too much memory.
+    private static HashMap<BorderKey, Bitmap> sBorderLines =
+            new HashMap<BorderKey, Bitmap>();
+    private static BorderKey sBorderKey = new BorderKey();
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "Texture";
+    private boolean mContentValid = true;
+    private boolean mOpaque = true;
+    private boolean mThrottled = false;
+    private static int sUploadedCount;
+    private static final int UPLOAD_LIMIT = 100;
+
+    protected Bitmap mBitmap;
+
+    protected UploadedTexture() {
+        super(null, 0, STATE_UNLOADED);
+    }
+
+    private static class BorderKey implements Cloneable {
+        public boolean vertical;
+        public Config config;
+        public int length;
+
+        @Override
+        public int hashCode() {
+            int x = config.hashCode() ^ length;
+            return vertical ? x : -x;
+        }
+
+        @Override
+        public boolean equals(Object object) {
+            if (!(object instanceof BorderKey)) return false;
+            BorderKey o = (BorderKey) object;
+            return vertical == o.vertical
+                    && config == o.config && length == o.length;
+        }
+
+        @Override
+        public BorderKey clone() {
+            try {
+                return (BorderKey) super.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
+
+    protected void setThrottled(boolean throttled) {
+        mThrottled = throttled;
+    }
+
+    private static Bitmap getBorderLine(
+            boolean vertical, Config config, int length) {
+        BorderKey key = sBorderKey;
+        key.vertical = vertical;
+        key.config = config;
+        key.length = length;
+        Bitmap bitmap = sBorderLines.get(key);
+        if (bitmap == null) {
+            bitmap = vertical
+                    ? Bitmap.createBitmap(1, length, config)
+                    : Bitmap.createBitmap(length, 1, config);
+            sBorderLines.put(key.clone(), bitmap);
+        }
+        return bitmap;
+    }
+
+    private Bitmap getBitmap() {
+        if (mBitmap == null) {
+            mBitmap = onGetBitmap();
+            if (mWidth == UNSPECIFIED) {
+                setSize(mBitmap.getWidth(), mBitmap.getHeight());
+            } else if (mWidth != mBitmap.getWidth()
+                    || mHeight != mBitmap.getHeight()) {
+                throw new IllegalStateException(String.format(
+                        "cannot change size: this = %s, orig = %sx%s, new = %sx%s",
+                        toString(), mWidth, mHeight, mBitmap.getWidth(),
+                        mBitmap.getHeight()));
+            }
+        }
+        return mBitmap;
+    }
+
+    private void freeBitmap() {
+        Utils.assertTrue(mBitmap != null);
+        onFreeBitmap(mBitmap);
+        mBitmap = null;
+    }
+
+    @Override
+    public int getWidth() {
+        if (mWidth == UNSPECIFIED) getBitmap();
+        return mWidth;
+    }
+
+    @Override
+    public int getHeight() {
+        if (mWidth == UNSPECIFIED) getBitmap();
+        return mHeight;
+    }
+
+    protected abstract Bitmap onGetBitmap();
+
+    protected abstract void onFreeBitmap(Bitmap bitmap);
+
+    protected void invalidateContent() {
+        if (mBitmap != null) freeBitmap();
+        mContentValid = false;
+    }
+
+    /**
+     * Whether the content on GPU is valid.
+     */
+    public boolean isContentValid(GLCanvas canvas) {
+        return isLoaded(canvas) && mContentValid;
+    }
+
+    /**
+     * Updates the content on GPU's memory.
+     * @param canvas
+     */
+    public void updateContent(GLCanvas canvas) {
+        if (!isLoaded(canvas)) {
+            if (mThrottled && ++sUploadedCount > UPLOAD_LIMIT) {
+                return;
+            }
+            uploadToCanvas(canvas);
+        } else if (!mContentValid) {
+            Bitmap bitmap = getBitmap();
+            int format = GLUtils.getInternalFormat(bitmap);
+            int type = GLUtils.getType(bitmap);
+            canvas.getGLInstance().glBindTexture(GL11.GL_TEXTURE_2D, mId);
+            GLUtils.texSubImage2D(
+                    GL11.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type);
+            freeBitmap();
+            mContentValid = true;
+        }
+    }
+
+    public static void resetUploadLimit() {
+        sUploadedCount = 0;
+    }
+
+    public static boolean uploadLimitReached() {
+        return sUploadedCount > UPLOAD_LIMIT;
+    }
+
+    static int[] sTextureId = new int[1];
+    static float[] sCropRect = new float[4];
+
+    private void uploadToCanvas(GLCanvas canvas) {
+        GL11 gl = canvas.getGLInstance();
+
+        Bitmap bitmap = getBitmap();
+        if (bitmap != null) {
+            try {
+                // Define a vertically flipped crop rectangle for
+                // OES_draw_texture.
+                int width = bitmap.getWidth();
+                int height = bitmap.getHeight();
+                sCropRect[0] = 0;
+                sCropRect[1] = height;
+                sCropRect[2] = width;
+                sCropRect[3] = -height;
+
+                // Upload the bitmap to a new texture.
+                gl.glGenTextures(1, sTextureId, 0);
+                gl.glBindTexture(GL11.GL_TEXTURE_2D, sTextureId[0]);
+                gl.glTexParameterfv(GL11.GL_TEXTURE_2D,
+                        GL11Ext.GL_TEXTURE_CROP_RECT_OES, sCropRect, 0);
+                gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+                        GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
+                gl.glTexParameteri(GL11.GL_TEXTURE_2D,
+                        GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
+                gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+                        GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
+                gl.glTexParameterf(GL11.GL_TEXTURE_2D,
+                        GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
+
+                if (width == getTextureWidth() && height == getTextureHeight()) {
+                    GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, bitmap, 0);
+                } else {
+                    int format = GLUtils.getInternalFormat(bitmap);
+                    int type = GLUtils.getType(bitmap);
+                    Config config = bitmap.getConfig();
+
+                    gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, format,
+                            getTextureWidth(), getTextureHeight(),
+                            0, format, type, null);
+                    GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, bitmap,
+                            format, type);
+
+                    if (width != getTextureWidth()) {
+                        Bitmap line = getBorderLine(true, config, getTextureHeight());
+                        GLUtils.texSubImage2D(
+                                GL11.GL_TEXTURE_2D, 0, width, 0, line, format, type);
+                    }
+
+                    if (height != getTextureHeight()) {
+                        Bitmap line = getBorderLine(false, config, getTextureWidth());
+                        GLUtils.texSubImage2D(
+                                GL11.GL_TEXTURE_2D, 0, 0, height, line, format, type);
+                    }
+
+                }
+            } finally {
+                freeBitmap();
+            }
+            // Update texture state.
+            setAssociatedCanvas(canvas);
+            mId = sTextureId[0];
+            mState = UploadedTexture.STATE_LOADED;
+            mContentValid = true;
+        } else {
+            mState = STATE_ERROR;
+            throw new RuntimeException("Texture load fail, no bitmap");
+        }
+    }
+
+    @Override
+    protected boolean onBind(GLCanvas canvas) {
+        updateContent(canvas);
+        return isContentValid(canvas);
+    }
+
+    public void setOpaque(boolean isOpaque) {
+        mOpaque = isOpaque;
+    }
+
+    public boolean isOpaque() {
+        return mOpaque;
+    }
+
+    @Override
+    public void recycle() {
+        super.recycle();
+        if (mBitmap != null) freeBitmap();
+    }
+}
diff --git a/src/com/android/gallery3d/ui/UserInteractionListener.java b/src/com/android/gallery3d/ui/UserInteractionListener.java
new file mode 100644
index 0000000..bc4a718
--- /dev/null
+++ b/src/com/android/gallery3d/ui/UserInteractionListener.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ui;
+
+public interface UserInteractionListener {
+    // Called when a user interaction begins (for example, fling).
+    public void onUserInteractionBegin();
+    // Called when the user interaction ends.
+    public void onUserInteractionEnd();
+    // Other one-shot user interactions.
+    public void onUserInteraction();
+}
diff --git a/src/com/android/gallery3d/util/CacheManager.java b/src/com/android/gallery3d/util/CacheManager.java
new file mode 100644
index 0000000..fcc444e
--- /dev/null
+++ b/src/com/android/gallery3d/util/CacheManager.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import com.android.gallery3d.common.BlobCache;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+
+public class CacheManager {
+    private static final String TAG = "CacheManager";
+    private static final String KEY_CACHE_UP_TO_DATE = "cache-up-to-date";
+    private static HashMap<String, BlobCache> sCacheMap =
+            new HashMap<String, BlobCache>();
+    private static boolean sOldCheckDone = false;
+
+    // Return null when we cannot instantiate a BlobCache, e.g.:
+    // there is no SD card found.
+    // This can only be called from data thread.
+    public static BlobCache getCache(Context context, String filename,
+            int maxEntries, int maxBytes, int version) {
+        synchronized (sCacheMap) {
+            if (!sOldCheckDone) {
+                removeOldFilesIfNecessary(context);
+                sOldCheckDone = true;
+            }
+            BlobCache cache = sCacheMap.get(filename);
+            if (cache == null) {
+                File cacheDir = context.getExternalCacheDir();
+                String path = cacheDir.getAbsolutePath() + "/" + filename;
+                try {
+                    cache = new BlobCache(path, maxEntries, maxBytes, false,
+                            version);
+                    sCacheMap.put(filename, cache);
+                } catch (IOException e) {
+                    Log.e(TAG, "Cannot instantiate cache!", e);
+                }
+            }
+            return cache;
+        }
+    }
+
+    // Removes the old files if the data is wiped.
+    private static void removeOldFilesIfNecessary(Context context) {
+        SharedPreferences pref = PreferenceManager
+                .getDefaultSharedPreferences(context);
+        int n = 0;
+        try {
+            n = pref.getInt(KEY_CACHE_UP_TO_DATE, 0);
+        } catch (Throwable t) {
+            // ignore.
+        }
+        if (n != 0) return;
+        pref.edit().putInt(KEY_CACHE_UP_TO_DATE, 1).commit();
+
+        File cacheDir = context.getExternalCacheDir();
+        String prefix = cacheDir.getAbsolutePath() + "/";
+
+        BlobCache.deleteFiles(prefix + "imgcache");
+        BlobCache.deleteFiles(prefix + "rev_geocoding");
+        BlobCache.deleteFiles(prefix + "bookmark");
+    }
+}
diff --git a/src/com/android/gallery3d/util/Future.java b/src/com/android/gallery3d/util/Future.java
new file mode 100644
index 0000000..580a2a1
--- /dev/null
+++ b/src/com/android/gallery3d/util/Future.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+// This Future differs from the java.util.concurrent.Future in these aspects:
+//
+// - Once cancel() is called, isCancelled() always returns true. It is a sticky
+//   flag used to communicate to the implementation. The implmentation may
+//   ignore that flag. Regardless whether the Future is cancelled, a return
+//   value will be provided to get(). The implementation may choose to return
+//   null if it finds the Future is cancelled.
+//
+// - get() does not throw exceptions.
+//
+public interface Future<T> {
+    public void cancel();
+    public boolean isCancelled();
+    public boolean isDone();
+    public T get();
+    public void waitDone();
+}
diff --git a/src/com/android/gallery3d/util/FutureListener.java b/src/com/android/gallery3d/util/FutureListener.java
new file mode 100644
index 0000000..ed1f820
--- /dev/null
+++ b/src/com/android/gallery3d/util/FutureListener.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+public interface FutureListener<T> {
+    public void onFutureDone(Future<T> future);
+}
diff --git a/src/com/android/gallery3d/util/FutureTask.java b/src/com/android/gallery3d/util/FutureTask.java
new file mode 100644
index 0000000..9cfab27
--- /dev/null
+++ b/src/com/android/gallery3d/util/FutureTask.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import java.util.concurrent.Callable;
+
+// NOTE: If the Callable throws any Throwable, the result value will be null.
+public class FutureTask<T> implements Runnable, Future<T> {
+    private static final String TAG = "FutureTask";
+    private Callable<T> mCallable;
+    private FutureListener<T> mListener;
+    private volatile boolean mIsCancelled;
+    private boolean mIsDone;
+    private T mResult;
+
+    public FutureTask(Callable<T> callable, FutureListener<T> listener) {
+        mCallable = callable;
+        mListener = listener;
+    }
+
+    public FutureTask(Callable<T> callable) {
+        this(callable, null);
+    }
+
+    public void cancel() {
+        mIsCancelled = true;
+    }
+
+    public synchronized T get() {
+        while (!mIsDone) {
+            try {
+                wait();
+            } catch (InterruptedException t) {
+                // ignore.
+            }
+        }
+        return mResult;
+    }
+
+    public void waitDone() {
+        get();
+    }
+
+    public synchronized boolean isDone() {
+        return mIsDone;
+    }
+
+    public boolean isCancelled() {
+        return mIsCancelled;
+    }
+
+    public void run() {
+        T result = null;
+
+        if (!mIsCancelled) {
+            try {
+                result = mCallable.call();
+            } catch (Throwable ex) {
+                Log.w(TAG, "Exception in running a task", ex);
+            }
+        }
+
+        synchronized(this) {
+            mResult = result;
+            mIsDone = true;
+            if (mListener != null) {
+                mListener.onFutureDone(this);
+            }
+            notifyAll();
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/util/GalleryUtils.java b/src/com/android/gallery3d/util/GalleryUtils.java
new file mode 100644
index 0000000..2fed46a
--- /dev/null
+++ b/src/com/android/gallery3d/util/GalleryUtils.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.PackagesMonitor;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.ConditionVariable;
+import android.os.Environment;
+import android.os.StatFs;
+import android.preference.PreferenceManager;
+import android.provider.MediaStore;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class GalleryUtils {
+    private static final String TAG = "GalleryUtils";
+    private static final String MAPS_PACKAGE_NAME = "com.google.android.apps.maps";
+    private static final String MAPS_CLASS_NAME = "com.google.android.maps.MapsActivity";
+
+    private static final String MIME_TYPE_IMAGE = "image/*";
+    private static final String MIME_TYPE_VIDEO = "video/*";
+    private static final String MIME_TYPE_ALL = "*/*";
+
+    private static final String PREFIX_PHOTO_EDITOR_UPDATE = "editor-update-";
+    private static final String PREFIX_HAS_PHOTO_EDITOR = "has-editor-";
+
+    private static final String KEY_CAMERA_UPDATE = "camera-update";
+    private static final String KEY_HAS_CAMERA = "has-camera";
+
+    private static Context sContext;
+
+
+    static float sPixelDensity = -1f;
+
+    public static void initialize(Context context) {
+        sContext = context;
+        if (sPixelDensity < 0) {
+            DisplayMetrics metrics = new DisplayMetrics();
+            WindowManager wm = (WindowManager)
+                    context.getSystemService(Context.WINDOW_SERVICE);
+            wm.getDefaultDisplay().getMetrics(metrics);
+            sPixelDensity = metrics.density;
+        }
+    }
+
+    public static float dpToPixel(float dp) {
+        return sPixelDensity * dp;
+    }
+
+    public static int dpToPixel(int dp) {
+        return Math.round(dpToPixel((float) dp));
+    }
+
+    public static int meterToPixel(float meter) {
+        // 1 meter = 39.37 inches, 1 inch = 160 dp.
+        return Math.round(dpToPixel(meter * 39.37f * 160));
+    }
+
+    public static byte[] getBytes(String in) {
+        byte[] result = new byte[in.length() * 2];
+        int output = 0;
+        for (char ch : in.toCharArray()) {
+            result[output++] = (byte) (ch & 0xFF);
+            result[output++] = (byte) (ch >> 8);
+        }
+        return result;
+    }
+
+    // Below are used the detect using database in the render thread. It only
+    // works most of the time, but that's ok because it's for debugging only.
+
+    private static volatile Thread sCurrentThread;
+    private static volatile boolean sWarned;
+
+    public static void setRenderThread() {
+        sCurrentThread = Thread.currentThread();
+    }
+
+    public static void assertNotInRenderThread() {
+        if (!sWarned) {
+            if (Thread.currentThread() == sCurrentThread) {
+                sWarned = true;
+                Log.w(TAG, new Throwable("Should not do this in render thread"));
+            }
+        }
+    }
+
+    private static final double RAD_PER_DEG = Math.PI / 180.0;
+    private static final double EARTH_RADIUS_METERS = 6367000.0;
+
+    public static double fastDistanceMeters(double latRad1, double lngRad1,
+            double latRad2, double lngRad2) {
+       if ((Math.abs(latRad1 - latRad2) > RAD_PER_DEG)
+             || (Math.abs(lngRad1 - lngRad2) > RAD_PER_DEG)) {
+           return accurateDistanceMeters(latRad1, lngRad1, latRad2, lngRad2);
+       }
+       // Approximate sin(x) = x.
+       double sineLat = (latRad1 - latRad2);
+
+       // Approximate sin(x) = x.
+       double sineLng = (lngRad1 - lngRad2);
+
+       // Approximate cos(lat1) * cos(lat2) using
+       // cos((lat1 + lat2)/2) ^ 2
+       double cosTerms = Math.cos((latRad1 + latRad2) / 2.0);
+       cosTerms = cosTerms * cosTerms;
+       double trigTerm = sineLat * sineLat + cosTerms * sineLng * sineLng;
+       trigTerm = Math.sqrt(trigTerm);
+
+       // Approximate arcsin(x) = x
+       return EARTH_RADIUS_METERS * trigTerm;
+    }
+
+    public static double accurateDistanceMeters(double lat1, double lng1,
+            double lat2, double lng2) {
+        double dlat = Math.sin(0.5 * (lat2 - lat1));
+        double dlng = Math.sin(0.5 * (lng2 - lng1));
+        double x = dlat * dlat + dlng * dlng * Math.cos(lat1) * Math.cos(lat2);
+        return (2 * Math.atan2(Math.sqrt(x), Math.sqrt(Math.max(0.0,
+                1.0 - x)))) * EARTH_RADIUS_METERS;
+    }
+
+
+    public static final double toMile(double meter) {
+        return meter / 1609;
+    }
+
+    // For debugging, it will block the caller for timeout millis.
+    public static void fakeBusy(JobContext jc, int timeout) {
+        final ConditionVariable cv = new ConditionVariable();
+        jc.setCancelListener(new CancelListener() {
+            public void onCancel() {
+                cv.open();
+            }
+        });
+        cv.block(timeout);
+        jc.setCancelListener(null);
+    }
+
+    public static boolean isEditorAvailable(Context context, String mimeType) {
+        int version = PackagesMonitor.getPackagesVersion(context);
+
+        String updateKey = PREFIX_PHOTO_EDITOR_UPDATE + mimeType;
+        String hasKey = PREFIX_HAS_PHOTO_EDITOR + mimeType;
+
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        if (prefs.getInt(updateKey, 0) != version) {
+            PackageManager packageManager = context.getPackageManager();
+            List<ResolveInfo> infos = packageManager.queryIntentActivities(
+                    new Intent(Intent.ACTION_EDIT).setType(mimeType), 0);
+            prefs.edit().putInt(updateKey, version)
+                        .putBoolean(hasKey, !infos.isEmpty())
+                        .commit();
+        }
+
+        return prefs.getBoolean(hasKey, true);
+    }
+
+    public static boolean isCameraAvailable(Context context) {
+        int version = PackagesMonitor.getPackagesVersion(context);
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        if (prefs.getInt(KEY_CAMERA_UPDATE, 0) != version) {
+            PackageManager packageManager = context.getPackageManager();
+            List<ResolveInfo> infos = packageManager.queryIntentActivities(
+                    new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA), 0);
+            prefs.edit().putInt(KEY_CAMERA_UPDATE, version)
+                        .putBoolean(KEY_HAS_CAMERA, !infos.isEmpty())
+                        .commit();
+        }
+        return prefs.getBoolean(KEY_HAS_CAMERA, true);
+    }
+
+    public static boolean isValidLocation(double latitude, double longitude) {
+        // TODO: change || to && after we fix the default location issue
+        return (latitude != MediaItem.INVALID_LATLNG || longitude != MediaItem.INVALID_LATLNG);
+    }
+    public static void showOnMap(Context context, double latitude, double longitude) {
+        try {
+            // We don't use "geo:latitude,longitude" because it only centers
+            // the MapView to the specified location, but we need a marker
+            // for further operations (routing to/from).
+            // The q=(lat, lng) syntax is suggested by geo-team.
+            String uri = String.format("http://maps.google.com/maps?f=q&q=(%f,%f)",
+                    latitude, longitude);
+            ComponentName compName = new ComponentName(MAPS_PACKAGE_NAME,
+                    MAPS_CLASS_NAME);
+            Intent mapsIntent = new Intent(Intent.ACTION_VIEW,
+                    Uri.parse(uri)).setComponent(compName);
+            context.startActivity(mapsIntent);
+        } catch (ActivityNotFoundException e) {
+            // Use the "geo intent" if no GMM is installed
+            Log.e(TAG, "GMM activity not found!", e);
+            String url = String.format("geo:%f,%f", latitude, longitude);
+            Intent mapsIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+            context.startActivity(mapsIntent);
+        }
+    }
+
+    public static void setViewPointMatrix(
+            float matrix[], float x, float y, float z) {
+        // The matrix is
+        // -z,  0,  x,  0
+        //  0, -z,  y,  0
+        //  0,  0,  1,  0
+        //  0,  0,  1, -z
+        Arrays.fill(matrix, 0, 16, 0);
+        matrix[0] = matrix[5] = matrix[15] = -z;
+        matrix[8] = x;
+        matrix[9] = y;
+        matrix[10] = matrix[11] = 1;
+    }
+
+    public static int getBucketId(String path) {
+        return path.toLowerCase().hashCode();
+    }
+
+    // Returns a (localized) string for the given duration (in seconds).
+    public static String formatDuration(final Context context, int duration) {
+        int h = duration / 3600;
+        int m = (duration - h * 3600) / 60;
+        int s = duration - (h * 3600 + m * 60);
+        String durationValue;
+        if (h == 0) {
+            durationValue = String.format(context.getString(R.string.details_ms), m, s);
+        } else {
+            durationValue = String.format(context.getString(R.string.details_hms), h, m, s);
+        }
+        return durationValue;
+    }
+
+    public static void setSpinnerVisibility(final Activity activity,
+            final boolean visible) {
+        activity.runOnUiThread(new Runnable() {
+            public void run() {
+                activity.setProgressBarIndeterminateVisibility(visible);
+            }
+        });
+    }
+
+    public static int determineTypeBits(Context context, Intent intent) {
+        int typeBits = 0;
+        String type = intent.resolveType(context);
+        if (intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false)) {
+            if (MIME_TYPE_ALL.equals(type)) {
+                typeBits = DataManager.INCLUDE_LOCAL_ALL_ONLY;
+            } else if (MIME_TYPE_IMAGE.equals(type)) {
+                typeBits = DataManager.INCLUDE_LOCAL_IMAGE_ONLY;
+            } else if (MIME_TYPE_VIDEO.equals(type)) {
+                typeBits = DataManager.INCLUDE_LOCAL_VIDEO_ONLY;
+            }
+        } else {
+            if (MIME_TYPE_ALL.equals(type)) {
+                typeBits = DataManager.INCLUDE_ALL;
+            } else if (MIME_TYPE_IMAGE.equals(type)) {
+                typeBits = DataManager.INCLUDE_IMAGE;
+            } else if (MIME_TYPE_VIDEO.equals(type)) {
+                typeBits = DataManager.INCLUDE_VIDEO;
+            }
+        }
+        if (typeBits == 0) typeBits = DataManager.INCLUDE_ALL;
+
+        return typeBits;
+    }
+
+    public static int getSelectionModePrompt(int typeBits) {
+        if ((typeBits & DataManager.INCLUDE_VIDEO) != 0) {
+            return (typeBits & DataManager.INCLUDE_IMAGE) == 0
+                    ? R.string.select_video
+                    : R.string.select_item;
+        }
+        return R.string.select_image;
+    }
+
+    public static boolean hasSpaceForSize(long size) {
+        String state = Environment.getExternalStorageState();
+        if (!Environment.MEDIA_MOUNTED.equals(state)) {
+            return false;
+        }
+
+        String path = Environment.getExternalStorageDirectory().getPath();
+        try {
+            StatFs stat = new StatFs(path);
+            return stat.getAvailableBlocks() * (long) stat.getBlockSize() > size;
+        } catch (Exception e) {
+            Log.i(TAG, "Fail to access external storage", e);
+        }
+        return false;
+    }
+
+    public static void assertInMainThread() {
+        if (Thread.currentThread() == sContext.getMainLooper().getThread()) {
+            throw new AssertionError();
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/util/IdentityCache.java b/src/com/android/gallery3d/util/IdentityCache.java
new file mode 100644
index 0000000..02a46ae
--- /dev/null
+++ b/src/com/android/gallery3d/util/IdentityCache.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Set;
+
+public class IdentityCache<K, V> {
+
+    private final HashMap<K, Entry<K, V>> mWeakMap =
+            new HashMap<K, Entry<K, V>>();
+    private ReferenceQueue<V> mQueue = new ReferenceQueue<V>();
+
+    public IdentityCache() {
+    }
+
+    private static class Entry<K, V> extends WeakReference<V> {
+        K mKey;
+
+        public Entry(K key, V value, ReferenceQueue<V> queue) {
+            super(value, queue);
+            mKey = key;
+        }
+    }
+
+    private void cleanUpWeakMap() {
+        Entry<K, V> entry = (Entry<K, V>) mQueue.poll();
+        while (entry != null) {
+            mWeakMap.remove(entry.mKey);
+            entry = (Entry<K, V>) mQueue.poll();
+        }
+    }
+
+    public synchronized V put(K key, V value) {
+        cleanUpWeakMap();
+        Entry<K, V> entry = mWeakMap.put(
+                key, new Entry<K, V>(key, value, mQueue));
+        return entry == null ? null : entry.get();
+    }
+
+    public synchronized V get(K key) {
+        cleanUpWeakMap();
+        Entry<K, V> entry = mWeakMap.get(key);
+        return entry == null ? null : entry.get();
+    }
+
+    public synchronized void clear() {
+        mWeakMap.clear();
+        mQueue = new ReferenceQueue<V>();
+    }
+
+    public synchronized ArrayList<K> keys() {
+        Set<K> set = mWeakMap.keySet();
+        ArrayList<K> result = new ArrayList<K>(set);
+        return result;
+    }
+}
diff --git a/src/com/android/gallery3d/util/IntArray.java b/src/com/android/gallery3d/util/IntArray.java
new file mode 100644
index 0000000..88657bb
--- /dev/null
+++ b/src/com/android/gallery3d/util/IntArray.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+public class IntArray {
+    private static final int INIT_CAPACITY = 8;
+
+    private int mData[] = new int[INIT_CAPACITY];
+    private int mSize = 0;
+
+    public void add(int value) {
+        if (mData.length == mSize) {
+            int temp[] = new int[mSize + mSize];
+            System.arraycopy(mData, 0, temp, 0, mSize);
+            mData = temp;
+        }
+        mData[mSize++] = value;
+    }
+
+    public int size() {
+        return mSize;
+    }
+
+    public int[] toArray(int[] result) {
+        if (result == null || result.length < mSize) {
+            result = new int[mSize];
+        }
+        System.arraycopy(mData, 0, result, 0, mSize);
+        return result;
+    }
+
+    public int[] getInternalArray() {
+        return mData;
+    }
+
+    public void clear() {
+        mSize = 0;
+        if (mData.length != INIT_CAPACITY) mData = new int[INIT_CAPACITY];
+    }
+}
diff --git a/src/com/android/gallery3d/util/InterruptableOutputStream.java b/src/com/android/gallery3d/util/InterruptableOutputStream.java
new file mode 100644
index 0000000..1ab62ab
--- /dev/null
+++ b/src/com/android/gallery3d/util/InterruptableOutputStream.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import com.android.gallery3d.common.Utils;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+
+public class InterruptableOutputStream extends OutputStream {
+
+    private static final int MAX_WRITE_BYTES = 4096;
+
+    private OutputStream mOutputStream;
+    private volatile boolean mIsInterrupted = false;
+
+    public InterruptableOutputStream(OutputStream outputStream) {
+        mOutputStream = Utils.checkNotNull(outputStream);
+    }
+
+    @Override
+    public void write(int oneByte) throws IOException {
+        if (mIsInterrupted) throw new InterruptedIOException();
+        mOutputStream.write(oneByte);
+    }
+
+    @Override
+    public void write(byte[] buffer, int offset, int count) throws IOException {
+        int end = offset + count;
+        while (offset < end) {
+            if (mIsInterrupted) throw new InterruptedIOException();
+            int bytesCount = Math.min(MAX_WRITE_BYTES, end - offset);
+            mOutputStream.write(buffer, offset, bytesCount);
+            offset += bytesCount;
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        mOutputStream.close();
+    }
+
+    @Override
+    public void flush() throws IOException {
+        if (mIsInterrupted) throw new InterruptedIOException();
+        mOutputStream.flush();
+    }
+
+    public void interrupt() {
+        mIsInterrupted = true;
+    }
+}
diff --git a/src/com/android/gallery3d/util/LinkedNode.java b/src/com/android/gallery3d/util/LinkedNode.java
new file mode 100644
index 0000000..8554acd
--- /dev/null
+++ b/src/com/android/gallery3d/util/LinkedNode.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+
+public class LinkedNode {
+    private LinkedNode mPrev;
+    private LinkedNode mNext;
+
+    public LinkedNode() {
+        mPrev = mNext = this;
+    }
+
+    public void insert(LinkedNode node) {
+        node.mNext = mNext;
+        mNext.mPrev = node;
+        node.mPrev = this;
+        mNext = node;
+    }
+
+    public void remove() {
+        if (mNext == this) throw new IllegalStateException();
+        mPrev.mNext = mNext;
+        mNext.mPrev = mPrev;
+        mPrev = mNext = null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static class List<T extends LinkedNode> {
+        private LinkedNode mHead = new LinkedNode();
+
+        public void insertFirst(T node) {
+            mHead.insert(node);
+        }
+
+        public void insertLast(T node) {
+            mHead.mPrev.insert(node);
+        }
+
+        public T getFirst() {
+            return (T) (mHead.mNext == mHead ? null : mHead.mNext);
+        }
+
+        public T getLast() {
+            return (T) (mHead.mPrev == mHead ? null : mHead.mPrev);
+        }
+
+        public T nextOf(T node) {
+            return (T) (node.mNext == mHead ? null : node.mNext);
+        }
+
+        public T previousOf(T node) {
+            return (T) (node.mPrev == mHead ? null : node.mPrev);
+        }
+
+    }
+
+    public static <T extends LinkedNode> List<T> newList() {
+        return new List<T>();
+    }
+}
diff --git a/src/com/android/gallery3d/util/Log.java b/src/com/android/gallery3d/util/Log.java
new file mode 100644
index 0000000..d7f8e85
--- /dev/null
+++ b/src/com/android/gallery3d/util/Log.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+public class Log {
+    public static int v(String tag, String msg) {
+        return android.util.Log.v(tag, msg);
+    }
+    public static int v(String tag, String msg, Throwable tr) {
+        return android.util.Log.v(tag, msg, tr);
+    }
+    public static int d(String tag, String msg) {
+        return android.util.Log.d(tag, msg);
+    }
+    public static int d(String tag, String msg, Throwable tr) {
+        return android.util.Log.d(tag, msg, tr);
+    }
+    public static int i(String tag, String msg) {
+        return android.util.Log.i(tag, msg);
+    }
+    public static int i(String tag, String msg, Throwable tr) {
+        return android.util.Log.i(tag, msg, tr);
+    }
+    public static int w(String tag, String msg) {
+        return android.util.Log.w(tag, msg);
+    }
+    public static int w(String tag, String msg, Throwable tr) {
+        return android.util.Log.w(tag, msg, tr);
+    }
+    public static int w(String tag, Throwable tr) {
+        return android.util.Log.w(tag, tr);
+    }
+    public static int e(String tag, String msg) {
+        return android.util.Log.e(tag, msg);
+    }
+    public static int e(String tag, String msg, Throwable tr) {
+        return android.util.Log.e(tag, msg, tr);
+    }
+}
diff --git a/src/com/android/gallery3d/util/MediaSetUtils.java b/src/com/android/gallery3d/util/MediaSetUtils.java
new file mode 100644
index 0000000..817ffed
--- /dev/null
+++ b/src/com/android/gallery3d/util/MediaSetUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.MtpContext;
+import com.android.gallery3d.data.Path;
+
+import android.os.Environment;
+
+import java.util.Comparator;
+
+public class MediaSetUtils {
+    public static final Comparator<MediaSet> NAME_COMPARATOR = new NameComparator();
+
+    public static final int CAMERA_BUCKET_ID = GalleryUtils.getBucketId(
+            Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera");
+    public static final int DOWNLOAD_BUCKET_ID = GalleryUtils.getBucketId(
+            Environment.getExternalStorageDirectory().toString() + "/download");
+    public static final int IMPORTED_BUCKET_ID = GalleryUtils.getBucketId(
+            Environment.getExternalStorageDirectory().toString() + "/"
+            + MtpContext.NAME_IMPORTED_FOLDER);
+
+    private static final Path[] CAMERA_PATHS = {
+            Path.fromString("/local/all/" + CAMERA_BUCKET_ID),
+            Path.fromString("/local/image/" + CAMERA_BUCKET_ID),
+            Path.fromString("/local/video/" + CAMERA_BUCKET_ID)};
+
+    public static boolean isCameraSource(Path path) {
+        return CAMERA_PATHS[0] == path || CAMERA_PATHS[1] == path
+                || CAMERA_PATHS[2] == path;
+    }
+
+    // Sort MediaSets by name
+    public static class NameComparator implements Comparator<MediaSet> {
+        public int compare(MediaSet set1, MediaSet set2) {
+            int result = set1.getName().compareToIgnoreCase(set2.getName());
+            if (result != 0) return result;
+            return set1.getPath().toString().compareTo(set2.getPath().toString());
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/util/PriorityThreadFactory.java b/src/com/android/gallery3d/util/PriorityThreadFactory.java
new file mode 100644
index 0000000..67b2152
--- /dev/null
+++ b/src/com/android/gallery3d/util/PriorityThreadFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.gallery3d.util;
+
+
+import android.os.Process;
+
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A thread factory that creates threads with a given thread priority.
+ */
+public class PriorityThreadFactory implements ThreadFactory {
+
+    private final int mPriority;
+    private final AtomicInteger mNumber = new AtomicInteger();
+    private final String mName;
+
+    public PriorityThreadFactory(String name, int priority) {
+        mName = name;
+        mPriority = priority;
+    }
+
+    public Thread newThread(Runnable r) {
+        return new Thread(r, mName + '-' + mNumber.getAndIncrement()) {
+            @Override
+            public void run() {
+                Process.setThreadPriority(mPriority);
+                super.run();
+            }
+        };
+    }
+
+}
diff --git a/src/com/android/gallery3d/util/ReverseGeocoder.java b/src/com/android/gallery3d/util/ReverseGeocoder.java
new file mode 100644
index 0000000..d253b4b
--- /dev/null
+++ b/src/com/android/gallery3d/util/ReverseGeocoder.java
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import com.android.gallery3d.common.BlobCache;
+
+import android.content.Context;
+import android.location.Address;
+import android.location.Geocoder;
+import android.location.Location;
+import android.location.LocationManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+public class ReverseGeocoder {
+    private static final String TAG = "ReverseGeocoder";
+    public static final int EARTH_RADIUS_METERS = 6378137;
+    public static final int LAT_MIN = -90;
+    public static final int LAT_MAX = 90;
+    public static final int LON_MIN = -180;
+    public static final int LON_MAX = 180;
+    private static final int MAX_COUNTRY_NAME_LENGTH = 8;
+    // If two points are within 20 miles of each other, use
+    // "Around Palo Alto, CA" or "Around Mountain View, CA".
+    // instead of directly jumping to the next level and saying
+    // "California, US".
+    private static final int MAX_LOCALITY_MILE_RANGE = 20;
+
+    private static final String GEO_CACHE_FILE = "rev_geocoding";
+    private static final int GEO_CACHE_MAX_ENTRIES = 1000;
+    private static final int GEO_CACHE_MAX_BYTES = 500 * 1024;
+    private static final int GEO_CACHE_VERSION = 0;
+
+    public static class SetLatLong {
+        // The latitude and longitude of the min latitude point.
+        public double mMinLatLatitude = LAT_MAX;
+        public double mMinLatLongitude;
+        // The latitude and longitude of the max latitude point.
+        public double mMaxLatLatitude = LAT_MIN;
+        public double mMaxLatLongitude;
+        // The latitude and longitude of the min longitude point.
+        public double mMinLonLatitude;
+        public double mMinLonLongitude = LON_MAX;
+        // The latitude and longitude of the max longitude point.
+        public double mMaxLonLatitude;
+        public double mMaxLonLongitude = LON_MIN;
+    }
+
+    private Context mContext;
+    private Geocoder mGeocoder;
+    private BlobCache mGeoCache;
+    private ConnectivityManager mConnectivityManager;
+    private static Address sCurrentAddress; // last known address
+
+    public ReverseGeocoder(Context context) {
+        mContext = context;
+        mGeocoder = new Geocoder(mContext);
+        mGeoCache = CacheManager.getCache(context, GEO_CACHE_FILE,
+                GEO_CACHE_MAX_ENTRIES, GEO_CACHE_MAX_BYTES,
+                GEO_CACHE_VERSION);
+        mConnectivityManager = (ConnectivityManager)
+                context.getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    public String computeAddress(SetLatLong set) {
+        // The overall min and max latitudes and longitudes of the set.
+        double setMinLatitude = set.mMinLatLatitude;
+        double setMinLongitude = set.mMinLatLongitude;
+        double setMaxLatitude = set.mMaxLatLatitude;
+        double setMaxLongitude = set.mMaxLatLongitude;
+        if (Math.abs(set.mMaxLatLatitude - set.mMinLatLatitude)
+                < Math.abs(set.mMaxLonLongitude - set.mMinLonLongitude)) {
+            setMinLatitude = set.mMinLonLatitude;
+            setMinLongitude = set.mMinLonLongitude;
+            setMaxLatitude = set.mMaxLonLatitude;
+            setMaxLongitude = set.mMaxLonLongitude;
+        }
+        Address addr1 = lookupAddress(setMinLatitude, setMinLongitude, true);
+        Address addr2 = lookupAddress(setMaxLatitude, setMaxLongitude, true);
+        if (addr1 == null)
+            addr1 = addr2;
+        if (addr2 == null)
+            addr2 = addr1;
+        if (addr1 == null || addr2 == null) {
+            return null;
+        }
+
+        // Get current location, we decide the granularity of the string based
+        // on this.
+        LocationManager locationManager =
+                (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+        Location location = null;
+        List<String> providers = locationManager.getAllProviders();
+        for (int i = 0; i < providers.size(); ++i) {
+            String provider = providers.get(i);
+            location = (provider != null) ? locationManager.getLastKnownLocation(provider) : null;
+            if (location != null)
+                break;
+        }
+        String currentCity = "";
+        String currentAdminArea = "";
+        String currentCountry = Locale.getDefault().getCountry();
+        if (location != null) {
+            Address currentAddress = lookupAddress(
+                    location.getLatitude(), location.getLongitude(), true);
+            if (currentAddress == null) {
+                currentAddress = sCurrentAddress;
+            } else {
+                sCurrentAddress = currentAddress;
+            }
+            if (currentAddress != null && currentAddress.getCountryCode() != null) {
+                currentCity = checkNull(currentAddress.getLocality());
+                currentCountry = checkNull(currentAddress.getCountryCode());
+                currentAdminArea = checkNull(currentAddress.getAdminArea());
+            }
+        }
+
+        String closestCommonLocation = null;
+        String addr1Locality = checkNull(addr1.getLocality());
+        String addr2Locality = checkNull(addr2.getLocality());
+        String addr1AdminArea = checkNull(addr1.getAdminArea());
+        String addr2AdminArea = checkNull(addr2.getAdminArea());
+        String addr1CountryCode = checkNull(addr1.getCountryCode());
+        String addr2CountryCode = checkNull(addr2.getCountryCode());
+
+        if (currentCity.equals(addr1Locality) || currentCity.equals(addr2Locality)) {
+            String otherCity = currentCity;
+            if (currentCity.equals(addr1Locality)) {
+                otherCity = addr2Locality;
+                if (otherCity.length() == 0) {
+                    otherCity = addr2AdminArea;
+                    if (!currentCountry.equals(addr2CountryCode)) {
+                        otherCity += " " + addr2CountryCode;
+                    }
+                }
+                addr2Locality = addr1Locality;
+                addr2AdminArea = addr1AdminArea;
+                addr2CountryCode = addr1CountryCode;
+            } else {
+                otherCity = addr1Locality;
+                if (otherCity.length() == 0) {
+                    otherCity = addr1AdminArea;
+                    if (!currentCountry.equals(addr1CountryCode)) {
+                        otherCity += " " + addr1CountryCode;
+                    }
+                }
+                addr1Locality = addr2Locality;
+                addr1AdminArea = addr2AdminArea;
+                addr1CountryCode = addr2CountryCode;
+            }
+            closestCommonLocation = valueIfEqual(addr1.getAddressLine(0), addr2.getAddressLine(0));
+            if (closestCommonLocation != null && !("null".equals(closestCommonLocation))) {
+                if (!currentCity.equals(otherCity)) {
+                    closestCommonLocation += " - " + otherCity;
+                }
+                return closestCommonLocation;
+            }
+
+            // Compare thoroughfare (street address) next.
+            closestCommonLocation = valueIfEqual(addr1.getThoroughfare(), addr2.getThoroughfare());
+            if (closestCommonLocation != null && !("null".equals(closestCommonLocation))) {
+                return closestCommonLocation;
+            }
+        }
+
+        // Compare the locality.
+        closestCommonLocation = valueIfEqual(addr1Locality, addr2Locality);
+        if (closestCommonLocation != null && !("".equals(closestCommonLocation))) {
+            String adminArea = addr1AdminArea;
+            String countryCode = addr1CountryCode;
+            if (adminArea != null && adminArea.length() > 0) {
+                if (!countryCode.equals(currentCountry)) {
+                    closestCommonLocation += ", " + adminArea + " " + countryCode;
+                } else {
+                    closestCommonLocation += ", " + adminArea;
+                }
+            }
+            return closestCommonLocation;
+        }
+
+        // If the admin area is the same as the current location, we hide it and
+        // instead show the city name.
+        if (currentAdminArea.equals(addr1AdminArea) && currentAdminArea.equals(addr2AdminArea)) {
+            if ("".equals(addr1Locality)) {
+                addr1Locality = addr2Locality;
+            }
+            if ("".equals(addr2Locality)) {
+                addr2Locality = addr1Locality;
+            }
+            if (!"".equals(addr1Locality)) {
+                if (addr1Locality.equals(addr2Locality)) {
+                    closestCommonLocation = addr1Locality + ", " + currentAdminArea;
+                } else {
+                    closestCommonLocation = addr1Locality + " - " + addr2Locality;
+                }
+                return closestCommonLocation;
+            }
+        }
+
+        // Just choose one of the localities if within a MAX_LOCALITY_MILE_RANGE
+        // mile radius.
+        float[] distanceFloat = new float[1];
+        Location.distanceBetween(setMinLatitude, setMinLongitude,
+                setMaxLatitude, setMaxLongitude, distanceFloat);
+        int distance = (int) GalleryUtils.toMile(distanceFloat[0]);
+        if (distance < MAX_LOCALITY_MILE_RANGE) {
+            // Try each of the points and just return the first one to have a
+            // valid address.
+            closestCommonLocation = getLocalityAdminForAddress(addr1, true);
+            if (closestCommonLocation != null) {
+                return closestCommonLocation;
+            }
+            closestCommonLocation = getLocalityAdminForAddress(addr2, true);
+            if (closestCommonLocation != null) {
+                return closestCommonLocation;
+            }
+        }
+
+        // Check the administrative area.
+        closestCommonLocation = valueIfEqual(addr1AdminArea, addr2AdminArea);
+        if (closestCommonLocation != null && !("".equals(closestCommonLocation))) {
+            String countryCode = addr1CountryCode;
+            if (!countryCode.equals(currentCountry)) {
+                if (countryCode != null && countryCode.length() > 0) {
+                    closestCommonLocation += " " + countryCode;
+                }
+            }
+            return closestCommonLocation;
+        }
+
+        // Check the country codes.
+        closestCommonLocation = valueIfEqual(addr1CountryCode, addr2CountryCode);
+        if (closestCommonLocation != null && !("".equals(closestCommonLocation))) {
+            return closestCommonLocation;
+        }
+        // There is no intersection, let's choose a nicer name.
+        String addr1Country = addr1.getCountryName();
+        String addr2Country = addr2.getCountryName();
+        if (addr1Country == null)
+            addr1Country = addr1CountryCode;
+        if (addr2Country == null)
+            addr2Country = addr2CountryCode;
+        if (addr1Country == null || addr2Country == null)
+            return null;
+        if (addr1Country.length() > MAX_COUNTRY_NAME_LENGTH || addr2Country.length() > MAX_COUNTRY_NAME_LENGTH) {
+            closestCommonLocation = addr1CountryCode + " - " + addr2CountryCode;
+        } else {
+            closestCommonLocation = addr1Country + " - " + addr2Country;
+        }
+        return closestCommonLocation;
+    }
+
+    private String checkNull(String locality) {
+        if (locality == null)
+            return "";
+        if (locality.equals("null"))
+            return "";
+        return locality;
+    }
+
+    private String getLocalityAdminForAddress(final Address addr, final boolean approxLocation) {
+        if (addr == null)
+            return "";
+        String localityAdminStr = addr.getLocality();
+        if (localityAdminStr != null && !("null".equals(localityAdminStr))) {
+            if (approxLocation) {
+                // TODO: Uncomment these lines as soon as we may translations
+                // for Res.string.around.
+                // localityAdminStr =
+                // mContext.getResources().getString(Res.string.around) + " " +
+                // localityAdminStr;
+            }
+            String adminArea = addr.getAdminArea();
+            if (adminArea != null && adminArea.length() > 0) {
+                localityAdminStr += ", " + adminArea;
+            }
+            return localityAdminStr;
+        }
+        return null;
+    }
+
+    public Address lookupAddress(final double latitude, final double longitude,
+            boolean useCache) {
+        try {
+            long locationKey = (long) (((latitude + LAT_MAX) * 2 * LAT_MAX
+                    + (longitude + LON_MAX)) * EARTH_RADIUS_METERS);
+            byte[] cachedLocation = null;
+            if (useCache && mGeoCache != null) {
+                cachedLocation = mGeoCache.lookup(locationKey);
+            }
+            Address address = null;
+            NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
+            if (cachedLocation == null || cachedLocation.length == 0) {
+                if (networkInfo == null || !networkInfo.isConnected()) {
+                    return null;
+                }
+                List<Address> addresses = mGeocoder.getFromLocation(latitude, longitude, 1);
+                if (!addresses.isEmpty()) {
+                    address = addresses.get(0);
+                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                    DataOutputStream dos = new DataOutputStream(bos);
+                    Locale locale = address.getLocale();
+                    writeUTF(dos, locale.getLanguage());
+                    writeUTF(dos, locale.getCountry());
+                    writeUTF(dos, locale.getVariant());
+
+                    writeUTF(dos, address.getThoroughfare());
+                    int numAddressLines = address.getMaxAddressLineIndex();
+                    dos.writeInt(numAddressLines);
+                    for (int i = 0; i < numAddressLines; ++i) {
+                        writeUTF(dos, address.getAddressLine(i));
+                    }
+                    writeUTF(dos, address.getFeatureName());
+                    writeUTF(dos, address.getLocality());
+                    writeUTF(dos, address.getAdminArea());
+                    writeUTF(dos, address.getSubAdminArea());
+
+                    writeUTF(dos, address.getCountryName());
+                    writeUTF(dos, address.getCountryCode());
+                    writeUTF(dos, address.getPostalCode());
+                    writeUTF(dos, address.getPhone());
+                    writeUTF(dos, address.getUrl());
+
+                    dos.flush();
+                    if (mGeoCache != null) {
+                        mGeoCache.insert(locationKey, bos.toByteArray());
+                    }
+                    dos.close();
+                }
+            } else {
+                // Parsing the address from the byte stream.
+                DataInputStream dis = new DataInputStream(
+                        new ByteArrayInputStream(cachedLocation));
+                String language = readUTF(dis);
+                String country = readUTF(dis);
+                String variant = readUTF(dis);
+                Locale locale = null;
+                if (language != null) {
+                    if (country == null) {
+                        locale = new Locale(language);
+                    } else if (variant == null) {
+                        locale = new Locale(language, country);
+                    } else {
+                        locale = new Locale(language, country, variant);
+                    }
+                }
+                if (!locale.getLanguage().equals(Locale.getDefault().getLanguage())) {
+                    dis.close();
+                    return lookupAddress(latitude, longitude, false);
+                }
+                address = new Address(locale);
+
+                address.setThoroughfare(readUTF(dis));
+                int numAddressLines = dis.readInt();
+                for (int i = 0; i < numAddressLines; ++i) {
+                    address.setAddressLine(i, readUTF(dis));
+                }
+                address.setFeatureName(readUTF(dis));
+                address.setLocality(readUTF(dis));
+                address.setAdminArea(readUTF(dis));
+                address.setSubAdminArea(readUTF(dis));
+
+                address.setCountryName(readUTF(dis));
+                address.setCountryCode(readUTF(dis));
+                address.setPostalCode(readUTF(dis));
+                address.setPhone(readUTF(dis));
+                address.setUrl(readUTF(dis));
+                dis.close();
+            }
+            return address;
+        } catch (Exception e) {
+            // Ignore.
+        }
+        return null;
+    }
+
+    private String valueIfEqual(String a, String b) {
+        return (a != null && b != null && a.equalsIgnoreCase(b)) ? a : null;
+    }
+
+    public static final void writeUTF(DataOutputStream dos, String string) throws IOException {
+        if (string == null) {
+            dos.writeUTF("");
+        } else {
+            dos.writeUTF(string);
+        }
+    }
+
+    public static final String readUTF(DataInputStream dis) throws IOException {
+        String retVal = dis.readUTF();
+        if (retVal.length() == 0)
+            return null;
+        return retVal;
+    }
+}
diff --git a/src/com/android/gallery3d/util/ThreadPool.java b/src/com/android/gallery3d/util/ThreadPool.java
new file mode 100644
index 0000000..71bb3c5
--- /dev/null
+++ b/src/com/android/gallery3d/util/ThreadPool.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.util;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class ThreadPool {
+    private static final String TAG = "ThreadPool";
+    private static final int CORE_POOL_SIZE = 4;
+    private static final int MAX_POOL_SIZE = 8;
+    private static final int KEEP_ALIVE_TIME = 10; // 10 seconds
+
+    // Resource type
+    public static final int MODE_NONE = 0;
+    public static final int MODE_CPU = 1;
+    public static final int MODE_NETWORK = 2;
+
+    public static final JobContext JOB_CONTEXT_STUB = new JobContextStub();
+
+    ResourceCounter mCpuCounter = new ResourceCounter(2);
+    ResourceCounter mNetworkCounter = new ResourceCounter(2);
+
+    // A Job is like a Callable, but it has an addition JobContext parameter.
+    public interface Job<T> {
+        public T run(JobContext jc);
+    }
+
+    public interface JobContext {
+        boolean isCancelled();
+        void setCancelListener(CancelListener listener);
+        boolean setMode(int mode);
+    }
+
+    private static class JobContextStub implements JobContext {
+        @Override
+        public boolean isCancelled() {
+            return false;
+        }
+
+        @Override
+        public void setCancelListener(CancelListener listener) {
+        }
+
+        @Override
+        public boolean setMode(int mode) {
+            return true;
+        }
+    }
+
+    public interface CancelListener {
+        public void onCancel();
+    }
+
+    private static class ResourceCounter {
+        public int value;
+        public ResourceCounter(int v) {
+            value = v;
+        }
+    }
+
+    private final Executor mExecutor;
+
+    public ThreadPool() {
+        mExecutor = new ThreadPoolExecutor(
+                CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME,
+                TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
+                new PriorityThreadFactory("thread-pool",
+                android.os.Process.THREAD_PRIORITY_BACKGROUND));
+    }
+
+    // Submit a job to the thread pool. The listener will be called when the
+    // job is finished (or cancelled).
+    public <T> Future<T> submit(Job<T> job, FutureListener<T> listener) {
+        Worker<T> w = new Worker<T>(job, listener);
+        mExecutor.execute(w);
+        return w;
+    }
+
+    public <T> Future<T> submit(Job<T> job) {
+        return submit(job, null);
+    }
+
+    private class Worker<T> implements Runnable, Future<T>, JobContext {
+        private static final String TAG = "Worker";
+        private Job<T> mJob;
+        private FutureListener<T> mListener;
+        private CancelListener mCancelListener;
+        private ResourceCounter mWaitOnResource;
+        private volatile boolean mIsCancelled;
+        private boolean mIsDone;
+        private T mResult;
+        private int mMode;
+
+        public Worker(Job<T> job, FutureListener<T> listener) {
+            mJob = job;
+            mListener = listener;
+        }
+
+        // This is called by a thread in the thread pool.
+        public void run() {
+            T result = null;
+
+            // A job is in CPU mode by default. setMode returns false
+            // if the job is cancelled.
+            if (setMode(MODE_CPU)) {
+                try {
+                    result = mJob.run(this);
+                } catch (Throwable ex) {
+                    Log.w(TAG, "Exception in running a job", ex);
+                }
+            }
+
+            synchronized(this) {
+                setMode(MODE_NONE);
+                mResult = result;
+                mIsDone = true;
+                notifyAll();
+            }
+            if (mListener != null) mListener.onFutureDone(this);
+        }
+
+        // Below are the methods for Future.
+        public synchronized void cancel() {
+            if (mIsCancelled) return;
+            mIsCancelled = true;
+            if (mWaitOnResource != null) {
+                synchronized (mWaitOnResource) {
+                    mWaitOnResource.notifyAll();
+                }
+            }
+            if (mCancelListener != null) {
+                mCancelListener.onCancel();
+            }
+        }
+
+        public boolean isCancelled() {
+            return mIsCancelled;
+        }
+
+        public synchronized boolean isDone() {
+            return mIsDone;
+        }
+
+        public synchronized T get() {
+            while (!mIsDone) {
+                try {
+                    wait();
+                } catch (Exception ex) {
+                    Log.w(TAG, "ingore exception", ex);
+                    // ignore.
+                }
+            }
+            return mResult;
+        }
+
+        public void waitDone() {
+            get();
+        }
+
+        // Below are the methods for JobContext (only called from the
+        // thread running the job)
+        public synchronized void setCancelListener(CancelListener listener) {
+            mCancelListener = listener;
+            if (mIsCancelled && mCancelListener != null) {
+                mCancelListener.onCancel();
+            }
+        }
+
+        public boolean setMode(int mode) {
+            // Release old resource
+            ResourceCounter rc = modeToCounter(mMode);
+            if (rc != null) releaseResource(rc);
+            mMode = MODE_NONE;
+
+            // Acquire new resource
+            rc = modeToCounter(mode);
+            if (rc != null) {
+                if (!acquireResource(rc)) {
+                    return false;
+                }
+                mMode = mode;
+            }
+
+            return true;
+        }
+
+        private ResourceCounter modeToCounter(int mode) {
+            if (mode == MODE_CPU) {
+                return mCpuCounter;
+            } else if (mode == MODE_NETWORK) {
+                return mNetworkCounter;
+            } else {
+                return null;
+            }
+        }
+
+        private boolean acquireResource(ResourceCounter counter) {
+            while (true) {
+                synchronized (this) {
+                    if (mIsCancelled) {
+                        mWaitOnResource = null;
+                        return false;
+                    }
+                    mWaitOnResource = counter;
+                }
+
+                synchronized (counter) {
+                    if (counter.value > 0) {
+                        counter.value--;
+                        break;
+                    } else {
+                        try {
+                            counter.wait();
+                        } catch (InterruptedException ex) {
+                            // ignore.
+                        }
+                    }
+                }
+            }
+
+            synchronized (this) {
+                mWaitOnResource = null;
+            }
+
+            return true;
+        }
+
+        private void releaseResource(ResourceCounter counter) {
+            synchronized (counter) {
+                counter.value++;
+                counter.notifyAll();
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/util/UpdateHelper.java b/src/com/android/gallery3d/util/UpdateHelper.java
new file mode 100644
index 0000000..9fdade6
--- /dev/null
+++ b/src/com/android/gallery3d/util/UpdateHelper.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.gallery3d.util;
+
+import com.android.gallery3d.common.Utils;
+
+public class UpdateHelper {
+
+    private boolean mUpdated = false;
+
+    public int update(int original, int update) {
+        if (original != update) {
+            mUpdated = true;
+            original = update;
+        }
+        return original;
+    }
+
+    public long update(long original, long update) {
+        if (original != update) {
+            mUpdated = true;
+            original = update;
+        }
+        return original;
+    }
+
+    public double update(double original, double update) {
+        if (original != update) {
+            mUpdated = true;
+            original = update;
+        }
+        return original;
+    }
+
+    public double update(float original, float update) {
+        if (original != update) {
+            mUpdated = true;
+            original = update;
+        }
+        return original;
+    }
+
+    public <T> T update(T original, T update) {
+        if (!Utils.equals(original, update)) {
+            mUpdated = true;
+            original = update;
+        }
+        return original;
+    }
+
+    public boolean isUpdated() {
+        return mUpdated;
+    }
+}
diff --git a/src/com/android/gallery3d/widget/LocalPhotoSource.java b/src/com/android/gallery3d/widget/LocalPhotoSource.java
new file mode 100644
index 0000000..de16a71
--- /dev/null
+++ b/src/com/android/gallery3d/widget/LocalPhotoSource.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Handler;
+import android.provider.MediaStore.Images.Media;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+
+public class LocalPhotoSource implements WidgetSource {
+
+    private static final String TAG = "LocalPhotoSource";
+
+    private static final int MAX_PHOTO_COUNT = 128;
+
+    /* Static fields used to query for the correct set of images */
+    private static final Uri CONTENT_URI = Media.EXTERNAL_CONTENT_URI;
+    private static final String DATE_TAKEN = Media.DATE_TAKEN;
+    private static final String[] PROJECTION = {Media._ID};
+    private static final String[] COUNT_PROJECTION = {"count(*)"};
+    /* We don't want to include the download directory */
+    private static final String SELECTION =
+            String.format("%s != %s", Media.BUCKET_ID, getDownloadBucketId());
+    private static final String ORDER = String.format("%s DESC", DATE_TAKEN);
+
+    private Context mContext;
+    private ArrayList<Long> mPhotos = new ArrayList<Long>();
+    private ContentListener mContentListener;
+    private ContentObserver mContentObserver;
+    private boolean mContentDirty = true;
+    private DataManager mDataManager;
+    private static final Path LOCAL_IMAGE_ROOT = Path.fromString("/local/image/item");
+
+    public LocalPhotoSource(Context context) {
+        mContext = context;
+        mDataManager = ((GalleryApp) context.getApplicationContext()).getDataManager();
+        mContentObserver = new ContentObserver(new Handler()) {
+            @Override
+            public void onChange(boolean selfChange) {
+                mContentDirty = true;
+                if (mContentListener != null) mContentListener.onContentDirty();
+            }
+        };
+        mContext.getContentResolver()
+                .registerContentObserver(CONTENT_URI, true, mContentObserver);
+    }
+
+    public void close() {
+        mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+    }
+
+    @Override
+    public Uri getContentUri(int index) {
+        if (index < mPhotos.size()) {
+            return CONTENT_URI.buildUpon()
+                    .appendPath(String.valueOf(mPhotos.get(index)))
+                    .build();
+        }
+        return null;
+    }
+
+    @Override
+    public Bitmap getImage(int index) {
+        if (index >= mPhotos.size()) return null;
+        long id = mPhotos.get(index);
+        MediaItem image = (MediaItem)
+                mDataManager.getMediaObject(LOCAL_IMAGE_ROOT.getChild(id));
+        if (image == null) return null;
+
+        return WidgetUtils.createWidgetBitmap(image);
+    }
+
+    private int[] getExponentialIndice(int total, int count) {
+        Random random = new Random();
+        if (count > total) count = total;
+        HashSet<Integer> selected = new HashSet<Integer>(count);
+        while (selected.size() < count) {
+            int row = (int)(-Math.log(random.nextDouble()) * total / 2);
+            if (row < total) selected.add(row);
+        }
+        int values[] = new int[count];
+        int index = 0;
+        for (int value : selected) {
+            values[index++] = value;
+        }
+        return values;
+    }
+
+    private int getPhotoCount(ContentResolver resolver) {
+        Cursor cursor = resolver.query(
+                CONTENT_URI, COUNT_PROJECTION, SELECTION, null, null);
+        if (cursor == null) return 0;
+        try {
+            Utils.assertTrue(cursor.moveToNext());
+            return cursor.getInt(0);
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private boolean isContentSound(int totalCount) {
+        if (mPhotos.size() < Math.min(totalCount, MAX_PHOTO_COUNT)) return false;
+        if (mPhotos.size() == 0) return true; // totalCount is also 0
+
+        StringBuilder builder = new StringBuilder();
+        for (Long imageId : mPhotos) {
+            if (builder.length() > 0) builder.append(",");
+            builder.append(imageId);
+        }
+        Cursor cursor = mContext.getContentResolver().query(
+                CONTENT_URI, COUNT_PROJECTION,
+                String.format("%s in (%s)", Media._ID, builder.toString()),
+                null, null);
+        if (cursor == null) return false;
+        try {
+            Utils.assertTrue(cursor.moveToNext());
+            return cursor.getInt(0) == mPhotos.size();
+        } finally {
+            cursor.close();
+        }
+    }
+
+    public void reload() {
+        if (!mContentDirty) return;
+        mContentDirty = false;
+
+        ContentResolver resolver = mContext.getContentResolver();
+        int photoCount = getPhotoCount(resolver);
+        if (isContentSound(photoCount)) return;
+
+        int choosedIds[] = getExponentialIndice(photoCount, MAX_PHOTO_COUNT);
+        Arrays.sort(choosedIds);
+
+        mPhotos.clear();
+        Cursor cursor = mContext.getContentResolver().query(
+                CONTENT_URI, PROJECTION, SELECTION, null, ORDER);
+        if (cursor == null) return;
+        try {
+            for (int index : choosedIds) {
+                if (cursor.moveToPosition(index)) {
+                    mPhotos.add(cursor.getLong(0));
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    @Override
+    public int size() {
+        reload();
+        return mPhotos.size();
+    }
+
+    /**
+     * Builds the bucket ID for the public external storage Downloads directory
+     * @return the bucket ID
+     */
+    private static int getDownloadBucketId() {
+        String downloadsPath = Environment
+                .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+                .getAbsolutePath();
+        return GalleryUtils.getBucketId(downloadsPath);
+    }
+
+    @Override
+    public void setContentListener(ContentListener listener) {
+        mContentListener = listener;
+    }
+}
diff --git a/src/com/android/gallery3d/widget/MediaSetSource.java b/src/com/android/gallery3d/widget/MediaSetSource.java
new file mode 100644
index 0000000..1677f69
--- /dev/null
+++ b/src/com/android/gallery3d/widget/MediaSetSource.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Binder;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MediaSetSource implements WidgetSource, ContentListener {
+    private static final int CACHE_SIZE = 32;
+
+    private static final String TAG = "MediaSetSource";
+
+    private MediaSet mSource;
+    private MediaItem mCache[] = new MediaItem[CACHE_SIZE];
+    private int mCacheStart;
+    private int mCacheEnd;
+    private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
+
+    private ContentListener mContentListener;
+
+    public MediaSetSource(MediaSet source) {
+        mSource = Utils.checkNotNull(source);
+        mSource.addContentListener(this);
+    }
+
+    @Override
+    public void close() {
+        mSource.removeContentListener(this);
+    }
+
+    private void ensureCacheRange(int index) {
+        if (index >= mCacheStart && index < mCacheEnd) return;
+
+        long token = Binder.clearCallingIdentity();
+        try {
+            mCacheStart = index;
+            ArrayList<MediaItem> items = mSource.getMediaItem(mCacheStart, CACHE_SIZE);
+            mCacheEnd = mCacheStart + items.size();
+            items.toArray(mCache);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public synchronized Uri getContentUri(int index) {
+        ensureCacheRange(index);
+        if (index < mCacheStart || index >= mCacheEnd) return null;
+        return mCache[index - mCacheStart].getContentUri();
+    }
+
+    @Override
+    public synchronized Bitmap getImage(int index) {
+        ensureCacheRange(index);
+        if (index < mCacheStart || index >= mCacheEnd) return null;
+        return WidgetUtils.createWidgetBitmap(mCache[index - mCacheStart]);
+    }
+
+    @Override
+    public void reload() {
+        long version = mSource.reload();
+        if (mSourceVersion != version) {
+            mSourceVersion = version;
+            mCacheStart = 0;
+            mCacheEnd = 0;
+            Arrays.fill(mCache, null);
+        }
+    }
+
+    @Override
+    public void setContentListener(ContentListener listener) {
+        mContentListener = listener;
+    }
+
+    @Override
+    public int size() {
+        long token = Binder.clearCallingIdentity();
+        try {
+            return mSource.getMediaItemCount();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public void onContentDirty() {
+        if (mContentListener != null) mContentListener.onContentDirty();
+    }
+}
diff --git a/src/com/android/gallery3d/widget/WidgetClickHandler.java b/src/com/android/gallery3d/widget/WidgetClickHandler.java
new file mode 100644
index 0000000..362e4d2
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetClickHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.Gallery;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.Toast;
+
+public class WidgetClickHandler extends Activity {
+    private static final String TAG = "PhotoAppWidgetClickHandler";
+
+    private boolean isValidDataUri(Uri dataUri) {
+        if (dataUri == null) return false;
+        try {
+            AssetFileDescriptor f = getContentResolver()
+                    .openAssetFileDescriptor(dataUri, "r");
+            f.close();
+            return true;
+        } catch (Throwable e) {
+            Log.w(TAG, "cannot open uri: " + dataUri, e);
+            return false;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        Intent intent = getIntent();
+        if (isValidDataUri(intent.getData())) {
+            startActivity(new Intent(Intent.ACTION_VIEW, intent.getData()));
+        } else {
+            Toast.makeText(this,
+                    R.string.no_such_item, Toast.LENGTH_LONG).show();
+            startActivity(new Intent(this, Gallery.class));
+        }
+        finish();
+    }
+}
diff --git a/src/com/android/gallery3d/widget/WidgetConfigure.java b/src/com/android/gallery3d/widget/WidgetConfigure.java
new file mode 100644
index 0000000..3bcd9c4
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetConfigure.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.AlbumPicker;
+import com.android.gallery3d.app.CropImage;
+import com.android.gallery3d.app.DialogPicker;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.widget.RemoteViews;
+
+public class WidgetConfigure extends Activity {
+    @SuppressWarnings("unused")
+    private static final String TAG = "WidgetConfigure";
+
+    public static final String KEY_WIDGET_TYPE = "widget-type";
+
+    private static final int REQUEST_WIDGET_TYPE = 1;
+    private static final int REQUEST_CHOOSE_ALBUM = 2;
+    private static final int REQUEST_CROP_IMAGE = 3;
+    private static final int REQUEST_GET_PHOTO = 4;
+
+    public static final int RESULT_ERROR = RESULT_FIRST_USER;
+
+    // Scale up the widget size since we only specified the minimized
+    // size of the gadget. The real size could be larger.
+    // Note: There is also a limit on the size of data that can be
+    // passed in Binder's transaction.
+    private static float WIDGET_SCALE_FACTOR = 1.5f;
+
+    private int mAppWidgetId = -1;
+    private int mWidgetType = 0;
+    private Uri mPickedItem;
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        mAppWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
+
+        if (mAppWidgetId == -1) {
+            setResult(Activity.RESULT_CANCELED);
+            finish();
+            return;
+        }
+
+        if (mWidgetType == 0) {
+            Intent intent = new Intent(this, WidgetTypeChooser.class);
+            startActivityForResult(intent, REQUEST_WIDGET_TYPE);
+        }
+    }
+
+    private void updateWidgetAndFinish(WidgetDatabaseHelper.Entry entry) {
+        AppWidgetManager manager = AppWidgetManager.getInstance(this);
+        RemoteViews views = WidgetProvider.buildWidget(this, mAppWidgetId, entry);
+        manager.updateAppWidget(mAppWidgetId, views);
+        setResult(RESULT_OK, new Intent().putExtra(
+                AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
+        finish();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (resultCode != RESULT_OK) {
+            setResult(resultCode, new Intent().putExtra(
+                    AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
+            finish();
+            return;
+        }
+
+        if (requestCode == REQUEST_WIDGET_TYPE) {
+            setWidgetType(data);
+        } else if (requestCode == REQUEST_CHOOSE_ALBUM) {
+            setChoosenAlbum(data);
+        } else if (requestCode == REQUEST_GET_PHOTO) {
+            setChoosenPhoto(data);
+        } else if (requestCode == REQUEST_CROP_IMAGE) {
+            setPhotoWidget(data);
+        } else {
+            throw new AssertionError("unknown request: " + requestCode);
+        }
+    }
+
+    private void setPhotoWidget(Intent data) {
+        // Store the cropped photo in our database
+        Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
+        WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
+        try {
+            helper.setPhoto(mAppWidgetId, mPickedItem, bitmap);
+            updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
+        } finally {
+            helper.close();
+        }
+    }
+
+    private void setChoosenPhoto(Intent data) {
+        Resources res = getResources();
+        int widgetWidth = Math.round(WIDGET_SCALE_FACTOR
+                * res.getDimension(R.dimen.appwidget_width));
+        int widgetHeight = Math.round(WIDGET_SCALE_FACTOR
+                * res.getDimension(R.dimen.appwidget_height));
+        mPickedItem = data.getData();
+        Intent request = new Intent(CropImage.ACTION_CROP, mPickedItem)
+                .putExtra(CropImage.KEY_OUTPUT_X, widgetWidth)
+                .putExtra(CropImage.KEY_OUTPUT_Y, widgetHeight)
+                .putExtra(CropImage.KEY_ASPECT_X, widgetWidth)
+                .putExtra(CropImage.KEY_ASPECT_Y, widgetHeight)
+                .putExtra(CropImage.KEY_SCALE_UP_IF_NEEDED, true)
+                .putExtra(CropImage.KEY_SCALE, true)
+                .putExtra(CropImage.KEY_RETURN_DATA, true);
+        startActivityForResult(request, REQUEST_CROP_IMAGE);
+    }
+
+    private void setChoosenAlbum(Intent data) {
+        String albumPath = data.getStringExtra(AlbumPicker.KEY_ALBUM_PATH);
+        WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
+        try {
+            helper.setWidget(mAppWidgetId,
+                    WidgetDatabaseHelper.TYPE_ALBUM, albumPath);
+            updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
+        } finally {
+            helper.close();
+        }
+    }
+
+    private void setWidgetType(Intent data) {
+        mWidgetType = data.getIntExtra(KEY_WIDGET_TYPE, R.id.widget_type_shuffle);
+        if (mWidgetType == R.id.widget_type_album) {
+            Intent intent = new Intent(this, AlbumPicker.class);
+            startActivityForResult(intent, REQUEST_CHOOSE_ALBUM);
+        } else if (mWidgetType == R.id.widget_type_shuffle) {
+            WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this);
+            try {
+                helper.setWidget(mAppWidgetId, WidgetDatabaseHelper.TYPE_SHUFFLE, null);
+                updateWidgetAndFinish(helper.getEntry(mAppWidgetId));
+            } finally {
+                helper.close();
+            }
+        } else {
+            // Explicitly send the intent to the DialogPhotoPicker
+            Intent request = new Intent(this, DialogPicker.class)
+                    .setAction(Intent.ACTION_GET_CONTENT)
+                    .setType("image/*");
+            startActivityForResult(request, REQUEST_GET_PHOTO);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/widget/WidgetDatabaseHelper.java b/src/com/android/gallery3d/widget/WidgetDatabaseHelper.java
new file mode 100644
index 0000000..d5bf22e
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetDatabaseHelper.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.common.Utils;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+
+public class WidgetDatabaseHelper extends SQLiteOpenHelper {
+    private static final String TAG = "PhotoDatabaseHelper";
+    private static final String DATABASE_NAME = "launcher.db";
+
+    private static final int DATABASE_VERSION = 4;
+
+    private static final String TABLE_WIDGETS = "widgets";
+
+    private static final String FIELD_APPWIDGET_ID = "appWidgetId";
+    private static final String FIELD_IMAGE_URI = "imageUri";
+    private static final String FIELD_PHOTO_BLOB = "photoBlob";
+    private static final String FIELD_WIDGET_TYPE = "widgetType";
+    private static final String FIELD_ALBUM_PATH = "albumPath";
+
+    public static final int TYPE_SINGLE_PHOTO = 0;
+    public static final int TYPE_SHUFFLE = 1;
+    public static final int TYPE_ALBUM = 2;
+
+    private static final String[] PROJECTION = {
+            FIELD_WIDGET_TYPE, FIELD_IMAGE_URI, FIELD_PHOTO_BLOB, FIELD_ALBUM_PATH};
+    private static final int INDEX_WIDGET_TYPE = 0;
+    private static final int INDEX_IMAGE_URI = 1;
+    private static final int INDEX_PHOTO_BLOB = 2;
+    private static final int INDEX_ALBUM_PATH = 3;
+    private static final String WHERE_CLAUSE = FIELD_APPWIDGET_ID + " = ?";
+
+    public static class Entry {
+        public int widgetId;
+        public int type;
+        public Uri imageUri;
+        public Bitmap image;
+        public String albumPath;
+
+        private Entry(int id, Cursor cursor) {
+            widgetId = id;
+            type = cursor.getInt(INDEX_WIDGET_TYPE);
+
+            if (type == TYPE_SINGLE_PHOTO) {
+                imageUri = Uri.parse(cursor.getString(INDEX_IMAGE_URI));
+                image = loadBitmap(cursor, INDEX_PHOTO_BLOB);
+            } else if (type == TYPE_ALBUM) {
+                albumPath = cursor.getString(INDEX_ALBUM_PATH);
+            }
+        }
+    }
+
+    public WidgetDatabaseHelper(Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        db.execSQL("CREATE TABLE " + TABLE_WIDGETS + " ("
+                + FIELD_APPWIDGET_ID + " INTEGER PRIMARY KEY, "
+                + FIELD_WIDGET_TYPE + " INTEGER DEFAULT 0, "
+                + FIELD_IMAGE_URI + " TEXT, "
+                + FIELD_ALBUM_PATH + " TEXT, "
+                + FIELD_PHOTO_BLOB + " BLOB)");
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        int version = oldVersion;
+
+        if (version != DATABASE_VERSION) {
+            Log.w(TAG, "destroying all old data.");
+            // Table "photos" is renamed to "widget" in version 4
+            db.execSQL("DROP TABLE IF EXISTS photos");
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_WIDGETS);
+            onCreate(db);
+        }
+    }
+
+    /**
+     * Store the given bitmap in this database for the given appWidgetId.
+     */
+    public boolean setPhoto(int appWidgetId, Uri imageUri, Bitmap bitmap) {
+        try {
+            // Try go guesstimate how much space the icon will take when
+            // serialized to avoid unnecessary allocations/copies during
+            // the write.
+            int size = bitmap.getWidth() * bitmap.getHeight() * 4;
+            ByteArrayOutputStream out = new ByteArrayOutputStream(size);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+            out.close();
+
+            ContentValues values = new ContentValues();
+            values.put(FIELD_APPWIDGET_ID, appWidgetId);
+            values.put(FIELD_WIDGET_TYPE, TYPE_SINGLE_PHOTO);
+            values.put(FIELD_IMAGE_URI, imageUri.toString());
+            values.put(FIELD_PHOTO_BLOB, out.toByteArray());
+
+            SQLiteDatabase db = getWritableDatabase();
+            db.replaceOrThrow(TABLE_WIDGETS, null, values);
+            return true;
+        } catch (Throwable e) {
+            Log.e(TAG, "set widget photo fail", e);
+            return false;
+        }
+    }
+
+    public boolean setWidget(int id, int type, String albumPath) {
+        try {
+            ContentValues values = new ContentValues();
+            values.put(FIELD_APPWIDGET_ID, id);
+            values.put(FIELD_WIDGET_TYPE, type);
+            values.put(FIELD_ALBUM_PATH, Utils.ensureNotNull(albumPath));
+            getWritableDatabase().replaceOrThrow(TABLE_WIDGETS, null, values);
+            return true;
+        } catch (Throwable e) {
+            Log.e(TAG, "set widget fail", e);
+            return false;
+        }
+    }
+
+    private static Bitmap loadBitmap(Cursor cursor, int columnIndex) {
+        byte[] data = cursor.getBlob(columnIndex);
+        if (data == null) return null;
+        return BitmapFactory.decodeByteArray(data, 0, data.length);
+    }
+
+    public Entry getEntry(int appWidgetId) {
+        Cursor cursor = null;
+        try {
+            SQLiteDatabase db = getReadableDatabase();
+            cursor = db.query(TABLE_WIDGETS, PROJECTION,
+                    WHERE_CLAUSE, new String[] {String.valueOf(appWidgetId)},
+                    null, null, null);
+            if (cursor == null || !cursor.moveToNext()) {
+                Log.e(TAG, "query fail: empty cursor: " + cursor);
+                return null;
+            }
+            return new Entry(appWidgetId, cursor);
+        } catch (Throwable e) {
+            Log.e(TAG, "Could not load photo from database", e);
+            return null;
+        } finally {
+            Utils.closeSilently(cursor);
+        }
+    }
+
+    /**
+     * Remove any bitmap associated with the given appWidgetId.
+     */
+    public void deleteEntry(int appWidgetId) {
+        try {
+            SQLiteDatabase db = getWritableDatabase();
+            db.delete(TABLE_WIDGETS, WHERE_CLAUSE,
+                    new String[] {String.valueOf(appWidgetId)});
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Could not delete photo from database", e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/widget/WidgetProvider.java b/src/com/android/gallery3d/widget/WidgetProvider.java
new file mode 100644
index 0000000..0a2fbfb
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetProvider.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.widget.WidgetDatabaseHelper.Entry;
+
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+public class WidgetProvider extends AppWidgetProvider {
+
+    private static final String TAG = "WidgetProvider";
+
+    static RemoteViews buildWidget(Context context, int id, Entry entry) {
+
+        switch (entry.type) {
+            case WidgetDatabaseHelper.TYPE_ALBUM:
+            case WidgetDatabaseHelper.TYPE_SHUFFLE:
+                return buildStackWidget(context, id, entry);
+            case WidgetDatabaseHelper.TYPE_SINGLE_PHOTO:
+                return buildFrameWidget(context, id, entry);
+        }
+        throw new RuntimeException("invalid type - " + entry.type);
+    }
+
+    @Override
+    public void onUpdate(Context context,
+            AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+        WidgetDatabaseHelper helper = new WidgetDatabaseHelper(context);
+        try {
+            for (int id : appWidgetIds) {
+                Entry entry = helper.getEntry(id);
+                if (entry != null) {
+                    RemoteViews views = buildWidget(context, id, entry);
+                    appWidgetManager.updateAppWidget(id, views);
+                } else {
+                    Log.e(TAG, "cannot load widget: " + id);
+                }
+            }
+        } finally {
+            helper.close();
+        }
+        super.onUpdate(context, appWidgetManager, appWidgetIds);
+    }
+
+    private static RemoteViews buildStackWidget(Context context, int widgetId, Entry entry) {
+        RemoteViews views = new RemoteViews(
+                context.getPackageName(), R.layout.appwidget_main);
+
+        Intent intent = new Intent(context, WidgetService.class);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
+        intent.putExtra(WidgetService.EXTRA_WIDGET_TYPE, entry.type);
+        intent.putExtra(WidgetService.EXTRA_ALBUM_PATH, entry.albumPath);
+        intent.setData(Uri.parse("widget://gallery/" + widgetId));
+
+        views.setRemoteAdapter(R.id.appwidget_stack_view, intent);
+        views.setEmptyView(R.id.appwidget_stack_view, R.id.appwidget_empty_view);
+
+        Intent clickIntent = new Intent(context, WidgetClickHandler.class);
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+        views.setPendingIntentTemplate(R.id.appwidget_stack_view, pendingIntent);
+
+        return views;
+    }
+
+    static RemoteViews buildFrameWidget(Context context, int appWidgetId, Entry entry) {
+        RemoteViews views = new RemoteViews(
+                context.getPackageName(), R.layout.photo_frame);
+        views.setImageViewBitmap(R.id.photo, entry.image);
+        Intent clickIntent = new Intent(context,
+                WidgetClickHandler.class).setData(entry.imageUri);
+        PendingIntent pendingClickIntent = PendingIntent.getActivity(context, 0,
+                clickIntent, PendingIntent.FLAG_CANCEL_CURRENT);
+        views.setOnClickPendingIntent(R.id.photo, pendingClickIntent);
+        return views;
+    }
+
+    @Override
+    public void onDeleted(Context context, int[] appWidgetIds) {
+        // Clean deleted photos out of our database
+        WidgetDatabaseHelper helper = new WidgetDatabaseHelper(context);
+        for (int appWidgetId : appWidgetIds) {
+            helper.deleteEntry(appWidgetId);
+        }
+        helper.close();
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/widget/WidgetService.java b/src/com/android/gallery3d/widget/WidgetService.java
new file mode 100644
index 0000000..aa167c7
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetService.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.data.ContentListener;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.widget.RemoteViews;
+import android.widget.RemoteViewsService;
+
+public class WidgetService extends RemoteViewsService {
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "GalleryAppWidgetService";
+
+    public static final String EXTRA_WIDGET_TYPE = "widget-type";
+    public static final String EXTRA_ALBUM_PATH = "album-path";
+
+    @Override
+    public RemoteViewsFactory onGetViewFactory(Intent intent) {
+        int id = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                AppWidgetManager.INVALID_APPWIDGET_ID);
+        int type = intent.getIntExtra(EXTRA_WIDGET_TYPE, 0);
+        String albumPath = intent.getStringExtra(EXTRA_ALBUM_PATH);
+
+        return new PhotoRVFactory((GalleryApp) getApplicationContext(),
+                id, type, albumPath);
+    }
+
+    private static class EmptySource implements WidgetSource {
+
+        @Override
+        public int size() {
+            return 0;
+        }
+
+        @Override
+        public Bitmap getImage(int index) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Uri getContentUri(int index) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setContentListener(ContentListener listener) {}
+
+        @Override
+        public void reload() {}
+
+        @Override
+        public void close() {}
+    }
+
+    private static class PhotoRVFactory implements
+            RemoteViewsService.RemoteViewsFactory, ContentListener {
+
+        private final int mAppWidgetId;
+        private final int mType;
+        private final String mAlbumPath;
+        private final GalleryApp mApp;
+
+        private WidgetSource mSource;
+
+        public PhotoRVFactory(GalleryApp app, int id, int type, String albumPath) {
+            mApp = app;
+            mAppWidgetId = id;
+            mType = type;
+            mAlbumPath = albumPath;
+        }
+
+        @Override
+        public void onCreate() {
+            if (mType == WidgetDatabaseHelper.TYPE_ALBUM) {
+                Path path = Path.fromString(mAlbumPath);
+                DataManager manager = mApp.getDataManager();
+                MediaSet mediaSet = (MediaSet) manager.getMediaObject(path);
+                mSource = mediaSet == null
+                        ? new EmptySource()
+                        : new MediaSetSource(mediaSet);
+            } else {
+                mSource = new LocalPhotoSource(mApp.getAndroidContext());
+            }
+            mSource.setContentListener(this);
+            AppWidgetManager.getInstance(mApp.getAndroidContext())
+                    .notifyAppWidgetViewDataChanged(
+                    mAppWidgetId, R.id.appwidget_stack_view);
+        }
+
+        @Override
+        public void onDestroy() {
+            mSource.close();
+            mSource = null;
+        }
+
+        public int getCount() {
+            return mSource.size();
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public int getViewTypeCount() {
+            return 1;
+        }
+
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        public RemoteViews getLoadingView() {
+            RemoteViews rv = new RemoteViews(
+                    mApp.getAndroidContext().getPackageName(),
+                    R.layout.appwidget_loading_item);
+            rv.setProgressBar(R.id.appwidget_loading_item, 0, 0, true);
+            return rv;
+        }
+
+        public RemoteViews getViewAt(int position) {
+            Bitmap bitmap = mSource.getImage(position);
+            if (bitmap == null) return getLoadingView();
+            RemoteViews views = new RemoteViews(
+                    mApp.getAndroidContext().getPackageName(),
+                    R.layout.appwidget_photo_item);
+            views.setImageViewBitmap(R.id.appwidget_photo_item, bitmap);
+            views.setOnClickFillInIntent(R.id.appwidget_photo_item, new Intent()
+                    .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                    .setData(mSource.getContentUri(position)));
+            return views;
+        }
+
+        @Override
+        public void onDataSetChanged() {
+            mSource.reload();
+        }
+
+        @Override
+        public void onContentDirty() {
+            AppWidgetManager.getInstance(mApp.getAndroidContext())
+                    .notifyAppWidgetViewDataChanged(
+                    mAppWidgetId, R.id.appwidget_stack_view);
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/widget/WidgetSource.java b/src/com/android/gallery3d/widget/WidgetSource.java
new file mode 100644
index 0000000..3c73e88
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetSource.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.data.ContentListener;
+
+import android.graphics.Bitmap;
+import android.net.Uri;
+
+public interface WidgetSource {
+    public int size();
+    public Bitmap getImage(int index);
+    public Uri getContentUri(int index);
+    public void setContentListener(ContentListener listener);
+    public void reload();
+    public void close();
+}
diff --git a/src/com/android/gallery3d/widget/WidgetTypeChooser.java b/src/com/android/gallery3d/widget/WidgetTypeChooser.java
new file mode 100644
index 0000000..9718e0c
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetTypeChooser.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.RadioGroup;
+import android.widget.RadioGroup.OnCheckedChangeListener;
+
+public class WidgetTypeChooser extends Activity {
+
+    private OnCheckedChangeListener mListener = new OnCheckedChangeListener() {
+        @Override
+        public void onCheckedChanged(RadioGroup group, int checkedId) {
+            Intent data = new Intent()
+                    .putExtra(WidgetConfigure.KEY_WIDGET_TYPE, checkedId);
+            setResult(RESULT_OK, data);
+            finish();
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setTitle(R.string.widget_type);
+        setContentView(R.layout.choose_widget_type);
+        RadioGroup rg = (RadioGroup) findViewById(R.id.widget_type);
+        rg.setOnCheckedChangeListener(mListener);
+
+        Button cancel = (Button) findViewById(R.id.cancel);
+        cancel.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setResult(RESULT_CANCELED);
+                finish();
+            }
+        });
+    }
+}
diff --git a/src/com/android/gallery3d/widget/WidgetUtils.java b/src/com/android/gallery3d/widget/WidgetUtils.java
new file mode 100644
index 0000000..481bbdd
--- /dev/null
+++ b/src/com/android/gallery3d/widget/WidgetUtils.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.widget;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.data.MediaItem;
+import com.android.gallery3d.util.ThreadPool;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Bitmap.Config;
+import android.util.Log;
+
+public class WidgetUtils {
+
+    private static final String TAG = "WidgetUtils";
+
+    private static int sStackPhotoWidth = 220;
+    private static int sStackPhotoHeight = 170;
+
+    private WidgetUtils() {
+    }
+
+    public static void initialize(Context context) {
+        Resources r = context.getResources();
+        sStackPhotoWidth = r.getDimensionPixelSize(R.dimen.stack_photo_width);
+        sStackPhotoHeight = r.getDimensionPixelSize(R.dimen.stack_photo_height);
+    }
+
+    public static Bitmap createWidgetBitmap(MediaItem image) {
+        Bitmap bitmap = image.requestImage(MediaItem.TYPE_THUMBNAIL)
+               .run(ThreadPool.JOB_CONTEXT_STUB);
+        if (bitmap == null) {
+            Log.w(TAG, "fail to get image of " + image.toString());
+            return null;
+        }
+        return createWidgetBitmap(bitmap, image.getRotation());
+    }
+
+    public static Bitmap createWidgetBitmap(Bitmap bitmap, int rotation) {
+        int w = bitmap.getWidth();
+        int h = bitmap.getHeight();
+
+        float scale;
+        if (((rotation / 90) & 1) == 0) {
+            scale = Math.max((float) sStackPhotoWidth / w,
+                    (float) sStackPhotoHeight / h);
+        } else {
+            scale = Math.max((float) sStackPhotoWidth / h,
+                    (float) sStackPhotoHeight / w);
+        }
+
+        Bitmap target = Bitmap.createBitmap(
+                sStackPhotoWidth, sStackPhotoHeight, Config.ARGB_8888);
+        Canvas canvas = new Canvas(target);
+        canvas.translate(sStackPhotoWidth / 2, sStackPhotoHeight / 2);
+        canvas.rotate(rotation);
+        canvas.scale(scale, scale);
+        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
+        canvas.drawBitmap(bitmap, -w / 2, -h / 2, paint);
+        return target;
+    }
+}
