Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 949b05db authored by Aurimas Liutikas's avatar Aurimas Liutikas
Browse files

Update TypedArray and TypedValue to store source layouts.

In ag/5859897 we started tracking source styles for each TypedValue.
It is also useful to keep track of source layouts if the attribute
was resolved against a layout (attribute set in XML layout inside
of <View> tag).

Test: atest CtsContentTestCases:android.content.res.cts.TypedArrayTest
Bug: 111439551
Change-Id: Ie6bc6ecd9a22b536a2f3288263b896f9cec67d38
parent c7829fca
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -12387,7 +12387,7 @@ package android.content.res {
    method public String getPositionDescription();
    method @AnyRes public int getResourceId(@StyleableRes int, int);
    method public android.content.res.Resources getResources();
    method @StyleRes public int getSourceStyleResourceId(@StyleableRes int, @StyleRes int);
    method @StyleRes public int getSourceResourceId(@StyleableRes int, @StyleRes int);
    method @Nullable public String getString(@StyleableRes int);
    method public CharSequence getText(@StyleableRes int);
    method public CharSequence[] getTextArray(@StyleableRes int);
@@ -48534,7 +48534,7 @@ package android.util {
    field public int data;
    field public int density;
    field @AnyRes public int resourceId;
    field public int sourceStyleResourceId;
    field public int sourceResourceId;
    field public CharSequence string;
    field public int type;
  }
+33 −10
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public class TypedArray {
    static final int STYLE_RESOURCE_ID = 3;
    static final int STYLE_CHANGING_CONFIGURATIONS = 4;
    static final int STYLE_DENSITY = 5;
    static final int SYTLE_SOURCE_STYLE_RESOURCE_ID = 6;
    static final int SYTLE_SOURCE_RESOURCE_ID = 6;

    @UnsupportedAppUsage
    private final Resources mResources;
@@ -1101,28 +1101,51 @@ public class TypedArray {
    }

    /**
     * Returns the resource ID of the style against which the specified attribute was resolved,
     * otherwise returns defValue.
     * Returns the resource ID of the style or layout against which the specified attribute was
     * resolved, otherwise returns defValue.
     *
     * For example, if you we resolving two attributes {@code android:attribute1} and
     * {@code android:attribute2} and you were inflating a {@link android.view.View} from
     * {@code layout/my_layout.xml}:
     * <pre>
     *     &lt;View
     *         style="@style/viewStyle"
     *         android:layout_width="wrap_content"
     *         android:layout_height="wrap_content"
     *         android:attribute1="foo"/&gt;
     * </pre>
     *
     * and {@code @style/viewStyle} is:
     * <pre>
     *     &lt;style android:name="viewStyle"&gt;
     *         &lt;item name="android:attribute2"&gt;bar&lt;item/&gt;
     *     &lt;style/&gt;
     * </pre>
     *
     * then resolved {@link TypedArray} will have values that return source resource ID of
     * {@code R.layout.my_layout} for {@code android:attribute1} and {@code R.style.viewStyle} for
     * {@code android:attribute2}.
     *
     * @param index Index of attribute whose source style to retrieve.
     * @param defValue Value to return if the attribute is not defined or
     * @param defaultValue Value to return if the attribute is not defined or
     *                     not a resource.
     *
     * @return Attribute source style resource ID or defValue if it was not resolved in any style.
     * @return Either a style resource ID, layout resource ID, or defaultValue if it was not
     * resolved in a style or layout.
     * @throws RuntimeException if the TypedArray has already been recycled.
     */
    @StyleRes
    public int getSourceStyleResourceId(@StyleableRes int index, @StyleRes int defValue) {
    public int getSourceResourceId(@StyleableRes int index, @StyleRes int defaultValue) {
        if (mRecycled) {
            throw new RuntimeException("Cannot make calls to a recycled instance!");
        }

        index *= STYLE_NUM_ENTRIES;
        final int resid = mData[index + SYTLE_SOURCE_STYLE_RESOURCE_ID];
        final int resid = mData[index + SYTLE_SOURCE_RESOURCE_ID];
        if (resid != 0) {
            return resid;
        }
        return defValue;
        return defaultValue;
    }

    /**
@@ -1337,7 +1360,7 @@ public class TypedArray {
                data[index + STYLE_CHANGING_CONFIGURATIONS]);
        outValue.density = data[index + STYLE_DENSITY];
        outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
        outValue.sourceStyleResourceId = data[index + SYTLE_SOURCE_STYLE_RESOURCE_ID];
        outValue.sourceResourceId = data[index + SYTLE_SOURCE_RESOURCE_ID];
        return true;
    }

+6 −6
Original line number Diff line number Diff line
@@ -82,23 +82,22 @@ final class XmlBlock implements AutoCloseable {
    public XmlResourceParser newParser(@AnyRes int resId) {
        synchronized (this) {
            if (mNative != 0) {
                return new Parser(nativeCreateParseState(mNative), this, resId);
                return new Parser(nativeCreateParseState(mNative, resId), this);
            }
            return null;
        }
    }

    /*package*/ final class Parser implements XmlResourceParser {
        Parser(long parseState, XmlBlock block, @AnyRes int sourceResId) {
        Parser(long parseState, XmlBlock block) {
            mParseState = parseState;
            mBlock = block;
            block.mOpenCount++;
            mSourceResId = sourceResId;
        }

        @AnyRes
        public int getSourceResId() {
            return mSourceResId;
            return nativeGetSourceResId(mParseState);
        }

        public void setFeature(String name, boolean state) throws XmlPullParserException {
@@ -486,7 +485,6 @@ final class XmlBlock implements AutoCloseable {
        private boolean mDecNextDepth = false;
        private int mDepth = 0;
        private int mEventType = START_DOCUMENT;
        private @AnyRes int mSourceResId;
    }

    protected void finalize() throws Throwable {
@@ -515,7 +513,7 @@ final class XmlBlock implements AutoCloseable {
                                                 int offset,
                                                 int size);
    private static final native long nativeGetStringBlock(long obj);
    private static final native long nativeCreateParseState(long obj);
    private static final native long nativeCreateParseState(long obj, int resId);
    private static final native void nativeDestroyParseState(long state);
    private static final native void nativeDestroy(long obj);

@@ -553,4 +551,6 @@ final class XmlBlock implements AutoCloseable {
    private static final native int nativeGetStyleAttribute(long state);
    @FastNative
    private static final native int nativeGetAttributeIndex(long state, String namespace, String name);
    @FastNative
    private static final native int nativeGetSourceResId(long state);
}
+3 −3
Original line number Diff line number Diff line
@@ -217,10 +217,10 @@ public class TypedValue {
    public int density;

    /**
     * If the Value came from a style resource, this holds the corresponding style resource id
     * against which the attribute was resolved.
     * If the Value came from a style resource or a layout resource (set in an XML layout), this
     * holds the corresponding style or layout resource id against which the attribute was resolved.
     */
    public int sourceStyleResourceId;
    public int sourceResourceId;

    /* ------------------------------------------------------------ */

+16 −2
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ static jlong android_content_XmlBlock_nativeGetStringBlock(JNIEnv* env, jobject
}

static jlong android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobject clazz,
                                                          jlong token)
                                                          jlong token, jint res_id)
{
    ResXMLTree* osb = reinterpret_cast<ResXMLTree*>(token);
    if (osb == NULL) {
@@ -81,6 +81,7 @@ static jlong android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobjec
    }

    ResXMLParser* st = new ResXMLParser(*osb);
    st->setSourceResourceId(res_id);
    if (st == NULL) {
        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        return 0;
@@ -335,6 +336,17 @@ static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobjec
        ? value.data : 0;
}

static jint android_content_XmlBlock_nativeGetSourceResId(JNIEnv* env, jobject clazz,
                                                          jlong token)
{
    ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token);
    if (st == NULL) {
        return 0;
    } else {
        return st->getSourceResourceId();
    }
}

static void android_content_XmlBlock_nativeDestroyParseState(JNIEnv* env, jobject clazz,
                                                          jlong token)
{
@@ -370,7 +382,7 @@ static const JNINativeMethod gXmlBlockMethods[] = {
            (void*) android_content_XmlBlock_nativeCreate },
    { "nativeGetStringBlock",       "(J)J",
            (void*) android_content_XmlBlock_nativeGetStringBlock },
    { "nativeCreateParseState",     "(J)J",
    { "nativeCreateParseState",     "(JI)J",
            (void*) android_content_XmlBlock_nativeCreateParseState },
    { "nativeDestroyParseState",    "(J)V",
            (void*) android_content_XmlBlock_nativeDestroyParseState },
@@ -411,6 +423,8 @@ static const JNINativeMethod gXmlBlockMethods[] = {
            (void*) android_content_XmlBlock_nativeGetClassAttribute },
    { "nativeGetStyleAttribute",   "(J)I",
            (void*) android_content_XmlBlock_nativeGetStyleAttribute },
    { "nativeGetSourceResId",      "(J)I",
            (void*) android_content_XmlBlock_nativeGetSourceResId},
};

int register_android_content_XmlBlock(JNIEnv* env)
Loading