diff --git a/core/java/android/util/TypedXmlPullParser.java b/core/java/android/util/TypedXmlPullParser.java index b3b51b54e6519..aa68bf42fe525 100644 --- a/core/java/android/util/TypedXmlPullParser.java +++ b/core/java/android/util/TypedXmlPullParser.java @@ -30,67 +30,168 @@ import org.xmlpull.v1.XmlPullParserException; */ public interface TypedXmlPullParser extends XmlPullParser { /** - * @return decoded strongly-typed {@link #getAttributeValue} - * @throws XmlPullParserException if the value is malformed or undefined + * @return index of requested attribute, otherwise {@code -1} if undefined */ - @NonNull byte[] getAttributeBytesHex(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default int getAttributeIndex(@Nullable String namespace, @NonNull String name) { + final boolean namespaceNull = (namespace == null); + final int count = getAttributeCount(); + for (int i = 0; i < count; i++) { + if ((namespaceNull || namespace.equals(getAttributeNamespace(i))) + && name.equals(getAttributeName(i))) { + return i; + } + } + return -1; + } + + /** + * @return index of requested attribute + * @throws XmlPullParserException if the value is undefined + */ + default int getAttributeIndexOrThrow(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + final int index = getAttributeIndex(namespace, name); + if (index == -1) { + throw new XmlPullParserException("Missing attribute " + name); + } else { + return index; + } + } + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + @NonNull byte[] getAttributeBytesHex(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + @NonNull byte[] getAttributeBytesBase64(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + int getAttributeInt(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + int getAttributeIntHex(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + long getAttributeLong(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + long getAttributeLongHex(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + float getAttributeFloat(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + double getAttributeDouble(int index) throws XmlPullParserException; + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed + */ + boolean getAttributeBoolean(int index) throws XmlPullParserException; /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - @NonNull byte[] getAttributeBytesBase64(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default @NonNull byte[] getAttributeBytesHex(@Nullable String namespace, + @NonNull String name) throws XmlPullParserException { + return getAttributeBytesHex(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - int getAttributeInt(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default @NonNull byte[] getAttributeBytesBase64(@Nullable String namespace, + @NonNull String name) throws XmlPullParserException { + return getAttributeBytesBase64(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - int getAttributeIntHex(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default int getAttributeInt(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + return getAttributeInt(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - long getAttributeLong(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default int getAttributeIntHex(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + return getAttributeIntHex(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - long getAttributeLongHex(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default long getAttributeLong(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + return getAttributeLong(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - float getAttributeFloat(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default long getAttributeLongHex(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + return getAttributeLongHex(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - double getAttributeDouble(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default float getAttributeFloat(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + return getAttributeFloat(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue} * @throws XmlPullParserException if the value is malformed or undefined */ - boolean getAttributeBoolean(@Nullable String namespace, @NonNull String name) - throws XmlPullParserException; + default double getAttributeDouble(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + return getAttributeDouble(getAttributeIndexOrThrow(namespace, name)); + } + + /** + * @return decoded strongly-typed {@link #getAttributeValue} + * @throws XmlPullParserException if the value is malformed or undefined + */ + default boolean getAttributeBoolean(@Nullable String namespace, @NonNull String name) + throws XmlPullParserException { + return getAttributeBoolean(getAttributeIndexOrThrow(namespace, name)); + } /** * @return decoded strongly-typed {@link #getAttributeValue}, otherwise @@ -98,8 +199,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default @Nullable byte[] getAttributeBytesHex(@Nullable String namespace, @NonNull String name, @Nullable byte[] defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeBytesHex(namespace, name); + return getAttributeBytesHex(index); } catch (Exception ignored) { return defaultValue; } @@ -111,8 +214,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default @Nullable byte[] getAttributeBytesBase64(@Nullable String namespace, @NonNull String name, @Nullable byte[] defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeBytesBase64(namespace, name); + return getAttributeBytesBase64(index); } catch (Exception ignored) { return defaultValue; } @@ -124,8 +229,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default int getAttributeInt(@Nullable String namespace, @NonNull String name, int defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeInt(namespace, name); + return getAttributeInt(index); } catch (Exception ignored) { return defaultValue; } @@ -137,8 +244,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default int getAttributeIntHex(@Nullable String namespace, @NonNull String name, int defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeIntHex(namespace, name); + return getAttributeIntHex(index); } catch (Exception ignored) { return defaultValue; } @@ -150,8 +259,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default long getAttributeLong(@Nullable String namespace, @NonNull String name, long defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeLong(namespace, name); + return getAttributeLong(index); } catch (Exception ignored) { return defaultValue; } @@ -163,8 +274,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default long getAttributeLongHex(@Nullable String namespace, @NonNull String name, long defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeLongHex(namespace, name); + return getAttributeLongHex(index); } catch (Exception ignored) { return defaultValue; } @@ -176,8 +289,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default float getAttributeFloat(@Nullable String namespace, @NonNull String name, float defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeFloat(namespace, name); + return getAttributeFloat(index); } catch (Exception ignored) { return defaultValue; } @@ -189,8 +304,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default double getAttributeDouble(@Nullable String namespace, @NonNull String name, double defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeDouble(namespace, name); + return getAttributeDouble(index); } catch (Exception ignored) { return defaultValue; } @@ -202,8 +319,10 @@ public interface TypedXmlPullParser extends XmlPullParser { */ default boolean getAttributeBoolean(@Nullable String namespace, @NonNull String name, boolean defaultValue) { + final int index = getAttributeIndex(namespace, name); + if (index == -1) return defaultValue; try { - return getAttributeBoolean(namespace, name); + return getAttributeBoolean(index); } catch (Exception ignored) { return defaultValue; } diff --git a/core/java/com/android/internal/util/BinaryXmlPullParser.java b/core/java/com/android/internal/util/BinaryXmlPullParser.java index ff7743fbe361b..68921ade30800 100644 --- a/core/java/com/android/internal/util/BinaryXmlPullParser.java +++ b/core/java/com/android/internal/util/BinaryXmlPullParser.java @@ -414,29 +414,21 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser { mAttributeCount = 0; } - /** - * Search through the pool of currently allocated {@link Attribute} - * instances for one that matches the given name. - */ - private @NonNull Attribute findAttribute(@NonNull String name) - throws XmlPullParserException { + @Override + public int getAttributeIndex(String namespace, String name) { + if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); for (int i = 0; i < mAttributeCount; i++) { if (Objects.equals(mAttributes[i].name, name)) { - return mAttributes[i]; + return i; } } - throw new XmlPullParserException("Missing attribute " + name); + return -1; } @Override public String getAttributeValue(String namespace, String name) { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - try { - return findAttribute(name).getValueString(); - } catch (XmlPullParserException e) { - // Missing attributes default to null - return null; - } + final int index = getAttributeIndex(namespace, name); + return mAttributes[index].getValueString(); } @Override @@ -445,66 +437,48 @@ public final class BinaryXmlPullParser implements TypedXmlPullParser { } @Override - public byte[] getAttributeBytesHex(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueBytesHex(); + public byte[] getAttributeBytesHex(int index) throws XmlPullParserException { + return mAttributes[index].getValueBytesHex(); } @Override - public byte[] getAttributeBytesBase64(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueBytesBase64(); + public byte[] getAttributeBytesBase64(int index) throws XmlPullParserException { + return mAttributes[index].getValueBytesBase64(); } @Override - public int getAttributeInt(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueInt(); + public int getAttributeInt(int index) throws XmlPullParserException { + return mAttributes[index].getValueInt(); } @Override - public int getAttributeIntHex(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueIntHex(); + public int getAttributeIntHex(int index) throws XmlPullParserException { + return mAttributes[index].getValueIntHex(); } @Override - public long getAttributeLong(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueLong(); + public long getAttributeLong(int index) throws XmlPullParserException { + return mAttributes[index].getValueLong(); } @Override - public long getAttributeLongHex(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueLongHex(); + public long getAttributeLongHex(int index) throws XmlPullParserException { + return mAttributes[index].getValueLongHex(); } @Override - public float getAttributeFloat(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueFloat(); + public float getAttributeFloat(int index) throws XmlPullParserException { + return mAttributes[index].getValueFloat(); } @Override - public double getAttributeDouble(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueDouble(); + public double getAttributeDouble(int index) throws XmlPullParserException { + return mAttributes[index].getValueDouble(); } @Override - public boolean getAttributeBoolean(String namespace, String name) - throws XmlPullParserException { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - return findAttribute(name).getValueBoolean(); + public boolean getAttributeBoolean(int index) throws XmlPullParserException { + return mAttributes[index].getValueBoolean(); } @Override diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java index 244efc596926d..de6b65f36eedf 100644 --- a/core/java/com/android/internal/util/XmlUtils.java +++ b/core/java/com/android/internal/util/XmlUtils.java @@ -142,95 +142,104 @@ public class XmlUtils { } @Override - public byte[] getAttributeBytesHex(String namespace, String name) + public byte[] getAttributeBytesHex(int index) throws XmlPullParserException { try { - return HexDump.hexStringToByteArray(getAttributeValue(namespace, name)); + return HexDump.hexStringToByteArray(getAttributeValue(index)); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public byte[] getAttributeBytesBase64(String namespace, String name) + public byte[] getAttributeBytesBase64(int index) throws XmlPullParserException { try { - return Base64.decode(getAttributeValue(namespace, name), Base64.NO_WRAP); + return Base64.decode(getAttributeValue(index), Base64.NO_WRAP); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public int getAttributeInt(String namespace, String name) + public int getAttributeInt(int index) throws XmlPullParserException { try { - return Integer.parseInt(getAttributeValue(namespace, name)); + return Integer.parseInt(getAttributeValue(index)); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public int getAttributeIntHex(String namespace, String name) + public int getAttributeIntHex(int index) throws XmlPullParserException { try { - return Integer.parseInt(getAttributeValue(namespace, name), 16); + return Integer.parseInt(getAttributeValue(index), 16); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public long getAttributeLong(String namespace, String name) + public long getAttributeLong(int index) throws XmlPullParserException { try { - return Long.parseLong(getAttributeValue(namespace, name)); + return Long.parseLong(getAttributeValue(index)); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public long getAttributeLongHex(String namespace, String name) + public long getAttributeLongHex(int index) throws XmlPullParserException { try { - return Long.parseLong(getAttributeValue(namespace, name), 16); + return Long.parseLong(getAttributeValue(index), 16); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public float getAttributeFloat(String namespace, String name) + public float getAttributeFloat(int index) throws XmlPullParserException { try { - return Float.parseFloat(getAttributeValue(namespace, name)); + return Float.parseFloat(getAttributeValue(index)); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public double getAttributeDouble(String namespace, String name) + public double getAttributeDouble(int index) throws XmlPullParserException { try { - return Double.parseDouble(getAttributeValue(namespace, name)); + return Double.parseDouble(getAttributeValue(index)); } catch (Exception e) { - throw new XmlPullParserException("Invalid attribute " + name + ": " + e); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + e); } } @Override - public boolean getAttributeBoolean(String namespace, String name) + public boolean getAttributeBoolean(int index) throws XmlPullParserException { - final String value = getAttributeValue(namespace, name); + final String value = getAttributeValue(index); if ("true".equalsIgnoreCase(value)) { return true; } else if ("false".equalsIgnoreCase(value)) { return false; } else { - throw new XmlPullParserException("Invalid attribute " + name + ": " + value); + throw new XmlPullParserException( + "Invalid attribute " + getAttributeName(index) + ": " + value); } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 692e97a4ad16c..10cfecf530c18 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -9180,7 +9180,16 @@ public class NotificationManagerService extends SystemService { @Override protected void readExtraAttributes(String tag, TypedXmlPullParser parser, int userId) throws IOException { - boolean userSet = parser.getAttributeBoolean(null, ATT_USER_SET, false); + // TODO: this logic looks broken, since it's trying to convert a + // list into a boolean; for now we preserve the old parsing behavior + // to avoid a performance regression, but someone should investigate + final String value = parser.getAttributeValue(null, ATT_USER_SET); + final boolean userSet; + if (TextUtils.isEmpty(value)) { + userSet = false; + } else { + userSet = Boolean.parseBoolean(value); + } setUserSet(userId, userSet); }