Merge changes Ic62822a4,Ie6505c8e into gb-ub-photos-arches

* changes:
  Change how stitched images are inserted into Gallery.
  Move panorama stitch progress outside the image.
diff --git a/res/layout/photopage_progress_bar.xml b/res/layout/photopage_progress_bar.xml
new file mode 100644
index 0000000..778feb3
--- /dev/null
+++ b/res/layout/photopage_progress_bar.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/photopage_progress_bar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:padding="25dp"
+        android:visibility="invisible">
+        <View
+                android:id="@+id/photopage_progress_background"
+                android:background="#ff000000"
+                android:layout_width="match_parent"
+                android:layout_height="8dp"
+                android:layout_alignParentBottom="true"
+                android:visibility="visible"/>
+        <View
+                android:id="@+id/photopage_progress_foreground"
+                android:background="#ff33b5e5"
+                android:layout_width="10dp"
+                android:layout_height="8dp"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentBottom="true"
+                android:visibility="visible"/>
+        <TextView
+                android:id="@+id/photopage_progress_bar_text"
+                android:text="@string/pano_progress_text"
+                android:textColor="#ffffffff"
+                android:textSize="14dp"
+                android:shadowColor="#ff000000"
+                android:shadowDx="0"
+                android:shadowDy="0"
+                android:shadowRadius="2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_above="@id/photopage_progress_background"
+                android:paddingBottom="8dp"
+                android:visibility="visible"/>
+</RelativeLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c6ef704..92d4308 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -496,4 +496,8 @@
 
     <!-- Toast if the trimmed video is the same as the original one. [CHAR LIMIT=80] -->
     <string name="trim_too_long">Did not trim : the same length as origin</string>
+
+    <!-- Text to show with progress bar while stitching in Gallery -->
+    <string name="pano_progress_text">Rendering panorama</string>
+
 </resources>
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
index 7f8414c..d6723ca 100644
--- a/src/com/android/gallery3d/app/PhotoPage.java
+++ b/src/com/android/gallery3d/app/PhotoPage.java
@@ -46,6 +46,7 @@
 import com.android.gallery3d.data.DataManager;
 import com.android.gallery3d.data.FilterDeleteSet;
 import com.android.gallery3d.data.FilterSource;
+import com.android.gallery3d.data.LocalImage;
 import com.android.gallery3d.data.MediaDetails;
 import com.android.gallery3d.data.MediaItem;
 import com.android.gallery3d.data.MediaObject;
@@ -91,6 +92,7 @@
     private static final int MSG_REFRESH_BOTTOM_CONTROLS = 8;
     private static final int MSG_ON_CAMERA_CENTER = 9;
     private static final int MSG_ON_PICTURE_CENTER = 10;
+    private static final int MSG_REFRESH_IMAGE = 11;
 
     private static final int HIDE_BARS_TIMEOUT = 3500;
     private static final int UNFREEZE_GLROOT_TIMEOUT = 250;
@@ -144,6 +146,7 @@
     private boolean mIsMenuVisible;
     private boolean mHaveImageEditor;
     private PhotoPageBottomControls mBottomControls;
+    private PhotoPageProgressBar mProgressBar;
     private MediaItem mCurrentPhoto = null;
     private MenuExecutor mMenuExecutor;
     private boolean mIsActive;
@@ -178,6 +181,7 @@
 
     private final MyMenuVisibilityListener mMenuVisibilityListener =
             new MyMenuVisibilityListener();
+    private UpdateProgressListener mProgressListener;
 
     public static interface Model extends PhotoView.Model {
         public void resume();
@@ -201,6 +205,32 @@
         }
     }
 
+    private class UpdateProgressListener implements StitchingChangeListener {
+
+        @Override
+        public void onStitchingResult(Uri uri) {
+            sendUpdate(uri);
+        }
+
+        @Override
+        public void onStitchingQueued(Uri uri) {
+            sendUpdate(uri);
+        }
+
+        @Override
+        public void onStitchingProgress(Uri uri, final int progress) {
+            sendUpdate(uri);
+        }
+
+        private void sendUpdate(Uri uri) {
+            boolean isCurrentPhoto = mCurrentPhoto instanceof LocalImage
+                    && mCurrentPhoto.getContentUri().equals(uri);
+            if (isCurrentPhoto) {
+                mHandler.sendEmptyMessage(MSG_REFRESH_IMAGE);
+            }
+        }
+    };
+
     private final FloatAnimation mBackgroundFade = new BackgroundFadeOut();
 
     @Override
@@ -310,6 +340,12 @@
                         }
                         break;
                     }
+                    case MSG_REFRESH_IMAGE: {
+                        MediaItem currentPhoto = mCurrentPhoto;
+                        mCurrentPhoto = null;
+                        updateCurrentPhoto(currentPhoto);
+                        break;
+                    }
                     default: throw new AssertionError(message.what);
                 }
             }
@@ -352,20 +388,13 @@
                     mFlags |= FLAG_SHOW_WHEN_LOCKED;
                 }
 
-                // Don't display "empty album" action item or panorama
-                // progress for capture intents.
+                // Don't display "empty album" action item for capture intents.
                 if (!mSetPathString.equals("/local/all/0")) {
                     // Check if the path is a secure album.
                     if (SecureSource.isSecurePath(mSetPathString)) {
                         mSecureAlbum = (SecureAlbum) mActivity.getDataManager()
                                 .getMediaSet(mSetPathString);
                         mShowSpinner = false;
-                    } else {
-                        // Use lightcycle album to handle panorama progress if
-                        // the path is not a secure album.
-                        if (LightCycleHelper.hasLightCycleCapture(mActivity.getAndroidContext())) {
-                            mSetPathString = LightCycleHelper.wrapGalleryPath(mSetPathString);
-                        }
                     }
                     mSetPathString = "/filter/empty/{"+mSetPathString+"}";
                 }
@@ -481,12 +510,18 @@
         }
 
         mPhotoView.setFilmMode(mStartInFilmstrip && mMediaSet.getMediaItemCount() > 1);
-        if (mSecureAlbum == null) {
-            RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity)
-                        .findViewById(mAppBridge != null ? R.id.content : R.id.gallery_root);
-            if (galleryRoot != null) {
+        RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity)
+                .findViewById(mAppBridge != null ? R.id.content : R.id.gallery_root);
+        if (galleryRoot != null) {
+            if (mSecureAlbum == null) {
                 mBottomControls = new PhotoPageBottomControls(this, mActivity, galleryRoot);
             }
+            StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
+            if (progressManager != null) {
+                mProgressBar = new PhotoPageProgressBar(mActivity, galleryRoot);
+                mProgressListener = new UpdateProgressListener();
+                progressManager.addChangeListener(mProgressListener);
+            }
         }
     }
 
@@ -626,6 +661,14 @@
                 && (photo.getSupportedOperations() & MediaItem.SUPPORT_SHARE) != 0) {
             updateShareURI(photo.getPath());
         }
+        StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
+        mProgressBar.hideProgress();
+        if (progressManager != null && mCurrentPhoto instanceof LocalImage) {
+            Integer progress = progressManager.getProgress(photo.getContentUri());
+            if (progress != null) {
+                mProgressBar.setProgress(progress);
+            }
+        }
     }
 
     private void updateMenuOperations() {
@@ -1209,6 +1252,7 @@
         mActivity.getGLRoot().unfreeze();
     }
 
+    @Override
     public void onFilmModeChanged(boolean enabled) {
         mHandler.sendEmptyMessage(MSG_REFRESH_BOTTOM_CONTROLS);
         if (enabled) {
diff --git a/src/com/android/gallery3d/app/PhotoPageProgressBar.java b/src/com/android/gallery3d/app/PhotoPageProgressBar.java
new file mode 100644
index 0000000..141fea6
--- /dev/null
+++ b/src/com/android/gallery3d/app/PhotoPageProgressBar.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 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.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.RelativeLayout;
+
+import com.android.gallery3d.R;
+
+public class PhotoPageProgressBar {
+    private ViewGroup mContainer;
+    private View mProgress;
+
+    public PhotoPageProgressBar(Context context, RelativeLayout parentLayout) {
+        LayoutInflater inflater = (LayoutInflater) context
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        mContainer = (ViewGroup) inflater.inflate(R.layout.photopage_progress_bar, parentLayout,
+                false);
+        parentLayout.addView(mContainer);
+        mProgress = mContainer.findViewById(R.id.photopage_progress_foreground);
+    }
+
+    public void setProgress(int progressPercent) {
+        mContainer.setVisibility(View.VISIBLE);
+        LayoutParams layoutParams = mProgress.getLayoutParams();
+        layoutParams.width = mContainer.getWidth() * progressPercent / 100;
+        mProgress.setLayoutParams(layoutParams);
+    }
+
+    public void hideProgress() {
+        mContainer.setVisibility(View.INVISIBLE);
+    }
+}
diff --git a/src/com/android/gallery3d/app/StitchingChangeListener.java b/src/com/android/gallery3d/app/StitchingChangeListener.java
index 40f59a5..0b8c2d6 100644
--- a/src/com/android/gallery3d/app/StitchingChangeListener.java
+++ b/src/com/android/gallery3d/app/StitchingChangeListener.java
@@ -16,14 +16,12 @@
 
 package com.android.gallery3d.app;
 
-import com.android.gallery3d.data.Path;
-
 import android.net.Uri;
 
 public interface StitchingChangeListener {
-    public void onStitchingQueued(Path path);
+    public void onStitchingQueued(Uri uri);
 
-    public void onStitchingResult(Path path, Uri uri);
+    public void onStitchingResult(Uri uri);
 
-    public void onStitchingProgress(Path path, int progress);
+    public void onStitchingProgress(Uri uri, int progress);
 }
diff --git a/src/com/android/gallery3d/data/DataManager.java b/src/com/android/gallery3d/data/DataManager.java
index e3b7bfc..95954e5 100644
--- a/src/com/android/gallery3d/data/DataManager.java
+++ b/src/com/android/gallery3d/data/DataManager.java
@@ -28,7 +28,6 @@
 import com.android.gallery3d.data.MediaSet.ItemConsumer;
 import com.android.gallery3d.data.MediaSource.PathId;
 import com.android.gallery3d.picasasource.PicasaSource;
-import com.android.gallery3d.util.LightCycleHelper;
 
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -131,7 +130,6 @@
         addSource(new SecureSource(mApplication));
         addSource(new UriSource(mApplication));
         addSource(new SnailSource(mApplication));
-        addSource(LightCycleHelper.createMediaSourceInstance(mApplication));
 
         if (mActiveCount > 0) {
             for (MediaSource source : mSourceMap.values()) {
diff --git a/src/com/android/gallery3d/data/LocalAlbumSet.java b/src/com/android/gallery3d/data/LocalAlbumSet.java
index afaac49..b2b4b8c 100644
--- a/src/com/android/gallery3d/data/LocalAlbumSet.java
+++ b/src/com/android/gallery3d/data/LocalAlbumSet.java
@@ -26,7 +26,6 @@
 import com.android.gallery3d.data.BucketHelper.BucketEntry;
 import com.android.gallery3d.util.Future;
 import com.android.gallery3d.util.FutureListener;
-import com.android.gallery3d.util.LightCycleHelper;
 import com.android.gallery3d.util.MediaSetUtils;
 import com.android.gallery3d.util.ThreadPool;
 import com.android.gallery3d.util.ThreadPool.JobContext;
@@ -128,11 +127,6 @@
             for (BucketEntry entry : entries) {
                 MediaSet album = getLocalAlbum(dataManager,
                         mType, mPath, entry.bucketId, entry.bucketName);
-                if (LightCycleHelper.hasLightCycleCapture(mApplication.getAndroidContext())
-                        && album.isCameraRoll()) {
-                    album = dataManager.getMediaSet(Path.fromString(
-                            LightCycleHelper.wrapGalleryPath(album.getPath().toString())));
-                }
                 albums.add(album);
             }
             return albums;
diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java
index 52f707b..7006b0a 100644
--- a/src/com/android/gallery3d/data/LocalImage.java
+++ b/src/com/android/gallery3d/data/LocalImage.java
@@ -33,6 +33,7 @@
 import android.util.Log;
 
 import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.app.StitchingProgressManager;
 import com.android.gallery3d.common.ApiHelper;
 import com.android.gallery3d.common.BitmapUtils;
 import com.android.gallery3d.util.GalleryUtils;
@@ -236,6 +237,10 @@
 
     @Override
     public int getSupportedOperations() {
+        StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
+        if (progressManager != null && progressManager.getProgress(getContentUri()) != null) {
+            return 0; // doesn't support anything while stitching!
+        }
         int operation = SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_CROP
                 | SUPPORT_SETAS | SUPPORT_EDIT | SUPPORT_INFO;
         if (BitmapUtils.isSupportedByRegionDecoder(mimeType)) {
diff --git a/src/com/android/gallery3d/data/SecureAlbum.java b/src/com/android/gallery3d/data/SecureAlbum.java
index 4e33cda..c666bdc 100644
--- a/src/com/android/gallery3d/data/SecureAlbum.java
+++ b/src/com/android/gallery3d/data/SecureAlbum.java
@@ -19,19 +19,17 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
-import android.provider.MediaStore.MediaColumns;
 import android.provider.MediaStore.Images;
+import android.provider.MediaStore.MediaColumns;
 import android.provider.MediaStore.Video;
 
 import com.android.gallery3d.app.GalleryApp;
-import com.android.gallery3d.app.StitchingChangeListener;
-import com.android.gallery3d.app.StitchingProgressManager;
 import com.android.gallery3d.util.MediaSetUtils;
 
 import java.util.ArrayList;
 
 // This class lists all media items added by the client.
-public class SecureAlbum extends MediaSet implements StitchingChangeListener {
+public class SecureAlbum extends MediaSet {
     @SuppressWarnings("unused")
     private static final String TAG = "SecureAlbum";
     private static final String[] PROJECTION = {MediaColumns._ID};
@@ -44,10 +42,8 @@
     // The types of items in mAllItems. True is video and false is image.
     private ArrayList<Boolean> mAllItemTypes = new ArrayList<Boolean>();
     private ArrayList<Path> mExistingItems = new ArrayList<Path>();
-    private ArrayList<Path> mStitchingItems = new ArrayList<Path>();
     private Context mContext;
     private DataManager mDataManager;
-    private StitchingProgressManager mStitchingProgressManager;
     private static final Uri[] mWatchUris =
         {Images.Media.EXTERNAL_CONTENT_URI, Video.Media.EXTERNAL_CONTENT_URI};
     private final ChangeNotifier mNotifier;
@@ -64,8 +60,6 @@
         mUnlockItem = unlock;
         mShowUnlockItem = (!isCameraBucketEmpty(Images.Media.EXTERNAL_CONTENT_URI)
                 || !isCameraBucketEmpty(Video.Media.EXTERNAL_CONTENT_URI));
-        mStitchingProgressManager = application.getStitchingProgressManager();
-        mStitchingProgressManager.addChangeListener(this);
     }
 
     public void addMediaItem(boolean isVideo, int id) {
@@ -85,26 +79,14 @@
     // The sequence is stitching items, local media items, and unlock image.
     @Override
     public ArrayList<MediaItem> getMediaItem(int start, int count) {
-        int stitchingCount = mStitchingItems.size();
         int existingCount = mExistingItems.size();
-        if (start >= stitchingCount + existingCount + 1) {
+        if (start >= existingCount + 1) {
             return new ArrayList<MediaItem>();
         }
 
         // Add paths of requested stitching items.
-        int end = Math.min(start + count, stitchingCount + existingCount);
-        ArrayList<Path> subset = new ArrayList<Path>();
-        if (start < stitchingCount) {
-            subset.addAll(mStitchingItems.subList(
-                    start, Math.min(stitchingCount, end)));
-        }
-
-        // Add paths of requested local media items.
-        if (end >= stitchingCount) {
-            int existingStart = Math.max(0, start - stitchingCount);
-            int existingEnd = end - stitchingCount;
-            subset.addAll(mExistingItems.subList(existingStart, existingEnd));
-        }
+        int end = Math.min(start + count, existingCount);
+        ArrayList<Path> subset = new ArrayList<Path>(mExistingItems.subList(start, end));
 
         // Convert paths to media items.
         final MediaItem[] buf = new MediaItem[end - start];
@@ -125,8 +107,7 @@
 
     @Override
     public int getMediaItemCount() {
-        return (mStitchingItems.size() + mExistingItems.size()
-                + (mShowUnlockItem ? 1 : 0));
+        return (mExistingItems.size() + (mShowUnlockItem ? 1 : 0));
     }
 
     @Override
@@ -202,26 +183,4 @@
     public boolean isLeafAlbum() {
         return true;
     }
-
-    @Override
-    public void onStitchingQueued(Path path) {
-        mStitchingItems.add(path);
-        notifyContentChanged();
-    }
-
-    @Override
-    public void onStitchingResult(Path path, Uri uri) {
-        if (mStitchingItems.remove(path)) {
-            int id = Integer.parseInt(uri.getLastPathSegment());
-            addMediaItem(false, id);
-            notifyContentChanged();
-        }
-    }
-
-    @Override
-    public void onStitchingProgress(Path path, int progress) {
-        if (mStitchingItems.contains(path)) {
-            notifyContentChanged();
-        }
-    }
 }
diff --git a/src_pd/com/android/gallery3d/app/StitchingProgressManager.java b/src_pd/com/android/gallery3d/app/StitchingProgressManager.java
index d0e2a69..7386847 100644
--- a/src_pd/com/android/gallery3d/app/StitchingProgressManager.java
+++ b/src_pd/com/android/gallery3d/app/StitchingProgressManager.java
@@ -16,30 +16,19 @@
 
 package com.android.gallery3d.app;
 
-import com.android.gallery3d.data.MediaItem;
-
-import java.util.ArrayList;
+import android.net.Uri;
 
 public class StitchingProgressManager {
+    public StitchingProgressManager(GalleryApp app) {
+    }
+
     public void addChangeListener(StitchingChangeListener l) {
     }
 
     public void removeChangeListener(StitchingChangeListener l) {
     }
 
-    public int getItemCount() {
-        return 0;
-    }
-
-    public MediaItem getItem(int i) {
+    public Integer getProgress(Uri uri) {
         return null;
     }
-
-    public ArrayList<MediaItem> getAllItems() {
-        return null;
-    }
-
-    public int getProgress(String filePath) {
-        return 100;
-    }
 }
diff --git a/src_pd/com/android/gallery3d/util/LightCycleHelper.java b/src_pd/com/android/gallery3d/util/LightCycleHelper.java
index d455ff7..cc8ea20 100644
--- a/src_pd/com/android/gallery3d/util/LightCycleHelper.java
+++ b/src_pd/com/android/gallery3d/util/LightCycleHelper.java
@@ -25,7 +25,6 @@
 import com.android.camera.CameraModule;
 import com.android.gallery3d.app.GalleryApp;
 import com.android.gallery3d.app.StitchingProgressManager;
-import com.android.gallery3d.data.MediaSource;
 
 public class LightCycleHelper {
 
@@ -60,12 +59,4 @@
     public static StitchingProgressManager createStitchingManagerInstance(GalleryApp app) {
         return null;
     }
-
-    public static MediaSource createMediaSourceInstance(GalleryApp app) {
-        return null;
-    }
-
-    public static String wrapGalleryPath(String path) {
-        return path;
-    }
 }