auto import from //branches/cupcake/...@132569
diff --git a/res/anim/on_screen_hint_accelerate.xml b/res/anim/on_screen_hint_accelerate.xml
deleted file mode 100644
index ffbfc39..0000000
--- a/res/anim/on_screen_hint_accelerate.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
--->
-
-<accelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android" factor="1" />
diff --git a/res/anim/on_screen_hint_decelerate.xml b/res/anim/on_screen_hint_decelerate.xml
deleted file mode 100644
index e63421d..0000000
--- a/res/anim/on_screen_hint_decelerate.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-
-<decelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android" factor="1" />
diff --git a/res/anim/on_screen_hint_enter.xml b/res/anim/on_screen_hint_enter.xml
index c7ae9c3..0f00760 100644
--- a/res/anim/on_screen_hint_enter.xml
+++ b/res/anim/on_screen_hint_enter.xml
@@ -18,5 +18,6 @@
 -->
 
 <alpha xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@+android:anim/on_screen_hint_decelerate"
-        android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="400" />
+        android:interpolator="@android:anim/decelerate_interpolator"
+        android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="400"
+/>
diff --git a/res/anim/on_screen_hint_exit.xml b/res/anim/on_screen_hint_exit.xml
index e1d1ff2..e9b38f8 100644
--- a/res/anim/on_screen_hint_exit.xml
+++ b/res/anim/on_screen_hint_exit.xml
@@ -18,6 +18,6 @@
 -->
 
 <alpha xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@+android:anim/on_screen_hint_accelerate"
+        android:interpolator="@android:anim/accelerate_interpolator"
         android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="400"
 />
diff --git a/res/drawable/ic_error_mms_video_overlay.png b/res/drawable/ic_error_mms_video_overlay.png
new file mode 100644
index 0000000..4f50072
--- /dev/null
+++ b/res/drawable/ic_error_mms_video_overlay.png
Binary files differ
diff --git a/res/layout/viewimage.xml b/res/layout/viewimage.xml
index a1c9d4d..99d76b0 100644
--- a/res/layout/viewimage.xml
+++ b/res/layout/viewimage.xml
@@ -139,6 +139,7 @@
         />
     </LinearLayout>
 	<ImageView android:id="@+id/prev_image"
+		android:clickable="true"
 		android:layout_width="wrap_content" android:layout_height="wrap_content"
 		android:layout_alignParentLeft="true"
 		android:layout_centerVertical="true"
@@ -147,6 +148,7 @@
 	/>
 
 	<ImageView android:id="@+id/next_image"
+		android:clickable="true"
 		android:layout_width="wrap_content" android:layout_height="wrap_content"
 		android:layout_alignParentRight="true"
 		android:layout_centerVertical="true"
diff --git a/res/raw/camera_click.ogg b/res/raw/camera_click.ogg
index be0a0d3..0a769ff 100644
--- a/res/raw/camera_click.ogg
+++ b/res/raw/camera_click.ogg
Binary files differ
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 161f960..ab7d88e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -448,5 +448,11 @@
     <!-- Video Camera format string for new video files. Passed to java.text.SimpleDateFormat.
          Do not localize -->
     <string name="video_file_name_format">"'video'-yyyy-MM-dd-HH-mm-ss"</string>
+
+    <!-- Title for the file information dialog -->
+    <string name="file_info_title">File info:</string>
+    
+    <!-- The video is execeed the size limit of a MMS, and suggest user to record a shorter length clip -->
+    <string name="video_exceed_mms_limit">The video you recorded is too large to send via MMS. Try recording a shorter length clip.</string>
     
 </resources>
diff --git a/res/xml/gadget_info.xml b/res/xml/gadget_info.xml
index 05fb515..5efaddd 100644
--- a/res/xml/gadget_info.xml
+++ b/res/xml/gadget_info.xml
@@ -15,8 +15,8 @@
 -->
 
 <gadget-provider xmlns:android="http://schemas.android.com/apk/res/android"
-    android:minWidth="148px"
-    android:minHeight="148px"
+    android:minWidth="146dip"
+    android:minHeight="146dip"
     android:updatePeriodMillis="0"
     android:initialLayout="@layout/photo_frame"
     android:configure="com.android.camera.PhotoGadgetConfigure"
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 9bf101c..04a30cf 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -39,12 +39,10 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
-import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
 import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
 import android.graphics.drawable.TransitionDrawable;
@@ -62,25 +60,23 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
-import android.os.StatFs;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.provider.MediaStore;
-import android.provider.MediaStore.Images;
 import android.text.format.DateFormat;
 import android.util.Config;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
 import android.view.OrientationEventListener;
 import android.view.SurfaceHolder;
 import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.MenuItem.OnMenuItemClickListener;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
+import android.view.Window;
+import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -94,7 +90,6 @@
 
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_TIME_OPERATIONS = DEBUG && false;
-    private static final boolean DEBUG_FAKE_GPS_LOCATION = DEBUG && false;
 
     private static final int CROP_MSG = 1;
     private static final int KEEP = 2;
@@ -581,23 +576,7 @@
             mParameters.remove("gps-altitude");
             mParameters.remove("gps-timestamp");
 
-            if (DEBUG_FAKE_GPS_LOCATION) {
-                // Google London office, having trouble encoding longitude
-
-                if (false) {
-                    // This fails:
-                    mParameters.set("gps-latitude", "51.49473309516907");
-                    mParameters.set("gps-longitude", "-0.14598190784454346");
-                    mParameters.set("gps-altitude", "71.0"); // meters
-                    mParameters.set("gps-timestamp", "1233744883");
-                } else {
-                    // This works OK:
-                    mParameters.set("gps-latitude", "51.49473309516907");
-                    mParameters.set("gps-longitude", "-1.0");
-                    mParameters.set("gps-altitude", "71.0"); // meters
-                    mParameters.set("gps-timestamp", "1233744883");
-                }
-            } else if (loc != null) {
+            if (loc != null) {
                 double lat = loc.getLatitude();
                 double lon = loc.getLongitude();
                 boolean hasLatLon = (lat != 0.0d) || (lon != 0.0d);
@@ -853,6 +832,8 @@
             loadServiceThread.join();
         } catch (InterruptedException ex) {
         }
+        
+        ImageManager.ensureOSXCompatibleFolder();
     }
 
     @Override
diff --git a/src/com/android/camera/GalleryPicker.java b/src/com/android/camera/GalleryPicker.java
index cf883dd..9c687c8 100644
--- a/src/com/android/camera/GalleryPicker.java
+++ b/src/com/android/camera/GalleryPicker.java
@@ -228,6 +228,8 @@
                 });
             }
         });
+ 
+        ImageManager.ensureOSXCompatibleFolder();
     }
 
     private void launchFolderGallery(int position) {
diff --git a/src/com/android/camera/ImageGallery2.java b/src/com/android/camera/ImageGallery2.java
index 566bfcb..008eb21 100644
--- a/src/com/android/camera/ImageGallery2.java
+++ b/src/com/android/camera/ImageGallery2.java
@@ -19,8 +19,10 @@
 import android.content.BroadcastReceiver;
 import android.app.Activity;
 import android.app.Dialog;
+import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
@@ -68,13 +70,13 @@
     private View mNoImagesView;
     public final static int CROP_MSG = 2;
     public final static int VIEW_MSG = 3;
-
     private static final String INSTANCE_STATE_TAG = "scrollY";
 
     private Dialog mMediaScanningDialog;
 
     private MenuItem mSlideShowItem;
     private SharedPreferences mPrefs;
+    private long mVideoSizeLimit = Long.MAX_VALUE;
 
     public ImageGallery2() {
     }
@@ -106,7 +108,13 @@
         mGvs = (GridViewSpecial) findViewById(R.id.grid);
         mGvs.requestFocus();
 
-        if (!isPickIntent()) {
+        if (isPickIntent()) {
+            mVideoSizeLimit = getIntent().getLongExtra(
+                    MediaStore.EXTRA_SIZE_LIMIT, Long.MAX_VALUE);
+            mGvs.mVideoSizeLimit = mVideoSizeLimit;
+        } else {
+            mVideoSizeLimit = Long.MAX_VALUE;
+            mGvs.mVideoSizeLimit = mVideoSizeLimit;
             mGvs.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
                 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                     if (mSelectedImageGetter.getCurrentImage() == null)
@@ -306,7 +314,7 @@
             default:
                 handled = false;
                 break;
-        }
+            }
         }
         if (handled) {
             mGvs.select(sel, pressed);
@@ -324,6 +332,23 @@
     private void launchCropperOrFinish(ImageManager.IImage img) {
         Bundle myExtras = getIntent().getExtras();
 
+        if (MenuHelper.getImageFileSize(img) > mVideoSizeLimit) {
+
+            DialogInterface.OnClickListener buttonListener =
+                    new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    dialog.dismiss();
+                }
+            };
+            new AlertDialog.Builder(this)
+                    .setIcon(android.R.drawable.ic_dialog_info)
+                    .setTitle(R.string.file_info_title)
+                    .setMessage(R.string.video_exceed_mms_limit)
+                    .setNeutralButton(R.string.details_ok, buttonListener)
+                    .show();
+            return;
+        }
+
         String cropValue = myExtras != null ? myExtras.getString("crop") : null;
         if (cropValue != null) {
             Bundle newExtras = new Bundle();
@@ -714,6 +739,8 @@
         private boolean mDirectionBiasDown = true;
         private final static boolean sDump = false;
 
+        private long mVideoSizeLimit;
+
         class LayoutSpec {
             LayoutSpec(int cols, int w, int h, int leftEdgePadding, int rightEdgePadding, int intercellSpacing) {
                 mColumns = cols;
@@ -997,6 +1024,9 @@
             private Bitmap mMissingImageThumbnailBitmap;
             private Bitmap mMissingVideoThumbnailBitmap;
 
+            private Drawable mVideoOverlay;
+            private Drawable mVideoMmsErrorOverlay;
+
             public void dump() {
                 synchronized (ImageBlockManager.this) {
                     StringBuilder line1 = new StringBuilder();
@@ -1350,7 +1380,6 @@
                 int     mRequestedMask;   // columns which have been requested to the loader
                 int     mCompletedMask;   // columns which have been completed from the loader
                 boolean mIsVisible;
-                Drawable mVideoOverlay;
 
                 public void dump(StringBuilder line1, StringBuilder line2) {
                     synchronized (ImageBlock.this) {
@@ -1523,17 +1552,31 @@
                         mCanvas.drawBitmap(error, source, dest, mPaint);
                     }
                     if (ImageManager.isVideo(image)) {
-                        if (mVideoOverlay == null) {
-                            mVideoOverlay = getResources().getDrawable(
-                                    R.drawable.ic_gallery_video_overlay);
+                        Drawable overlay = null;
+                        if (MenuHelper.getImageFileSize(image) <= mVideoSizeLimit) {
+                            if (mVideoOverlay == null) {
+                                mVideoOverlay = getResources().getDrawable(
+                                        R.drawable.ic_gallery_video_overlay);
+                            }
+                            overlay = mVideoOverlay;
+                        } else {
+                            if (mVideoMmsErrorOverlay == null) {
+                                mVideoMmsErrorOverlay = getResources().getDrawable(
+                                        R.drawable.ic_error_mms_video_overlay);
+                            }
+                            overlay = mVideoMmsErrorOverlay;
+                            Paint paint = new Paint();
+                            paint.setARGB(0x80, 0x00, 0x00, 0x00);
+                            mCanvas.drawRect(xPos, yPos, xPos + mCurrentSpec.mCellWidth,
+                                    yPos + mCurrentSpec.mCellHeight, paint);
                         }
-                        int width = mVideoOverlay.getIntrinsicWidth();
-                        int height = mVideoOverlay.getIntrinsicHeight();
+                        int width = overlay.getIntrinsicWidth();
+                        int height = overlay.getIntrinsicHeight();
                         int left = (mCurrentSpec.mCellWidth - width) / 2 + xPos;
                         int top = (mCurrentSpec.mCellHeight - height) / 2 + yPos;
                         Rect newBounds = new Rect(left, top, left + width, top + height);
-                        mVideoOverlay.setBounds(newBounds);
-                        mVideoOverlay.draw(mCanvas);
+                        overlay.setBounds(newBounds);
+                        overlay.draw(mCanvas);
                     }
                     paintSel(base + baseOffset, xPos, yPos);
                 }
diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java
index 4a83958..cc76e83 100755
--- a/src/com/android/camera/ImageManager.java
+++ b/src/com/android/camera/ImageManager.java
@@ -73,6 +73,18 @@
     public static String getBucketId(String path) {
         return String.valueOf(path.toLowerCase().hashCode());
     }
+    
+    /**
+     * OSX requires plugged-in USB storage to have path /DCIM/NNNAAAAA to be imported.
+     * This is a temporary fix for bug#1655552.
+     */
+    public static void ensureOSXCompatibleFolder() {
+        File nnnAAAAA = new File(
+            Environment.getExternalStorageDirectory().toString() + "/DCIM/100ANDRO");
+        if ((!nnnAAAAA.exists()) && (!nnnAAAAA.mkdir())) {
+            Log.e(TAG, "create NNNAAAAA file: "+ nnnAAAAA.getPath()+" failed");
+        }
+    }
 
     // To enable verbose logging for this class, change false to true. The other logic ensures that
     // this logging can be disabled by turned off DEBUG and lower, and that it can be enabled by
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java
index 2aedb02..ffb99ef 100644
--- a/src/com/android/camera/MenuHelper.java
+++ b/src/com/android/camera/MenuHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.camera;
 
+import java.io.Closeable;
 import java.util.ArrayList;
 
 import android.app.Activity;
@@ -101,6 +102,25 @@
         public void run(Uri uri, ImageManager.IImage image);
     }
 
+    private static void closeSilently(Closeable target) {
+        try {
+            if (target != null) target.close();
+        } catch (Throwable t) {
+            // ignore all exceptions, that's what silently means
+        }
+    }
+
+    public static long getImageFileSize(ImageManager.IImage image) {
+        java.io.InputStream data = image.fullSizeImageData();
+        try {
+            return data.available();
+        } catch (java.io.IOException ex) {
+            return -1;
+        } finally {
+            closeSilently(data);
+        }
+    }
+
     static MenuItemsResult addImageMenuItems(
             Menu menu,
             int inclusions,
@@ -264,17 +284,9 @@
                             TextView textView = (TextView) d.findViewById(R.id.details_image_title);
                             textView.setText(image.getDisplayName());
 
-                            java.io.InputStream data = image.fullSizeImageData();
-                            String lengthString = "";
-                            try {
-                                long length = data.available();
-                                lengthString =
-                                    android.text.format.Formatter.formatFileSize(activity, length);
-                                data.close();
-                            } catch (java.io.IOException ex) {
-
-                            } finally {
-                            }
+                            long length = getImageFileSize(image);
+                            String lengthString = lengthString = length < 0 ? ""
+                                    : android.text.format.Formatter.formatFileSize(activity, length);
                             ((TextView)d.findViewById(R.id.details_file_size_value))
                                 .setText(lengthString);
 
diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java
index 57d7051..ad27ae3 100644
--- a/src/com/android/camera/ViewImage.java
+++ b/src/com/android/camera/ViewImage.java
@@ -34,12 +34,12 @@
 import android.util.AttributeSet;
 import android.util.Config;
 import android.util.Log;
+import android.view.GestureDetector; 
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
@@ -225,21 +225,10 @@
     static public class ImageViewTouch extends ImageViewTouchBase {
         private ViewImage mViewImage;
         private boolean mEnableTrackballScroll;
-
-        private static int TOUCH_STATE_REST = 0;
-        private static int TOUCH_STATE_LEFT_PRESS = 1;
-        private static int TOUCH_STATE_RIGHT_PRESS = 2;
-        private static int TOUCH_STATE_PANNING = 3;
-
+        private GestureDetector mGestureDetector;
+        
         private static int TOUCH_AREA_WIDTH = 60;
 
-        private int mTouchState = TOUCH_STATE_REST;
-
-        // The event time of the previous touch up.
-        private long mPreviousUpTime;
-        // The duration in milliseconds we will wait to see if it is a double tap.
-        private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
-        
         // Returns current scale step (numbered from 0 to 10).
         private int getCurrentStep() {
             float s = getScale();
@@ -356,18 +345,20 @@
 
         public ImageViewTouch(Context context) {
             super(context);
-            mViewImage = (ViewImage) context;
-
-            mZoomRingController = new ZoomRingController(context, this);
-            mZoomRingController.setCallback(mZoomListener);
+            setup(context);
         }
 
         public ImageViewTouch(Context context, AttributeSet attrs) {
             super(context, attrs);
-            mViewImage = (ViewImage) context;
+            setup(context);
+        }
 
+        private void setup(Context context) {
+            mViewImage = (ViewImage) context;
             mZoomRingController = new ZoomRingController(context, this);
             mZoomRingController.setCallback(mZoomListener);
+            mGestureDetector = new GestureDetector(new MyGestureListener());
+            mGestureDetector.setOnDoubleTapListener(new MyDoubleTapListener());
         }
 
         public void setEnableTrackballScroll(boolean enable) {
@@ -389,105 +380,47 @@
         }
 
         public boolean handleTouchEvent(MotionEvent m) {
-            int viewWidth = getWidth();
-            ViewImage viewImage = mViewImage;
-            int x = (int) m.getX();
-            int y = (int) m.getY();
+            return mGestureDetector.onTouchEvent(m);
+        }
 
-            switch (m.getAction()) {
-                case MotionEvent.ACTION_DOWN:
-                    long downTime = m.getEventTime();
-                    if ((downTime - mPreviousUpTime) < DOUBLE_TAP_TIMEOUT) {
-                        mZoomRingController.setVisible(true);
-                    } else {
-                        viewImage.setMode(MODE_NORMAL);
-                        viewImage.showOnScreenControls();
-                        mLastXTouchPos = x;
-                        mLastYTouchPos = y;
-                        mTouchState = TOUCH_STATE_REST;
-                    }
-                    break;
-                case MotionEvent.ACTION_MOVE:
-                    if (x < TOUCH_AREA_WIDTH) {
-                        if (mTouchState == TOUCH_STATE_REST) {
-                            mTouchState = TOUCH_STATE_LEFT_PRESS;
-                        }
-                        if (mTouchState == TOUCH_STATE_LEFT_PRESS) {
-                            viewImage.mPrevImageView.setPressed(true);
-                            viewImage.mNextImageView.setPressed(false);
-                        }
-                        mLastXTouchPos = x;
-                        mLastYTouchPos = y;
-                    } else if (x > viewWidth - TOUCH_AREA_WIDTH) {
-                        if (mTouchState == TOUCH_STATE_REST) {
-                            mTouchState = TOUCH_STATE_RIGHT_PRESS;
-                        }
-                        if (mTouchState == TOUCH_STATE_RIGHT_PRESS) {
-                            viewImage.mPrevImageView.setPressed(false);
-                            viewImage.mNextImageView.setPressed(true);
-                        }
-                        mLastXTouchPos = x;
-                        mLastYTouchPos = y;
-                    } else {
-                        mTouchState = TOUCH_STATE_PANNING;
-                        viewImage.mPrevImageView.setPressed(false);
-                        viewImage.mNextImageView.setPressed(false);
-
-                        int deltaX;
-                        int deltaY;
-
-                        if (mLastXTouchPos == -1) {
-                            deltaX = 0;
-                            deltaY = 0;
-                        } else {
-                            deltaX = x - mLastXTouchPos;
-                            deltaY = y - mLastYTouchPos;
-                        }
-
-                        mLastXTouchPos = x;
-                        mLastYTouchPos = y;
-
-                        if (mBitmapDisplayed == null)
-                            return true;
-
-                        if (deltaX != 0) {
-                            // Second.  Pan to whatever degree is possible.
-                            if (getScale() > 1F) {
-                                postTranslate(deltaX, deltaY, sUseBounce);
-                                ImageViewTouch.this.center(true, true, false);
-                            }
-                        }
-                        setImageMatrix(getImageViewMatrix());
-                    }
-                    break;
-                case MotionEvent.ACTION_UP:
-                    int nextImagePos = -1;
-                    if (mTouchState == TOUCH_STATE_LEFT_PRESS && x < TOUCH_AREA_WIDTH) {
-                        nextImagePos = viewImage.mCurrentPosition - 1;
-                    } else if (mTouchState == TOUCH_STATE_RIGHT_PRESS &&
-                           x > viewWidth - TOUCH_AREA_WIDTH) {
-                        nextImagePos = viewImage.mCurrentPosition + 1;
-                    }
-                    if (nextImagePos >= 0
-                            && nextImagePos < viewImage.mAllImages.getCount()) {
-                        synchronized (viewImage) {
-                            viewImage.setMode(MODE_NORMAL);
-                            viewImage.setImage(nextImagePos);
-                        }
-                    }
-                    viewImage.scheduleDismissOnScreenControls();
-                    viewImage.mPrevImageView.setPressed(false);
-                    viewImage.mNextImageView.setPressed(false);
-                    mTouchState = TOUCH_STATE_REST;
-                    mPreviousUpTime = m.getEventTime();
-                    break;
-                case MotionEvent.ACTION_CANCEL:
-                    viewImage.mPrevImageView.setPressed(false);
-                    viewImage.mNextImageView.setPressed(false);
-                    mTouchState = TOUCH_STATE_REST;
-                    break;
+        private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
+            public boolean onScroll(MotionEvent e1, MotionEvent e2,
+                    float distanceX, float distanceY) {
+                if (getScale() > 1F) {
+                    postTranslate(-distanceX, -distanceY, sUseBounce);
+                    ImageViewTouch.this.center(true, true, false);
+                }
+                return true;
             }
-            return true;
+        }
+        
+        private class MyDoubleTapListener implements GestureDetector.OnDoubleTapListener {
+            // On single tap, we show the arrows. We also change to the
+            // prev/next image if the user taps on the left/right region. 
+            public boolean onSingleTapConfirmed(MotionEvent e) {
+                ViewImage viewImage = mViewImage;
+
+                int viewWidth = getWidth();
+                int x = (int) e.getX();
+                int y = (int) e.getY(); 
+                if (x < TOUCH_AREA_WIDTH) {
+                    viewImage.moveNextOrPrevious(-1);
+                } else if (x > viewWidth - TOUCH_AREA_WIDTH) {
+                    viewImage.moveNextOrPrevious(1);
+                }
+                
+                viewImage.setMode(MODE_NORMAL);
+                viewImage.showOnScreenControls();
+
+                return true;
+            }
+            
+            // On double tap, we show the zoom ring control.
+            public boolean onDoubleTapEvent(MotionEvent e) {
+                mViewImage.setMode(MODE_NORMAL);
+                mZoomRingController.setVisible(true);
+                return true;
+            }
         }
 
         @Override
@@ -1254,13 +1187,14 @@
 
         mNextImageView = findViewById(R.id.next_image);
         mPrevImageView = findViewById(R.id.prev_image);
+        mNextImageView.setOnClickListener(this);
+        mPrevImageView.setOnClickListener(this);
 
         if (mShowActionIcons) {
-            mNextImageView.setOnClickListener(this);
             mNextImageView.setFocusable(true);
-            mPrevImageView.setOnClickListener(this);
             mPrevImageView.setFocusable(true);
         }
+
         setOrientation();
 
         // Show a tutorial for the new zoom interaction (the method ensure we only show it once)