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

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

[res] Use fstat() for idmap::IsUpToDate()

The most common operation when getting a new Resources object
is checking if all apks and overlays are still up to date to
reuse the cached object. It makes sense to optimize it by
excluding the file by path lookups and instead keeping an open
FD to the file in the cache

+ Make IsFabricatedOverlay() more efficient via a name check
  and string_view where possible

Bug: 282215580
Test: build + boot + presubmit
Change-Id: Ib1ab20cba359c2195a72dd2e10096883d95b4453
parent 43ff4a40
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ TEST(FabricatedOverlayTests, SerializeAndDeserialize) {
              "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "")
          .Build();
  ASSERT_TRUE(overlay);
  TemporaryFile tf;
  TempFrroFile tf;
  std::ofstream out(tf.path);
  ASSERT_TRUE((*overlay).ToBinaryStream(out));
  out.close();
+4 −4
Original line number Diff line number Diff line
@@ -274,7 +274,7 @@ TEST(IdmapTests, FabricatedOverlay) {
                  .Build();

  ASSERT_TRUE(frro);
  TemporaryFile tf;
  TempFrroFile tf;
  std::ofstream out(tf.path);
  ASSERT_TRUE((*frro).ToBinaryStream(out));
  out.close();
@@ -467,9 +467,9 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) {
TEST(IdmapTests, IdmapHeaderIsUpToDate) {
  fclose(stderr);  // silence expected warnings from libandroidfw

  const std::string target_apk_path = kIdmapRawTargetPath;
  const std::string overlay_apk_path = kIdmapRawOverlayPath;
  const std::string overlay_name = kIdmapRawOverlayName;
  const std::string target_apk_path {kIdmapRawTargetPath};
  const std::string overlay_apk_path {kIdmapRawOverlayPath};
  const std::string overlay_name {kIdmapRawOverlayName};
  const PolicyBitmask policies = kIdmapRawDataPolicies;
  const uint32_t target_crc = kIdmapRawDataTargetCrc;
  const uint32_t overlay_crc = kIdmapRawOverlayCrc;
+1 −1
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ TEST(ResourceMappingTests, FabricatedOverlay) {
                  .Build();

  ASSERT_TRUE(frro);
  TemporaryFile tf;
  TempFrroFile tf;
  std::ofstream out(tf.path);
  ASSERT_TRUE((*frro).ToBinaryStream(out));
  out.close();
+18 −3
Original line number Diff line number Diff line
@@ -17,11 +17,15 @@
#ifndef IDMAP2_TESTS_TESTHELPERS_H_
#define IDMAP2_TESTS_TESTHELPERS_H_

#include <stdio.h>
#include <string>
#include <string_view>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "android-base/file.h"

namespace android::idmap2 {

const unsigned char kIdmapRawData[] = {
@@ -197,12 +201,23 @@ const unsigned int kIdmapRawDataOffset = 0x54;
const unsigned int kIdmapRawDataTargetCrc = 0x1234;
const unsigned int kIdmapRawOverlayCrc = 0x5678;
const unsigned int kIdmapRawDataPolicies = 0x11;
inline const std::string kIdmapRawTargetPath = "targetX.apk";
inline const std::string kIdmapRawOverlayPath = "overlayX.apk";
inline const std::string kIdmapRawOverlayName = "OverlayName";
inline const std::string_view kIdmapRawTargetPath = "targetX.apk";
inline const std::string_view kIdmapRawOverlayPath = "overlayX.apk";
inline const std::string_view kIdmapRawOverlayName = "OverlayName";

std::string GetTestDataPath();

class TempFrroFile : public TemporaryFile {
public:
  TempFrroFile() {
    std::string new_path = path;
    new_path += ".frro";
    ::rename(path, new_path.c_str());
    const auto new_len = new_path.copy(path, sizeof(path) - 1);
    path[new_len] = '\0';
  }
};

class Idmap2Tests : public testing::Test {
 protected:
  void SetUp() override {
+2 −3
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ ApkAssetsPtr ApkAssets::LoadOverlay(const std::string& idmap_path, package_prope
  std::string overlay_path(loaded_idmap->OverlayApkPath());
  auto fd = unique_fd(base::utf8::open(overlay_path.c_str(), O_RDONLY | O_CLOEXEC));
  std::unique_ptr<AssetsProvider> overlay_assets;
  if (IsFabricatedOverlay(fd)) {
  if (IsFabricatedOverlayName(overlay_path) && IsFabricatedOverlay(fd)) {
    // Fabricated overlays do not contain resource definitions. All of the overlay resource values
    // are defined inline in the idmap.
    overlay_assets = EmptyAssetsProvider::Create(std::move(overlay_path));
@@ -137,8 +137,7 @@ ApkAssetsPtr ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_asset,
      return {};
    }
    loaded_arsc = LoadedArsc::Load(data, length, loaded_idmap.get(), property_flags);
  } else if (loaded_idmap != nullptr &&
      IsFabricatedOverlay(std::string(loaded_idmap->OverlayApkPath()))) {
  } else if (loaded_idmap != nullptr && IsFabricatedOverlay(loaded_idmap->OverlayApkPath())) {
    loaded_arsc = LoadedArsc::Load(loaded_idmap.get());
  } else {
    loaded_arsc = LoadedArsc::CreateEmpty();
Loading