Merge "Add support for SMS-PP data download to USIM."
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c30675b..e593d5b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2174,6 +2174,7 @@
         info.screenOrientation = target.info.screenOrientation;
         info.taskAffinity = target.info.taskAffinity;
         info.theme = target.info.theme;
+        info.softInputMode = target.info.softInputMode;
         info.uiOptions = target.info.uiOptions;
         
         Activity a = new Activity(mParseActivityAliasArgs, info);
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index ccacd09..5ee1b8a 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -1090,6 +1090,7 @@
         setMaxLength(maxLength);
         setHorizontallyScrolling(single);
         setInputType(inputType);
+        clearComposingText();
         setImeOptions(imeOptions);
         setVisibility(VISIBLE);
         if (!autoComplete) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a814b12..3731097 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4804,16 +4804,7 @@
             mTextGeneration = 0;
         }
         mWebTextView.updateTextSize();
-        Rect visibleRect = new Rect();
-        calcOurContentVisibleRect(visibleRect);
-        // Note that sendOurVisibleRect calls viewToContent, so the coordinates
-        // should be in content coordinates.
-        Rect bounds = nativeFocusCandidateNodeBounds();
-        Rect vBox = contentToViewRect(bounds);
-        mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
-        if (!Rect.intersects(bounds, visibleRect)) {
-            revealSelection();
-        }
+        updateWebTextViewPosition();
         String text = nativeFocusCandidateText();
         int nodePointer = nativeFocusCandidatePointer();
         // This needs to be called before setType, which may call
@@ -4822,7 +4813,6 @@
         mWebTextView.setType(nativeFocusCandidateType());
         // Gravity needs to be set after setType
         mWebTextView.setGravityForRtl(nativeFocusCandidateIsRtlText());
-        updateWebTextViewPadding();
         if (null == text) {
             if (DebugFlags.WEB_VIEW) {
                 Log.v(LOGTAG, "rebuildWebTextView null == text");
@@ -4833,12 +4823,27 @@
         InputMethodManager imm = InputMethodManager.peekInstance();
         if (imm != null && imm.isActive(mWebTextView)) {
             imm.restartInput(mWebTextView);
+            mWebTextView.clearComposingText();
         }
         if (isFocused()) {
             mWebTextView.requestFocus();
         }
     }
 
+    private void updateWebTextViewPosition() {
+        Rect visibleRect = new Rect();
+        calcOurContentVisibleRect(visibleRect);
+        // Note that sendOurVisibleRect calls viewToContent, so the coordinates
+        // should be in content coordinates.
+        Rect bounds = nativeFocusCandidateNodeBounds();
+        Rect vBox = contentToViewRect(bounds);
+        mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
+        if (!Rect.intersects(bounds, visibleRect)) {
+            revealSelection();
+        }
+        updateWebTextViewPadding();
+    }
+
     /**
      * Update the padding of mWebTextView based on the native textfield/textarea
      */
@@ -8453,7 +8458,7 @@
                     // this is sent after finishing resize in WebViewCore. Make
                     // sure the text edit box is still on the  screen.
                     if (inEditingMode() && nativeCursorIsTextInput()) {
-                        rebuildWebTextView();
+                        updateWebTextViewPosition();
                     }
                     break;
                 case CLEAR_TEXT_ENTRY:
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 0cd14d0..03e6e99 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -55,7 +55,6 @@
      * Default animation parameters
      */
     private static final int DEFAULT_ANIMATION_DURATION = 400;
-    private static final int FADE_IN_ANIMATION_DURATION = 800;
     private static final int MINIMUM_ANIMATION_DURATION = 50;
     private static final int STACK_RELAYOUT_DURATION = 100;
 
@@ -222,8 +221,6 @@
      * Animate the views between different relative indexes within the {@link AdapterViewAnimator}
      */
     void transformViewForTransition(int fromIndex, int toIndex, final View view, boolean animate) {
-        ObjectAnimator alphaOa;
-
         if (!animate) {
             ((StackFrame) view).cancelSliderAnimator();
             view.setRotationX(0f);
@@ -233,22 +230,9 @@
         }
 
         if (fromIndex == -1 && toIndex == getNumActiveViews() -1) {
-            // Fade item in
-            if (view.getAlpha() == 1) {
-                view.setAlpha(0);
-            }
             transformViewAtIndex(toIndex, view, false);
             view.setVisibility(VISIBLE);
-
-            ((StackFrame) view).cancelAlphaAnimator();
-            if (animate) {
-                alphaOa = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f);
-                alphaOa.setDuration(FADE_IN_ANIMATION_DURATION);
-                ((StackFrame) view).setAlphaAnimator(alphaOa);
-                alphaOa.start();
-            } else {
-                view.setAlpha(1.0f);
-            }
+            view.setAlpha(1.0f);
         } else if (fromIndex == 0 && toIndex == 1) {
             // Slide item in
             ((StackFrame) view).cancelSliderAnimator();
@@ -306,13 +290,12 @@
             view.setAlpha(1.0f);
             view.setVisibility(VISIBLE);
         } else if (toIndex == -1) {
-            // Fade item out
-            ((StackFrame) view).cancelAlphaAnimator();
             if (animate) {
-                alphaOa = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 0.0f);
-                alphaOa.setDuration(STACK_RELAYOUT_DURATION);
-                ((StackFrame) view).setAlphaAnimator(alphaOa);
-                alphaOa.start();
+                postDelayed(new Runnable() {
+                    public void run() {
+                        view.setAlpha(0);
+                    }
+                }, STACK_RELAYOUT_DURATION);
             } else {
                 view.setAlpha(0f);
             }
@@ -485,7 +468,6 @@
     }
 
     private static class StackFrame extends FrameLayout {
-        WeakReference<ObjectAnimator> alphaAnimator;
         WeakReference<ObjectAnimator> transformAnimator;
         WeakReference<ObjectAnimator> sliderAnimator;
 
@@ -493,10 +475,6 @@
             super(context);
         }
 
-        void setAlphaAnimator(ObjectAnimator oa) {
-            alphaAnimator = new WeakReference<ObjectAnimator>(oa);
-        }
-
         void setTransformAnimator(ObjectAnimator oa) {
             transformAnimator = new WeakReference<ObjectAnimator>(oa);
         }
@@ -505,17 +483,6 @@
             sliderAnimator = new WeakReference<ObjectAnimator>(oa);
         }
 
-        boolean cancelAlphaAnimator() {
-            if (alphaAnimator != null) {
-                ObjectAnimator oa = alphaAnimator.get();
-                if (oa != null) {
-                    oa.cancel();
-                    return true;
-                }
-            }
-            return false;
-        }
-
         boolean cancelTransformAnimator() {
             if (transformAnimator != null) {
                 ObjectAnimator oa = transformAnimator.get();
diff --git a/docs/html/sdk/android-4.0-highlights.jd b/docs/html/sdk/android-4.0-highlights.jd
index d6a2dcd..c1162d4 100644
--- a/docs/html/sdk/android-4.0-highlights.jd
+++ b/docs/html/sdk/android-4.0-highlights.jd
@@ -176,7 +176,7 @@
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Swipe to dismiss
 notifications, tasks, and browser tabs</strong></p>
 
-<p>Android 4.0 makes managing notifications, recent apps, and brwoser tabs even
+<p>Android 4.0 makes managing notifications, recent apps, and browser tabs even
 easier. Users can now dismiss individual notifications, apps from the Recent
 Apps list, and browser tabs with a simple swipe of a finger. </p>
 
diff --git a/packages/SystemUI/res/drawable-hdpi/global_screenshot_background.9.png b/packages/SystemUI/res/drawable-hdpi/global_screenshot_background.9.png
deleted file mode 100644
index e14111d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/global_screenshot_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
new file mode 100644
index 0000000..9447e01
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/global_screenshot_background.9.png b/packages/SystemUI/res/drawable-mdpi/global_screenshot_background.9.png
deleted file mode 100644
index e14111d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/global_screenshot_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
new file mode 100644
index 0000000..7f1aea1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/global_screenshot_background.9.png b/packages/SystemUI/res/drawable-xhdpi/global_screenshot_background.9.png
deleted file mode 100644
index db116b1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/global_screenshot_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
new file mode 100644
index 0000000..e5cfc36
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/status_bar_recents_background.xml b/packages/SystemUI/res/drawable/status_bar_recents_background.xml
index 8b22bf1..7831db0 100644
--- a/packages/SystemUI/res/drawable/status_bar_recents_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_recents_background.xml
@@ -17,9 +17,9 @@
  */
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-  <gradient name="status_bar_recents_background"
-            android:startColor="#cc000000"
-            android:endColor="#66000000"
-            android:angle="@integer/status_bar_recents_bg_gradient_degrees"
-	    />
+    <gradient name="status_bar_recents_background"
+        android:startColor="#e6000000"
+        android:endColor="#c0000000"
+        android:angle="@integer/status_bar_recents_bg_gradient_degrees"
+        />
 </shape>
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 6d70135..d416af9 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -26,11 +26,16 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
-        android:background="@drawable/global_screenshot_background"
+        android:background="@drawable/screenshot_panel"
         android:visibility="gone">
         <ImageView android:id="@+id/global_screenshot"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:adjustViewBounds="true" />
     </FrameLayout>
+    <ImageView android:id="@+id/global_screenshot_flash"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#FFFFFFFF"
+        android:visibility="gone" />
 </FrameLayout>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index bce0bc4..ce390a0 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -29,5 +29,5 @@
     <drawable name="notification_header_bg">#d8000000</drawable>
     <drawable name="notification_tracking_bg">#d8000000</drawable>
     <color name="notification_list_shadow_top">#80000000</color>
-    <drawable name="recents_callout_line">#66ffffff</drawable>
+    <drawable name="recents_callout_line">#99ffffff</drawable>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bf19286..55b722b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -89,9 +89,6 @@
     <dimen name="collapse_accel">2000dp</dimen>
 
     <!-- The padding on the global screenshot background image -->
-    <dimen name="global_screenshot_bg_padding">0dp</dimen>
-    <!-- The top-left offset for the screenshot drop animation target bounds -->
-    <dimen name="global_screenshot_drop_offset_x">6dp</dimen>
-    <dimen name="global_screenshot_drop_offset_y">0dp</dimen>
+    <dimen name="global_screenshot_bg_padding">20dp</dimen>
 
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index cc1b8ed..6549610 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -34,7 +34,6 @@
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
 import android.graphics.PointF;
-import android.graphics.RectF;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Environment;
@@ -52,6 +51,7 @@
 import android.view.WindowManager;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
@@ -229,15 +229,18 @@
 class GlobalScreenshot {
     private static final String TAG = "GlobalScreenshot";
     private static final int SCREENSHOT_NOTIFICATION_ID = 789;
-    private static final int SCREENSHOT_FADE_IN_DURATION = 250;
-    private static final int SCREENSHOT_FADE_OUT_DELAY = 750;
-    private static final int SCREENSHOT_FADE_OUT_DURATION = 500;
-    private static final int SCREENSHOT_FAST_FADE_OUT_DURATION = 350;
-    private static final float BACKGROUND_ALPHA = 0.65f;
-    private static final float SCREENSHOT_SCALE_FUDGE = 0.075f; // To account for the border padding
-    private static final float SCREENSHOT_SCALE = 0.55f;
-    private static final float SCREENSHOT_FADE_IN_MIN_SCALE = SCREENSHOT_SCALE * 0.975f;
-    private static final float SCREENSHOT_FADE_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.925f;
+    private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
+    private static final int SCREENSHOT_DROP_IN_DURATION = 430;
+    private static final int SCREENSHOT_DROP_OUT_DELAY = 500;
+    private static final int SCREENSHOT_DROP_OUT_DURATION = 430;
+    private static final int SCREENSHOT_DROP_OUT_SCALE_DURATION = 370;
+    private static final int SCREENSHOT_FAST_DROP_OUT_DURATION = 320;
+    private static final float BACKGROUND_ALPHA = 0.5f;
+    private static final float SCREENSHOT_SCALE = 1f;
+    private static final float SCREENSHOT_DROP_IN_MIN_SCALE = SCREENSHOT_SCALE * 0.725f;
+    private static final float SCREENSHOT_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.45f;
+    private static final float SCREENSHOT_FAST_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.6f;
+    private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f;
 
     private Context mContext;
     private LayoutInflater mLayoutInflater;
@@ -254,13 +257,11 @@
     private ImageView mBackgroundView;
     private FrameLayout mScreenshotContainerView;
     private ImageView mScreenshotView;
+    private ImageView mScreenshotFlash;
 
     private AnimatorSet mScreenshotAnimation;
 
-    private int mStatusBarIconSize;
     private int mNotificationIconSize;
-    private float mDropOffsetX;
-    private float mDropOffsetY;
     private float mBgPadding;
     private float mBgPaddingScale;
 
@@ -280,6 +281,7 @@
         mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background);
         mScreenshotContainerView = (FrameLayout) mScreenshotLayout.findViewById(R.id.global_screenshot_container);
         mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot);
+        mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
         mScreenshotLayout.setFocusable(true);
         mScreenshotLayout.setOnTouchListener(new View.OnTouchListener() {
             @Override
@@ -309,16 +311,12 @@
         mDisplay.getRealMetrics(mDisplayMetrics);
 
         // Get the various target sizes
-        mStatusBarIconSize =
-            r.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
         mNotificationIconSize =
             r.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
-        mDropOffsetX = r.getDimensionPixelSize(R.dimen.global_screenshot_drop_offset_x);
-        mDropOffsetY = r.getDimensionPixelSize(R.dimen.global_screenshot_drop_offset_y);
 
         // Scale has to account for both sides of the bg
         mBgPadding = (float) r.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
-        mBgPaddingScale = (2f * mBgPadding) /  mDisplayMetrics.widthPixels;
+        mBgPaddingScale = mBgPadding /  mDisplayMetrics.widthPixels;
     }
 
     /**
@@ -413,11 +411,11 @@
         }
 
         mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
-        ValueAnimator screenshotFadeInAnim = createScreenshotFadeInAnimation();
-        ValueAnimator screenshotFadeOutAnim = createScreenshotFadeOutAnimation(w, h,
+        ValueAnimator screenshotDropInAnim = createScreenshotDropInAnimation();
+        ValueAnimator screenshotFadeOutAnim = createScreenshotDropOutAnimation(w, h,
                 statusBarVisible, navBarVisible);
         mScreenshotAnimation = new AnimatorSet();
-        mScreenshotAnimation.play(screenshotFadeInAnim).before(screenshotFadeOutAnim);
+        mScreenshotAnimation.playSequentially(screenshotDropInAnim, screenshotFadeOutAnim);
         mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -435,42 +433,71 @@
             }
         });
     }
-    private ValueAnimator createScreenshotFadeInAnimation() {
+    private ValueAnimator createScreenshotDropInAnimation() {
+        final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)
+                / SCREENSHOT_DROP_IN_DURATION);
+        final float flashDurationPct = 2f * flashPeakDurationPct;
+        final Interpolator flashAlphaInterpolator = new Interpolator() {
+            @Override
+            public float getInterpolation(float x) {
+                // Flash the flash view in and out quickly
+                if (x <= flashDurationPct) {
+                    return (float) Math.sin(Math.PI * (x / flashDurationPct));
+                }
+                return 0;
+            }
+        };
+        final Interpolator scaleInterpolator = new Interpolator() {
+            @Override
+            public float getInterpolation(float x) {
+                // We start scaling when the flash is at it's peak
+                if (x < flashPeakDurationPct) {
+                    return 0;
+                }
+                return (x - flashDurationPct) / (1f - flashDurationPct);
+            }
+        };
         ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
-        anim.setInterpolator(new AccelerateInterpolator(1.5f));
-        anim.setDuration(SCREENSHOT_FADE_IN_DURATION);
+        anim.setDuration(SCREENSHOT_DROP_IN_DURATION);
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
                 mBackgroundView.setAlpha(0f);
                 mBackgroundView.setVisibility(View.VISIBLE);
+                mScreenshotContainerView.setAlpha(0f);
                 mScreenshotContainerView.setTranslationX(0f);
                 mScreenshotContainerView.setTranslationY(0f);
-                mScreenshotContainerView.setScaleX(SCREENSHOT_FADE_IN_MIN_SCALE);
-                mScreenshotContainerView.setScaleY(SCREENSHOT_FADE_IN_MIN_SCALE);
-                mScreenshotContainerView.setAlpha(0f);
+                mScreenshotContainerView.setScaleX(SCREENSHOT_SCALE + mBgPaddingScale);
+                mScreenshotContainerView.setScaleY(SCREENSHOT_SCALE + mBgPaddingScale);
                 mScreenshotContainerView.setVisibility(View.VISIBLE);
+                mScreenshotFlash.setAlpha(0f);
+                mScreenshotFlash.setVisibility(View.VISIBLE);
+            }
+            @Override
+            public void onAnimationEnd(android.animation.Animator animation) {
+                mScreenshotFlash.setVisibility(View.GONE);
             }
         });
         anim.addUpdateListener(new AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
                 float t = ((Float) animation.getAnimatedValue()).floatValue();
-                float scaleT = (SCREENSHOT_FADE_IN_MIN_SCALE)
-                    + (float) t * (SCREENSHOT_SCALE - SCREENSHOT_FADE_IN_MIN_SCALE);
-                mBackgroundView.setAlpha(t * BACKGROUND_ALPHA);
+                float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)
+                    - (float) scaleInterpolator.getInterpolation(t)
+                        * (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE);
+                mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
+                mScreenshotContainerView.setAlpha(t);
                 mScreenshotContainerView.setScaleX(scaleT);
                 mScreenshotContainerView.setScaleY(scaleT);
-                mScreenshotContainerView.setAlpha(t);
+                mScreenshotFlash.setAlpha(flashAlphaInterpolator.getInterpolation(t));
             }
         });
         return anim;
     }
-    private ValueAnimator createScreenshotFadeOutAnimation(int w, int h, boolean statusBarVisible,
+    private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible,
             boolean navBarVisible) {
         ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
-        anim.setInterpolator(new DecelerateInterpolator(0.5f));
-        anim.setStartDelay(SCREENSHOT_FADE_OUT_DELAY);
+        anim.setStartDelay(SCREENSHOT_DROP_OUT_DELAY);
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -482,54 +509,58 @@
 
         if (!statusBarVisible || !navBarVisible) {
             // There is no status bar/nav bar, so just fade the screenshot away in place
-            anim.setDuration(SCREENSHOT_FAST_FADE_OUT_DURATION);
+            anim.setDuration(SCREENSHOT_FAST_DROP_OUT_DURATION);
             anim.addUpdateListener(new AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
                     float t = ((Float) animation.getAnimatedValue()).floatValue();
-                    float scaleT = (SCREENSHOT_FADE_OUT_MIN_SCALE)
-                            + (float) (1f - t) * (SCREENSHOT_SCALE - SCREENSHOT_FADE_OUT_MIN_SCALE);
+                    float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
+                            - (float) t * (SCREENSHOT_DROP_IN_MIN_SCALE
+                                    - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);
                     mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
-                    mScreenshotContainerView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+                    mScreenshotContainerView.setAlpha(1f - t);
                     mScreenshotContainerView.setScaleX(scaleT);
                     mScreenshotContainerView.setScaleY(scaleT);
                 }
             });
         } else {
+            // In the case where there is a status bar, animate to the origin of the bar (top-left)
+            final float scaleDurationPct = (float) SCREENSHOT_DROP_OUT_SCALE_DURATION
+                    / SCREENSHOT_DROP_OUT_DURATION;
+            final Interpolator scaleInterpolator = new Interpolator() {
+                @Override
+                public float getInterpolation(float x) {
+                    if (x < scaleDurationPct) {
+                        // Decelerate, and scale the input accordingly
+                        return (float) (1f - Math.pow(1f - (x / scaleDurationPct), 2f));
+                    }
+                    return 1f;
+                }
+            };
+
             // Determine the bounds of how to scale
             float halfScreenWidth = (w - 2f * mBgPadding) / 2f;
             float halfScreenHeight = (h - 2f * mBgPadding) / 2f;
-            final RectF finalBounds = new RectF(mDropOffsetX, mDropOffsetY,
-                    mDropOffsetX + mStatusBarIconSize,
-                    mDropOffsetY + mStatusBarIconSize);
-            final PointF currentPos = new PointF(0f, 0f);
-            final PointF finalPos = new PointF(-halfScreenWidth + finalBounds.centerX(),
-                    -halfScreenHeight + finalBounds.centerY());
-            final DecelerateInterpolator d = new DecelerateInterpolator(2f);
-            // Note: since the scale origin is in the center of the view, divide difference by 2
-            float tmpMinScale = 0f;
-            if (w > h) {
-                tmpMinScale = finalBounds.width() / (2f * w);
-            } else {
-                tmpMinScale = finalBounds.height() / (2f * h);
-            }
-            final float minScale = tmpMinScale;
+            final float offsetPct = SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET;
+            final PointF finalPos = new PointF(
+                -halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth,
+                -halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight);
 
             // Animate the screenshot to the status bar
-            anim.setDuration(SCREENSHOT_FADE_OUT_DURATION);
+            anim.setDuration(SCREENSHOT_DROP_OUT_DURATION);
             anim.addUpdateListener(new AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
                     float t = ((Float) animation.getAnimatedValue()).floatValue();
-                    float scaleT = minScale
-                            + (float) (1f - t) * (SCREENSHOT_SCALE - minScale - mBgPaddingScale)
-                            + mBgPaddingScale;
-                    mScreenshotContainerView.setAlpha(d.getInterpolation(1f - t));
-                    mScreenshotContainerView.setTranslationX(d.getInterpolation(t) * finalPos.x);
-                    mScreenshotContainerView.setTranslationY(d.getInterpolation(t) * finalPos.y);
+                    float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
+                        - (float) scaleInterpolator.getInterpolation(t)
+                            * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_DROP_OUT_MIN_SCALE);
+                    mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+                    mScreenshotContainerView.setAlpha(1f - scaleInterpolator.getInterpolation(t));
                     mScreenshotContainerView.setScaleX(scaleT);
                     mScreenshotContainerView.setScaleY(scaleT);
-                    mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+                    mScreenshotContainerView.setTranslationX(t * finalPos.x);
+                    mScreenshotContainerView.setTranslationY(t * finalPos.y);
                 }
             });
         }
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 994201b..99dcd9b 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -264,7 +264,7 @@
     // could be either static or controllable at runtime
     private static final boolean mSpew = false;
     private static final boolean mDebugProximitySensor = (false || mSpew);
-    private static final boolean mDebugLightSensor = (false || mSpew);
+    private static final boolean mDebugLightSensor = (true || mSpew);
     
     private native void nativeInit();
     private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index a0e28ed..7fa404e 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -102,7 +102,7 @@
      * everytime the wallpaper is changed.
      */
     private final FileObserver mWallpaperObserver = new FileObserver(
-            WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE | DELETE | DELETE_SELF) {
+            WALLPAPER_DIR.getAbsolutePath(), CLOSE_WRITE | DELETE | DELETE_SELF) {
                 @Override
                 public void onEvent(int event, String path) {
                     if (path == null) {
@@ -118,8 +118,11 @@
                         File changedFile = new File(WALLPAPER_DIR, path);
                         if (WALLPAPER_FILE.equals(changedFile)) {
                             notifyCallbacksLocked();
-                            if (mWallpaperComponent == null || mImageWallpaperPending) {
-                                mImageWallpaperPending = false;
+                            if (mWallpaperComponent == null || event != CLOSE_WRITE
+                                    || mImageWallpaperPending) {
+                                if (event == CLOSE_WRITE) {
+                                    mImageWallpaperPending = false;
+                                }
                                 bindWallpaperComponentLocked(mImageWallpaperComponent,
                                         true, false);
                                 saveSettingsLocked();
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 28552f6..d3b0dbf 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -284,8 +284,8 @@
         glMatrixMode(GL_TEXTURE);
         glLoadMatrixf(mTextureMatrix);
         glMatrixMode(GL_MODELVIEW);
-        glEnable(GL_TEXTURE_EXTERNAL_OES);
         glDisable(GL_TEXTURE_2D);
+        glEnable(GL_TEXTURE_EXTERNAL_OES);
     } else {
         glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
         glMatrixMode(GL_TEXTURE);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index dc47a03..e869ba2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -742,6 +742,8 @@
         }
 
     unlockPageFlip(currentLayers);
+
+    mDirtyRegion.orSelf(getAndClearInvalidateRegion());
     mDirtyRegion.andSelf(screenRegion);
 }
 
@@ -1716,12 +1718,24 @@
 }
 
 void SurfaceFlinger::repaintEverything() {
-    Mutex::Autolock _l(mStateLock);
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    mDirtyRegion.set(hw.bounds());
+    const Rect bounds(hw.getBounds());
+    setInvalidateRegion(Region(bounds));
     signalEvent();
 }
 
+void SurfaceFlinger::setInvalidateRegion(const Region& reg) {
+    Mutex::Autolock _l(mInvalidateLock);
+    mInvalidateRegion = reg;
+}
+
+Region SurfaceFlinger::getAndClearInvalidateRegion() {
+    Mutex::Autolock _l(mInvalidateLock);
+    Region reg(mInvalidateRegion);
+    mInvalidateRegion.clear();
+    return reg;
+}
+
 // ---------------------------------------------------------------------------
 
 status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1490dec..ea5bfa7 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -303,6 +303,9 @@
             void        composeSurfaces(const Region& dirty);
 
 
+            void        setInvalidateRegion(const Region& reg);
+            Region      getAndClearInvalidateRegion();
+
             ssize_t     addClientLayer(const sp<Client>& client,
                     const sp<LayerBaseClient>& lbc);
             status_t    addLayer_l(const sp<LayerBase>& layer);
@@ -348,6 +351,10 @@
                 bool                        mLayersRemoved;
                 DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayerMap;
 
+                // access must be protected by mInvalidateLock
+    mutable     Mutex                       mInvalidateLock;
+                Region                      mInvalidateRegion;
+
                 // constant members (no synchronization needed for access)
                 sp<IMemoryHeap>             mServerHeap;
                 surface_flinger_cblk_t*     mServerCblk;