diff options
| -rw-r--r-- | api/current.txt | 6 | ||||
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 22 | ||||
| -rw-r--r-- | core/java/android/content/res/AssetManager.java | 10 | ||||
| -rw-r--r-- | core/java/android/content/res/Resources.java | 62 | ||||
| -rw-r--r-- | core/java/android/content/res/ResourcesImpl.java | 26 | ||||
| -rw-r--r-- | core/java/android/provider/Settings.java | 8 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 144 | ||||
| -rw-r--r-- | core/java/android/widget/TextView.java | 2 | ||||
| -rw-r--r-- | core/jni/android_util_AssetManager.cpp | 41 | ||||
| -rw-r--r-- | core/proto/android/providers/settings/global.proto | 2 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/provider/SettingsBackupTest.java | 1 | ||||
| -rw-r--r-- | libs/androidfw/AssetManager2.cpp | 22 | ||||
| -rw-r--r-- | libs/androidfw/include/androidfw/AssetManager2.h | 6 | ||||
| -rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java | 3 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/CoreSettingsObserver.java | 2 |
15 files changed, 347 insertions, 10 deletions
diff --git a/api/current.txt b/api/current.txt index b7577d1e1b85..98d30a3fd8eb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12330,8 +12330,10 @@ package android.content.res { public final class Resources.Theme { method public void applyStyle(int, boolean); method public void dump(int, String, String); + method public int[] getAttributeResolutionStack(@AttrRes int, @StyleRes int, @StyleRes int); method public int getChangingConfigurations(); method public android.graphics.drawable.Drawable getDrawable(@DrawableRes int) throws android.content.res.Resources.NotFoundException; + method @StyleRes public int getExplicitStyle(@Nullable android.util.AttributeSet); method public android.content.res.Resources getResources(); method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[]); method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@StyleRes int, @NonNull @StyleableRes int[]) throws android.content.res.Resources.NotFoundException; @@ -50301,6 +50303,8 @@ package android.view { method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getAlpha(); method public android.view.animation.Animation getAnimation(); method public android.os.IBinder getApplicationWindowToken(); + method @NonNull public java.util.List<java.lang.Integer> getAttributeResolutionStack(); + method @NonNull public java.util.Map<java.lang.Integer,java.lang.Integer> getAttributeSourceResourceMap(); method @android.view.ViewDebug.ExportedProperty @Nullable public String[] getAutofillHints(); method public final android.view.autofill.AutofillId getAutofillId(); method public int getAutofillType(); @@ -50331,6 +50335,7 @@ package android.view { method public void getDrawingRect(android.graphics.Rect); method public long getDrawingTime(); method @android.view.ViewDebug.ExportedProperty(category="drawing") public float getElevation(); + method @StyleRes public int getExplicitStyle(); method @android.view.ViewDebug.ExportedProperty public boolean getFilterTouchesWhenObscured(); method @android.view.ViewDebug.ExportedProperty public boolean getFitsSystemWindows(); method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.NOT_FOCUSABLE, to="NOT_FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE, to="FOCUSABLE"), @android.view.ViewDebug.IntToString(from=android.view.View.FOCUSABLE_AUTO, to="FOCUSABLE_AUTO")}, category="focus") public int getFocusable(); @@ -50625,6 +50630,7 @@ package android.view { method public static int resolveSizeAndState(int, int, int); method public boolean restoreDefaultFocus(); method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>); + method public final void saveAttributeDataForStyleable(@NonNull android.content.Context, @NonNull int[], @Nullable android.util.AttributeSet, @NonNull android.content.res.TypedArray, int, int); method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>); method public void scheduleDrawable(@NonNull android.graphics.drawable.Drawable, @NonNull Runnable, long); method public void scrollBy(int, int); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 21d66e567a81..cc419b8d837a 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4565,16 +4565,25 @@ public final class ActivityThread extends ClientTransactionHandler { } private void onCoreSettingsChange() { - boolean debugViewAttributes = - mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; - if (debugViewAttributes != View.mDebugViewAttributes) { - View.mDebugViewAttributes = debugViewAttributes; - + if (updateDebugViewAttributeState()) { // request all activities to relaunch for the changes to take place relaunchAllActivities(); } } + private boolean updateDebugViewAttributeState() { + boolean previousState = View.sDebugViewAttributes; + + View.sDebugViewAttributesApplicationPackage = mCoreSettings.getString( + Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, ""); + String currentPackage = (mBoundApplication != null && mBoundApplication.appInfo != null) + ? mBoundApplication.appInfo.packageName : ""; + View.sDebugViewAttributes = + mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0 + || View.sDebugViewAttributesApplicationPackage.equals(currentPackage); + return previousState != View.sDebugViewAttributes; + } + private void relaunchAllActivities() { for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { final Activity activity = entry.getValue().activity; @@ -5950,8 +5959,7 @@ public final class ActivityThread extends ClientTransactionHandler { // true : use 24 hour format. DateFormat.set24HourTimePref(is24Hr); - View.mDebugViewAttributes = - mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0; + updateDebugViewAttributeState(); StrictMode.initThreadDefaults(data.appInfo); StrictMode.initVmDefaults(data.appInfo); diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 9e0a9ba0dc7b..faf17e011b23 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1051,6 +1051,14 @@ public final class AssetManager implements AutoCloseable { } } + int[] getAttributeResolutionStack(long themePtr, @AttrRes int defStyleAttr, + @StyleRes int defStyleRes, @StyleRes int xmlStyle) { + synchronized (this) { + return nativeAttributeResolutionStack( + mObject, themePtr, xmlStyle, defStyleAttr, defStyleRes); + } + } + @UnsupportedAppUsage boolean resolveAttrs(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes, @Nullable int[] inValues, @NonNull int[] inAttrs, @NonNull int[] outValues, @@ -1419,6 +1427,8 @@ public final class AssetManager implements AutoCloseable { private static native @Nullable String nativeGetLastResourceResolution(long ptr); // Style attribute retrieval native methods. + private static native int[] nativeAttributeResolutionStack(long ptr, long themePtr, + @StyleRes int xmlStyleRes, @AttrRes int defStyleAttr, @StyleRes int defStyleRes); private static native void nativeApplyStyle(long ptr, long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes, long xmlParserPtr, @NonNull int[] inAttrs, long outValuesAddress, long outIndicesAddress); diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 59db49e0d37e..a2ae994f7b0f 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1725,6 +1725,68 @@ public class Resources { public void rebase() { mThemeImpl.rebase(); } + + /** + * Returns the resource ID for the style specified using {@code style="..."} in the + * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise if not + * specified or otherwise not applicable. + * <p> + * Each {@link android.view.View} can have an explicit style specified in the layout file. + * This style is used first during the {@link android.view.View} attribute resolution, then + * if an attribute is not defined there the resource system looks at default style and theme + * as fallbacks. + * + * @param set The base set of attribute values. + * + * @return The resource ID for the style specified using {@code style="..."} in the + * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise + * if not specified or otherwise not applicable. + */ + @StyleRes + public int getExplicitStyle(@Nullable AttributeSet set) { + if (set == null) { + return ID_NULL; + } + int styleAttr = set.getStyleAttribute(); + if (styleAttr == ID_NULL) { + return ID_NULL; + } + String styleAttrType = getResources().getResourceTypeName(styleAttr); + if ("attr".equals(styleAttrType)) { + TypedValue explicitStyle = new TypedValue(); + boolean resolved = resolveAttribute(styleAttr, explicitStyle, true); + if (resolved) { + return explicitStyle.resourceId; + } + } else if ("style".equals(styleAttrType)) { + return styleAttr; + } + return ID_NULL; + } + + /** + * Returns the ordered list of resource ID that are considered when resolving attribute + * values when making an equivalent call to + * {@link #obtainStyledAttributes(AttributeSet, int[], int, int)} . The list will include + * a set of explicit styles ({@code explicitStyleRes} and it will include the default styles + * ({@code defStyleAttr} and {@code defStyleRes}). + * + * @param defStyleAttr An attribute in the current theme that contains a + * reference to a style resource that supplies + * defaults values for the TypedArray. Can be + * 0 to not look for defaults. + * @param defStyleRes A resource identifier of a style resource that + * supplies default values for the TypedArray, + * used only if defStyleAttr is 0 or can not be found + * in the theme. Can be 0 to not look for defaults. + * @param explicitStyleRes A resource identifier of an explicit style resource. + * @return ordered list of resource ID that are considered when resolving attribute values. + */ + public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr, + @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) { + return mThemeImpl.getAttributeResolutionStack( + defStyleAttr, defStyleRes, explicitStyleRes); + } } static class ThemeKey implements Cloneable { diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 98980799a365..da064c956fcc 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -1488,6 +1488,32 @@ public class ResourcesImpl { } } } + + /** + * Returns the ordered list of resource ID that are considered when resolving attribute + * values when making an equivalent call to + * {@link #obtainStyledAttributes(Resources.Theme, AttributeSet, int[], int, int)}. The list + * will include a set of explicit styles ({@code explicitStyleRes} and it will include the + * default styles ({@code defStyleAttr} and {@code defStyleRes}). + * + * @param defStyleAttr An attribute in the current theme that contains a + * reference to a style resource that supplies + * defaults values for the TypedArray. Can be + * 0 to not look for defaults. + * @param defStyleRes A resource identifier of a style resource that + * supplies default values for the TypedArray, + * used only if defStyleAttr is 0 or can not be found + * in the theme. Can be 0 to not look for defaults. + * @param explicitStyleRes A resource identifier of an explicit style resource. + * @return ordered list of resource ID that are considered when resolving attribute values. + */ + public int[] getAttributeResolutionStack(@AttrRes int defStyleAttr, + @StyleRes int defStyleRes, @StyleRes int explicitStyleRes) { + synchronized (mKey) { + return mAssets.getAttributeResolutionStack( + mTheme, defStyleAttr, defStyleRes, explicitStyleRes); + } + } } private static class LookupStack { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a8976aa56241..e95d60465371 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -9300,6 +9300,13 @@ public final class Settings { public static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes"; /** + * Which application package is allowed to save View attribute data. + * @hide + */ + public static final String DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE = + "debug_view_attributes_application_package"; + + /** * Whether assisted GPS should be enabled or not. * @hide */ @@ -14022,6 +14029,7 @@ public final class Settings { INSTANT_APP_SETTINGS.add(TRANSITION_ANIMATION_SCALE); INSTANT_APP_SETTINGS.add(ANIMATOR_DURATION_SCALE); INSTANT_APP_SETTINGS.add(DEBUG_VIEW_ATTRIBUTES); + INSTANT_APP_SETTINGS.add(DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE); INSTANT_APP_SETTINGS.add(WTF_IS_FATAL); INSTANT_APP_SETTINGS.add(SEND_ACTION_APP_ERROR); INSTANT_APP_SETTINGS.add(ZEN_MODE); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index cb8f70341ff2..c641552d8d72 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -35,6 +35,7 @@ import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; +import android.annotation.StyleRes; import android.annotation.TestApi; import android.annotation.UiThread; import android.annotation.UnsupportedAppUsage; @@ -91,6 +92,7 @@ import android.util.LongSparseLongArray; import android.util.Pools.SynchronizedPool; import android.util.Property; import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.StateSet; import android.util.SuperNotCalledException; import android.util.TypedValue; @@ -821,7 +823,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @hide */ - public static boolean mDebugViewAttributes = false; + public static boolean sDebugViewAttributes = false; + + /** + * When set to this application package view will save its attribute data. + * + * @hide + */ + public static String sDebugViewAttributesApplicationPackage; /** * Used to mark a View that has no ID. @@ -5079,6 +5088,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @LayoutRes private int mSourceLayoutId = ID_NULL; + @Nullable + private SparseIntArray mAttributeSourceResId; + + @Nullable + private int[] mAttributeResolutionStack; + + @StyleRes + private int mExplicitStyle; + /** * Cached reference to the {@link ContentCaptureSession}, is reset on {@link #invalidate()}. */ @@ -5254,7 +5272,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final TypedArray a = context.obtainStyledAttributes( attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes); - if (mDebugViewAttributes) { + retrieveExplicitStyle(context.getTheme(), attrs); + saveAttributeDataForStyleable(context, com.android.internal.R.styleable.View, attrs, a, + defStyleAttr, defStyleRes); + + if (sDebugViewAttributes) { saveAttributeData(attrs, a); } @@ -5916,6 +5938,84 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Returns the ordered list of resource ID that are considered when resolving attribute values + * for this {@link View}. The list will include layout resource ID if the View is inflated from + * XML. It will also include a set of explicit styles if specified in XML using + * {@code style="..."}. Finally, it will include the default styles resolved from the theme. + * + * <p> + * <b>Note:</b> this method will only return actual values if the view attribute debugging + * is enabled in Android developer options. + * + * @return ordered list of resource ID that are considered when resolving attribute values for + * this {@link View}. + */ + @NonNull + public List<Integer> getAttributeResolutionStack() { + ArrayList<Integer> stack = new ArrayList<>(); + if (!sDebugViewAttributes) { + return stack; + } + if (mSourceLayoutId != ID_NULL) { + stack.add(mSourceLayoutId); + } + for (int i = 0; i < mAttributeResolutionStack.length; i++) { + stack.add(mAttributeResolutionStack[i]); + } + return stack; + } + + /** + * Returns the mapping of attribute resource ID to source resource ID where the attribute value + * was set. Source resource ID can either be a layout resource ID, if the value was set in XML + * within the View tag, or a style resource ID, if the attribute was set in a style. The source + * resource value will be one of the resource IDs from {@link #getAttributeSourceResourceMap()}. + * + * <p> + * <b>Note:</b> this method will only return actual values if the view attribute debugging + * is enabled in Android developer options. + * + * @return mapping of attribute resource ID to source resource ID where the attribute value + * was set. + */ + @NonNull + public Map<Integer, Integer> getAttributeSourceResourceMap() { + HashMap<Integer, Integer> map = new HashMap<>(); + if (!sDebugViewAttributes) { + return map; + } + for (int i = 0; i < mAttributeSourceResId.size(); i++) { + map.put(mAttributeSourceResId.keyAt(i), mAttributeSourceResId.valueAt(i)); + } + return map; + } + + /** + * Returns the resource ID for the style specified using {@code style="..."} in the + * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise if not + * specified or otherwise not applicable. + * <p> + * Each {@link View} can have an explicit style specified in the layout file. + * This style is used first during the {@link View} attribute resolution, then if an attribute + * is not defined there the resource system looks at default style and theme as fallbacks. + * + * <p> + * <b>Note:</b> this method will only return actual values if the view attribute debugging + * is enabled in Android developer options. + * + * @return The resource ID for the style specified using {@code style="..."} in the + * {@link AttributeSet}'s backing XML element or {@link Resources#ID_NULL} otherwise + * if not specified or otherwise not applicable. + */ + @StyleRes + public int getExplicitStyle() { + if (!sDebugViewAttributes) { + return ID_NULL; + } + return mExplicitStyle; + } + + /** * An implementation of OnClickListener that attempts to lazily load a * named click handling method from a parent or ancestor context. */ @@ -6001,6 +6101,46 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return mAttributeMap; } + private void retrieveExplicitStyle(@NonNull Resources.Theme theme, + @Nullable AttributeSet attrs) { + if (!sDebugViewAttributes) { + return; + } + mExplicitStyle = theme.getExplicitStyle(attrs); + } + + /** + * Stores debugging information about attributes. This should be called in a constructor by + * every custom {@link View} that uses a custom styleable. + * @param context Context under which this view is created. + * @param styleable A reference to styleable array R.styleable.Foo + * @param attrs AttributeSet used to construct this view. + * @param t Resolved {@link TypedArray} returned by a call to + * {@link Resources#obtainAttributes(AttributeSet, int[])}. + * @param defStyleAttr Default style attribute passed into the view constructor. + * @param defStyleRes Default style resource passed into the view constructor. + */ + public final void saveAttributeDataForStyleable(@NonNull Context context, + @NonNull int[] styleable, @Nullable AttributeSet attrs, @NonNull TypedArray t, + int defStyleAttr, int defStyleRes) { + if (!sDebugViewAttributes) { + return; + } + + mAttributeResolutionStack = context.getTheme().getAttributeResolutionStack( + defStyleAttr, defStyleRes, mExplicitStyle); + + if (mAttributeSourceResId == null) { + mAttributeSourceResId = new SparseIntArray(); + } + + final int indexCount = t.getIndexCount(); + for (int j = 0; j < indexCount; ++j) { + final int index = t.getIndex(j); + mAttributeSourceResId.append(styleable[index], t.getSourceResourceId(index, 0)); + } + } + private void saveAttributeData(@Nullable AttributeSet attrs, @NonNull TypedArray t) { final int attrsCount = attrs == null ? 0 : attrs.getAttributeCount(); final int indexCount = t.getIndexCount(); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 0f4e23d87e0e..d87600125a54 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -1055,6 +1055,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int inputType = EditorInfo.TYPE_NULL; a = theme.obtainStyledAttributes( attrs, com.android.internal.R.styleable.TextView, defStyleAttr, defStyleRes); + saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TextView, attrs, a, + defStyleAttr, defStyleRes); int firstBaselineToTopHeight = -1; int lastBaselineToBottomHeight = -1; int lineHeight = -1; diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 4101c04162af..d493ddfaae13 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -1105,6 +1105,46 @@ static jobjectArray NativeGetSizeConfigurations(JNIEnv* env, jclass /*clazz*/, j return array; } +static jintArray NativeAttributeResolutionStack( + JNIEnv* env, jclass /*clazz*/, jlong ptr, + jlong theme_ptr, jint xml_style_res, + jint def_style_attr, jint def_style_resid) { + + ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr)); + Theme* theme = reinterpret_cast<Theme*>(theme_ptr); + CHECK(theme->GetAssetManager() == &(*assetmanager)); + (void) assetmanager; + + // Load default style from attribute, if specified... + uint32_t def_style_flags = 0u; + if (def_style_attr != 0) { + Res_value value; + if (theme->GetAttribute(def_style_attr, &value, &def_style_flags) != kInvalidCookie) { + if (value.dataType == Res_value::TYPE_REFERENCE) { + def_style_resid = value.data; + } + } + } + + auto style_stack = assetmanager->GetBagResIdStack(xml_style_res); + auto def_style_stack = assetmanager->GetBagResIdStack(def_style_resid); + + jintArray array = env->NewIntArray(style_stack.size() + def_style_stack.size()); + if (env->ExceptionCheck()) { + return nullptr; + } + + for (uint32_t i = 0; i < style_stack.size(); i++) { + jint attr_resid = style_stack[i]; + env->SetIntArrayRegion(array, i, 1, &attr_resid); + } + for (uint32_t i = 0; i < def_style_stack.size(); i++) { + jint attr_resid = def_style_stack[i]; + env->SetIntArrayRegion(array, style_stack.size() + i, 1, &attr_resid); + } + return array; +} + static void NativeApplyStyle(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong theme_ptr, jint def_style_attr, jint def_style_resid, jlong xml_parser_ptr, jintArray java_attrs, jlong out_values_ptr, jlong out_indices_ptr) { @@ -1456,6 +1496,7 @@ static const JNINativeMethod gAssetManagerMethods[] = { (void*)NativeGetSizeConfigurations}, // Style attribute related methods. + {"nativeAttributeResolutionStack", "(JJIII)[I", (void*)NativeAttributeResolutionStack}, {"nativeApplyStyle", "(JJIIJ[IJJ)V", (void*)NativeApplyStyle}, {"nativeResolveAttrs", "(JJII[I[I[I[I)Z", (void*)NativeResolveAttrs}, {"nativeRetrieveAttributes", "(JJ[I[I[I)Z", (void*)NativeRetrieveAttributes}, diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index a160451ecfed..d5776534bb90 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -259,6 +259,8 @@ message GlobalSettingsProto { optional SettingProto app = 1; // Whether views are allowed to save their attribute data. optional SettingProto view_attributes = 2 [ (android.privacy).dest = DEST_AUTOMATIC ]; + // Which application package is allowed to save view attribute data. + optional SettingProto view_attributes_application_package = 3 [ (android.privacy).dest = DEST_AUTOMATIC ]; } optional Debug debug = 37; diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 2cb925aa9549..ec57f793f15f 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -210,6 +210,7 @@ public class SettingsBackupTest { Settings.Global.DATA_STALL_VALID_DNS_TIME_THRESHOLD, Settings.Global.DEBUG_APP, Settings.Global.DEBUG_VIEW_ATTRIBUTES, + Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, Settings.Global.DEFAULT_DNS_SERVER, Settings.Global.DEFAULT_INSTALL_LOCATION, Settings.Global.DEFAULT_RESTRICT_BACKGROUND_DATA, diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index 20303eba6667..81afd937d85e 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -704,9 +704,29 @@ ApkAssetsCookie AssetManager2::ResolveReference(ApkAssetsCookie cookie, Res_valu return cookie; } +const std::vector<uint32_t> AssetManager2::GetBagResIdStack(uint32_t resid) { + auto cached_iter = cached_bag_resid_stacks_.find(resid); + if (cached_iter != cached_bag_resid_stacks_.end()) { + return cached_iter->second; + } else { + auto found_resids = std::vector<uint32_t>(); + GetBag(resid, found_resids); + // Cache style stacks if they are not already cached. + cached_bag_resid_stacks_[resid] = found_resids; + return found_resids; + } +} + const ResolvedBag* AssetManager2::GetBag(uint32_t resid) { auto found_resids = std::vector<uint32_t>(); - return GetBag(resid, found_resids); + auto bag = GetBag(resid, found_resids); + + // Cache style stacks if they are not already cached. + auto cached_iter = cached_bag_resid_stacks_.find(resid); + if (cached_iter == cached_bag_resid_stacks_.end()) { + cached_bag_resid_stacks_[resid] = found_resids; + } + return bag; } const ResolvedBag* AssetManager2::GetBag(uint32_t resid, std::vector<uint32_t>& child_resids) { diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index f29769b834d1..d862182d8960 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -237,6 +237,8 @@ class AssetManager2 { // resource has been resolved yet. std::string GetLastResourceResolution() const; + const std::vector<uint32_t> GetBagResIdStack(uint32_t resid); + // Retrieves the best matching bag/map resource with ID `resid`. // This method will resolve all parent references for this bag and merge keys with the child. // To iterate over the keys, use the following idiom: @@ -355,6 +357,10 @@ class AssetManager2 { // which involves some calculation. std::unordered_map<uint32_t, util::unique_cptr<ResolvedBag>> cached_bags_; + // Cached set of bag resid stacks for each bag. These are cached because they might be requested + // a number of times for each view during View inspection. + std::unordered_map<uint32_t, std::vector<uint32_t>> cached_bag_resid_stacks_; + // Whether or not to save resource resolution steps bool resource_resolution_logging_enabled_ = false; diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index fad93cbf83da..6152b8cbd562 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -457,6 +457,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Global.DEBUG_VIEW_ATTRIBUTES, GlobalSettingsProto.Debug.VIEW_ATTRIBUTES); + dumpSetting(s, p, + Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, + GlobalSettingsProto.Debug.VIEW_ATTRIBUTES_APPLICATION_PACKAGE); p.end(debugToken); final long defaultToken = p.start(GlobalSettingsProto.DEFAULT); diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index 360d2960f61a..01946247bd12 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -56,6 +56,8 @@ final class CoreSettingsObserver extends ContentObserver { sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class); sGlobalSettingToTypeMap.put( + Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, String.class); + sGlobalSettingToTypeMap.put( Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, String.class); sGlobalSettingToTypeMap.put( Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, String.class); |