Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd1db5d3 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi
Browse files

Only fail GetBag if there was an IO Error

AssetManager2::GetBag* functions may return "no value" for
the missing resources, that's not an error and shouldn't
result in java exceptions

+ fix the perf regression from extra level of indirection

Bug: 282264161
Test: libandroidfw_tests + boot
Change-Id: Iea32b248b1ca9f6a366b44a14866da16d6b2ef6b
parent 24fc8379
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -1126,30 +1126,29 @@ static jintArray NativeAttributeResolutionStack(JNIEnv* env, jclass /*clazz*/, j
    }
  }

  auto style_stack = assetmanager->GetBagResIdStack(xml_style_res);
  if (!style_stack.ok()) {
  const auto maybe_style_stack = assetmanager->GetBagResIdStack(xml_style_res);
  if (!maybe_style_stack.ok()) {
    jniThrowIOException(env, EBADMSG);
    return nullptr;
  }
  auto def_style_stack = assetmanager->GetBagResIdStack(def_style_resid);
  if (!def_style_stack.ok()) {
  const auto& style_stack = *maybe_style_stack.value();
  const auto maybe_def_style_stack = assetmanager->GetBagResIdStack(def_style_resid);
  if (!maybe_def_style_stack.ok()) {
    jniThrowIOException(env, EBADMSG);
    return nullptr;
  }
  const auto& def_style_stack = *maybe_def_style_stack.value();

  jintArray array = env->NewIntArray(style_stack.value()->size() + def_style_stack.value()->size());
  jintArray array = env->NewIntArray(style_stack.size() + def_style_stack.size());
  if (env->ExceptionCheck()) {
    return nullptr;
  }

  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.value()->size(); i++) {
    jint attr_resid = (*def_style_stack.value())[i];
    env->SetIntArrayRegion(array, style_stack.value()->size() + i, 1, &attr_resid);
  }
  static_assert(sizeof(jint) == sizeof(decltype(style_stack.front())));
  env->SetIntArrayRegion(array, 0, style_stack.size(),
                         reinterpret_cast<const jint*>(style_stack.data()));
  env->SetIntArrayRegion(array, style_stack.size(), def_style_stack.size(),
                         reinterpret_cast<const jint*>(def_style_stack.data()));
  return array;
}

+8 −4
Original line number Diff line number Diff line
@@ -1097,7 +1097,7 @@ base::expected<const std::vector<uint32_t>*, NullOrIOError> AssetManager2::GetBa
  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()) {
    if (auto maybe_bag = GetBag(resid, it->second); UNLIKELY(IsIOError(maybe_bag))) {
      cached_bag_resid_stacks_.erase(it);
      return base::unexpected(maybe_bag.error());
    }
@@ -1119,9 +1119,13 @@ base::expected<const ResolvedBag*, NullOrIOError> AssetManager2::ResolveBag(
}

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_.try_emplace(resid, std::move(found_resids));
  auto [resid_stacks_it, _] = cached_bag_resid_stacks_.try_emplace(resid);
  resid_stacks_it->second.clear();
  const auto bag = GetBag(resid, resid_stacks_it->second);
  if (UNLIKELY(IsIOError(bag))) {
    cached_bag_resid_stacks_.erase(resid_stacks_it);
    return base::unexpected(bag.error());
  }
  return bag;
}