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

Commit ce231553 authored by Brandon Liu's avatar Brandon Liu Committed by Android (Google) Code Review
Browse files

Merge "Fix tests affected by sparse.apk"

parents 6c82da41 742b11e0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -211,6 +211,8 @@ cc_test {
        "tests/data/**/*.apk",
        "tests/data/**/*.arsc",
        "tests/data/**/*.idmap",
        ":FrameworkResourcesSparseTestApp",
        ":FrameworkResourcesNotSparseTestApp",
    ],
    test_suites: ["device-tests"],
}
+80 −56
Original line number Diff line number Diff line
@@ -71,62 +71,6 @@ TEST(LoadedArscTest, LoadSinglePackageArsc) {
  ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
}

TEST(LoadedArscTest, LoadSparseEntryApp) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/sparse/sparse.apk", "resources.arsc",
                                      &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(),
                                                                   contents.length());
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package =
      loaded_arsc->GetPackageById(get_package_id(sparse::R::integer::foo_9));
  ASSERT_THAT(package, NotNull());

  const uint8_t type_index = get_type_id(sparse::R::integer::foo_9) - 1;
  const uint16_t entry_index = get_entry_id(sparse::R::integer::foo_9);

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));

  auto type = type_spec->type_entries[0];
  ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
}

TEST(LoadedArscTest, FindSparseEntryApp) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/sparse/sparse.apk", "resources.arsc",
                                      &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(),
                                                                   contents.length());
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package =
      loaded_arsc->GetPackageById(get_package_id(sparse::R::string::only_v26));
  ASSERT_THAT(package, NotNull());

  const uint8_t type_index = get_type_id(sparse::R::string::only_v26) - 1;
  const uint16_t entry_index = get_entry_id(sparse::R::string::only_v26);

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));

  // Ensure that AAPT2 sparsely encoded the v26 config as expected.
  auto type_entry = std::find_if(
    type_spec->type_entries.begin(), type_spec->type_entries.end(),
    [](const TypeSpec::TypeEntry& x) { return x.config.sdkVersion == 26; });
  ASSERT_NE(type_entry, type_spec->type_entries.end());
  ASSERT_NE(type_entry->type->flags & ResTable_type::FLAG_SPARSE, 0);

  // Test fetching a resource with only sparsely encoded configs by name.
  auto id = package->FindEntryByName(u"string", u"only_v26");
  ASSERT_EQ(id.value(), fix_package_id(sparse::R::string::only_v26, 0));
}

TEST(LoadedArscTest, LoadSharedLibrary) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc",
@@ -404,4 +348,84 @@ TEST(LoadedArscTest, LoadCustomLoader) {
// sizeof(Res_value) might not be backwards compatible.
// TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }

class LoadedArscParameterizedTest :
    public testing::TestWithParam<std::string> {
};

TEST_P(LoadedArscParameterizedTest, LoadSparseEntryApp) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetParam(), "resources.arsc", &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(),
                                                                   contents.length());
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package =
      loaded_arsc->GetPackageById(get_package_id(sparse::R::integer::foo_9));
  ASSERT_THAT(package, NotNull());

  const uint8_t type_index = get_type_id(sparse::R::integer::foo_9) - 1;
  const uint16_t entry_index = get_entry_id(sparse::R::integer::foo_9);

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));

  auto type = type_spec->type_entries[0];
  ASSERT_TRUE(LoadedPackage::GetEntry(type.type, entry_index).has_value());
}

TEST_P(LoadedArscParameterizedTest, FindSparseEntryApp) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetParam(), "resources.arsc", &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(),
                                                                   contents.length());
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package =
      loaded_arsc->GetPackageById(get_package_id(sparse::R::string::only_land));
  ASSERT_THAT(package, NotNull());

  const uint8_t type_index = get_type_id(sparse::R::string::only_land) - 1;

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_entries.size(), Ge(1u));

  // Type Entry with default orientation is not sparse encoded because the ratio of
  // populated entries to total entries is above threshold.
  // Only find out default locale because Soong build system will introduce pseudo
  // locales for the apk generated at runtime.
  auto type_entry_default = std::find_if(
    type_spec->type_entries.begin(), type_spec->type_entries.end(),
    [] (const TypeSpec::TypeEntry& x) { return x.config.orientation == 0 &&
                                               x.config.locale == 0; });
  ASSERT_NE(type_entry_default, type_spec->type_entries.end());
  ASSERT_EQ(type_entry_default->type->flags & ResTable_type::FLAG_SPARSE, 0);

  // Type Entry with land orientation is sparse encoded as expected.
  // Only find out default locale because Soong build system will introduce pseudo
  // locales for the apk generated at runtime.
  auto type_entry_land = std::find_if(
    type_spec->type_entries.begin(), type_spec->type_entries.end(),
    [](const TypeSpec::TypeEntry& x) { return x.config.orientation ==
                                              ResTable_config::ORIENTATION_LAND &&
                                              x.config.locale == 0; });
  ASSERT_NE(type_entry_land, type_spec->type_entries.end());
  ASSERT_NE(type_entry_land->type->flags & ResTable_type::FLAG_SPARSE, 0);

  // Test fetching a resource with only sparsely encoded configs by name.
  auto id = package->FindEntryByName(u"string", u"only_land");
  ASSERT_EQ(id.value(), fix_package_id(sparse::R::string::only_land, 0));
}

INSTANTIATE_TEST_SUITE_P(
        FrameWorkResourcesLoadedArscTests,
        LoadedArscParameterizedTest,
        ::testing::Values(
          base::GetExecutableDirectory() + "/tests/data/sparse/sparse.apk",
          base::GetExecutableDirectory() + "/FrameworkResourcesSparseTestApp.apk"
        ));

}  // namespace android
+40 −28
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include "androidfw/ResourceTypes.h"
#include "android-base/file.h"

#include <codecvt>
#include <locale>
@@ -41,34 +42,6 @@ TEST(ResTableTest, ShouldLoadSuccessfully) {
  ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));
}

TEST(ResTableTest, ShouldLoadSparseEntriesSuccessfully) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/sparse/sparse.apk", "resources.arsc",
                                      &contents));

  ResTable table;
  ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));

  ResTable_config config;
  memset(&config, 0, sizeof(config));
  config.sdkVersion = 26;
  table.setParameters(&config);

  String16 name(u"com.android.sparse:integer/foo_9");
  uint32_t flags;
  uint32_t resid =
      table.identifierForName(name.string(), name.size(), nullptr, 0, nullptr, 0, &flags);
  ASSERT_NE(0u, resid);

  Res_value val;
  ResTable_config selected_config;
  ASSERT_GE(
      table.getResource(resid, &val, false /*mayBeBag*/, 0u /*density*/, &flags, &selected_config),
      0);
  EXPECT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
  EXPECT_EQ(900u, val.data);
}

TEST(ResTableTest, SimpleTypeIsRetrievedCorrectly) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
@@ -476,4 +449,43 @@ TEST(ResTableTest, TruncatedEncodeLength) {
  ASSERT_FALSE(invalid_pool->stringAt(invalid_val.data).has_value());
}

class ResTableParameterizedTest :
    public testing::TestWithParam<std::string> {
};

TEST_P(ResTableParameterizedTest, ShouldLoadSparseEntriesSuccessfully) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetParam(), "resources.arsc", &contents));

  ResTable table;
  ASSERT_EQ(NO_ERROR, table.add(contents.data(), contents.size()));

  ResTable_config config;
  memset(&config, 0, sizeof(config));
  config.orientation = ResTable_config::ORIENTATION_LAND;
  table.setParameters(&config);

  String16 name(u"com.android.sparse:integer/foo_9");
  uint32_t flags;
  uint32_t resid =
      table.identifierForName(name.string(), name.size(), nullptr, 0, nullptr, 0, &flags);
  ASSERT_NE(0u, resid);

  Res_value val;
  ResTable_config selected_config;
  ASSERT_GE(
      table.getResource(resid, &val, false /*mayBeBag*/, 0u /*density*/, &flags, &selected_config),
      0);
  EXPECT_EQ(Res_value::TYPE_INT_DEC, val.dataType);
  EXPECT_EQ(900u, val.data);
}

INSTANTIATE_TEST_SUITE_P(
        FrameWorkResourcesResTableTests,
        ResTableParameterizedTest,
        ::testing::Values(
           base::GetExecutableDirectory() + "/tests/data/sparse/sparse.apk",
           base::GetExecutableDirectory() + "/FrameworkResourcesSparseTestApp.apk"
        ));

}  // namespace android
+51 −16
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include "androidfw/AssetManager.h"
#include "androidfw/ResourceTypes.h"
#include "android-base/file.h"

#include "BenchmarkHelpers.h"
#include "data/sparse/R.h"
@@ -24,40 +25,74 @@ namespace sparse = com::android::sparse;

namespace android {

static void BM_SparseEntryGetResourceOldSparse(benchmark::State& state, uint32_t resid) {
static void BM_SparseEntryGetResourceHelper(const std::vector<std::string>& paths,
                    uint32_t resid, benchmark::State& state, void (*GetResourceBenchmarkFunc)(
                    const std::vector<std::string>&, const ResTable_config*,
                    uint32_t, benchmark::State&)){
    ResTable_config config;
    memset(&config, 0, sizeof(config));
  config.sdkVersion = 26;
  GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/sparse.apk"}, &config, resid, state);
    config.orientation = ResTable_config::ORIENTATION_LAND;
    GetResourceBenchmarkFunc(paths, &config, resid, state);
}

static void BM_SparseEntryGetResourceOldSparse(benchmark::State& state, uint32_t resid) {
  BM_SparseEntryGetResourceHelper({GetTestDataPath() + "/sparse/sparse.apk"}, resid,
                                    state, &GetResourceBenchmarkOld);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldSparse, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldSparse, Large, sparse::R::string::foo_999);

static void BM_SparseEntryGetResourceOldNotSparse(benchmark::State& state, uint32_t resid) {
  ResTable_config config;
  memset(&config, 0, sizeof(config));
  config.sdkVersion = 26;
  GetResourceBenchmarkOld({GetTestDataPath() + "/sparse/not_sparse.apk"}, &config, resid, state);
   BM_SparseEntryGetResourceHelper({GetTestDataPath() + "/sparse/not_sparse.apk"}, resid,
                                   state, &GetResourceBenchmarkOld);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldNotSparse, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldNotSparse, Large, sparse::R::string::foo_999);

static void BM_SparseEntryGetResourceSparse(benchmark::State& state, uint32_t resid) {
  ResTable_config config;
  memset(&config, 0, sizeof(config));
  config.sdkVersion = 26;
  GetResourceBenchmark({GetTestDataPath() + "/sparse/sparse.apk"}, &config, resid, state);
  BM_SparseEntryGetResourceHelper({GetTestDataPath() + "/sparse/sparse.apk"}, resid,
                                  state, &GetResourceBenchmark);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceSparse, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceSparse, Large, sparse::R::string::foo_999);

static void BM_SparseEntryGetResourceNotSparse(benchmark::State& state, uint32_t resid) {
  ResTable_config config;
  memset(&config, 0, sizeof(config));
  config.sdkVersion = 26;
  GetResourceBenchmark({GetTestDataPath() + "/sparse/not_sparse.apk"}, &config, resid, state);
  BM_SparseEntryGetResourceHelper({GetTestDataPath() + "/sparse/not_sparse.apk"}, resid,
                                  state, &GetResourceBenchmark);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceNotSparse, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceNotSparse, Large, sparse::R::string::foo_999);

static void BM_SparseEntryGetResourceOldSparseRuntime(benchmark::State& state, uint32_t resid) {
  BM_SparseEntryGetResourceHelper({base::GetExecutableDirectory() +
                                  "/FrameworkResourcesSparseTestApp.apk"}, resid, state,
                                  &GetResourceBenchmarkOld);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldSparseRuntime, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldSparseRuntime, Large, sparse::R::string::foo_999);

static void BM_SparseEntryGetResourceOldNotSparseRuntime(benchmark::State& state, uint32_t resid) {
  BM_SparseEntryGetResourceHelper({base::GetExecutableDirectory() +
                                  "/FrameworkResourcesNotSparseTestApp.apk"}, resid, state,
                                  &GetResourceBenchmarkOld);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldNotSparseRuntime, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceOldNotSparseRuntime, Large, sparse::R::string::foo_999);

static void BM_SparseEntryGetResourceSparseRuntime(benchmark::State& state, uint32_t resid) {
  BM_SparseEntryGetResourceHelper({base::GetExecutableDirectory() +
                                  "/FrameworkResourcesSparseTestApp.apk"}, resid, state,
                                  &GetResourceBenchmark);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceSparseRuntime, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceSparseRuntime, Large, sparse::R::string::foo_999);

static void BM_SparseEntryGetResourceNotSparseRuntime(benchmark::State& state, uint32_t resid) {
  BM_SparseEntryGetResourceHelper({base::GetExecutableDirectory() +
                                  "/FrameworkResourcesNotSparseTestApp.apk"}, resid, state,
                                  &GetResourceBenchmark);
}
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceNotSparseRuntime, Small, sparse::R::integer::foo_9);
BENCHMARK_CAPTURE(BM_SparseEntryGetResourceNotSparseRuntime, Large, sparse::R::string::foo_999);

}  // namespace android
+14 −0
Original line number Diff line number Diff line
android_test_helper_app {
    name: "FrameworkResourcesSparseTestApp",
    sdk_version: "current",
    min_sdk_version: "32",
    aaptflags: [
        "--enable-sparse-encoding",
    ],
}

android_test_helper_app {
    name: "FrameworkResourcesNotSparseTestApp",
    sdk_version: "current",
    min_sdk_version: "32",
}
Loading