merge in ics-mr0-release history after reset to ics-mr0
diff --git a/res/layout/share_popup.xml b/res/layout/share_popup.xml
index c9beb3a..ccc74d9 100644
--- a/res/layout/share_popup.xml
+++ b/res/layout/share_popup.xml
@@ -37,14 +37,22 @@
                     android:layout_alignParentTop="true"
                     android:layout_alignParentLeft="true">
                 <!-- The size of the thumbnail is calculated in SharePopup.java -->
-                <ImageView android:id="@+id/thumbnail"
+                <FrameLayout
                         android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:adjustViewBounds="true"
-                        android:scaleType="fitCenter"/>
-            </com.android.camera.ui.RotateLayout>
-            <ImageView android:id="@+id/play"
-                    style="@style/ReviewPlayIcon"/>
+                        android:layout_height="wrap_content" >
+                    <ImageView android:id="@+id/thumbnail"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:adjustViewBounds="true"
+                            android:scaleType="fitCenter"/>
+                    <ImageView android:id="@+id/play"
+                            android:layout_width="match_parent"
+                            android:layout_height="match_parent"
+                            android:layout_gravity="center"
+                            android:scaleType="center"
+                            style="@style/ReviewPlayIcon"/>
+                </FrameLayout>
+            </com.android.camera.ui.RotateLayout> 
         </RelativeLayout>
         <LinearLayout
                 android:layout_width="@dimen/share_item_width"
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 685319f..589a5c8 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -1184,10 +1184,6 @@
         if (mThumbnailView != null) mThumbnailView.setEnabled(enable);
     }
 
-    public static int roundOrientation(int orientation) {
-        return ((orientation + 45) / 90 * 90) % 360;
-    }
-
     private class MyOrientationEventListener
             extends OrientationEventListener {
         public MyOrientationEventListener(Context context) {
@@ -1200,7 +1196,7 @@
             // the camera then point the camera to floor or sky, we still have
             // the correct orientation.
             if (orientation == ORIENTATION_UNKNOWN) return;
-            mOrientation = roundOrientation(orientation);
+            mOrientation = Util.roundOrientation(orientation, mOrientation);
             // When the screen is unlocked, display rotation may change. Always
             // calculate the up-to-date orientationCompensation.
             int orientationCompensation = mOrientation
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index 768bf27..31a54d5 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -71,6 +71,9 @@
     // Use the same setting among the Camera, VideoCamera and Panorama modes.
     private static final float DEFAULT_CAMERA_BRIGHTNESS = 0.7f;
 
+    // Orientation hysteresis amount used in rounding, in degrees
+    public static final int ORIENTATION_HYSTERESIS = 5;
+
     public static final String REVIEW_ACTION = "com.android.camera.action.REVIEW";
 
     // Private intent extras. Test only.
@@ -345,6 +348,21 @@
         return result;
     }
 
+    public static int roundOrientation(int orientation, int orientationHistory) {
+        boolean changeOrientation = false;
+        if (orientationHistory == OrientationEventListener.ORIENTATION_UNKNOWN) {
+            changeOrientation = true;
+        } else {
+            int dist = Math.abs(orientation - orientationHistory);
+            dist = Math.min( dist, 360 - dist );
+            changeOrientation = ( dist >= 45 + ORIENTATION_HYSTERESIS );
+        }
+        if (changeOrientation) {
+            return ((orientation + 45) / 90 * 90) % 360;
+        }
+        return orientationHistory;
+    }
+
     public static Size getOptimalPreviewSize(Activity currentActivity,
             List<Size> sizes, double targetRatio) {
         // Use a very small tolerance because we want an exact match.
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index 0d63dae..8960311 100755
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -500,9 +500,6 @@
         }
     }
 
-    public static int roundOrientation(int orientation) {
-        return ((orientation + 45) / 90 * 90) % 360;
-    }
 
     private class MyOrientationEventListener
             extends OrientationEventListener {
@@ -516,7 +513,7 @@
             // the camera then point the camera to floor or sky, we still have
             // the correct orientation.
             if (orientation == ORIENTATION_UNKNOWN) return;
-            mOrientation = roundOrientation(orientation);
+            mOrientation = Util.roundOrientation(orientation, mOrientation);
             // When the screen is unlocked, display rotation may change. Always
             // calculate the up-to-date orientationCompensation.
             int orientationCompensation = mOrientation
@@ -723,8 +720,10 @@
                         null);
                 }
             } else {
-                // Set quality to 480p for effects
-                quality = CamcorderProfile.QUALITY_480P;
+                // Set quality to 480p for effects, unless intent is overriding it
+                if (!intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
+                    quality = CamcorderProfile.QUALITY_480P;
+                }
                 // On initial startup, can get here before indicator control is
                 // enabled. In that case, UI quality override handled in
                 // initializeIndicatorControl.
diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java
index 48a455e..0e055e5 100755
--- a/src/com/android/camera/panorama/PanoramaActivity.java
+++ b/src/com/android/camera/panorama/PanoramaActivity.java
@@ -190,10 +190,6 @@
         public final boolean isValid;
     }
 
-    public static int roundOrientation(int orientation) {
-        return ((orientation + 45) / 90 * 90) % 360;
-    }
-
     private class PanoOrientationEventListener extends OrientationEventListener {
         public PanoOrientationEventListener(Context context) {
             super(context);
@@ -205,7 +201,7 @@
             // the camera then point the camera to floor or sky, we still have
             // the correct orientation.
             if (orientation == ORIENTATION_UNKNOWN) return;
-            mDeviceOrientation = roundOrientation(orientation);
+            mDeviceOrientation = Util.roundOrientation(orientation, mDeviceOrientation);
             // When the screen is unlocked, display rotation may change. Always
             // calculate the up-to-date orientationCompensation.
             int orientationCompensation = mDeviceOrientation
diff --git a/src/com/android/camera/ui/SharePopup.java b/src/com/android/camera/ui/SharePopup.java
index 3917c54..de78f66 100644
--- a/src/com/android/camera/ui/SharePopup.java
+++ b/src/com/android/camera/ui/SharePopup.java
@@ -130,41 +130,6 @@
         // Show play button if this is a video thumbnail.
         if (mMimeType.startsWith("video/")) {
             sharePopup.findViewById(R.id.play).setVisibility(View.VISIBLE);
-
-            // for some reason we want to show video thumbnail in a 4/3 ratio
-            // crop the image here, for dispaly, as necessary
-            final float targetRatio = 4F/3F;
-            final float existingRatio = (float)mBitmapWidth / (float)mBitmapHeight;
-
-            if (existingRatio > targetRatio) {
-                int newWidth = (int) ((float)mBitmapHeight * targetRatio);
-
-                // check if we end up with the same width due to rounding
-                if (newWidth != mBitmapWidth) {
-                    bitmap = Bitmap.createBitmap(
-                            bitmap,
-                            (mBitmapWidth - newWidth) / 2,
-                            0,        // yCoord
-                            newWidth,
-                            mBitmapHeight,
-                            null,
-                            false);
-                }
-            } else if (existingRatio < targetRatio) {
-                int newHeight = (int) ((float)mBitmapWidth * targetRatio);
-
-                // check if we end up with the same width due to rounding
-                if (newHeight != mBitmapHeight) {
-                    bitmap = Bitmap.createBitmap(
-                            bitmap,
-                            0,        // xCoord
-                            (mBitmapHeight - newHeight) / 2,
-                            mBitmapWidth,
-                            newHeight,
-                            null,
-                            false);
-                }
-            }
         }
         mBitmapWidth = bitmap.getWidth();
         mBitmapHeight = bitmap.getHeight();
@@ -242,6 +207,14 @@
         }
         float actualAspect = maxWidth / maxHeight;
         float desiredAspect = (float) mBitmapWidth / mBitmapHeight;
+
+        if (mMimeType.startsWith("video/")) {
+            desiredAspect = 4F/3F;
+            mThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP);
+        } else {
+            mThumbnail.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+        }
+
         LayoutParams params = mThumbnail.getLayoutParams();
         if (actualAspect > desiredAspect) {
             params.width = Math.round(maxHeight * desiredAspect);
diff --git a/tests/src/com/android/camera/unittest/CameraTest.java b/tests/src/com/android/camera/unittest/CameraTest.java
index b4bd632..ad0eed5 100644
--- a/tests/src/com/android/camera/unittest/CameraTest.java
+++ b/tests/src/com/android/camera/unittest/CameraTest.java
@@ -30,19 +30,47 @@
 @SmallTest
 public class CameraTest extends TestCase {
     public void testRoundOrientation() {
-        assertEquals(0, Camera.roundOrientation(0));
-        assertEquals(0, Camera.roundOrientation(0 + 44));
-        assertEquals(90, Camera.roundOrientation(0 + 45));
-        assertEquals(90, Camera.roundOrientation(90));
-        assertEquals(90, Camera.roundOrientation(90 + 44));
-        assertEquals(180, Camera.roundOrientation(90 + 45));
-        assertEquals(180, Camera.roundOrientation(180));
-        assertEquals(180, Camera.roundOrientation(180 + 44));
-        assertEquals(270, Camera.roundOrientation(180 + 45));
-        assertEquals(270, Camera.roundOrientation(270));
-        assertEquals(270, Camera.roundOrientation(270 + 44));
-        assertEquals(0, Camera.roundOrientation(270 + 45));
-        assertEquals(0, Camera.roundOrientation(359));
+        int h = Util.ORIENTATION_HYSTERESIS;
+        assertEquals(0, Util.roundOrientation(0, 0));
+        assertEquals(0, Util.roundOrientation(359, 0));
+        assertEquals(0, Util.roundOrientation(0 + 44 + h, 0));
+        assertEquals(90, Util.roundOrientation(0 + 45 + h, 0));
+        assertEquals(0, Util.roundOrientation(360 - 44 - h, 0));
+        assertEquals(270, Util.roundOrientation(360 - 45 - h, 0));
+
+        assertEquals(90, Util.roundOrientation(90, 90));
+        assertEquals(90, Util.roundOrientation(90 + 44 + h, 90));
+        assertEquals(180, Util.roundOrientation(90 + 45 + h, 90));
+        assertEquals(90, Util.roundOrientation(90 - 44 - h, 90));
+        assertEquals(0, Util.roundOrientation(90 - 45 - h, 90));
+
+        assertEquals(180, Util.roundOrientation(180, 180));
+        assertEquals(180, Util.roundOrientation(180 + 44 + h, 180));
+        assertEquals(270, Util.roundOrientation(180 + 45 + h, 180));
+        assertEquals(180, Util.roundOrientation(180 - 44 - h, 180));
+        assertEquals(90, Util.roundOrientation(180 - 45 - h, 180));
+
+        assertEquals(270, Util.roundOrientation(270, 270));
+        assertEquals(270, Util.roundOrientation(270 + 44 + h, 270));
+        assertEquals(0, Util.roundOrientation(270 + 45 + h, 270));
+        assertEquals(270, Util.roundOrientation(270 - 44 - h, 270));
+        assertEquals(180, Util.roundOrientation(270 - 45 - h, 270));
+
+        assertEquals(90, Util.roundOrientation(90, 0));
+        assertEquals(180, Util.roundOrientation(180, 0));
+        assertEquals(270, Util.roundOrientation(270, 0));
+
+        assertEquals(0, Util.roundOrientation(0, 90));
+        assertEquals(180, Util.roundOrientation(180, 90));
+        assertEquals(270, Util.roundOrientation(270, 90));
+
+        assertEquals(0, Util.roundOrientation(0, 180));
+        assertEquals(90, Util.roundOrientation(90, 180));
+        assertEquals(270, Util.roundOrientation(270, 180));
+
+        assertEquals(0, Util.roundOrientation(0, 270));
+        assertEquals(90, Util.roundOrientation(90, 270));
+        assertEquals(180, Util.roundOrientation(180, 270));
     }
 
     public void testConvertToFocusArea() {