Merge "Implement type collapsing for Elements and Types.  Now if a user creates two or more identical objects we simply reuse the existing object rather than create a new one."
diff --git a/api/current.xml b/api/current.xml
index 1608ebf..c3a7b26 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -201496,6 +201496,19 @@
  native="false"
  synchronized="false"
  static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="color" type="int">
+</parameter>
+</method>
+<method name="setColorFilter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 39e14e4..6a79c6d 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -268,7 +268,10 @@
     char anr_traces_path[PATH_MAX];
     strlcpy(anr_traces_path, traces_path, sizeof(anr_traces_path));
     strlcat(anr_traces_path, ".anr", sizeof(anr_traces_path));
-    rename(traces_path, anr_traces_path);
+    if (rename(traces_path, anr_traces_path) && errno != ENOENT) {
+        fprintf(stderr, "rename(%s, %s): %s\n", traces_path, anr_traces_path, strerror(errno));
+        return NULL;  // Can't rename old traces.txt -- no permission? -- leave it alone instead
+    }
 
     /* create a new, empty traces.txt file to receive stack dumps */
     int fd = open(traces_path, O_CREAT | O_WRONLY | O_TRUNC, 0666);  /* -rw-rw-rw- */
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index f7cb2273..942a303 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -157,13 +157,18 @@
     long numIterationsLeft = gNumRepetitions;
     MediaSource::ReadOptions options;
 
+    int64_t sumDecodeUs = 0;
+
     while (numIterationsLeft-- > 0) {
         long numFrames = 0;
 
         MediaBuffer *buffer;
 
         for (;;) {
+            int64_t startDecodeUs = getNowUs();
             status_t err = rawSource->read(&buffer, &options);
+            int64_t delayDecodeUs = getNowUs() - startDecodeUs;
+
             options.clearSeekTo();
 
             if (err != OK) {
@@ -182,6 +187,8 @@
                 fflush(stdout);
             }
 
+            sumDecodeUs += delayDecodeUs;
+
             buffer->release();
             buffer = NULL;
 
@@ -210,6 +217,8 @@
 
     int64_t delay = getNowUs() - startTime;
     printf("avg. %.2f fps\n", n * 1E6 / delay);
+    printf("avg. time to decode one buffer %.2f usecs\n",
+           (double)sumDecodeUs / n);
 
     printf("decoded a total of %d frame(s).\n", n);
 }
diff --git a/core/java/android/backup/BackupDataInput.java b/core/java/android/backup/BackupDataInput.java
index 67d51ea..295dc66 100644
--- a/core/java/android/backup/BackupDataInput.java
+++ b/core/java/android/backup/BackupDataInput.java
@@ -133,7 +133,7 @@
 
     /**
      * Consume the current record's data without actually reading it into a buffer
-     * for further processing.  This allows a {@link android.backup.BackupAgent} to
+     * for further processing.  This allows a {@link android.app.BackupAgent} to
      * efficiently discard obsolete or otherwise uninteresting records during the
      * restore operation.
      * 
diff --git a/core/java/android/backup/RestoreSession.java b/core/java/android/backup/RestoreSession.java
index fc53854..bc410c4 100644
--- a/core/java/android/backup/RestoreSession.java
+++ b/core/java/android/backup/RestoreSession.java
@@ -63,7 +63,7 @@
      *
      * @return Zero on success; nonzero on error.  The observer will only receive
      *   progress callbacks if this method returned zero.
-     * @param token The token from {@link getAvailableRestoreSets()} corresponding to
+     * @param token The token from {@link #getAvailableRestoreSets()} corresponding to
      *   the restore set that should be used.
      * @param observer If non-null, this binder points to an object that will receive
      *   progress callbacks during the restore operation.
@@ -120,8 +120,7 @@
      * object is no longer valid.
      *
      * <p><b>Note:</b> The caller <i>must</i> invoke this method to end the restore session,
-     *   even if {@link #getAvailableRestoreSets()} or
-     *   {@link #restorePackage(long, String, RestoreObserver)} failed.
+     *   even if {@link #restorePackage(String, RestoreObserver)} failed.
      */
     public void endRestoreSession() {
         try {
diff --git a/core/java/android/gesture/Learner.java b/core/java/android/gesture/Learner.java
index 60997e0..a105652 100755
--- a/core/java/android/gesture/Learner.java
+++ b/core/java/android/gesture/Learner.java
@@ -72,7 +72,8 @@
         for (int i = 0; i < count; i++) {
             final Instance instance = instances.get(i);
             // the label can be null, as specified in Instance
-            if ((instance.label == null && name == null) || instance.label.equals(name)) {
+            if ((instance.label == null && name == null)
+                    || (instance.label != null && instance.label.equals(name))) {
                 toDelete.add(instance);
             }
         }
diff --git a/core/java/android/text/style/LeadingMarginSpan.java b/core/java/android/text/style/LeadingMarginSpan.java
index 6635ddb8..f320701 100644
--- a/core/java/android/text/style/LeadingMarginSpan.java
+++ b/core/java/android/text/style/LeadingMarginSpan.java
@@ -45,7 +45,7 @@
 
     /**
      * Renders the leading margin.  This is called before the margin has been
-     * adjusted by the value returned by {@link getLeadingMargin(boolean)}.
+     * adjusted by the value returned by {@link #getLeadingMargin(boolean)}.
      * 
      * @param c the canvas
      * @param p the paint. The this should be left unchanged on exit.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e5db120..bc49439 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3050,6 +3050,7 @@
      *
      * @param enabled True if this view is enabled, false otherwise.
      */
+    @RemotableViewMethod
     public void setEnabled(boolean enabled) {
         if (enabled == isEnabled()) return;
 
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 254efe7..a79bbee 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2364,7 +2364,16 @@
     public void draw(Canvas canvas) {
         super.draw(canvas);
         if (mFastScroller != null) {
-            mFastScroller.draw(canvas);
+            final int scrollY = mScrollY;
+            if (scrollY != 0) {
+                // Pin the fast scroll thumb to the top/bottom during overscroll.
+                int restoreCount = canvas.save();
+                canvas.translate(0, (float) scrollY);
+                mFastScroller.draw(canvas);
+                canvas.restoreToCount(restoreCount);
+            } else {
+                mFastScroller.draw(canvas);
+            }
         }
     }
 
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 3853359..233ce30 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -32,6 +32,7 @@
 import android.net.Uri;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.RemotableViewMethod;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -69,6 +70,7 @@
     private ColorFilter mColorFilter;
     private int mAlpha = 255;
     private int mViewAlphaScale = 256;
+    private boolean mColorMod = false;
 
     private Drawable mDrawable = null;
     private int[] mState = null;
@@ -138,7 +140,7 @@
 
         int tint = a.getInt(com.android.internal.R.styleable.ImageView_tint, 0);
         if (tint != 0) {
-            setColorFilter(tint, PorterDuff.Mode.SRC_ATOP);
+            setColorFilter(tint);
         }
         
         mCropToPadding = a.getBoolean(
@@ -877,6 +879,18 @@
         setColorFilter(new PorterDuffColorFilter(color, mode));
     }
 
+    /**
+     * Set a tinting option for the image. Assumes
+     * {@link PorterDuff.Mode#SRC_ATOP} blending mode.
+     *
+     * @param color Color tint to apply.
+     * @attr ref android.R.styleable#ImageView_tint
+     */
+    @RemotableViewMethod
+    public final void setColorFilter(int color) {
+        setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+    }
+
     public final void clearColorFilter() {
         setColorFilter(null);
     }
@@ -889,22 +903,29 @@
     public void setColorFilter(ColorFilter cf) {
         if (mColorFilter != cf) {
             mColorFilter = cf;
+            mColorMod = true;
             applyColorMod();
             invalidate();
         }
     }
 
+    @RemotableViewMethod
     public void setAlpha(int alpha) {
         alpha &= 0xFF;          // keep it legal
         if (mAlpha != alpha) {
             mAlpha = alpha;
+            mColorMod = true;
             applyColorMod();
             invalidate();
         }
     }
 
     private void applyColorMod() {
-        if (mDrawable != null) {
+        // Only mutate and apply when modifications have occurred. This should
+        // not reset the mColorMod flag, since these filters need to be
+        // re-applied if the Drawable is changed.
+        if (mDrawable != null && mColorMod) {
+            mDrawable = mDrawable.mutate();
             mDrawable.setColorFilter(mColorFilter);
             mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);
         }
diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java
index aee25b0..8034961 100644
--- a/core/java/android/widget/ViewFlipper.java
+++ b/core/java/android/widget/ViewFlipper.java
@@ -38,7 +38,7 @@
 @RemoteView
 public class ViewFlipper extends ViewAnimator {
     private static final String TAG = "ViewFlipper";
-    private static final boolean LOGD = true;
+    private static final boolean LOGD = false;
 
     private static final int DEFAULT_INTERVAL = 3000;
 
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index b1d588e..b94df84 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -238,7 +238,10 @@
             final int count = sets.length;
             mStateListState.mStateSets = new int[count][];
             for (int i = 0; i < count; i++) {
-                mStateListState.mStateSets[i] = sets[i].clone();
+                final int[] set = sets[i];
+                if (set != null) {
+                    mStateListState.mStateSets[i] = set.clone();
+                }
             }
             mMutated = true;
         }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 75b7b6f..6cf7cff 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -102,7 +102,6 @@
     { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
     { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
     { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
-    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
     { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index d43039d..ea0fc65 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -66,6 +66,7 @@
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -517,6 +518,9 @@
                     }
                 }
             }
+        } catch (FileNotFoundException fnf) {
+            // Probably innocuous
+            Log.v(TAG, "No ancestral data");
         } catch (IOException e) {
             Log.w(TAG, "Unable to read token file", e);
         }