Merge "Account for the _ADRENO constant being moved."
diff --git a/api/current.xml b/api/current.xml
index d935c38..54ba4a3 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -20080,6 +20080,17 @@
  visibility="public"
 >
 </method>
+<method name="getDuration"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getFrameDelay"
  return="long"
  abstract="false"
@@ -20091,6 +20102,17 @@
  visibility="public"
 >
 </method>
+<method name="getInterpolator"
+ return="android.view.animation.Interpolator"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getRepeatCount"
  return="int"
  abstract="false"
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 951d104..385e75d 100755
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.util.AttributeSet;
 import android.view.animation.AccelerateDecelerateInterpolator;
@@ -197,15 +198,13 @@
     /**
      * The property/value sets being animated.
      */
-    HashMap<String, PropertyValuesHolder> mValues;
+    PropertyValuesHolder[] mValues;
 
     /**
-     * This value is used in the simple/common case of animating just one value; the user
-     * may call getAnimatedValue(), which should return the value of the first (and only)
-     * ProeprtyValuesHolder animated value, which is looked up using this string.
+     * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values
+     * by property name during calls to getAnimatedValue(String).
      */
-    String mFirstPropertyName;
-
+    HashMap<String, PropertyValuesHolder> mValuesMap;
 
     /**
      * The type of the values, as determined by the valueFrom/valueTo properties.
@@ -290,11 +289,11 @@
                 break;
         }
 
-        mValues = new HashMap<String, PropertyValuesHolder>(1);
-        mFirstPropertyName = "";
-        PropertyValuesHolder valuesHolder = new PropertyValuesHolder(mFirstPropertyName,
-                valueFrom, valueTo);
-        mValues.put(mFirstPropertyName, valuesHolder);
+        PropertyValuesHolder valuesHolder = new PropertyValuesHolder("", valueFrom, valueTo);
+        mValues = new PropertyValuesHolder[1];
+        mValues[0] = valuesHolder;
+        mValuesMap = new HashMap<String, PropertyValuesHolder>(1);
+        mValuesMap.put("", valuesHolder);
 
         mRepeatCount = a.getInt(com.android.internal.R.styleable.Animator_repeatCount, mRepeatCount);
         mRepeatMode = a.getInt(com.android.internal.R.styleable.Animator_repeatMode, RESTART);
@@ -323,15 +322,11 @@
 
     public void setValues(PropertyValuesHolder... values) {
         int numValues = values.length;
-        mValues = new HashMap<String, PropertyValuesHolder>(numValues);
+        mValues = values;
+        mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
         for (int i = 0; i < numValues; ++i) {
             PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
-            mValues.put(valuesHolder.getPropertyName(), valuesHolder);
-        }
-        if (numValues > 0 && values[0] != null) {
-            mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
-        } else {
-            mFirstPropertyName = "";
+            mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
         }
     }
 
@@ -348,26 +343,12 @@
      * @param values The set of values to animate between.
      */
     public void setValues(T... values) {
-        if (values[0] instanceof PropertyValuesHolder) {
-            int numValues = values.length;
-            mValues = new HashMap<String, PropertyValuesHolder>(numValues);
-            for (int i = 0; i < numValues; ++i) {
-                PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
-                mValues.put(valuesHolder.getPropertyName(), valuesHolder);
-            }
-            if (numValues > 0 && values[0] != null) {
-                mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
-            } else {
-                mFirstPropertyName = "";
-            }
+        if (mValues == null || mValues.length == 0) {
+            setValues(new PropertyValuesHolder[]{
+                    new PropertyValuesHolder("", (Object[])values)});
         } else {
-            if (mValues == null) {
-                setValues(new PropertyValuesHolder[]{
-                        new PropertyValuesHolder("", (Object[])values)});
-            } else {
-                PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
-                valuesHolder.setValues(values);
-            }
+            PropertyValuesHolder valuesHolder = mValues[0];
+            valuesHolder.setValues(values);
         }
     }
 
@@ -382,8 +363,9 @@
      *  that internal mechanisms for the animation are set up correctly.</p>
      */
     void initAnimation() {
-        for (PropertyValuesHolder pvHolder: mValues.values()) {
-            pvHolder.init();
+        int numValues = mValues.length;
+        for (int i = 0; i < numValues; ++i) {
+            mValues[i].init();
         }
         mCurrentIteration = 0;
         mInitialized = true;
@@ -394,8 +376,8 @@
      * be between 0 and the total duration of the animation, including any repetition. If
      * the animation has not yet been started, then it will not advance forward after it is
      * set to this time; it will simply set the time to this value and perform any appropriate
-     * actions based on that time. If the animation is already running, then seek() will
-     * set the current playing time to this value and continue playing from that point.
+     * actions based on that time. If the animation is already running, then setCurrentPlayTime()
+     * will set the current playing time to this value and continue playing from that point.
      *
      * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
      */
@@ -587,7 +569,11 @@
      * returns the animated value for the first of those objects.
      */
     public Object getAnimatedValue() {
-        return getAnimatedValue(mFirstPropertyName);
+        if (mValues != null && mValues.length > 0) {
+            return mValues[0].getAnimatedValue();
+        }
+        // Shouldn't get here; should always have values unless Animator was set up wrong
+        return null;
     }
 
     /**
@@ -601,7 +587,13 @@
      * by this <code>Animator</code>.
      */
     public Object getAnimatedValue(String propertyName) {
-        return mValues.get(mFirstPropertyName).getAnimatedValue();
+        PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
+        if (valuesHolder != null) {
+            return valuesHolder.getAnimatedValue();
+        } else {
+            // At least avoid crashing if called with bogus propertyName
+            return null;
+        }
     }
 
     /**
@@ -691,6 +683,15 @@
     }
 
     /**
+     * Returns the timing interpolator that this Animator uses.
+     *
+     * @return The timing interpolator for this Animator.
+     */
+    public Interpolator getInterpolator() {
+        return mInterpolator;
+    }
+
+    /**
      * The type evaluator to be used when calculating the animated values of this animation.
      * The system will automatically assign a float, int, or double evaluator based on the type
      * of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values
@@ -707,8 +708,8 @@
      * @param value the evaluator to be used this animation
      */
     public void setEvaluator(TypeEvaluator value) {
-        if (value != null && mValues != null) {
-            mValues.get(mFirstPropertyName).setEvaluator(value);
+        if (value != null && mValues != null && mValues.length > 0) {
+            mValues[0].setEvaluator(value);
         }
     }
 
@@ -720,6 +721,10 @@
      * @param playBackwards Whether the Animator should start playing in reverse.
      */
     private void start(boolean playBackwards) {
+        if ((mStartDelay == 0) && (Thread.currentThread() == Looper.getMainLooper().getThread())) {
+            // This sets the initial value of the animation, prior to actually starting it running
+            setCurrentPlayTime(getCurrentPlayTime());
+        }
         mPlayingBackwards = playBackwards;
         mPlayingState = STOPPED;
         sPendingAnimations.add(this);
@@ -731,6 +736,15 @@
         sAnimationHandler.sendEmptyMessage(ANIMATION_START);
     }
 
+    /**
+     * Returns the duration that this animation will run for.
+     *
+     * @return The length in time of the animation, in milliseconds.
+     */
+    public long getDuration() {
+        return mDuration;
+    }
+
     @Override
     public void start() {
         start(false);
@@ -928,8 +942,9 @@
      */
     void animateValue(float fraction) {
         fraction = mInterpolator.getInterpolation(fraction);
-        for (PropertyValuesHolder valuesHolder : mValues.values()) {
-            valuesHolder.calculateValue(fraction);
+        int numValues = mValues.length;
+        for (int i = 0; i < numValues; ++i) {
+            mValues[i].calculateValue(fraction);
         }
         if (mUpdateListeners != null) {
             int numListeners = mUpdateListeners.size();
diff --git a/core/java/android/animation/PropertyAnimator.java b/core/java/android/animation/PropertyAnimator.java
index 9366a71..1a010a9 100644
--- a/core/java/android/animation/PropertyAnimator.java
+++ b/core/java/android/animation/PropertyAnimator.java
@@ -21,10 +21,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 /**
  * This subclass of {@link Animator} provides support for animating properties on target objects.
@@ -61,10 +58,12 @@
      */
     public void setPropertyName(String propertyName) {
         if (mValues != null) {
-            // should always be the case
-            PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
+            // mValues should always be non-null
+            PropertyValuesHolder valuesHolder = mValues[0];
+            String oldName = valuesHolder.getPropertyName();
             valuesHolder.setPropertyName(propertyName);
-            mFirstPropertyName = propertyName;
+            mValuesMap.remove(oldName);
+            mValuesMap.put(propertyName, valuesHolder);
         }
         mPropertyName = propertyName;
     }
@@ -184,8 +183,9 @@
     @Override
     void initAnimation() {
         super.initAnimation();
-        for (PropertyValuesHolder valuesHolder : mValues.values()) {
-            valuesHolder.setupSetterAndGetter(mTarget);
+        int numValues = mValues.length;
+        for (int i = 0; i < numValues; ++i) {
+            mValues[i].setupSetterAndGetter(mTarget);
         }
     }
 
@@ -223,8 +223,9 @@
     @Override
     void animateValue(float fraction) {
         super.animateValue(fraction);
-        for (PropertyValuesHolder valuesHolder : mValues.values()) {
-            valuesHolder.setAnimatedValue(mTarget);
+        int numValues = mValues.length;
+        for (int i = 0; i < numValues; ++i) {
+            mValues[i].setAnimatedValue(mTarget);
         }
     }
 }
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 05e0bc1..fc829b8 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -261,11 +261,12 @@
                     // Swallow the error and keep trying other variants
                 }
             }
+            // If we got here, then no appropriate function was found
+            Log.e("PropertyValuesHolder",
+                    "Couldn't find setter/getter for property " + mPropertyName +
+                            "with value type "+ mValueType);
         }
-        // If we got here, then no appropriate function was found
-        Log.e("PropertyValuesHolder",
-                "Couldn't find setter/getter for property " + mPropertyName +
-                        "with value type "+ mValueType);
+
         return returnVal;
     }
 
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 0c9bab2..c8381c9 100644
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -261,6 +261,10 @@
     public static final int PROFILE_OPP = 2;
     /** @hide */
     public static final int PROFILE_HID = 3;
+    /** @hide */
+    public static final int PROFILE_PANU = 4;
+    /** @hide */
+    public static final int PROFILE_NAP = 5;
 
     /**
      * Check class bits for possible bluetooth profile support.
@@ -328,6 +332,12 @@
             }
         } else if (profile == PROFILE_HID) {
             return (getDeviceClass() & Device.Major.PERIPHERAL) == Device.Major.PERIPHERAL;
+        } else if (profile == PROFILE_PANU || profile == PROFILE_NAP){
+            // No good way to distinguish between the two, based on class bits.
+            if (hasService(Service.NETWORKING)) {
+                return true;
+            }
+            return (getDeviceClass() & Device.Major.NETWORKING) == Device.Major.NETWORKING;
         } else {
             return false;
         }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 4741b1d..b39157e 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -146,29 +146,36 @@
 
 static const CodecInfo kDecoderInfo[] = {
     { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
+    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.Nvidia.mp3.decoder" },
 //    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
     { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
 //    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
 //    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" },
     { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
 //    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amrwb.decoder" },
     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
 //    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
+    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.Nvidia.aac.decoder" },
     { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
     { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" },
 //    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
     { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" },
     { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.decoder.mpeg4" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
     { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" },
 //    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" },
     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" },
     { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
     { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" },
 //    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
@@ -199,6 +206,7 @@
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.encoder" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" },
 //    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
 };
@@ -337,6 +345,13 @@
 uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
     uint32_t quirks = 0;
 
+    if (!strcmp(componentName, "OMX.Nvidia.amr.decoder") ||
+         !strcmp(componentName, "OMX.Nvidia.amrwb.decoder") ||
+         !strcmp(componentName, "OMX.Nvidia.aac.decoder") ||
+         !strcmp(componentName, "OMX.Nvidia.mp3.decoder")) {
+        quirks |= kDecoderLiesAboutNumberOfChannels;
+    }
+
     if (!strcmp(componentName, "OMX.PV.avcdec")) {
         quirks |= kWantsNALFragments;
     }
@@ -854,6 +869,10 @@
     OMX_COLOR_FORMATTYPE colorFormat;
     CHECK_EQ(OK, findTargetColorFormat(meta, &colorFormat));
 
+    if (!strcasecmp("OMX.Nvidia.h264.encoder", mComponentName)) {
+        colorFormat = OMX_COLOR_FormatYUV420Planar;
+    }
+
     status_t err;
     OMX_PARAM_PORTDEFINITIONTYPE def;
     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
@@ -1193,6 +1212,10 @@
     h264type.bMBAFF = OMX_FALSE;
     h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
 
+    if (!strcasecmp("OMX.Nvidia.h264.encoder", mComponentName)) {
+        h264type.eLevel = OMX_VIDEO_AVCLevelMax;
+    }
+
     err = mOMX->setParameter(
             mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
     CHECK_EQ(err, OK);