[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
diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
index 6b1c7e8..15109d9 100644
--- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp
+++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp
@@ -144,7 +144,7 @@
               "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();
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index a384305..c85619c 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -274,7 +274,7 @@
                   .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, 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;
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index db44c23..1d22553 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -217,7 +217,7 @@
                   .Build();
 
   ASSERT_TRUE(frro);
-  TemporaryFile tf;
+  TempFrroFile tf;
   std::ofstream out(tf.path);
   ASSERT_TRUE((*frro).ToBinaryStream(out));
   out.close();
diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h
index cdc0b8f..bf01c32 100644
--- a/cmds/idmap2/tests/TestHelpers.h
+++ b/cmds/idmap2/tests/TestHelpers.h
@@ -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 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 {