IO error reporting in the last AssetManager func
GetBagResIdStack() used to report no errors
Bug: n/a
Test: UTs
Change-Id: I73c88715dff5ed9f621bcaea1910b05818e1d608
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index fc53a76..cac6f08 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1127,20 +1127,28 @@
}
auto style_stack = assetmanager->GetBagResIdStack(xml_style_res);
+ if (!style_stack.ok()) {
+ jniThrowIOException(env, EBADMSG);
+ return nullptr;
+ }
auto def_style_stack = assetmanager->GetBagResIdStack(def_style_resid);
+ if (!def_style_stack.ok()) {
+ jniThrowIOException(env, EBADMSG);
+ return nullptr;
+ }
- jintArray array = env->NewIntArray(style_stack.size() + def_style_stack.size());
+ jintArray array = env->NewIntArray(style_stack.value()->size() + def_style_stack.value()->size());
if (env->ExceptionCheck()) {
return nullptr;
}
- for (uint32_t i = 0; i < style_stack.size(); i++) {
- jint attr_resid = style_stack[i];
+ for (uint32_t i = 0; i < style_stack.value()->size(); i++) {
+ jint attr_resid = (*style_stack.value())[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);
+ for (uint32_t i = 0; i < def_style_stack.value()->size(); i++) {
+ jint attr_resid = (*def_style_stack.value())[i];
+ env->SetIntArrayRegion(array, style_stack.value()->size() + i, 1, &attr_resid);
}
return array;
}
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index fd5d07f..769e326 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -1092,16 +1092,17 @@
}
}
-const std::vector<uint32_t> AssetManager2::GetBagResIdStack(uint32_t resid) const {
- auto cached_iter = cached_bag_resid_stacks_.find(resid);
- if (cached_iter != cached_bag_resid_stacks_.end()) {
- return cached_iter->second;
+base::expected<const std::vector<uint32_t>*, NullOrIOError> AssetManager2::GetBagResIdStack(
+ uint32_t resid) const {
+ auto [it, inserted] = cached_bag_resid_stacks_.try_emplace(resid);
+ if (inserted) {
+ // This is a new entry in the cache, need to populate it.
+ if (auto maybe_bag = GetBag(resid, it->second); !maybe_bag.ok()) {
+ cached_bag_resid_stacks_.erase(it);
+ return base::unexpected(maybe_bag.error());
+ }
}
-
- std::vector<uint32_t> found_resids;
- GetBag(resid, found_resids);
- cached_bag_resid_stacks_.emplace(resid, found_resids);
- return found_resids;
+ return &it->second;
}
base::expected<const ResolvedBag*, NullOrIOError> AssetManager2::ResolveBag(
@@ -1120,7 +1121,7 @@
base::expected<const ResolvedBag*, NullOrIOError> AssetManager2::GetBag(uint32_t resid) const {
std::vector<uint32_t> found_resids;
const auto bag = GetBag(resid, found_resids);
- cached_bag_resid_stacks_.emplace(resid, std::move(found_resids));
+ cached_bag_resid_stacks_.try_emplace(resid, std::move(found_resids));
return bag;
}
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index cedf732..f611d0d 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -243,9 +243,14 @@
friend AssetManager2;
friend Theme;
SelectedValue() = default;
- SelectedValue(const ResolvedBag* bag, const ResolvedBag::Entry& entry) :
- cookie(entry.cookie), data(entry.value.data), type(entry.value.dataType),
- flags(bag->type_spec_flags), resid(0U), config({}) {};
+ SelectedValue(const ResolvedBag* bag, const ResolvedBag::Entry& entry)
+ : cookie(entry.cookie),
+ data(entry.value.data),
+ type(entry.value.dataType),
+ flags(bag->type_spec_flags),
+ resid(0U),
+ config() {
+ }
// The cookie representing the ApkAssets in which the value resides.
ApkAssetsCookie cookie = kInvalidCookie;
@@ -327,7 +332,8 @@
// resource data failed.
base::expected<uint32_t, NullOrIOError> GetResourceTypeSpecFlags(uint32_t resid) const;
- const std::vector<uint32_t> GetBagResIdStack(uint32_t resid) const;
+ base::expected<const std::vector<uint32_t>*, NullOrIOError> GetBagResIdStack(
+ uint32_t resid) const;
// Resets the resource resolution structures in preparation for the next resource retrieval.
void ResetResourceResolution() const;