diff options
author | 2022-08-18 22:06:55 +0000 | |
---|---|---|
committer | 2022-08-24 18:44:14 +0000 | |
commit | 77c8a939d64fd12729f9a3c7d6e736ead9d31798 (patch) | |
tree | 1140874e80430a87b90599324b8765861c8ef93c | |
parent | a6a9b179e9c9bad6fd99a92e76ef9c3c0e4a4426 (diff) |
Add ability to pass in a config string for FRROs
This enables passing them and and storing them in the .frro file but no
further.
Bug: 243066074
Test: Manual
Change-Id: I5c9723e69d175a536f9739619c6b6bf3162a5027
-rw-r--r-- | cmds/idmap2/idmap2d/Idmap2Service.cpp | 6 | ||||
-rw-r--r-- | cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl | 1 | ||||
-rw-r--r-- | cmds/idmap2/include/idmap2/FabricatedOverlay.h | 6 | ||||
-rw-r--r-- | cmds/idmap2/include/idmap2/ResourceContainer.h | 2 | ||||
-rw-r--r-- | cmds/idmap2/include/idmap2/ResourceMapping.h | 3 | ||||
-rw-r--r-- | cmds/idmap2/include/idmap2/ResourceUtils.h | 5 | ||||
-rw-r--r-- | cmds/idmap2/libidmap2/FabricatedOverlay.cpp | 50 | ||||
-rw-r--r-- | cmds/idmap2/libidmap2/ResourceContainer.cpp | 6 | ||||
-rw-r--r-- | cmds/idmap2/libidmap2/ResourceMapping.cpp | 6 | ||||
-rw-r--r-- | cmds/idmap2/libidmap2/proto/fabricated_v1.proto | 1 | ||||
-rw-r--r-- | cmds/idmap2/tests/FabricatedOverlayTests.cpp | 64 | ||||
-rw-r--r-- | cmds/idmap2/tests/IdmapTests.cpp | 6 | ||||
-rw-r--r-- | cmds/idmap2/tests/ResourceMappingTests.cpp | 6 | ||||
-rw-r--r-- | core/java/android/content/om/FabricatedOverlay.java | 44 | ||||
-rw-r--r-- | services/core/java/com/android/server/om/OverlayManagerShellCommand.java | 15 |
15 files changed, 154 insertions, 67 deletions
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 073d987f5dad..083bbf01bf5b 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -235,9 +235,11 @@ Status Idmap2Service::createFabricatedOverlay( for (const auto& res : overlay.entries) { if (res.dataType == Res_value::TYPE_STRING) { - builder.SetResourceValue(res.resourceName, res.dataType, res.stringData.value()); + builder.SetResourceValue(res.resourceName, res.dataType, res.stringData.value(), + res.configuration.value_or(std::string())); } else { - builder.SetResourceValue(res.resourceName, res.dataType, res.data); + builder.SetResourceValue(res.resourceName, res.dataType, res.data, + res.configuration.value_or(std::string())); } } diff --git a/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl b/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl index a6824da8c424..c773e112997d 100644 --- a/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl +++ b/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl @@ -24,4 +24,5 @@ parcelable FabricatedOverlayInternalEntry { int dataType; int data; @nullable @utf8InCpp String stringData; + @nullable @utf8InCpp String configuration; }
\ No newline at end of file diff --git a/cmds/idmap2/include/idmap2/FabricatedOverlay.h b/cmds/idmap2/include/idmap2/FabricatedOverlay.h index 2fc4d43b798a..05b0618131c9 100644 --- a/cmds/idmap2/include/idmap2/FabricatedOverlay.h +++ b/cmds/idmap2/include/idmap2/FabricatedOverlay.h @@ -39,10 +39,11 @@ struct FabricatedOverlay { Builder& SetOverlayable(const std::string& name); Builder& SetResourceValue(const std::string& resource_name, uint8_t data_type, - uint32_t data_value); + uint32_t data_value, const std::string& configuration); Builder& SetResourceValue(const std::string& resource_name, uint8_t data_type, - const std::string& data_string_value); + const std::string& data_string_value, + const std::string& configuration); WARN_UNUSED Result<FabricatedOverlay> Build(); @@ -52,6 +53,7 @@ struct FabricatedOverlay { DataType data_type; DataValue data_value; std::string data_string_value; + std::string configuration; }; std::string package_name_; diff --git a/cmds/idmap2/include/idmap2/ResourceContainer.h b/cmds/idmap2/include/idmap2/ResourceContainer.h index c3ba4640bd77..2452ff0784ce 100644 --- a/cmds/idmap2/include/idmap2/ResourceContainer.h +++ b/cmds/idmap2/include/idmap2/ResourceContainer.h @@ -66,7 +66,7 @@ struct OverlayData { struct Value { std::string resource_name; - std::variant<ResourceIdValue, TargetValue> value; + std::variant<ResourceIdValue, TargetValueWithConfig> value; }; struct InlineStringPoolData { diff --git a/cmds/idmap2/include/idmap2/ResourceMapping.h b/cmds/idmap2/include/idmap2/ResourceMapping.h index 5a0a384f75a3..21862a3635d5 100644 --- a/cmds/idmap2/include/idmap2/ResourceMapping.h +++ b/cmds/idmap2/include/idmap2/ResourceMapping.h @@ -69,7 +69,8 @@ class ResourceMapping { // If `allow_rewriting_` is true, then the overlay-to-target map will be populated if the target // resource id is mapped to an overlay resource id. Result<Unit> AddMapping(ResourceId target_resource, - const std::variant<OverlayData::ResourceIdValue, TargetValue>& value); + const std::variant<OverlayData::ResourceIdValue, + TargetValueWithConfig>& value); TargetResourceMap target_map_; OverlayResourceMap overlay_map_; diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h index 414aa064ada7..8ec749602c4a 100644 --- a/cmds/idmap2/include/idmap2/ResourceUtils.h +++ b/cmds/idmap2/include/idmap2/ResourceUtils.h @@ -43,6 +43,11 @@ struct TargetValue { std::string data_string_value; }; +struct TargetValueWithConfig { + TargetValue value; + std::string config; +}; + namespace utils { // Returns whether the Res_value::data_type represents a dynamic or regular resource reference. diff --git a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp index 5bbe08524c18..bde9b0be4361 100644 --- a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp +++ b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp @@ -70,19 +70,22 @@ FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetOverlayable(const std } FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetResourceValue( - const std::string& resource_name, uint8_t data_type, uint32_t data_value) { - entries_.emplace_back(Entry{resource_name, data_type, data_value, ""}); + const std::string& resource_name, uint8_t data_type, uint32_t data_value, + const std::string& configuration) { + entries_.emplace_back(Entry{resource_name, data_type, data_value, "", configuration}); return *this; } FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetResourceValue( - const std::string& resource_name, uint8_t data_type, const std::string& data_string_value) { - entries_.emplace_back(Entry{resource_name, data_type, 0, data_string_value}); + const std::string& resource_name, uint8_t data_type, const std::string& data_string_value, + const std::string& configuration) { + entries_.emplace_back(Entry{resource_name, data_type, 0, data_string_value, configuration}); return *this; } Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() { - using EntryMap = std::map<std::string, TargetValue>; + using ConfigMap = std::map<std::string, TargetValue>; + using EntryMap = std::map<std::string, ConfigMap>; using TypeMap = std::map<std::string, EntryMap>; using PackageMap = std::map<std::string, TypeMap>; PackageMap package_map; @@ -123,11 +126,16 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() { auto entry = type->second.find(entry_name.to_string()); if (entry == type->second.end()) { - entry = type->second.insert(std::make_pair(entry_name.to_string(), TargetValue())).first; + entry = type->second.insert(std::make_pair(entry_name.to_string(), ConfigMap())).first; } - entry->second = TargetValue{ - res_entry.data_type, res_entry.data_value, res_entry.data_string_value}; + auto value = entry->second.find(res_entry.configuration); + if (value == entry->second.end()) { + value = entry->second.insert(std::make_pair(res_entry.configuration, TargetValue())).first; + } + + value->second = TargetValue{res_entry.data_type, res_entry.data_value, + res_entry.data_string_value}; } pb::FabricatedOverlay overlay_pb; @@ -145,15 +153,18 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() { type_pb->set_name(type.first); for (auto& entry : type.second) { - auto entry_pb = type_pb->add_entries(); - entry_pb->set_name(entry.first); - pb::ResourceValue* value = entry_pb->mutable_res_value(); - value->set_data_type(entry.second.data_type); - if (entry.second.data_type == Res_value::TYPE_STRING) { - auto ref = string_pool.MakeRef(entry.second.data_string_value); - value->set_data_value(ref.index()); - } else { - value->set_data_value(entry.second.data_value); + for (const auto& value: entry.second) { + auto entry_pb = type_pb->add_entries(); + entry_pb->set_name(entry.first); + entry_pb->set_configuration(value.first); + pb::ResourceValue* pb_value = entry_pb->mutable_res_value(); + pb_value->set_data_type(value.second.data_type); + if (value.second.data_type == Res_value::TYPE_STRING) { + auto ref = string_pool.MakeRef(value.second.data_string_value); + pb_value->set_data_value(ref.index()); + } else { + pb_value->set_data_value(value.second.data_value); + } } } } @@ -330,8 +341,9 @@ Result<OverlayData> FabContainer::GetOverlayData(const OverlayManifestInfo& info entry.name().c_str()); const auto& res_value = entry.res_value(); result.pairs.emplace_back(OverlayData::Value{ - name, TargetValue{.data_type = static_cast<uint8_t>(res_value.data_type()), - .data_value = res_value.data_value()}}); + name, TargetValueWithConfig{.config = entry.configuration(), .value = TargetValue{ + .data_type = static_cast<uint8_t>(res_value.data_type()), + .data_value = res_value.data_value()}}}); } } } diff --git a/cmds/idmap2/libidmap2/ResourceContainer.cpp b/cmds/idmap2/libidmap2/ResourceContainer.cpp index a62472c8f11e..0e3590486c6f 100644 --- a/cmds/idmap2/libidmap2/ResourceContainer.cpp +++ b/cmds/idmap2/libidmap2/ResourceContainer.cpp @@ -226,8 +226,10 @@ Result<OverlayData> CreateResourceMapping(ResourceId id, const ZipAssetsProvider *target_resource, OverlayData::ResourceIdValue{overlay_resource->data, rewrite_id}}); } else { overlay_data.pairs.emplace_back( - OverlayData::Value{*target_resource, TargetValue{.data_type = overlay_resource->dataType, - .data_value = overlay_resource->data}}); + OverlayData::Value{*target_resource, TargetValueWithConfig{ + .config = std::string(), + .value = TargetValue{.data_type = overlay_resource->dataType, + .data_value = overlay_resource->data}}}); } } diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp index 3bbbf248c87d..8ebe5aa46e73 100644 --- a/cmds/idmap2/libidmap2/ResourceMapping.cpp +++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp @@ -160,7 +160,7 @@ Result<ResourceMapping> ResourceMapping::FromContainers(const TargetResourceCont Result<Unit> ResourceMapping::AddMapping( ResourceId target_resource, - const std::variant<OverlayData::ResourceIdValue, TargetValue>& value) { + const std::variant<OverlayData::ResourceIdValue, TargetValueWithConfig>& value) { if (target_map_.find(target_resource) != target_map_.end()) { return Error(R"(target resource id "0x%08x" mapped to multiple values)", target_resource); } @@ -176,8 +176,8 @@ Result<Unit> ResourceMapping::AddMapping( overlay_map_.insert(std::make_pair(overlay_resource->overlay_id, target_resource)); } } else { - auto overlay_value = std::get<TargetValue>(value); - target_map_.insert(std::make_pair(target_resource, overlay_value)); + auto overlay_value = std::get<TargetValueWithConfig>(value); + target_map_.insert(std::make_pair(target_resource, overlay_value.value)); } return Unit{}; diff --git a/cmds/idmap2/libidmap2/proto/fabricated_v1.proto b/cmds/idmap2/libidmap2/proto/fabricated_v1.proto index a392b2b6d856..c7a79b31e151 100644 --- a/cmds/idmap2/libidmap2/proto/fabricated_v1.proto +++ b/cmds/idmap2/libidmap2/proto/fabricated_v1.proto @@ -46,6 +46,7 @@ message ResourceEntry { oneof value { ResourceValue res_value = 2; } + string configuration = 3; } message ResourceValue { diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp index 91331ca1cc76..e804c879ee82 100644 --- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp +++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp @@ -43,10 +43,17 @@ TEST(FabricatedOverlayTests, OverlayInfo) { TEST(FabricatedOverlayTests, SetResourceValue) { auto overlay = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target") - .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U) - .SetResourceValue("com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U) - .SetResourceValue("string/int3", Res_value::TYPE_REFERENCE, 0x7f010000) - .SetResourceValue("com.example.target:string/string1", Res_value::TYPE_STRING, "foobar") + .SetResourceValue( + "com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "port") + .SetResourceValue( + "com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U, "land") + .SetResourceValue( + "string/int3", Res_value::TYPE_REFERENCE, 0x7f010000, "xxhdpi-v7") + .SetResourceValue( + "com.example.target:string/string1", + Res_value::TYPE_STRING, + "foobar", + "en-rUS-normal-xxhdpi-v21") .Build(); ASSERT_TRUE(overlay); auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay)); @@ -66,44 +73,48 @@ TEST(FabricatedOverlayTests, SetResourceValue) { auto& it = pairs->pairs[0]; ASSERT_EQ("com.example.target:integer/int1", it.resource_name); - auto entry = std::get_if<TargetValue>(&it.value); + auto entry = std::get_if<TargetValueWithConfig>(&it.value); ASSERT_NE(nullptr, entry); - ASSERT_EQ(1U, entry->data_value); - ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->data_type); + ASSERT_EQ(1U, entry->value.data_value); + ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type); + ASSERT_EQ("port", entry->config); it = pairs->pairs[1]; ASSERT_EQ("com.example.target:string/int3", it.resource_name); - entry = std::get_if<TargetValue>(&it.value); + entry = std::get_if<TargetValueWithConfig>(&it.value); ASSERT_NE(nullptr, entry); - ASSERT_EQ(0x7f010000, entry->data_value); - ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->data_type); + ASSERT_EQ(0x7f010000, entry->value.data_value); + ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->value.data_type); + ASSERT_EQ("xxhdpi-v7", entry->config); it = pairs->pairs[2]; ASSERT_EQ("com.example.target:string/string1", it.resource_name); - entry = std::get_if<TargetValue>(&it.value); + entry = std::get_if<TargetValueWithConfig>(&it.value); ASSERT_NE(nullptr, entry); - ASSERT_EQ(Res_value::TYPE_STRING, entry->data_type); - ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->data_value).value_or("")); + ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type); + ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or("")); + ASSERT_EQ("en-rUS-normal-xxhdpi-v21", entry->config); it = pairs->pairs[3]; ASSERT_EQ("com.example.target.split:integer/int2", it.resource_name); - entry = std::get_if<TargetValue>(&it.value); + entry = std::get_if<TargetValueWithConfig>(&it.value); ASSERT_NE(nullptr, entry); - ASSERT_EQ(2U, entry->data_value); - ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->data_type); + ASSERT_EQ(2U, entry->value.data_value); + ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type); + ASSERT_EQ("land", entry->config); } TEST(FabricatedOverlayTests, SetResourceValueBadArgs) { { auto builder = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target") - .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U); + .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U, ""); ASSERT_FALSE(builder.Build()); } { auto builder = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target") - .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U); + .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U, ""); ASSERT_FALSE(builder.Build()); } } @@ -112,8 +123,9 @@ TEST(FabricatedOverlayTests, SerializeAndDeserialize) { auto overlay = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target") .SetOverlayable("TestResources") - .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U) - .SetResourceValue("com.example.target:string/string1", Res_value::TYPE_STRING, "foobar") + .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "") + .SetResourceValue( + "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "") .Build(); ASSERT_TRUE(overlay); TemporaryFile tf; @@ -142,17 +154,17 @@ TEST(FabricatedOverlayTests, SerializeAndDeserialize) { auto& it = pairs->pairs[0]; ASSERT_EQ("com.example.target:integer/int1", it.resource_name); - auto entry = std::get_if<TargetValue>(&it.value); + auto entry = std::get_if<TargetValueWithConfig>(&it.value); ASSERT_NE(nullptr, entry); - EXPECT_EQ(1U, entry->data_value); - EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->data_type); + EXPECT_EQ(1U, entry->value.data_value); + EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type); it = pairs->pairs[1]; ASSERT_EQ("com.example.target:string/string1", it.resource_name); - entry = std::get_if<TargetValue>(&it.value); + entry = std::get_if<TargetValueWithConfig>(&it.value); ASSERT_NE(nullptr, entry); - ASSERT_EQ(Res_value::TYPE_STRING, entry->data_type); - ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->data_value).value_or("")); + ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type); + ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or("")); } } // namespace android::idmap2 diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index a3799f98c90c..ee9a424b3050 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -261,9 +261,9 @@ TEST(IdmapTests, FabricatedOverlay) { auto frro = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "test.target") .SetOverlayable("TestResources") - .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U) - .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000) - .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar") + .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "") + .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "") + .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "") .Build(); ASSERT_TRUE(frro); diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp index c05abcf31532..ca9a444bcb05 100644 --- a/cmds/idmap2/tests/ResourceMappingTests.cpp +++ b/cmds/idmap2/tests/ResourceMappingTests.cpp @@ -194,9 +194,9 @@ TEST(ResourceMappingTests, InlineResources) { TEST(ResourceMappingTests, FabricatedOverlay) { auto frro = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "test.target") .SetOverlayable("TestResources") - .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U) - .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000) - .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar") + .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "") + .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "") + .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "") .Build(); ASSERT_TRUE(frro); diff --git a/core/java/android/content/om/FabricatedOverlay.java b/core/java/android/content/om/FabricatedOverlay.java index 5efc1f9f7cca..3ca056097c1f 100644 --- a/core/java/android/content/om/FabricatedOverlay.java +++ b/core/java/android/content/om/FabricatedOverlay.java @@ -112,6 +112,28 @@ public class FabricatedOverlay { * @param resourceName name of the target resource to overlay (in the form * [package]:type/entry) * @param dataType the data type of the new value + * @param value the unsigned 32 bit integer representing the new value + * @param configuration The string representation of the config this overlay is enabled for + * + * @see android.util.TypedValue#type + */ + public Builder setResourceValue(@NonNull String resourceName, int dataType, int value, + String configuration) { + final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry(); + entry.resourceName = resourceName; + entry.dataType = dataType; + entry.data = value; + entry.configuration = configuration; + mEntries.add(entry); + return this; + } + + /** + * Sets the value of the fabricated overlay + * + * @param resourceName name of the target resource to overlay (in the form + * [package]:type/entry) + * @param dataType the data type of the new value * @param value the string representing the new value * * @see android.util.TypedValue#type @@ -125,6 +147,28 @@ public class FabricatedOverlay { return this; } + /** + * Sets the value of the fabricated overlay + * + * @param resourceName name of the target resource to overlay (in the form + * [package]:type/entry) + * @param dataType the data type of the new value + * @param value the string representing the new value + * @param configuration The string representation of the config this overlay is enabled for + * + * @see android.util.TypedValue#type + */ + public Builder setResourceValue(@NonNull String resourceName, int dataType, String value, + String configuration) { + final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry(); + entry.resourceName = resourceName; + entry.dataType = dataType; + entry.stringData = value; + entry.configuration = configuration; + mEntries.add(entry); + return this; + } + /** Builds an immutable fabricated overlay. */ public FabricatedOverlay build() { final FabricatedOverlayInternal overlay = new FabricatedOverlayInternal(); diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java index da76738fa025..bb918d594167 100644 --- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java +++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java @@ -257,6 +257,7 @@ final class OverlayManagerShellCommand extends ShellCommand { String name = ""; String filename = null; String opt; + String configuration = null; while ((opt = getNextOption()) != null) { switch (opt) { case "--user": @@ -274,6 +275,9 @@ final class OverlayManagerShellCommand extends ShellCommand { case "--file": filename = getNextArgRequired(); break; + case "--config": + configuration = getNextArgRequired(); + break; default: err.println("Error: Unknown option: " + opt); return 1; @@ -307,7 +311,7 @@ final class OverlayManagerShellCommand extends ShellCommand { final String resourceName = getNextArgRequired(); final String typeStr = getNextArgRequired(); final String strData = String.join(" ", peekRemainingArgs()); - addOverlayValue(overlayBuilder, resourceName, typeStr, strData); + addOverlayValue(overlayBuilder, resourceName, typeStr, strData, configuration); } mInterface.commit(new OverlayManagerTransaction.Builder() @@ -363,8 +367,9 @@ final class OverlayManagerShellCommand extends ShellCommand { err.println("Error: value missing at line " + parser.getLineNumber()); return 1; } + String config = parser.getAttributeValue(null, "config"); addOverlayValue(overlayBuilder, targetPackage + ':' + target, - overlayType, value); + overlayType, value, config); } } } @@ -379,7 +384,7 @@ final class OverlayManagerShellCommand extends ShellCommand { } private void addOverlayValue(FabricatedOverlay.Builder overlayBuilder, - String resourceName, String typeString, String valueString) { + String resourceName, String typeString, String valueString, String configuration) { final int type; typeString = typeString.toLowerCase(Locale.getDefault()); if (TYPE_MAP.containsKey(typeString)) { @@ -392,7 +397,7 @@ final class OverlayManagerShellCommand extends ShellCommand { } } if (type == TypedValue.TYPE_STRING) { - overlayBuilder.setResourceValue(resourceName, type, valueString); + overlayBuilder.setResourceValue(resourceName, type, valueString, configuration); } else { final int intData; if (valueString.startsWith("0x")) { @@ -400,7 +405,7 @@ final class OverlayManagerShellCommand extends ShellCommand { } else { intData = Integer.parseUnsignedInt(valueString); } - overlayBuilder.setResourceValue(resourceName, type, intData); + overlayBuilder.setResourceValue(resourceName, type, intData, configuration); } } |