Loading AconfigFlags.bp +11 −0 Original line number Original line Diff line number Diff line Loading @@ -800,6 +800,17 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], defaults: ["framework-minus-apex-aconfig-java-defaults"], } } cc_aconfig_library { name: "android.content.res.flags-aconfig-cc", aconfig_declarations: "android.content.res.flags-aconfig", } cc_aconfig_library { name: "android.content.res.flags-aconfig-cc-host", aconfig_declarations: "android.content.res.flags-aconfig", host_supported: true, } // Media BetterTogether // Media BetterTogether aconfig_declarations { aconfig_declarations { name: "com.android.media.flags.bettertogether-aconfig", name: "com.android.media.flags.bettertogether-aconfig", Loading cmds/idmap2/Android.bp +26 −1 Original line number Original line Diff line number Diff line Loading @@ -86,16 +86,20 @@ cc_library { static_libs: [ static_libs: [ "libidmap2_policies", "libidmap2_policies", "libidmap2_protos", "libidmap2_protos", "libpng", "android.content.res.flags-aconfig-cc", ], ], shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", "liblog", "libpng", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], }, }, host: { host: { Loading @@ -103,16 +107,20 @@ cc_library { enabled: false, enabled: false, }, }, static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc-host", "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", "libidmap2_policies", "libidmap2_policies", "libidmap2_protos", "libidmap2_protos", "liblog", "libpng", "libpng", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], }, }, }, }, Loading Loading @@ -193,6 +201,7 @@ cc_test { target: { target: { android: { android: { shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libidmap2", "libidmap2", Loading @@ -202,13 +211,17 @@ cc_test { "libz", "libz", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], static_libs: [ static_libs: [ "libidmap2_policies", "libidmap2_policies", "android.content.res.flags-aconfig-cc", ], ], }, }, host: { host: { static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc-host", "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", Loading @@ -218,6 +231,7 @@ cc_test { "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libziparchive", "libziparchive", "server_configurable_flags", ], ], shared_libs: [ shared_libs: [ "libz", "libz", Loading Loading @@ -258,22 +272,28 @@ cc_binary { target: { target: { android: { android: { shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", "libidmap2", "libidmap2", "liblog", "libpng", "libpng", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc", "libidmap2_policies", "libidmap2_policies", ], ], }, }, host: { host: { static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc-host", "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", Loading @@ -284,6 +304,7 @@ cc_binary { "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libziparchive", "libziparchive", "server_configurable_flags", ], ], shared_libs: [ shared_libs: [ "libz", "libz", Loading @@ -304,16 +325,20 @@ cc_binary { "idmap2d/Main.cpp", "idmap2d/Main.cpp", ], ], shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libbinder", "libbinder", "libcutils", "libcutils", "libidmap2", "libidmap2", "liblog", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libziparchive", "libziparchive", "server_configurable_flags", ], ], static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc", "libidmap2_policies", "libidmap2_policies", "libidmap2_protos", "libidmap2_protos", "libidmap2daidl", "libidmap2daidl", Loading cmds/idmap2/idmap2/CommandUtils.cpp +23 −14 Original line number Original line Diff line number Diff line Loading @@ -16,15 +16,20 @@ #include "idmap2/CommandUtils.h" #include "idmap2/CommandUtils.h" #include <android_content_res.h> #include <fstream> #include <fstream> #include <memory> #include <memory> #include <string> #include <string> #include <vector> #include <vector> #include "androidfw/misc.h" #include "idmap2/Idmap.h" #include "idmap2/Idmap.h" #include "idmap2/Result.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/SysTrace.h" using android::getFileModDate; using android::toTimeT; using android::idmap2::Error; using android::idmap2::Error; using android::idmap2::IdmapHeader; using android::idmap2::IdmapHeader; using android::idmap2::OverlayResourceContainer; using android::idmap2::OverlayResourceContainer; Loading @@ -42,21 +47,25 @@ Result<Unit> Verify(const std::string& idmap_path, const std::string& target_pat if (!header) { if (!header) { return Error("failed to parse idmap header"); return Error("failed to parse idmap header"); } } std::optional<Result<Unit>> header_ok; if (android_content_res_idmap_crc_is_mtime()) { header_ok = header->IsUpToDate( target_path, overlay_path, overlay_name, toTimeT(getFileModDate(target_path.c_str())), toTimeT(getFileModDate(overlay_path.c_str())), fulfilled_policies, enforce_overlayable); } else { auto target = TargetResourceContainer::FromPath(target_path); auto target = TargetResourceContainer::FromPath(target_path); if (!target) { if (!target) { return Error("failed to load target '%s'", target_path.c_str()); return Error("failed to load target '%s'", target_path.c_str()); } } auto overlay = OverlayResourceContainer::FromPath(overlay_path); auto overlay = OverlayResourceContainer::FromPath(overlay_path); if (!overlay) { if (!overlay) { return Error("failed to load overlay '%s'", overlay_path.c_str()); return Error("failed to load overlay '%s'", overlay_path.c_str()); } } header_ok = header->IsUpToDate(**target, **overlay, overlay_name, fulfilled_policies, const auto header_ok = header->IsUpToDate(**target, **overlay, overlay_name, fulfilled_policies, enforce_overlayable); enforce_overlayable); if (!header_ok) { } return Error(header_ok.GetError(), "idmap not up to date"); if (!*header_ok) { return Error(header_ok->GetError(), "idmap not up to date"); } } return Unit{}; return Unit{}; } } cmds/idmap2/idmap2d/Idmap2Service.cpp +29 −20 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ #include "idmap2d/Idmap2Service.h" #include "idmap2d/Idmap2Service.h" #include <android_content_res.h> #include <fcntl.h> #include <sys/stat.h> // umask #include <sys/stat.h> // umask #include <sys/types.h> // umask #include <sys/types.h> // umask Loading @@ -39,7 +41,6 @@ #include "idmap2/PrettyPrintVisitor.h" #include "idmap2/PrettyPrintVisitor.h" #include "idmap2/Result.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/SysTrace.h" #include <fcntl.h> using android::base::StringPrintf; using android::base::StringPrintf; using android::binder::Status; using android::binder::Status; Loading @@ -51,7 +52,9 @@ using android::idmap2::IdmapConstraints; using android::idmap2::IdmapHeader; using android::idmap2::IdmapHeader; using android::idmap2::OverlayResourceContainer; using android::idmap2::OverlayResourceContainer; using android::idmap2::PrettyPrintVisitor; using android::idmap2::PrettyPrintVisitor; using android::idmap2::Result; using android::idmap2::TargetResourceContainer; using android::idmap2::TargetResourceContainer; using android::idmap2::Unit; using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapFilePermissionMask; using android::idmap2::utils::kIdmapFilePermissionMask; using android::idmap2::utils::RandomStringForPath; using android::idmap2::utils::RandomStringForPath; Loading Loading @@ -149,31 +152,37 @@ Status Idmap2Service::verifyIdmap(const std::string& target_path, const std::str return ok(); return ok(); } } std::optional<Result<Unit>> up_to_date; if (android_content_res_idmap_crc_is_mtime()) { up_to_date = header->IsUpToDate( target_path, overlay_path, overlay_name, toTimeT(getFileModDate(target_path.c_str())), toTimeT(getFileModDate(overlay_path.c_str())), ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); } else { const auto target = GetTargetContainer(target_path); const auto target = GetTargetContainer(target_path); if (!target) { if (!target) { *_aidl_return = false; *_aidl_return = false; LOG(WARNING) << "failed to load target '" << target_path << "'"; LOG(WARNING) << "failed to load target '" << target_path << "'"; return ok(); return ok(); } } const auto overlay = OverlayResourceContainer::FromPath(overlay_path); const auto overlay = OverlayResourceContainer::FromPath(overlay_path); if (!overlay) { if (!overlay) { *_aidl_return = false; *_aidl_return = false; LOG(WARNING) << "failed to load overlay '" << overlay_path << "'"; LOG(WARNING) << "failed to load overlay '" << overlay_path << "'"; return ok(); return ok(); } } up_to_date = auto up_to_date = header->IsUpToDate(*GetPointer(*target), **overlay, overlay_name, header->IsUpToDate(*GetPointer(*target), **overlay, overlay_name, ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); } std::unique_ptr<const IdmapConstraints> newConstraints = std::unique_ptr<const IdmapConstraints> newConstraints = ConvertAidlConstraintsToIdmapConstraints(constraints); ConvertAidlConstraintsToIdmapConstraints(constraints); *_aidl_return = static_cast<bool>(up_to_date && (*oldConstraints == *newConstraints)); *_aidl_return = static_cast<bool>(*up_to_date && (*oldConstraints == *newConstraints)); if (!up_to_date) { if (!*up_to_date) { LOG(WARNING) << "idmap '" << idmap_path LOG(WARNING) << "idmap '" << idmap_path << "' not up to date : " << up_to_date.GetErrorMessage(); << "' not up to date : " << up_to_date->GetErrorMessage(); } } return ok(); return ok(); } } Loading cmds/idmap2/include/idmap2/Idmap.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -113,6 +113,13 @@ class IdmapHeader { return version_; return version_; } } // NOTE: The CRC fields used to be literal crc32, but now are just a way to identify if the // corresponding file has changed, so it's a stat.st_mtime now. // This means we may get false positives when the file changes, but the resources inside stay // the same. But it is so much faster to get and verify (a single stat() call instead of fully // parsing a zip archive and calculating a crc of the resources inside), that it is worth it: // false positives just make us re-create the idmaps occasionally and cause no correctness bugs. inline uint32_t GetTargetCrc() const { inline uint32_t GetTargetCrc() const { return target_crc_; return target_crc_; } } Loading Loading
AconfigFlags.bp +11 −0 Original line number Original line Diff line number Diff line Loading @@ -800,6 +800,17 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], defaults: ["framework-minus-apex-aconfig-java-defaults"], } } cc_aconfig_library { name: "android.content.res.flags-aconfig-cc", aconfig_declarations: "android.content.res.flags-aconfig", } cc_aconfig_library { name: "android.content.res.flags-aconfig-cc-host", aconfig_declarations: "android.content.res.flags-aconfig", host_supported: true, } // Media BetterTogether // Media BetterTogether aconfig_declarations { aconfig_declarations { name: "com.android.media.flags.bettertogether-aconfig", name: "com.android.media.flags.bettertogether-aconfig", Loading
cmds/idmap2/Android.bp +26 −1 Original line number Original line Diff line number Diff line Loading @@ -86,16 +86,20 @@ cc_library { static_libs: [ static_libs: [ "libidmap2_policies", "libidmap2_policies", "libidmap2_protos", "libidmap2_protos", "libpng", "android.content.res.flags-aconfig-cc", ], ], shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", "liblog", "libpng", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], }, }, host: { host: { Loading @@ -103,16 +107,20 @@ cc_library { enabled: false, enabled: false, }, }, static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc-host", "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", "libidmap2_policies", "libidmap2_policies", "libidmap2_protos", "libidmap2_protos", "liblog", "libpng", "libpng", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], }, }, }, }, Loading Loading @@ -193,6 +201,7 @@ cc_test { target: { target: { android: { android: { shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libidmap2", "libidmap2", Loading @@ -202,13 +211,17 @@ cc_test { "libz", "libz", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], static_libs: [ static_libs: [ "libidmap2_policies", "libidmap2_policies", "android.content.res.flags-aconfig-cc", ], ], }, }, host: { host: { static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc-host", "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", Loading @@ -218,6 +231,7 @@ cc_test { "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libziparchive", "libziparchive", "server_configurable_flags", ], ], shared_libs: [ shared_libs: [ "libz", "libz", Loading Loading @@ -258,22 +272,28 @@ cc_binary { target: { target: { android: { android: { shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", "libidmap2", "libidmap2", "liblog", "libpng", "libpng", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libz", "libz", "libziparchive", "libziparchive", "server_configurable_flags", ], ], static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc", "libidmap2_policies", "libidmap2_policies", ], ], }, }, host: { host: { static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc-host", "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libcutils", "libcutils", Loading @@ -284,6 +304,7 @@ cc_binary { "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libziparchive", "libziparchive", "server_configurable_flags", ], ], shared_libs: [ shared_libs: [ "libz", "libz", Loading @@ -304,16 +325,20 @@ cc_binary { "idmap2d/Main.cpp", "idmap2d/Main.cpp", ], ], shared_libs: [ shared_libs: [ "libaconfig_storage_read_api_cc", "libandroidfw", "libandroidfw", "libbase", "libbase", "libbinder", "libbinder", "libcutils", "libcutils", "libidmap2", "libidmap2", "liblog", "libprotobuf-cpp-lite", "libprotobuf-cpp-lite", "libutils", "libutils", "libziparchive", "libziparchive", "server_configurable_flags", ], ], static_libs: [ static_libs: [ "android.content.res.flags-aconfig-cc", "libidmap2_policies", "libidmap2_policies", "libidmap2_protos", "libidmap2_protos", "libidmap2daidl", "libidmap2daidl", Loading
cmds/idmap2/idmap2/CommandUtils.cpp +23 −14 Original line number Original line Diff line number Diff line Loading @@ -16,15 +16,20 @@ #include "idmap2/CommandUtils.h" #include "idmap2/CommandUtils.h" #include <android_content_res.h> #include <fstream> #include <fstream> #include <memory> #include <memory> #include <string> #include <string> #include <vector> #include <vector> #include "androidfw/misc.h" #include "idmap2/Idmap.h" #include "idmap2/Idmap.h" #include "idmap2/Result.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/SysTrace.h" using android::getFileModDate; using android::toTimeT; using android::idmap2::Error; using android::idmap2::Error; using android::idmap2::IdmapHeader; using android::idmap2::IdmapHeader; using android::idmap2::OverlayResourceContainer; using android::idmap2::OverlayResourceContainer; Loading @@ -42,21 +47,25 @@ Result<Unit> Verify(const std::string& idmap_path, const std::string& target_pat if (!header) { if (!header) { return Error("failed to parse idmap header"); return Error("failed to parse idmap header"); } } std::optional<Result<Unit>> header_ok; if (android_content_res_idmap_crc_is_mtime()) { header_ok = header->IsUpToDate( target_path, overlay_path, overlay_name, toTimeT(getFileModDate(target_path.c_str())), toTimeT(getFileModDate(overlay_path.c_str())), fulfilled_policies, enforce_overlayable); } else { auto target = TargetResourceContainer::FromPath(target_path); auto target = TargetResourceContainer::FromPath(target_path); if (!target) { if (!target) { return Error("failed to load target '%s'", target_path.c_str()); return Error("failed to load target '%s'", target_path.c_str()); } } auto overlay = OverlayResourceContainer::FromPath(overlay_path); auto overlay = OverlayResourceContainer::FromPath(overlay_path); if (!overlay) { if (!overlay) { return Error("failed to load overlay '%s'", overlay_path.c_str()); return Error("failed to load overlay '%s'", overlay_path.c_str()); } } header_ok = header->IsUpToDate(**target, **overlay, overlay_name, fulfilled_policies, const auto header_ok = header->IsUpToDate(**target, **overlay, overlay_name, fulfilled_policies, enforce_overlayable); enforce_overlayable); if (!header_ok) { } return Error(header_ok.GetError(), "idmap not up to date"); if (!*header_ok) { return Error(header_ok->GetError(), "idmap not up to date"); } } return Unit{}; return Unit{}; } }
cmds/idmap2/idmap2d/Idmap2Service.cpp +29 −20 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ #include "idmap2d/Idmap2Service.h" #include "idmap2d/Idmap2Service.h" #include <android_content_res.h> #include <fcntl.h> #include <sys/stat.h> // umask #include <sys/stat.h> // umask #include <sys/types.h> // umask #include <sys/types.h> // umask Loading @@ -39,7 +41,6 @@ #include "idmap2/PrettyPrintVisitor.h" #include "idmap2/PrettyPrintVisitor.h" #include "idmap2/Result.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/SysTrace.h" #include <fcntl.h> using android::base::StringPrintf; using android::base::StringPrintf; using android::binder::Status; using android::binder::Status; Loading @@ -51,7 +52,9 @@ using android::idmap2::IdmapConstraints; using android::idmap2::IdmapHeader; using android::idmap2::IdmapHeader; using android::idmap2::OverlayResourceContainer; using android::idmap2::OverlayResourceContainer; using android::idmap2::PrettyPrintVisitor; using android::idmap2::PrettyPrintVisitor; using android::idmap2::Result; using android::idmap2::TargetResourceContainer; using android::idmap2::TargetResourceContainer; using android::idmap2::Unit; using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapFilePermissionMask; using android::idmap2::utils::kIdmapFilePermissionMask; using android::idmap2::utils::RandomStringForPath; using android::idmap2::utils::RandomStringForPath; Loading Loading @@ -149,31 +152,37 @@ Status Idmap2Service::verifyIdmap(const std::string& target_path, const std::str return ok(); return ok(); } } std::optional<Result<Unit>> up_to_date; if (android_content_res_idmap_crc_is_mtime()) { up_to_date = header->IsUpToDate( target_path, overlay_path, overlay_name, toTimeT(getFileModDate(target_path.c_str())), toTimeT(getFileModDate(overlay_path.c_str())), ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); } else { const auto target = GetTargetContainer(target_path); const auto target = GetTargetContainer(target_path); if (!target) { if (!target) { *_aidl_return = false; *_aidl_return = false; LOG(WARNING) << "failed to load target '" << target_path << "'"; LOG(WARNING) << "failed to load target '" << target_path << "'"; return ok(); return ok(); } } const auto overlay = OverlayResourceContainer::FromPath(overlay_path); const auto overlay = OverlayResourceContainer::FromPath(overlay_path); if (!overlay) { if (!overlay) { *_aidl_return = false; *_aidl_return = false; LOG(WARNING) << "failed to load overlay '" << overlay_path << "'"; LOG(WARNING) << "failed to load overlay '" << overlay_path << "'"; return ok(); return ok(); } } up_to_date = auto up_to_date = header->IsUpToDate(*GetPointer(*target), **overlay, overlay_name, header->IsUpToDate(*GetPointer(*target), **overlay, overlay_name, ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable); } std::unique_ptr<const IdmapConstraints> newConstraints = std::unique_ptr<const IdmapConstraints> newConstraints = ConvertAidlConstraintsToIdmapConstraints(constraints); ConvertAidlConstraintsToIdmapConstraints(constraints); *_aidl_return = static_cast<bool>(up_to_date && (*oldConstraints == *newConstraints)); *_aidl_return = static_cast<bool>(*up_to_date && (*oldConstraints == *newConstraints)); if (!up_to_date) { if (!*up_to_date) { LOG(WARNING) << "idmap '" << idmap_path LOG(WARNING) << "idmap '" << idmap_path << "' not up to date : " << up_to_date.GetErrorMessage(); << "' not up to date : " << up_to_date->GetErrorMessage(); } } return ok(); return ok(); } } Loading
cmds/idmap2/include/idmap2/Idmap.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -113,6 +113,13 @@ class IdmapHeader { return version_; return version_; } } // NOTE: The CRC fields used to be literal crc32, but now are just a way to identify if the // corresponding file has changed, so it's a stat.st_mtime now. // This means we may get false positives when the file changes, but the resources inside stay // the same. But it is so much faster to get and verify (a single stat() call instead of fully // parsing a zip archive and calculating a crc of the resources inside), that it is worth it: // false positives just make us re-create the idmaps occasionally and cause no correctness bugs. inline uint32_t GetTargetCrc() const { inline uint32_t GetTargetCrc() const { return target_crc_; return target_crc_; } } Loading