Merge "Don't double-cancel the active ripple" into lmp-dev
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 645f7df..c7773ad 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -400,6 +400,8 @@
                 return csl.getDefaultColor();
             }
             return defValue;
+        } else if (type == TypedValue.TYPE_ATTRIBUTE) {
+            throw new RuntimeException("Failed to resolve attribute at index " + index);
         }
 
         throw new UnsupportedOperationException("Can't convert to color: type=0x"
@@ -422,6 +424,9 @@
 
         final TypedValue value = mValue;
         if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
+            if (value.type == TypedValue.TYPE_ATTRIBUTE) {
+                throw new RuntimeException("Failed to resolve attribute at index " + index);
+            }
             return mResources.loadColorStateList(value, value.resourceId);
         }
         return null;
@@ -449,6 +454,8 @@
         } else if (type >= TypedValue.TYPE_FIRST_INT
             && type <= TypedValue.TYPE_LAST_INT) {
             return data[index+AssetManager.STYLE_DATA];
+        } else if (type == TypedValue.TYPE_ATTRIBUTE) {
+            throw new RuntimeException("Failed to resolve attribute at index " + index);
         }
 
         throw new UnsupportedOperationException("Can't convert to integer: type=0x"
@@ -484,6 +491,8 @@
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimension(
                 data[index+AssetManager.STYLE_DATA], mMetrics);
+        } else if (type == TypedValue.TYPE_ATTRIBUTE) {
+            throw new RuntimeException("Failed to resolve attribute at index " + index);
         }
 
         throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
@@ -520,6 +529,8 @@
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimensionPixelOffset(
                 data[index+AssetManager.STYLE_DATA], mMetrics);
+        } else if (type == TypedValue.TYPE_ATTRIBUTE) {
+            throw new RuntimeException("Failed to resolve attribute at index " + index);
         }
 
         throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
@@ -557,6 +568,8 @@
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimensionPixelSize(
                 data[index+AssetManager.STYLE_DATA], mMetrics);
+        } else if (type == TypedValue.TYPE_ATTRIBUTE) {
+            throw new RuntimeException("Failed to resolve attribute at index " + index);
         }
 
         throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
@@ -589,6 +602,8 @@
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimensionPixelSize(
                 data[index+AssetManager.STYLE_DATA], mMetrics);
+        } else if (type == TypedValue.TYPE_ATTRIBUTE) {
+            throw new RuntimeException("Failed to resolve attribute at index " + index);
         }
 
         throw new RuntimeException(getPositionDescription()
@@ -655,6 +670,8 @@
         } else if (type == TypedValue.TYPE_FRACTION) {
             return TypedValue.complexToFraction(
                 data[index+AssetManager.STYLE_DATA], base, pbase);
+        } else if (type == TypedValue.TYPE_ATTRIBUTE) {
+            throw new RuntimeException("Failed to resolve attribute at index " + index);
         }
 
         throw new UnsupportedOperationException("Can't convert to fraction: type=0x"
@@ -692,33 +709,7 @@
     }
 
     /**
-     * Retrieve the theme attribute resource identifier for the attribute at
-     * <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or not a
-     *            resource.
-     * @return Theme attribute resource identifier, or defValue if not defined.
-     * @hide
-     */
-    public int getThemeAttributeId(int index, int defValue) {
-        if (mRecycled) {
-            throw new RuntimeException("Cannot make calls to a recycled instance!");
-        }
-
-        index *= AssetManager.STYLE_NUM_ENTRIES;
-        final int[] data = mData;
-        if (data[index + AssetManager.STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
-            return data[index + AssetManager.STYLE_DATA];
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the Drawable for the attribute at <var>index</var>.  This
-     * gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getDrawable Resources.getDrawable} of the owning
-     * Resources object to retrieve its Drawable.
+     * Retrieve the Drawable for the attribute at <var>index</var>.
      *
      * @param index Index of attribute to retrieve.
      *
@@ -731,14 +722,8 @@
 
         final TypedValue value = mValue;
         if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
-            if (false) {
-                System.out.println("******************************************************************");
-                System.out.println("Got drawable resource: type="
-                                   + value.type
-                                   + " str=" + value.string
-                                   + " int=0x" + Integer.toHexString(value.data)
-                                   + " cookie=" + value.assetCookie);
-                System.out.println("******************************************************************");
+            if (value.type == TypedValue.TYPE_ATTRIBUTE) {
+                throw new RuntimeException("Failed to resolve attribute at index " + index);
             }
             return mResources.loadDrawable(value, value.resourceId, mTheme);
         }
@@ -762,15 +747,6 @@
 
         final TypedValue value = mValue;
         if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
-            if (false) {
-                System.out.println("******************************************************************");
-                System.out.println("Got drawable resource: type="
-                                   + value.type
-                                   + " str=" + value.string
-                                   + " int=0x" + Integer.toHexString(value.data)
-                                   + " cookie=" + value.assetCookie);
-                System.out.println("******************************************************************");
-            }
             return mResources.getTextArray(value.resourceId);
         }
         return null;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 73a4da5..d05cabc 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -88,6 +88,8 @@
         return true;
     }
 
+    ATRACE_NAME("resizeLayer");
+
     const uint32_t maxTextureSize = caches.maxTextureSize;
     if (desiredWidth > maxTextureSize || desiredHeight > maxTextureSize) {
         ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index a92ef94..e3b0daf 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "OpenGLRenderer"
+#define ATRACE_TAG ATRACE_TAG_VIEW
 
 #include <ui/Rect.h>
 
@@ -184,6 +185,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height) {
+    ATRACE_CALL();
     LAYER_RENDERER_LOGD("Requesting new render layer %dx%d", width, height);
 
     Caches& caches = Caches::getInstance();
@@ -309,6 +311,7 @@
 
 void LayerRenderer::destroyLayer(Layer* layer) {
     if (layer) {
+        ATRACE_CALL();
         LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
                 layer->getWidth(), layer->getHeight(), layer->getFbo());
 
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index ec9e30a..3b8a9a4 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "OpenGLRenderer"
+#define ATRACE_TAG ATRACE_TAG_VIEW
 
 #include <GLES2/gl2.h>
 
@@ -265,6 +266,8 @@
         return;
     }
 
+    ATRACE_CALL();
+
     // We could also enable mipmapping if both bitmap dimensions are powers
     // of 2 but we'd have to deal with size changes. Let's keep this simple
     const bool canMipMap = Extensions::getInstance().hasNPot();
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1116127..ac63ea6 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3146,18 +3146,18 @@
          * Callback method called upon audio port list update.
          * @param portList the updated list of audio ports
          */
-        public void OnAudioPortListUpdate(AudioPort[] portList);
+        public void onAudioPortListUpdate(AudioPort[] portList);
 
         /**
          * Callback method called upon audio patch list update.
          * @param patchList the updated list of audio patches
          */
-        public void OnAudioPatchListUpdate(AudioPatch[] patchList);
+        public void onAudioPatchListUpdate(AudioPatch[] patchList);
 
         /**
          * Callback method called when the mediaserver dies
          */
-        public void OnServiceDied();
+        public void onServiceDied();
     }
 
     /**
diff --git a/media/java/android/media/AudioPortEventHandler.java b/media/java/android/media/AudioPortEventHandler.java
index d5fea07..8d2c172 100644
--- a/media/java/android/media/AudioPortEventHandler.java
+++ b/media/java/android/media/AudioPortEventHandler.java
@@ -91,7 +91,7 @@
                     case AUDIOPORT_EVENT_PORT_LIST_UPDATED:
                         AudioPort[] portList = ports.toArray(new AudioPort[0]);
                         for (int i = 0; i < listeners.size(); i++) {
-                            listeners.get(i).OnAudioPortListUpdate(portList);
+                            listeners.get(i).onAudioPortListUpdate(portList);
                         }
                         if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED) {
                             break;
@@ -101,13 +101,13 @@
                     case AUDIOPORT_EVENT_PATCH_LIST_UPDATED:
                         AudioPatch[] patchList = patches.toArray(new AudioPatch[0]);
                         for (int i = 0; i < listeners.size(); i++) {
-                            listeners.get(i).OnAudioPatchListUpdate(patchList);
+                            listeners.get(i).onAudioPatchListUpdate(patchList);
                         }
                         break;
 
                     case AUDIOPORT_EVENT_SERVICE_DIED:
                         for (int i = 0; i < listeners.size(); i++) {
-                            listeners.get(i).OnServiceDied();
+                            listeners.get(i).onServiceDied();
                         }
                         break;
 
diff --git a/tests/UsesFeature2Test/AndroidManifest.xml b/tests/UsesFeature2Test/AndroidManifest.xml
index 724d186..6b6c4da 100644
--- a/tests/UsesFeature2Test/AndroidManifest.xml
+++ b/tests/UsesFeature2Test/AndroidManifest.xml
@@ -30,6 +30,7 @@
     </feature-group>
     <feature-group android:label="@string/gamepad">
         <uses-feature android:name="android.hardware.gamepad" />
+        <uses-feature android:name="android.hardware.opengles.aep" />
     </feature-group>
 
     <application android:label="@string/app_title">
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index ac1ae70..afeb546 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -611,6 +611,8 @@
  * Represents a <feature-group> tag in the AndroidManifest.xml
  */
 struct FeatureGroup {
+    FeatureGroup() : openGLESVersion(-1) {}
+
     /**
      * Human readable label
      */
@@ -620,6 +622,11 @@
      * Explicit features defined in the group
      */
     KeyedVector<String8, bool> features;
+
+    /**
+     * OpenGL ES version required
+     */
+    int openGLESVersion;
 };
 
 static void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures,
@@ -637,6 +644,10 @@
         const KeyedVector<String8, ImpliedFeature>* impliedFeatures = NULL) {
     printf("feature-group: label='%s'\n", grp.label.string());
 
+    if (grp.openGLESVersion > 0) {
+        printf("  uses-gl-es: '0x%x'\n", grp.openGLESVersion);
+    }
+
     const size_t numFeatures = grp.features.size();
     for (size_t i = 0; i < numFeatures; i++) {
         if (!grp.features[i]) {
@@ -688,6 +699,11 @@
     } else if (name == "android.hardware.touchscreen.multitouch.distinct") {
         grp->features.add(String8("android.hardware.touchscreen.multitouch"), true);
         grp->features.add(String8("android.hardware.touchscreen"), true);
+    } else if (name == "android.hardware.opengles.aep") {
+        const int openGLESVersion31 = 0x00030001;
+        if (openGLESVersion31 > grp->openGLESVersion) {
+            grp->openGLESVersion = openGLESVersion31;
+        }
     }
 }
 
@@ -1316,14 +1332,16 @@
                             int vers = getIntegerAttribute(tree,
                                     GL_ES_VERSION_ATTR, &error);
                             if (error == "") {
-                                printf("uses-gl-es:'0x%x'\n", vers);
+                                if (vers > commonFeatures.openGLESVersion) {
+                                    commonFeatures.openGLESVersion = vers;
+                                }
                             }
                         }
                     } else if (tag == "uses-permission") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
                         if (name != "" && error == "") {
                             if (name == "android.permission.CAMERA") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.feature",
+                                addImpliedFeature(&impliedFeatures, "android.hardware.camera",
                                         String8::format("requested %s permission", name.string())
                                         .string());
                             } else if (name == "android.permission.ACCESS_FINE_LOCATION") {
@@ -1639,18 +1657,23 @@
                             }
                         }
                     } else if (withinFeatureGroup && tag == "uses-feature") {
-                        String8 name = getResolvedAttribute(&res, tree, NAME_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
-                                    error.string());
-                            goto bail;
-                        }
-
-                        int required = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
                         FeatureGroup& top = featureGroups.editTop();
-                        top.features.add(name, required);
-                        if (required) {
-                            addParentFeatures(&top, name);
+
+                        String8 name = getResolvedAttribute(&res, tree, NAME_ATTR, &error);
+                        if (name != "" && error == "") {
+                            int required = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
+                            top.features.add(name, required);
+                            if (required) {
+                                addParentFeatures(&top, name);
+                            }
+
+                        } else {
+                            int vers = getIntegerAttribute(tree, GL_ES_VERSION_ATTR, &error);
+                            if (error == "") {
+                                if (vers > top.openGLESVersion) {
+                                    top.openGLESVersion = vers;
+                                }
+                            }
                         }
                     }
                 } else if (depth == 4) {
@@ -1839,12 +1862,17 @@
                 for (size_t i = 0; i < numFeatureGroups; i++) {
                     FeatureGroup& grp = featureGroups.editItemAt(i);
 
+                    if (commonFeatures.openGLESVersion > grp.openGLESVersion) {
+                        grp.openGLESVersion = commonFeatures.openGLESVersion;
+                    }
+
                     // Merge the features defined in the top level (not inside a <feature-group>)
                     // with this feature group.
                     const size_t numCommonFeatures = commonFeatures.features.size();
                     for (size_t j = 0; j < numCommonFeatures; j++) {
                         if (grp.features.indexOfKey(commonFeatures.features.keyAt(j)) < 0) {
-                            grp.features.add(commonFeatures.features.keyAt(j), commonFeatures.features[j]);
+                            grp.features.add(commonFeatures.features.keyAt(j),
+                                    commonFeatures.features[j]);
                         }
                     }