summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.cpp3
-rw-r--r--cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl2
-rw-r--r--cmds/idmap2/include/idmap2/FabricatedOverlay.h14
-rw-r--r--cmds/idmap2/include/idmap2/ResourceUtils.h2
-rw-r--r--cmds/idmap2/libidmap2/FabricatedOverlay.cpp34
-rw-r--r--cmds/idmap2/self_targeting/SelfTargeting.cpp1
-rw-r--r--cmds/idmap2/tests/FabricatedOverlayTests.cpp2
-rw-r--r--cmds/idmap2/tests/IdmapTests.cpp2
-rw-r--r--cmds/idmap2/tests/ResourceMappingTests.cpp2
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/content/om/FabricatedOverlay.java61
-rw-r--r--core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp15
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h2
13 files changed, 118 insertions, 23 deletions
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index b94b3b458065..d76ca5bdce42 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -265,7 +265,8 @@ Status Idmap2Service::createFabricatedOverlay(
res.configuration.value_or(std::string()));
} else if (res.binaryData.has_value()) {
builder.SetResourceValue(res.resourceName, res.binaryData->get(),
- res.configuration.value_or(std::string()));
+ res.binaryDataOffset, res.binaryDataSize,
+ res.configuration.value_or(std::string()));
} else {
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 3ad6d58e8253..8ebd454705f0 100644
--- a/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl
+++ b/cmds/idmap2/idmap2d/aidl/core/android/os/FabricatedOverlayInternalEntry.aidl
@@ -26,4 +26,6 @@ parcelable FabricatedOverlayInternalEntry {
@nullable @utf8InCpp String stringData;
@nullable ParcelFileDescriptor binaryData;
@nullable @utf8InCpp String configuration;
+ long binaryDataOffset;
+ long binaryDataSize;
} \ No newline at end of file
diff --git a/cmds/idmap2/include/idmap2/FabricatedOverlay.h b/cmds/idmap2/include/idmap2/FabricatedOverlay.h
index a29fa8f3e1ab..1e7d4c28f45c 100644
--- a/cmds/idmap2/include/idmap2/FabricatedOverlay.h
+++ b/cmds/idmap2/include/idmap2/FabricatedOverlay.h
@@ -49,6 +49,8 @@ struct FabricatedOverlay {
Builder& SetResourceValue(const std::string& resource_name,
std::optional<android::base::borrowed_fd>&& binary_value,
+ off64_t data_binary_offset,
+ size_t data_binary_size,
const std::string& configuration);
inline Builder& setFrroPath(std::string frro_path) {
@@ -65,6 +67,8 @@ struct FabricatedOverlay {
DataValue data_value;
std::string data_string_value;
std::optional<android::base::borrowed_fd> data_binary_value;
+ off64_t data_binary_offset;
+ size_t data_binary_size;
std::string configuration;
};
@@ -76,6 +80,12 @@ struct FabricatedOverlay {
std::vector<Entry> entries_;
};
+ struct BinaryData {
+ android::base::borrowed_fd file_descriptor;
+ off64_t offset;
+ size_t size;
+ };
+
Result<Unit> ToBinaryStream(std::ostream& stream) const;
static Result<FabricatedOverlay> FromBinaryStream(std::istream& stream);
@@ -92,13 +102,13 @@ struct FabricatedOverlay {
explicit FabricatedOverlay(pb::FabricatedOverlay&& overlay,
std::string&& string_pool_data_,
- std::vector<android::base::borrowed_fd> binary_files_,
+ std::vector<FabricatedOverlay::BinaryData> binary_files_,
off_t total_binary_bytes_,
std::optional<uint32_t> crc_from_disk = {});
pb::FabricatedOverlay overlay_pb_;
std::string string_pool_data_;
- std::vector<android::base::borrowed_fd> binary_files_;
+ std::vector<FabricatedOverlay::BinaryData> binary_files_;
uint32_t total_binary_bytes_;
std::optional<uint32_t> crc_from_disk_;
mutable std::optional<SerializedData> data_;
diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h
index c2b0abed442c..d4490ef47b25 100644
--- a/cmds/idmap2/include/idmap2/ResourceUtils.h
+++ b/cmds/idmap2/include/idmap2/ResourceUtils.h
@@ -43,6 +43,8 @@ struct TargetValue {
DataValue data_value;
std::string data_string_value;
std::optional<android::base::borrowed_fd> data_binary_value;
+ off64_t data_binary_offset;
+ size_t data_binary_size;
};
struct TargetValueWithConfig {
diff --git a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
index dd5be21cd164..47daf23c6381 100644
--- a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
+++ b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
@@ -55,7 +55,7 @@ void Write32(std::ostream& stream, uint32_t value) {
FabricatedOverlay::FabricatedOverlay(pb::FabricatedOverlay&& overlay,
std::string&& string_pool_data,
- std::vector<android::base::borrowed_fd> binary_files,
+ std::vector<FabricatedOverlay::BinaryData> binary_files,
off_t total_binary_bytes,
std::optional<uint32_t> crc_from_disk)
: overlay_pb_(std::forward<pb::FabricatedOverlay>(overlay)),
@@ -81,7 +81,7 @@ FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetResourceValue(
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, "", std::nullopt, configuration});
+ Entry{resource_name, data_type, data_value, "", std::nullopt, 0, 0, configuration});
return *this;
}
@@ -89,14 +89,15 @@ FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetResourceValue(
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, std::nullopt, configuration});
+ Entry{resource_name, data_type, 0, data_string_value, std::nullopt, 0, 0, configuration});
return *this;
}
FabricatedOverlay::Builder& FabricatedOverlay::Builder::SetResourceValue(
const std::string& resource_name, std::optional<android::base::borrowed_fd>&& binary_value,
- const std::string& configuration) {
- entries_.emplace_back(Entry{resource_name, 0, 0, "", binary_value, configuration});
+ off64_t data_binary_offset, size_t data_binary_size, const std::string& configuration) {
+ entries_.emplace_back(Entry{resource_name, 0, 0, "", binary_value,
+ data_binary_offset, data_binary_size, configuration});
return *this;
}
@@ -148,7 +149,8 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() {
}
value->second = TargetValue{res_entry.data_type, res_entry.data_value,
- res_entry.data_string_value, res_entry.data_binary_value};
+ res_entry.data_string_value, res_entry.data_binary_value,
+ res_entry.data_binary_offset, res_entry.data_binary_size};
}
pb::FabricatedOverlay overlay_pb;
@@ -157,7 +159,7 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() {
overlay_pb.set_target_package_name(target_package_name_);
overlay_pb.set_target_overlayable(target_overlayable_);
- std::vector<android::base::borrowed_fd> binary_files;
+ std::vector<FabricatedOverlay::BinaryData> binary_files;
size_t total_binary_bytes = 0;
// 16 for the number of bytes in the frro file before the binary data
const size_t FRRO_HEADER_SIZE = 16;
@@ -182,16 +184,15 @@ Result<FabricatedOverlay> FabricatedOverlay::Builder::Build() {
pb_value->set_data_value(ref.index());
} else if (value.second.data_binary_value.has_value()) {
pb_value->set_data_type(Res_value::TYPE_STRING);
- struct stat s;
- if (fstat(value.second.data_binary_value->get(), &s) == -1) {
- return Error("unable to get size of binary file: %d", errno);
- }
std::string uri
= StringPrintf("frro:/%s?offset=%d&size=%d", frro_path_.c_str(),
static_cast<int> (FRRO_HEADER_SIZE + total_binary_bytes),
- static_cast<int> (s.st_size));
- total_binary_bytes += s.st_size;
- binary_files.emplace_back(value.second.data_binary_value->get());
+ static_cast<int> (value.second.data_binary_size));
+ total_binary_bytes += value.second.data_binary_size;
+ binary_files.emplace_back(FabricatedOverlay::BinaryData{
+ value.second.data_binary_value->get(),
+ value.second.data_binary_offset,
+ value.second.data_binary_size});
auto ref = string_pool.MakeRef(std::move(uri));
pb_value->set_data_value(ref.index());
} else {
@@ -310,8 +311,9 @@ Result<Unit> FabricatedOverlay::ToBinaryStream(std::ostream& stream) const {
Write32(stream, (*data)->pb_crc);
Write32(stream, total_binary_bytes_);
std::string file_contents;
- for (const android::base::borrowed_fd fd : binary_files_) {
- if (!ReadFdToString(fd, &file_contents)) {
+ for (const FabricatedOverlay::BinaryData fd : binary_files_) {
+ file_contents.resize(fd.size);
+ if (!ReadFullyAtOffset(fd.file_descriptor, file_contents.data(), fd.size, fd.offset)) {
return Error("Failed to read binary file data.");
}
stream.write(file_contents.data(), file_contents.length());
diff --git a/cmds/idmap2/self_targeting/SelfTargeting.cpp b/cmds/idmap2/self_targeting/SelfTargeting.cpp
index a8aa03309b16..c7f5cf3632c5 100644
--- a/cmds/idmap2/self_targeting/SelfTargeting.cpp
+++ b/cmds/idmap2/self_targeting/SelfTargeting.cpp
@@ -52,6 +52,7 @@ CreateFrroFile(std::string& out_err_result, const std::string& packageName,
const auto dataType = entry_params.data_type;
if (entry_params.data_binary_value.has_value()) {
builder.SetResourceValue(entry_params.resource_name, *entry_params.data_binary_value,
+ entry_params.binary_data_offset, entry_params.binary_data_size,
entry_params.configuration);
} else if (dataType >= Res_value::TYPE_FIRST_INT && dataType <= Res_value::TYPE_LAST_INT) {
builder.SetResourceValue(entry_params.resource_name, dataType,
diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
index e13a0eb5d488..b460bb33f559 100644
--- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp
+++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
@@ -59,7 +59,7 @@ TEST(FabricatedOverlayTests, SetResourceValue) {
Res_value::TYPE_STRING,
"foobar",
"en-rUS-normal-xxhdpi-v21")
- .SetResourceValue("com.example.target:drawable/dr1", fd, "port-xxhdpi-v7")
+ .SetResourceValue("com.example.target:drawable/dr1", fd, 0, 8341, "port-xxhdpi-v7")
.setFrroPath("/foo/bar/biz.frro")
.Build();
ASSERT_TRUE(overlay);
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index f6e48ba7a1f4..a3448fda60d9 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -269,7 +269,7 @@ TEST(IdmapTests, FabricatedOverlay) {
.SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "land-xxhdpi-v7")
.SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "land")
.SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "xxhdpi-v7")
- .SetResourceValue("drawable/dr1", fd, "port-xxhdpi-v7")
+ .SetResourceValue("drawable/dr1", fd, 0, 8341, "port-xxhdpi-v7")
.setFrroPath("/foo/bar/biz.frro")
.Build();
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 380e462a3aba..40f98c2f351b 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -212,7 +212,7 @@ TEST(ResourceMappingTests, FabricatedOverlay) {
.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("drawable/dr1", fd, "")
+ .SetResourceValue("drawable/dr1", fd, 0, 8341, "")
.setFrroPath("/foo/bar/biz.frro")
.Build();
diff --git a/core/api/current.txt b/core/api/current.txt
index 490195051f6a..0d9633e17376 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -11702,6 +11702,7 @@ package android.content.om {
method @NonNull public void setResourceValue(@NonNull String, @IntRange(from=android.util.TypedValue.TYPE_FIRST_INT, to=android.util.TypedValue.TYPE_LAST_INT) int, int, @Nullable String);
method @NonNull public void setResourceValue(@NonNull String, int, @NonNull String, @Nullable String);
method @NonNull public void setResourceValue(@NonNull String, @NonNull android.os.ParcelFileDescriptor, @Nullable String);
+ method @NonNull public void setResourceValue(@NonNull String, @NonNull android.content.res.AssetFileDescriptor, @Nullable String);
method public void setTargetOverlayable(@Nullable String);
}
diff --git a/core/java/android/content/om/FabricatedOverlay.java b/core/java/android/content/om/FabricatedOverlay.java
index 7e787c9c3a8c..c4547b8acc2b 100644
--- a/core/java/android/content/om/FabricatedOverlay.java
+++ b/core/java/android/content/om/FabricatedOverlay.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.res.AssetFileDescriptor;
import android.os.FabricatedOverlayInternal;
import android.os.FabricatedOverlayInternalEntry;
import android.os.ParcelFileDescriptor;
@@ -269,7 +270,7 @@ public class FabricatedOverlay {
* @param configuration The string representation of the config this overlay is enabled for
* @return the builder itself
* @deprecated Framework should use {@link FabricatedOverlay#setResourceValue(String,
- ParcelFileDescriptor, String)} instead.
+ ParcelFileDescriptor, String)} instead.
* @hide
*/
@Deprecated(since = "Please use FabricatedOverlay#setResourceValue instead")
@@ -285,6 +286,30 @@ public class FabricatedOverlay {
}
/**
+ * Sets the value of the fabricated overlay for the file descriptor type.
+ *
+ * @param resourceName name of the target resource to overlay (in the form
+ * [package]:type/entry)
+ * @param value the file descriptor whose contents are the value of the frro
+ * @param configuration The string representation of the config this overlay is enabled for
+ * @return the builder itself
+ * @deprecated Framework should use {@link FabricatedOverlay#setResourceValue(String,
+ ParcelFileDescriptor, String)} instead.
+ * @hide
+ */
+ @Deprecated(since = "Please use FabricatedOverlay#setResourceValue instead")
+ @NonNull
+ public Builder setResourceValue(
+ @NonNull String resourceName,
+ @NonNull AssetFileDescriptor value,
+ @Nullable String configuration) {
+ ensureValidResourceName(resourceName);
+ mEntries.add(
+ generateFabricatedOverlayInternalEntry(resourceName, value, configuration));
+ return this;
+ }
+
+ /**
* Builds an immutable fabricated overlay.
*
* @return the fabricated overlay
@@ -421,6 +446,21 @@ public class FabricatedOverlay {
entry.resourceName = resourceName;
entry.binaryData = Objects.requireNonNull(parcelFileDescriptor);
entry.configuration = configuration;
+ entry.binaryDataOffset = 0;
+ entry.binaryDataSize = parcelFileDescriptor.getStatSize();
+ return entry;
+ }
+
+ @NonNull
+ private static FabricatedOverlayInternalEntry generateFabricatedOverlayInternalEntry(
+ @NonNull String resourceName, @NonNull AssetFileDescriptor assetFileDescriptor,
+ @Nullable String configuration) {
+ final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
+ entry.resourceName = resourceName;
+ entry.binaryData = Objects.requireNonNull(assetFileDescriptor.getParcelFileDescriptor());
+ entry.binaryDataOffset = assetFileDescriptor.getStartOffset();
+ entry.binaryDataSize = assetFileDescriptor.getLength();
+ entry.configuration = configuration;
return entry;
}
@@ -495,4 +535,23 @@ public class FabricatedOverlay {
mOverlay.entries.add(
generateFabricatedOverlayInternalEntry(resourceName, value, configuration));
}
+
+ /**
+ * Sets the resource value in the fabricated overlay for the file descriptor type with the
+ * configuration.
+ *
+ * @param resourceName name of the target resource to overlay (in the form
+ * [package]:type/entry)
+ * @param value the file descriptor whose contents are the value of the frro
+ * @param configuration The string representation of the config this overlay is enabled for
+ */
+ @NonNull
+ public void setResourceValue(
+ @NonNull String resourceName,
+ @NonNull AssetFileDescriptor value,
+ @Nullable String configuration) {
+ ensureValidResourceName(resourceName);
+ mOverlay.entries.add(
+ generateFabricatedOverlayInternalEntry(resourceName, value, configuration));
+ }
}
diff --git a/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp b/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp
index bba1760bc45c..d4f6e1868695 100644
--- a/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp
+++ b/core/jni/com_android_internal_content_om_OverlayManagerImpl.cpp
@@ -44,6 +44,8 @@ static struct fabricated_overlay_internal_entry_offsets_t {
jfieldID stringData;
jfieldID binaryData;
jfieldID configuration;
+ jfieldID binaryDataOffset;
+ jfieldID binaryDataSize;
} gFabricatedOverlayInternalEntryOffsets;
static struct parcel_file_descriptor_offsets_t {
@@ -281,10 +283,17 @@ static void CreateFrroFile(JNIEnv* env, jclass /*clazz*/, jstring jsFrroFilePath
auto binary_data =
getNullableFileDescriptor(env, entry,
gFabricatedOverlayInternalEntryOffsets.binaryData);
+
+ const auto data_offset =
+ env->GetLongField(entry, gFabricatedOverlayInternalEntryOffsets.binaryDataOffset);
+ const auto data_size =
+ env->GetLongField(entry, gFabricatedOverlayInternalEntryOffsets.binaryDataSize);
entries_params.push_back(
FabricatedOverlayEntryParameters{resourceName.c_str(), (DataType)dataType,
(DataValue)data,
string_data.value_or(std::string()), binary_data,
+ static_cast<off64_t>(data_offset),
+ static_cast<size_t>(data_size),
configuration.value_or(std::string())});
ALOGV("resourceName = %s, dataType = 0x%08x, data = 0x%08x, dataString = %s,"
" binaryData = %d, configuration = %s",
@@ -440,6 +449,12 @@ int register_com_android_internal_content_om_OverlayManagerImpl(JNIEnv* env) {
gFabricatedOverlayInternalEntryOffsets.configuration =
GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject,
"configuration", "Ljava/lang/String;");
+ gFabricatedOverlayInternalEntryOffsets.binaryDataOffset =
+ GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject,
+ "binaryDataOffset", "J");
+ gFabricatedOverlayInternalEntryOffsets.binaryDataSize =
+ GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject,
+ "binaryDataSize", "J");
jclass parcelFileDescriptorClass =
android::FindClassOrDie(env, "android/os/ParcelFileDescriptor");
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 52666ab8d1d5..fdb355192676 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1872,6 +1872,8 @@ struct FabricatedOverlayEntryParameters {
DataValue data_value;
std::string data_string_value;
std::optional<android::base::borrowed_fd> data_binary_value;
+ off64_t binary_data_offset;
+ size_t binary_data_size;
std::string configuration;
};