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

Commit a47dafe2 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi Committed by Android (Google) Code Review
Browse files

Merge "Use reference counted pointers for ApkAssets"

parents 6ac28668 c357f719
Loading
Loading
Loading
Loading
+14 −17
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
    return Error("failed to parse config");
  }

  std::vector<std::unique_ptr<const ApkAssets>> apk_assets;
  std::vector<AssetManager2::ApkAssetsPtr> apk_assets;
  std::string target_path;
  std::string target_package_name;
  for (size_t i = 0; i < idmap_paths.size(); i++) {
@@ -217,13 +217,9 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
    apk_assets.push_back(std::move(overlay_apk));
  }

  // AssetManager2::SetApkAssets requires raw ApkAssets pointers, not unique_ptrs
  std::vector<const ApkAssets*> raw_pointer_apk_assets;
  std::transform(apk_assets.cbegin(), apk_assets.cend(), std::back_inserter(raw_pointer_apk_assets),
                 [](const auto& p) -> const ApkAssets* { return p.get(); });
  AssetManager2 am;
  am.SetApkAssets(raw_pointer_apk_assets);
  am.SetConfiguration(config);
  {
    // Make sure |apk_assets| vector outlives the asset manager as it doesn't own the assets.
    AssetManager2 am(apk_assets, config);

    const Result<ResourceId> resid = ParseResReference(am, resid_str, target_package_name);
    if (!resid) {
@@ -235,6 +231,7 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
      return Error(value.GetError(), "resource 0x%08x not found", *resid);
    }
    std::cout << *value << std::endl;
  }

  return Unit{};
}
+2 −2
Original line number Diff line number Diff line
@@ -262,7 +262,7 @@ OverlayData CreateResourceMappingLegacy(const AssetManager2* overlay_am,
}

struct ResState {
  std::unique_ptr<ApkAssets> apk_assets;
  AssetManager2::ApkAssetsPtr apk_assets;
  const LoadedArsc* arsc;
  const LoadedPackage* package;
  std::unique_ptr<AssetManager2> am;
@@ -284,7 +284,7 @@ struct ResState {
    }

    state.am = std::make_unique<AssetManager2>();
    if (!state.am->SetApkAssets({state.apk_assets.get()})) {
    if (!state.am->SetApkAssets({state.apk_assets})) {
      return Error("failed to create asset manager");
    }

+2 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ class ResourceUtilsTests : public Idmap2Tests {
    apk_assets_ = ApkAssets::Load(GetTargetApkPath());
    ASSERT_THAT(apk_assets_, NotNull());

    am_.SetApkAssets({apk_assets_.get()});
    am_.SetApkAssets({apk_assets_});
  }

  const AssetManager2& GetAssetManager() {
@@ -47,7 +47,7 @@ class ResourceUtilsTests : public Idmap2Tests {

 private:
  AssetManager2 am_;
  std::unique_ptr<const ApkAssets> apk_assets_;
  AssetManager2::ApkAssetsPtr apk_assets_;
};

TEST_F(ResourceUtilsTests, ResToTypeEntryName) {
+37 −11
Original line number Diff line number Diff line
@@ -74,16 +74,36 @@ enum : format_type_t {
  FORMAT_DIRECTORY = 3,
};

Guarded<std::unique_ptr<const ApkAssets>>& ApkAssetsFromLong(jlong ptr) {
    return *reinterpret_cast<Guarded<std::unique_ptr<const ApkAssets>>*>(ptr);
Guarded<AssetManager2::ApkAssetsPtr>& ApkAssetsFromLong(jlong ptr) {
  return *reinterpret_cast<Guarded<AssetManager2::ApkAssetsPtr>*>(ptr);
}

static jlong CreateGuardedApkAssets(std::unique_ptr<const ApkAssets> assets) {
    auto guarded_assets = new Guarded<std::unique_ptr<const ApkAssets>>(std::move(assets));
static jlong CreateGuardedApkAssets(AssetManager2::ApkAssetsPtr assets) {
  auto guarded_assets = new Guarded<AssetManager2::ApkAssetsPtr>(std::move(assets));
  return reinterpret_cast<jlong>(guarded_assets);
}

static void DeleteGuardedApkAssets(Guarded<std::unique_ptr<const ApkAssets>>& apk_assets) {
static void DeleteGuardedApkAssets(Guarded<AssetManager2::ApkAssetsPtr>& apk_assets) {
  apk_assets.safeDelete([&apk_assets](AssetManager2::ApkAssetsPtr* assets) {
    if (!assets) {
      ALOGE("ApkAssets: Double delete of native assets object %p, ignored", &apk_assets);
    } else if (!*assets) {
      ALOGE("ApkAssets: Empty native assets pointer in native assets object %p", &apk_assets);
    } else {
      // |RefBase| increments |StrongCount| for each |sp<>| instance, and |WeakCount| for
      // both |sp<>| and |wp<>| instances. This means the actual |wp<>| instance count
      // is |WeakCount - StrongCount|.
      const auto useCount = (*assets)->getStrongCount();
      const auto weakCount = (*assets)->getWeakRefs()->getWeakCount() - useCount;
      if (useCount > 1) {
        ALOGE("ApkAssets: Deleting an object '%s' with %d > 1 strong and %d weak references",
              (*assets)->GetDebugName().c_str(), int(useCount), int(weakCount));
      } else if (weakCount > 0) {
        ALOGE("ApkAssets: Deleting an ApkAssets object '%s' with %d weak references",
              (*assets)->GetDebugName().c_str(), int(weakCount));
      }
    }
  });
  delete &apk_assets;
}

@@ -209,7 +229,7 @@ static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, const format_type_t forma
  ATRACE_NAME(base::StringPrintf("LoadApkAssets(%s)", path.c_str()).c_str());

  auto loader_assets = LoaderAssetsProvider::Create(env, assets_provider);
  std::unique_ptr<ApkAssets> apk_assets;
  AssetManager2::ApkAssetsPtr apk_assets;
  switch (format) {
    case FORMAT_APK: {
        auto assets = MultiAssetsProvider::Create(std::move(loader_assets),
@@ -269,7 +289,7 @@ static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, const format_type_t
  }

  auto loader_assets = LoaderAssetsProvider::Create(env, assets_provider);
  std::unique_ptr<const ApkAssets> apk_assets;
  AssetManager2::ApkAssetsPtr apk_assets;
  switch (format) {
    case FORMAT_APK: {
        auto assets =
@@ -336,7 +356,7 @@ static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_
  }

  auto loader_assets = LoaderAssetsProvider::Create(env, assets_provider);
  std::unique_ptr<const ApkAssets> apk_assets;
  AssetManager2::ApkAssetsPtr apk_assets;
  switch (format) {
    case FORMAT_APK: {
        auto assets =
@@ -374,6 +394,12 @@ static jlong NativeLoadFromFdOffset(JNIEnv* env, jclass /*clazz*/, const format_

static jlong NativeLoadEmpty(JNIEnv* env, jclass /*clazz*/, jint flags, jobject assets_provider) {
  auto apk_assets = ApkAssets::Load(LoaderAssetsProvider::Create(env, assets_provider), flags);
  if (apk_assets == nullptr) {
    const std::string error_msg =
        base::StringPrintf("Failed to load empty assets with provider %p", (void*)assets_provider);
    jniThrowException(env, "java/io/IOException", error_msg.c_str());
    return 0;
  }
  return CreateGuardedApkAssets(std::move(apk_assets));
}

+2 −2
Original line number Diff line number Diff line
@@ -18,13 +18,13 @@
#define ANDROID_CONTENT_RES_APKASSETS_H

#include "androidfw/ApkAssets.h"
#include "androidfw/AssetManager2.h"
#include "androidfw/MutexGuard.h"

#include "jni.h"

namespace android {

Guarded<std::unique_ptr<const ApkAssets>>& ApkAssetsFromLong(jlong ptr);
Guarded<AssetManager2::ApkAssetsPtr>& ApkAssetsFromLong(jlong ptr);

} // namespace android

Loading