diff options
author | 2024-09-19 09:47:47 -0700 | |
---|---|---|
committer | 2024-09-27 11:44:03 -0700 | |
commit | f53a027bfa9820821be0fdd51faec51ddedf381f (patch) | |
tree | b8a5adf7b6f7422808bad71d3e0c8ca0b18ac668 | |
parent | a0811c0e93b9ec1ad1874a18789ea0dd5d0508ee (diff) |
Add flag support to styles elements
Test: Automated
Bug: 329436914
Flag: EXEMPT Aconfig not supported on host tools
Change-Id: I3041ebbaf98a90527809b541df8885edfc70d035
7 files changed, 88 insertions, 11 deletions
diff --git a/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java b/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java index d9e90fa001c5..a37000a40508 100644 --- a/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java +++ b/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java @@ -24,6 +24,7 @@ import android.content.res.ApkAssets; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; +import android.content.res.TypedArray; import android.os.FileUtils; import android.util.DisplayMetrics; import android.view.LayoutInflater; @@ -151,6 +152,27 @@ public class ResourceFlaggingTest { mResources.getDrawable(R.drawable.removedpng); } + @Test + public void testDisabledStyleDoesntOverride() { + TypedArray ta = mResources.newTheme().obtainStyledAttributes( + R.style.style1, new int[] { android.R.attr.windowIsTranslucent}); + assertThat(ta.getBoolean(0, false)).isTrue(); + } + + @Test + public void testEnabledStyleDoesOverride() { + TypedArray ta = mResources.newTheme().obtainStyledAttributes( + R.style.style2, new int[] { android.R.attr.windowIsTranslucent}); + assertThat(ta.getBoolean(0, false)).isTrue(); + } + + @Test + public void testEnabledStyleItemDoesOverride() { + TypedArray ta = mResources.newTheme().obtainStyledAttributes( + R.style.style3, new int[] { android.R.attr.windowIsTranslucent}); + assertThat(ta.getBoolean(0, false)).isTrue(); + } + private LayoutInflater getLayoutInflater() { ContextWrapper c = new ContextWrapper(mContext) { private LayoutInflater mInflater; diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index fce6aa7c80d9..da092f43caa4 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -1529,13 +1529,34 @@ bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) { ResolvePackage(parser, &maybe_key.value()); maybe_key.value().SetSource(source); + auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag")); + std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString); if (!value) { diag_->Error(android::DiagMessage(source) << "could not parse style item"); return false; } - style->entries.push_back(Style::Entry{std::move(maybe_key.value()), std::move(value)}); + if (flag) { + if (options_.flag) { + diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) + << "Resource flag are not allowed both in the path and in the file"); + return false; + } + std::string error; + auto flag_status = GetFlagStatus(flag, options_.feature_flag_values, &error); + if (flag_status) { + value->SetFlagStatus(flag_status.value()); + value->SetFlag(std::move(flag)); + } else { + diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) << error); + return false; + } + } + + if (value->GetFlagStatus() != FlagStatus::Disabled) { + style->entries.push_back(Style::Entry{std::move(maybe_key.value()), std::move(value)}); + } return true; } diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto index a0f60b62db3a..fe9b4a8843ca 100644 --- a/tools/aapt2/Resources.proto +++ b/tools/aapt2/Resources.proto @@ -302,6 +302,11 @@ message CompoundValue { Plural plural = 5; MacroBody macro = 6; } + + // The status of the flag the value is behind if any + uint32 flag_status = 7; + bool flag_negated = 8; + string flag_name = 9; } // Message holding a boolean, so it can be optionally encoded. diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp index 8583cadff6d2..91ec3485ac3b 100644 --- a/tools/aapt2/format/proto/ProtoDeserialize.cpp +++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp @@ -551,11 +551,10 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr return false; } - FeatureFlagAttribute flag; - flag.name = pb_config_value.value().item().flag_name(); - flag.negated = pb_config_value.value().item().flag_negated(); - ResourceConfigValue* config_value = - entry->FindOrCreateFlagDisabledValue(std::move(flag), config, pb_config.product()); + ResourceConfigValue* config_value = entry->FindOrCreateFlagDisabledValue( + FeatureFlagAttribute{.name = pb_config_value.value().item().flag_name(), + .negated = pb_config_value.value().item().flag_negated()}, + config, pb_config.product()); if (config_value->value != nullptr) { *out_error = "duplicate configuration in resource table"; return false; @@ -563,7 +562,6 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr config_value->value = DeserializeValueFromPb(pb_config_value.value(), src_pool, config, &out_table->string_pool, files, out_error); - if (config_value->value == nullptr) { return false; } @@ -896,6 +894,9 @@ std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value, LOG(FATAL) << "unknown compound value: " << (int)pb_compound_value.value_case(); break; } + value->SetFlagStatus((FlagStatus)pb_compound_value.flag_status()); + value->SetFlag(FeatureFlagAttribute{.name = pb_compound_value.flag_name(), + .negated = pb_compound_value.flag_negated()}); } else { LOG(FATAL) << "unknown value: " << (int)pb_value.value_case(); return {}; @@ -1052,10 +1053,8 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item, if (item) { item->SetFlagStatus((FlagStatus)pb_item.flag_status()); if (!pb_item.flag_name().empty()) { - FeatureFlagAttribute flag; - flag.name = pb_item.flag_name(); - flag.negated = pb_item.flag_negated(); - item->SetFlag(std::move(flag)); + item->SetFlag( + FeatureFlagAttribute{.name = pb_item.flag_name(), .negated = pb_item.flag_negated()}); } } return item; diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp index d83fe916ee95..fcc77d5a9d6d 100644 --- a/tools/aapt2/format/proto/ProtoSerialize.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize.cpp @@ -734,6 +734,13 @@ void SerializeValueToPb(const Value& value, pb::Value* out_value, android::Strin out_value->mutable_item()->set_flag_negated(flag->negated); out_value->mutable_item()->set_flag_name(flag->name); } + } else if (out_value->has_compound_value()) { + out_value->mutable_compound_value()->set_flag_status((uint32_t)value.GetFlagStatus()); + if (value.GetFlag()) { + const auto& flag = value.GetFlag(); + out_value->mutable_compound_value()->set_flag_negated(flag->negated); + out_value->mutable_compound_value()->set_flag_name(flag->name); + } } } diff --git a/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp b/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp index 7160b35033da..1b0f99753ce6 100644 --- a/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp +++ b/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp @@ -30,6 +30,7 @@ genrule { "res/values/bools2.xml", "res/values/ints.xml", "res/values/strings.xml", + "res/values/styles.xml", "res/layout/layout1.xml", "res/layout/layout3.xml", "res/flag(test.package.falseFlag)/values/bools.xml", @@ -50,6 +51,7 @@ genrule { "values_bools2.arsc.flat", "values_ints.arsc.flat", "values_strings.arsc.flat", + "values_styles.arsc.flat", "layout_layout1.xml.flat", "layout_layout2.(test.package.falseFlag).xml.flat", "layout_layout3.xml.flat", diff --git a/tools/aapt2/integration-tests/FlaggedResourcesTest/res/values/styles.xml b/tools/aapt2/integration-tests/FlaggedResourcesTest/res/values/styles.xml new file mode 100644 index 000000000000..604129c26fef --- /dev/null +++ b/tools/aapt2/integration-tests/FlaggedResourcesTest/res/values/styles.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <style name="style1"> + <item name="android:windowIsTranslucent">true</item> + </style> + <style name="style1" android:featureFlag="test.package.falseFlag"> + <item name="android:windowIsTranslucent">false</item> + </style> + + <style name="style2"> + <item name="android:windowIsTranslucent">false</item> + </style> + <style name="style2" android:featureFlag="test.package.trueFlag"> + <item name="android:windowIsTranslucent">true</item> + </style> + + <style name="style3"> + <item name="android:windowIsTranslucent" android:featureFlag="!test.package.trueFlag">false</item> + <item name="android:windowIsTranslucent" android:featureFlag="test.package.trueFlag">true</item> + </style> +</resources>
\ No newline at end of file |