From aae06631e19e4edbb25220c5175330b665ae58d0 Mon Sep 17 00:00:00 2001 From: Aurimas Liutikas Date: Wed, 30 Jan 2019 13:16:27 -0800 Subject: [PATCH] Add View#getSourceLayoutResId(). Add ability for developers to check which layout file did a given View was inflated from. Bug: 111439551 Test: atest CtsViewTestCases:android.view.cts.ViewSourceLayoutTest Change-Id: I0f2981648629d74fd576687a54a31b00cd636976 --- api/current.txt | 1 + core/java/android/content/res/Resources.java | 11 +++++++++++ .../android/content/res/ResourcesImpl.java | 14 ++++++++++++-- core/java/android/content/res/XmlBlock.java | 18 ++++++++++++++++-- core/java/android/view/View.java | 18 ++++++++++++++++++ 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/api/current.txt b/api/current.txt index 6a2c8424ef66b..97b4262b23505 100644 --- a/api/current.txt +++ b/api/current.txt @@ -50334,6 +50334,7 @@ package android.view { method public final int getScrollX(); method public final int getScrollY(); method @android.view.ViewDebug.ExportedProperty(category="drawing") @ColorInt public int getSolidColor(); + method @LayoutRes public int getSourceLayoutResId(); method public android.animation.StateListAnimator getStateListAnimator(); method protected int getSuggestedMinimumHeight(); method protected int getSuggestedMinimumWidth(); diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index baf64ad72a516..59db49e0d37e5 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1394,6 +1394,17 @@ public class Resources { mResourcesImpl.getValue(name, outValue, resolveRefs); } + + /** + * @param set AttributeSet for which we want to find the source. + * @return The resource id for the source that is backing the given AttributeSet + * @hide + */ + @AnyRes + public static int getAttributeSetSourceResId(@Nullable AttributeSet set) { + return ResourcesImpl.getAttributeSetSourceResId(set); + } + /** * This class holds the current attribute values for a particular theme. * In other words, a Theme is a set of values for resource attributes; diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index d8564d570a4d6..98980799a3652 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -15,6 +15,8 @@ */ package android.content.res; +import static android.content.res.Resources.ID_NULL; + import android.animation.Animator; import android.animation.StateListAnimator; import android.annotation.AnyRes; @@ -1222,7 +1224,7 @@ public class ResourcesImpl { for (int i = 0; i < num; i++) { if (cachedXmlBlockCookies[i] == assetCookie && cachedXmlBlockFiles[i] != null && cachedXmlBlockFiles[i].equals(file)) { - return cachedXmlBlocks[i].newParser(); + return cachedXmlBlocks[i].newParser(id); } } @@ -1239,7 +1241,7 @@ public class ResourcesImpl { cachedXmlBlockCookies[pos] = assetCookie; cachedXmlBlockFiles[pos] = file; cachedXmlBlocks[pos] = block; - return block.newParser(); + return block.newParser(id); } } } catch (Exception e) { @@ -1299,6 +1301,14 @@ public class ResourcesImpl { } } + @AnyRes + static int getAttributeSetSourceResId(@Nullable AttributeSet set) { + if (set == null) { + return ID_NULL; + } + return ((XmlBlock.Parser) set).getSourceResId(); + } + LongSparseArray getPreloadedDrawables() { return sPreloadedDrawables[0]; } diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java index 4e1159a9bce9d..d8c3ddec66f83 100644 --- a/core/java/android/content/res/XmlBlock.java +++ b/core/java/android/content/res/XmlBlock.java @@ -16,6 +16,9 @@ package android.content.res; +import static android.content.res.Resources.ID_NULL; + +import android.annotation.AnyRes; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.util.TypedValue; @@ -73,19 +76,29 @@ final class XmlBlock implements AutoCloseable { @UnsupportedAppUsage public XmlResourceParser newParser() { + return newParser(ID_NULL); + } + + public XmlResourceParser newParser(@AnyRes int resId) { synchronized (this) { if (mNative != 0) { - return new Parser(nativeCreateParseState(mNative), this); + return new Parser(nativeCreateParseState(mNative), this, resId); } return null; } } /*package*/ final class Parser implements XmlResourceParser { - Parser(long parseState, XmlBlock block) { + Parser(long parseState, XmlBlock block, @AnyRes int sourceResId) { mParseState = parseState; mBlock = block; block.mOpenCount++; + mSourceResId = sourceResId; + } + + @AnyRes + public int getSourceResId() { + return mSourceResId; } public void setFeature(String name, boolean state) throws XmlPullParserException { @@ -473,6 +486,7 @@ 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 { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 519181d364c2f..ec8ed5b2d5bed 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -16,6 +16,7 @@ package android.view; +import static android.content.res.Resources.ID_NULL; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; @@ -5052,6 +5053,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Nullable private WeakReference mContentCaptureSession; + @LayoutRes + private int mSourceLayoutId = ID_NULL; + /** * Simple constructor to use when creating a view from code. * @@ -5217,6 +5221,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { this(context); + mSourceLayoutId = Resources.getAttributeSetSourceResId(attrs); + final TypedArray a = context.obtainStyledAttributes( attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes); @@ -23252,6 +23258,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + /** + * A {@link View} can be inflated from an XML layout. For such Views this method returns the + * resource ID of the source layout. + * + * @return The layout resource id if this view was inflated from XML, otherwise + * {@link Resources#ID_NULL}. + */ + @LayoutRes + public int getSourceLayoutResId() { + return mSourceLayoutId; + } + /** * Returns the top padding of this view. *