auto import from //branches/cupcake/...@137873
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 66ef99e..ea8f12e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -197,26 +197,26 @@
             </intent-filter>
         </activity>
 
-        <receiver android:name="PhotoGadgetProvider" android:label="@string/gadget_title">
+        <receiver android:name="PhotoAppWidgetProvider" android:label="@string/gadget_title">
             <intent-filter>
-                <action android:name="android.gadget.action.GADGET_UPDATE" />
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
             </intent-filter>
-            <meta-data android:name="android.gadget.provider" android:resource="@xml/gadget_info" />
+            <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info" />
         </receiver>
 
-        <!-- We configure a gadget by asking to pick a photo, then crop it, and store the config internally -->
-        <activity android:name="PhotoGadgetConfigure">
+        <!-- We configure a widget by asking to pick a photo, then crop it, and store the config internally -->
+        <activity android:name="PhotoAppWidgetConfigure">
             <intent-filter>
-                <action android:name="android.gadget.action.GADGET_CONFIGURE" />
+                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
             </intent-filter>
         </activity>
 
         <!-- We also allow direct binding where the caller provides a bitmap and
-             gadgetId to bind.  We require the permission because this changes our
+             appWidgetId to bind.  We require the permission because this changes our
              internal database without user confirmation. -->
-        <activity android:name="PhotoGadgetBind" android:exported="true"
+        <activity android:name="PhotoAppWidgetBind" android:exported="true"
                 android:theme="@android:style/Theme.NoDisplay"
-                android:permission="android.permission.BIND_GADGET" />
+                android:permission="android.permission.BIND_APPWIDGET" />
 
     </application>
 </manifest>
diff --git a/res/drawable/ic_btn_actionmenu_attach_default.png b/res/drawable/ic_btn_actionmenu_attach_default.png
index f429206..043691d 100644
--- a/res/drawable/ic_btn_actionmenu_attach_default.png
+++ b/res/drawable/ic_btn_actionmenu_attach_default.png
Binary files differ
diff --git a/res/drawable/ic_btn_actionmenu_attach_pressed.png b/res/drawable/ic_btn_actionmenu_attach_pressed.png
index ee083a7..b092ac1 100644
--- a/res/drawable/ic_btn_actionmenu_attach_pressed.png
+++ b/res/drawable/ic_btn_actionmenu_attach_pressed.png
Binary files differ
diff --git a/res/drawable/ic_btn_actionmenu_attach_selected.png b/res/drawable/ic_btn_actionmenu_attach_selected.png
index 582c3b9..52a2ef0 100644
--- a/res/drawable/ic_btn_actionmenu_attach_selected.png
+++ b/res/drawable/ic_btn_actionmenu_attach_selected.png
Binary files differ
diff --git a/res/layout/camera.xml b/res/layout/camera.xml
index d23066e..a37a166 100644
--- a/res/layout/camera.xml
+++ b/res/layout/camera.xml
@@ -26,13 +26,6 @@
         android:layout_height="fill_parent"
         android:layout_centerInParent="true" />
           
-    <View
-        android:id="@+id/blackout"
-        android:background="#ff000000"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:visibility="invisible" />
-
     <com.android.camera.ShutterButton
         android:id="@+id/shutter_button"
         android:layout_width="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ab7d88e..0121bd1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -454,5 +454,9 @@
     
     <!-- 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>
+
+    <!-- Displayed as a toast when a video file is too large to attach
+         to a Gmail message. -->
+    <string name="too_large_to_attach">File too large to attach.</string>
     
 </resources>
diff --git a/res/xml/gadget_info.xml b/res/xml/appwidget_info.xml
similarity index 83%
rename from res/xml/gadget_info.xml
rename to res/xml/appwidget_info.xml
index 5efaddd..92ec85b 100644
--- a/res/xml/gadget_info.xml
+++ b/res/xml/appwidget_info.xml
@@ -14,11 +14,11 @@
      limitations under the License.
 -->
 
-<gadget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
     android:minWidth="146dip"
     android:minHeight="146dip"
     android:updatePeriodMillis="0"
     android:initialLayout="@layout/photo_frame"
-    android:configure="com.android.camera.PhotoGadgetConfigure"
+    android:configure="com.android.camera.PhotoAppWidgetConfigure"
     >
-</gadget-provider>
+</appwidget-provider>
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 3564508..71ed339 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -129,7 +129,6 @@
     private android.hardware.Camera.Parameters mParameters;
     private VideoPreview mSurfaceView;
     private SurfaceHolder mSurfaceHolder = null;
-    private View mBlackout = null;
 
     private int mOriginalViewFinderWidth, mOriginalViewFinderHeight;
     private int mViewFinderWidth, mViewFinderHeight;
@@ -204,7 +203,7 @@
                 case RESTART_PREVIEW: {
                     if (mStatus == SNAPSHOT_IN_PROGRESS) {
                         // We are still in the processing of taking the picture, wait.
-                        // This is is strange.  Why are we polling?
+                        // This is strange.  Why are we polling?
                         // TODO remove polling
                         mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, 100);
                     } else if (mStatus == SNAPSHOT_COMPLETED){
@@ -293,15 +292,20 @@
                 mShutterCallbackTime = System.currentTimeMillis();
                 Log.v(TAG, "Shutter lag was " + (mShutterCallbackTime - mCaptureStartTime) + " ms.");
             }
+
+            // We are going to change the size of surface view and show captured
+            // image. Set it to invisible now and set it back to visible in 
+            // surfaceChanged() so that users won't see the image is resized on
+            // the screen.
+            mSurfaceView.setVisibility(View.INVISIBLE);
+            // Resize the SurfaceView to the aspect-ratio of the still image
+            // and so that we can see the full image that was taken.
+            Size pictureSize = mParameters.getPictureSize();
+            mSurfaceView.setAspectRatio(pictureSize.width, pictureSize.height);
+
             if (mClickSound != null) {
                 mClickSound.start();
             }
-            mBlackout.setVisibility(View.VISIBLE);
-
-            Size pictureSize = mParameters.getPictureSize();
-            // Resize the SurfaceView to the aspect-ratio of the still image
-            // and so that we can see the full image that was taken.
-            mSurfaceView.setAspectRatio(pictureSize.width, pictureSize.height);
         }
     };
 
@@ -314,7 +318,6 @@
                 Log.v(TAG, (mRawPictureCallbackTime - mShutterCallbackTime) + "ms elapsed between" +
                         " ShutterCallback and RawPictureCallback.");
             }
-            mBlackout.setVisibility(View.GONE);
         }
     };
 
@@ -326,6 +329,9 @@
         }
 
         public void onPictureTaken(byte [] jpegData, android.hardware.Camera camera) {
+            if (!canHandleCameraEvent()) {
+                return;
+            }
             if (Config.LOGV)
                 Log.v(TAG, "got JpegPictureCallback...");
 
@@ -581,6 +587,9 @@
         }
 
         public void onSnap() {
+            if (!canHandleCameraEvent()) {
+                return;
+            }
             if (DEBUG_TIME_OPERATIONS) mCaptureStartTime = System.currentTimeMillis();
 
             // If we are already in the middle of taking a snapshot then we should just save
@@ -739,8 +748,6 @@
         holder.addCallback(this);
         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 
-        mBlackout = findViewById(R.id.blackout);
-
         if (!isImageCaptureIntent())  {
             mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button);
             mLastPictureButton.setOnClickListener(this);
@@ -823,6 +830,9 @@
     }
 
     private void doAttach() {
+        if (!canHandleCameraEvent()) {
+            return;
+        }
         Bitmap bitmap = mImageCapture.getLastBitmap();
 
         String cropValue = null;
@@ -928,7 +938,16 @@
         finish();
     }
 
+    private boolean canHandleCameraEvent() {
+        // don't handle any shutter event before we have a valid 
+        // imageCapture object.
+        return mImageCapture != null;
+    }
+
     public void onShutterButtonFocus(ShutterButton button, boolean pressed) {
+        if (!canHandleCameraEvent()) {
+            return;
+        }
         switch (button.getId()) {
             case R.id.shutter_button:
                 doFocus(pressed);
@@ -937,6 +956,9 @@
     }
 
     public void onShutterButtonClick(ShutterButton button) {
+        if (!canHandleCameraEvent()) {
+            return;
+        }
         switch (button.getId()) {
             case R.id.shutter_button:
                 doSnap();
@@ -1010,8 +1032,6 @@
             Log.w(TAG, "Exception caught while creating local tone generator: " + e);
             mFocusToneGenerator = null;
         }
-
-        mBlackout.setVisibility(View.GONE);
     }
 
     private ImageManager.DataLocation dataLocation() {
@@ -1129,7 +1149,7 @@
         mImageCapture.clearLastBitmap();
         mImageCapture = null;
         hidePostCaptureAlert();
-        
+
         super.onPause();
     }
 
@@ -1279,10 +1299,11 @@
     }
 
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        mSurfaceView.setVisibility(View.VISIBLE);
         // if we're creating the surface, start the preview as well.
         boolean preview = holder.isCreating();
         setViewFinder(w, h, preview);
-        mCaptureObject = mImageCapture;
+        mCaptureObject = mImageCapture;        
     }
 
     public void surfaceCreated(SurfaceHolder holder) {
diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java
index 6c3472b..b470f95 100755
--- a/src/com/android/camera/ImageManager.java
+++ b/src/com/android/camera/ImageManager.java
@@ -2095,6 +2095,9 @@
                         } catch (NullPointerException ex) {
                             // we seem to get this if the file doesn't exist anymore
                             Log.e(TAG, "couldn't open thumbnail " + thumbUri + "; " + ex);
+                        } catch (OutOfMemoryError ex) {
+                            Log.e(TAG, "failed to allocate memory for thumbnail "
+                                    + thumbUri + "; " + ex);
                         }
                     }
                 } catch (Exception ex) {
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java
index 2bb532e..568b3a6 100644
--- a/src/com/android/camera/MenuHelper.java
+++ b/src/com/android/camera/MenuHelper.java
@@ -82,6 +82,8 @@
     static public final int MENU_VIDEO_SHARE = 24;
     static public final int MENU_VIDEO_TOSS = 27;
 
+    static private final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L;
+
     public static final int NO_STORAGE_ERROR = -1;
     public static final int CANNOT_STAT_ERROR = -2;
 
@@ -226,8 +228,13 @@
                 public boolean onMenuItemClick(MenuItem item) {
                     onInvoke.run(new MenuCallback() {
                         public void run(Uri u, ImageManager.IImage image) {
-                            if (image == null)
+                            if (image == null) return;
+                            if (!isImage && getImageFileSize(image) > SHARE_FILE_LENGTH_LIMIT ) {
+                                Toast.makeText(activity,
+                                        R.string.too_large_to_attach, Toast.LENGTH_LONG).show();
                                 return;
+                            }
+
                             Intent intent = new Intent();
                             intent.setAction(Intent.ACTION_SEND);
                             String mimeType = image.getMimeType();
@@ -564,6 +571,7 @@
         Uri target = Images.Media.INTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("bucketId",
                 ImageManager.CAMERA_IMAGE_BUCKET_ID).build();
         Intent intent = new Intent(Intent.ACTION_VIEW, target);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         intent.putExtra("windowTitle", activity.getString(windowTitleId));
         intent.putExtra("mediaTypes", mediaTypes);
         // Request unspecified so that we match the current camera orientation rather than
@@ -586,6 +594,7 @@
                  new MenuItem.OnMenuItemClickListener() {
                      public boolean onMenuItemClick(MenuItem item) {
                         Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                         try {
                                activity.startActivity(intent);
                         } catch (android.content.ActivityNotFoundException e) {
@@ -601,6 +610,7 @@
                  new MenuItem.OnMenuItemClickListener() {
                      public boolean onMenuItemClick(MenuItem item) {
                          Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
+                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                          try {
                              activity.startActivity(intent);
                          } catch (android.content.ActivityNotFoundException e) {
diff --git a/src/com/android/camera/PhotoAppWidgetBind.java b/src/com/android/camera/PhotoAppWidgetBind.java
new file mode 100644
index 0000000..5e71a54
--- /dev/null
+++ b/src/com/android/camera/PhotoAppWidgetBind.java
@@ -0,0 +1,73 @@
+/*
+ * 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.camera;
+
+import com.android.camera.PhotoAppWidgetProvider.PhotoDatabaseHelper;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import java.util.ArrayList;
+
+public class PhotoAppWidgetBind extends Activity {
+    static final String TAG = "PhotoAppWidgetBind";
+    
+    static final String EXTRA_APPWIDGET_BITMAPS = "com.android.camera.appwidgetbitmaps";
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        finish();
+        
+        // The caller has requested that we bind a given bitmap to a specific
+        // appWidgetId, which probably is happening during a Launcher upgrade. This
+        // is dangerous because the caller could set bitmaps on appWidgetIds they
+        // don't own, so we guard this call at the manifest level by requiring
+        // the BIND_APPWIDGET permission.
+        
+        final Intent intent = getIntent();
+        final Bundle extras = intent.getExtras();
+        
+        final int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
+        final ArrayList<Bitmap> bitmaps = extras.getParcelableArrayList(EXTRA_APPWIDGET_BITMAPS);
+        
+        if (appWidgetIds == null || bitmaps == null ||
+                appWidgetIds.length != bitmaps.size()) {
+            Log.e(TAG, "Problem parsing photo widget bind request");
+            return;
+        }
+        
+        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
+        PhotoDatabaseHelper helper = new PhotoDatabaseHelper(this);
+        for (int i = 0; i < appWidgetIds.length; i++) {
+            // Store the cropped photo in our database
+            int appWidgetId = appWidgetIds[i];
+            helper.setPhoto(appWidgetId, bitmaps.get(i));
+            
+            // Push newly updated widget to surface
+            RemoteViews views = PhotoAppWidgetProvider.buildUpdate(this, appWidgetId, helper);
+            appWidgetManager.updateAppWidget(new int[] { appWidgetId }, views);
+        }
+        helper.close();
+        
+    }
+}
diff --git a/src/com/android/camera/PhotoGadgetConfigure.java b/src/com/android/camera/PhotoAppWidgetConfigure.java
similarity index 70%
rename from src/com/android/camera/PhotoGadgetConfigure.java
rename to src/com/android/camera/PhotoAppWidgetConfigure.java
index a94b5a3..14e6112 100644
--- a/src/com/android/camera/PhotoGadgetConfigure.java
+++ b/src/com/android/camera/PhotoAppWidgetConfigure.java
@@ -16,13 +16,13 @@
 
 package com.android.camera;
 
-import com.android.camera.PhotoGadgetProvider.PhotoDatabaseHelper;
+import com.android.camera.PhotoAppWidgetProvider.PhotoDatabaseHelper;
 
 import android.app.Activity;
+import android.appwidget.AppWidgetManager;
 import android.content.ContentValues;
 import android.content.Intent;
 import android.database.sqlite.SQLiteDatabase;
-import android.gadget.GadgetManager;
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.os.Parcelable;
@@ -32,22 +32,22 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 
-public class PhotoGadgetConfigure extends Activity {
-    static final private String TAG = "PhotoGadgetConfigure";
+public class PhotoAppWidgetConfigure extends Activity {
+    static final private String TAG = "PhotoAppWidgetConfigure";
     
     static final int REQUEST_GET_PHOTO = 2;
     
-    int gadgetId = -1;
+    int appWidgetId = -1;
 
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         
-        // Someone is requesting that we configure the given gadgetId, which means
+        // Someone is requesting that we configure the given appWidgetId, which means
         // we prompt the user to pick and crop a photo.
         
-        gadgetId = getIntent().getIntExtra(GadgetManager.EXTRA_GADGET_ID, -1);
-        if (gadgetId == -1) {
+        appWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
+        if (appWidgetId == -1) {
             setResult(Activity.RESULT_CANCELED);
             finish();
         }
@@ -69,27 +69,27 @@
     
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (resultCode == RESULT_OK && gadgetId != -1) {
+        if (resultCode == RESULT_OK && appWidgetId != -1) {
             // Store the cropped photo in our database
             Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
             
             PhotoDatabaseHelper helper = new PhotoDatabaseHelper(this);
-            if (helper.setPhoto(gadgetId, bitmap)) {
+            if (helper.setPhoto(appWidgetId, bitmap)) {
                 resultCode = Activity.RESULT_OK;
 
-                // Push newly updated gadget to surface
-                RemoteViews views = PhotoGadgetProvider.buildUpdate(this, gadgetId, helper);
-                GadgetManager gadgetManager = GadgetManager.getInstance(this);
-                gadgetManager.updateGadget(new int[] { gadgetId }, views);
+                // Push newly updated widget to surface
+                RemoteViews views = PhotoAppWidgetProvider.buildUpdate(this, appWidgetId, helper);
+                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
+                appWidgetManager.updateAppWidget(new int[] { appWidgetId }, views);
             }
             helper.close();
         } else {
             resultCode = Activity.RESULT_CANCELED;
         }
         
-        // Make sure we pass back the original gadgetId
+        // Make sure we pass back the original appWidgetId
         Intent resultValue = new Intent();
-        resultValue.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId);
+        resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
         setResult(resultCode, resultValue);
         finish();
     }
diff --git a/src/com/android/camera/PhotoGadgetProvider.java b/src/com/android/camera/PhotoAppWidgetProvider.java
similarity index 80%
rename from src/com/android/camera/PhotoGadgetProvider.java
rename to src/com/android/camera/PhotoAppWidgetProvider.java
index b03217d..398528e 100644
--- a/src/com/android/camera/PhotoGadgetProvider.java
+++ b/src/com/android/camera/PhotoAppWidgetProvider.java
@@ -23,6 +23,8 @@
 
 import android.app.Activity;
 import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -36,8 +38,6 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
 import android.database.sqlite.SQLiteOpenHelper;
-import android.gadget.GadgetManager;
-import android.gadget.GadgetProvider;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
@@ -61,41 +61,41 @@
 import java.io.IOException;
 
 /**
- * Simple gadget to show a user-selected picture.
+ * Simple widget to show a user-selected picture.
  */
-public class PhotoGadgetProvider extends GadgetProvider {
-    static final String TAG = "PhotoGadgetProvider";
+public class PhotoAppWidgetProvider extends AppWidgetProvider {
+    static final String TAG = "PhotoAppWidgetProvider";
     static final boolean LOGD = Config.LOGD || true;
     
     @Override
-    public void onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds) {
-        // Update each requested gadgetId with its unique photo
+    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+        // Update each requested appWidgetId with its unique photo
         PhotoDatabaseHelper helper = new PhotoDatabaseHelper(context);
-        for (int gadgetId : gadgetIds) {
-            int[] specificGadget = new int[] { gadgetId };
-            RemoteViews views = buildUpdate(context, gadgetId, helper);
-            if (LOGD) Log.d(TAG, "sending out views="+views+" for id="+gadgetId);
-            gadgetManager.updateGadget(specificGadget, views);
+        for (int appWidgetId : appWidgetIds) {
+            int[] specificAppWidget = new int[] { appWidgetId };
+            RemoteViews views = buildUpdate(context, appWidgetId, helper);
+            if (LOGD) Log.d(TAG, "sending out views="+views+" for id="+appWidgetId);
+            appWidgetManager.updateAppWidget(specificAppWidget, views);
         }
         helper.close();
     }
     
     @Override
-    public void onDeleted(Context context, int[] gadgetIds) {
+    public void onDeleted(Context context, int[] appWidgetIds) {
         // Clean deleted photos out of our database
         PhotoDatabaseHelper helper = new PhotoDatabaseHelper(context);
-        for (int gadgetId : gadgetIds) {
-            helper.deletePhoto(gadgetId);
+        for (int appWidgetId : appWidgetIds) {
+            helper.deletePhoto(appWidgetId);
         }
         helper.close();
     }
 
     /**
-     * Load photo for given gadget and build {@link RemoteViews} for it.
+     * Load photo for given widget and build {@link RemoteViews} for it.
      */
-    static RemoteViews buildUpdate(Context context, int gadgetId, PhotoDatabaseHelper helper) {
+    static RemoteViews buildUpdate(Context context, int appWidgetId, PhotoDatabaseHelper helper) {
         RemoteViews views = null;
-        Bitmap bitmap = helper.getPhoto(gadgetId);
+        Bitmap bitmap = helper.getPhoto(appWidgetId);
         if (bitmap != null) {
             views = new RemoteViews(context.getPackageName(), R.layout.photo_frame);
             views.setImageViewBitmap(R.id.photo, bitmap);
@@ -111,7 +111,7 @@
         private static final int DATABASE_VERSION = 1;
 
         static final String TABLE_PHOTOS = "photos";
-        static final String FIELD_GADGET_ID = "gadgetId";
+        static final String FIELD_APPWIDGET_ID = "appWidgetId";
         static final String FIELD_PHOTO_BLOB = "photoBlob";
 
         PhotoDatabaseHelper(Context context) {
@@ -122,7 +122,7 @@
         @Override
         public void onCreate(SQLiteDatabase db) {
             db.execSQL("CREATE TABLE " + TABLE_PHOTOS + " (" +
-                    FIELD_GADGET_ID + " INTEGER PRIMARY KEY," +
+                    FIELD_APPWIDGET_ID + " INTEGER PRIMARY KEY," +
                     FIELD_PHOTO_BLOB + " BLOB" +
                     ");");
         }
@@ -139,9 +139,9 @@
         }
         
         /**
-         * Store the given bitmap in this database for the given gadgetId.
+         * Store the given bitmap in this database for the given appWidgetId.
          */
-        public boolean setPhoto(int gadgetId, Bitmap bitmap) {
+        public boolean setPhoto(int appWidgetId, Bitmap bitmap) {
             boolean success = false;
             try {
                 // Try go guesstimate how much space the icon will take when serialized
@@ -153,7 +153,7 @@
                 out.close();
 
                 ContentValues values = new ContentValues();
-                values.put(PhotoDatabaseHelper.FIELD_GADGET_ID, gadgetId);
+                values.put(PhotoDatabaseHelper.FIELD_APPWIDGET_ID, appWidgetId);
                 values.put(PhotoDatabaseHelper.FIELD_PHOTO_BLOB, out.toByteArray());
                     
                 SQLiteDatabase db = getWritableDatabase();
@@ -176,14 +176,14 @@
         static final int INDEX_PHOTO_BLOB = 0;
         
         /**
-         * Inflate and return a bitmap for the given gadgetId.
+         * Inflate and return a bitmap for the given appWidgetId.
          */
-        public Bitmap getPhoto(int gadgetId) {
+        public Bitmap getPhoto(int appWidgetId) {
             Cursor c = null;
             Bitmap bitmap = null;
             try {
                 SQLiteDatabase db = getReadableDatabase();
-                String selection = String.format("%s=%d", FIELD_GADGET_ID, gadgetId);
+                String selection = String.format("%s=%d", FIELD_APPWIDGET_ID, appWidgetId);
                 c = db.query(TABLE_PHOTOS, PHOTOS_PROJECTION, selection, null,
                         null, null, null, null);
                 
@@ -206,12 +206,12 @@
         }
         
         /**
-         * Remove any bitmap associated with the given gadgetId.
+         * Remove any bitmap associated with the given appWidgetId.
          */
-        public void deletePhoto(int gadgetId) {
+        public void deletePhoto(int appWidgetId) {
             try {
                 SQLiteDatabase db = getWritableDatabase();
-                String whereClause = String.format("%s=%d", FIELD_GADGET_ID, gadgetId);
+                String whereClause = String.format("%s=%d", FIELD_APPWIDGET_ID, appWidgetId);
                 db.delete(TABLE_PHOTOS, whereClause, null);
             } catch (SQLiteException e) {
                 Log.e(TAG, "Could not delete photo from database", e);
diff --git a/src/com/android/camera/PhotoGadgetBind.java b/src/com/android/camera/PhotoGadgetBind.java
deleted file mode 100644
index fff19de..0000000
--- a/src/com/android/camera/PhotoGadgetBind.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.camera;
-
-import com.android.camera.PhotoGadgetProvider.PhotoDatabaseHelper;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.gadget.GadgetManager;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.RemoteViews;
-
-import java.util.ArrayList;
-
-public class PhotoGadgetBind extends Activity {
-    static final String TAG = "PhotoGadgetBind";
-    
-    static final String EXTRA_GADGET_BITMAPS = "com.android.camera.gadgetbitmaps";
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        finish();
-        
-        // The caller has requested that we bind a given bitmap to a specific
-        // gadgetId, which probably is happening during a Launcher upgrade. This
-        // is dangerous because the caller could set bitmaps on gadgetIds they
-        // don't own, so we guard this call at the manifest level by requiring
-        // the BIND_GADGET permission.
-        
-        final Intent intent = getIntent();
-        final Bundle extras = intent.getExtras();
-        
-        final int[] gadgetIds = extras.getIntArray(GadgetManager.EXTRA_GADGET_IDS);
-        final ArrayList<Bitmap> bitmaps = extras.getParcelableArrayList(EXTRA_GADGET_BITMAPS);
-        
-        if (gadgetIds == null || bitmaps == null ||
-                gadgetIds.length != bitmaps.size()) {
-            Log.e(TAG, "Problem parsing photo gadget bind request");
-            return;
-        }
-        
-        GadgetManager gadgetManager = GadgetManager.getInstance(this);
-        PhotoDatabaseHelper helper = new PhotoDatabaseHelper(this);
-        for (int i = 0; i < gadgetIds.length; i++) {
-            // Store the cropped photo in our database
-            int gadgetId = gadgetIds[i];
-            helper.setPhoto(gadgetId, bitmaps.get(i));
-            
-            // Push newly updated gadget to surface
-            RemoteViews views = PhotoGadgetProvider.buildUpdate(this, gadgetId, helper);
-            gadgetManager.updateGadget(new int[] { gadgetId }, views);
-        }
-        helper.close();
-        
-    }
-}
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index 70b1646..1fb22e1 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -84,6 +84,7 @@
     private static final long NO_STORAGE_ERROR = -1L;
     private static final long CANNOT_STAT_ERROR = -2L;
     private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L;
+    private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L;
 
     private static final int STORAGE_STATUS_OK = 0;
     private static final int STORAGE_STATUS_LOW = 1;
@@ -264,6 +265,24 @@
         mVideoFrame = (ImageView) findViewById(R.id.video_frame);
     }
 
+    private void startShareVideoActivity() {
+        long fileLength = new File(mCurrentVideoFilename).length();
+        if (fileLength > SHARE_FILE_LENGTH_LIMIT) {
+            Toast.makeText(VideoCamera.this,
+                    R.string.too_large_to_attach, Toast.LENGTH_LONG).show();
+            return;
+        }
+        Intent intent = new Intent();
+        intent.setAction(Intent.ACTION_SEND);
+        intent.setType("video/3gpp");
+        intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri);
+        try {
+            startActivity(Intent.createChooser(intent, getText(R.string.sendVideo)));
+        } catch (android.content.ActivityNotFoundException ex) {
+            Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show();
+        }
+    }
+
     public void onClick(View v) {
         switch (v.getId()) {
 
@@ -285,16 +304,7 @@
             }
 
             case R.id.share: {
-                Intent intent = new Intent();
-                intent.setAction(Intent.ACTION_SEND);
-                intent.setType("video/3gpp");
-                intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri);
-                try {
-                    startActivity(Intent.createChooser(intent, getText(R.string.sendVideo)));
-                } catch (android.content.ActivityNotFoundException ex) {
-                    Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show();
-                }
-
+                startShareVideoActivity();
                 break;
             }
 
@@ -932,6 +942,7 @@
         for(int id : hideIds) {
             mPostPictureAlert.findViewById(id).setVisibility(View.GONE);
         }
+
         connectAndFadeIn(connectIds);
         connectAndFadeIn(alwaysOnIds);
         mPostPictureAlert.setVisibility(View.VISIBLE);
diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java
index a5a3821..7963e66 100644
--- a/src/com/android/camera/ViewImage.java
+++ b/src/com/android/camera/ViewImage.java
@@ -249,14 +249,10 @@
             mGestureDetector = new GestureDetector(getContext(), new MyGestureListener());
             mGestureDetector.setOnDoubleTapListener(new MyDoubleTapListener());
             mZoomButtonsController = new ZoomButtonsController(context, this);
-            mZoomButtonsController.setOverviewVisible(false);
             mZoomButtonsController.setCallback(new ZoomButtonsController.OnZoomListener() {
                 public void onCenter(int x, int y) {
                 }
 
-                public void onOverview() {
-                }
-
                 public void onVisibilityChanged(boolean visible) {
                     if (visible) {
                         updateButtonsEnabled();
@@ -338,7 +334,9 @@
             // On double tap, we show the zoom controls.
             public boolean onDoubleTapEvent(MotionEvent e) {
                 mViewImage.setMode(MODE_NORMAL);
-                mZoomButtonsController.handleDoubleTapEvent(e);
+                if (mZoomButtonsController.handleDoubleTapEvent(e)) {
+                    ZoomButtonsController.finishZoomTutorial(mViewImage, true);
+                }
                 return true;
             }
 
@@ -901,7 +899,8 @@
             return;
         }
 
-        final boolean left = mCurrentPosition > pos;
+        final boolean left = (pos == mCurrentPosition - 1);
+        final boolean right = (pos == mCurrentPosition + 1);
 
         mCurrentPosition = pos;
 
@@ -919,7 +918,7 @@
             if (left) {
                 mImageViews[2].copyFrom(mImageViews[1]);
                 mImageViews[1].copyFrom(mImageViews[0]);
-            } else {
+            } else if (right) {
                 mImageViews[0].copyFrom(mImageViews[1]);
                 mImageViews[1].copyFrom(mImageViews[2]);
             }
@@ -1449,6 +1448,15 @@
     }
 
     @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        if (hasFocus) {
+            ZoomButtonsController.showZoomTutorialOnce(this);
+        } else {
+            ZoomButtonsController.finishZoomTutorial(this, false);
+        }
+    }
+
+    @Override
     public void onPause()
     {
         super.onPause();