Merge "Reduce OMS start time" into rvc-dev am: 84a84ac62a

Change-Id: I9a419e6be7cc950693e39c5d474e3c60161c4b69
This commit is contained in:
Ryan Mitchell
2020-04-28 23:47:58 +00:00
committed by Automerger Merge Worker
6 changed files with 67 additions and 22 deletions

View File

@@ -34,11 +34,13 @@
#include "idmap2/FileUtils.h" #include "idmap2/FileUtils.h"
#include "idmap2/Idmap.h" #include "idmap2/Idmap.h"
#include "idmap2/SysTrace.h" #include "idmap2/SysTrace.h"
#include "idmap2/ZipFile.h"
#include "utils/String8.h" #include "utils/String8.h"
using android::IPCThreadState; using android::IPCThreadState;
using android::binder::Status; using android::binder::Status;
using android::idmap2::BinaryStreamVisitor; using android::idmap2::BinaryStreamVisitor;
using android::idmap2::GetPackageCrc;
using android::idmap2::Idmap; using android::idmap2::Idmap;
using android::idmap2::IdmapHeader; using android::idmap2::IdmapHeader;
using android::idmap2::utils::kIdmapCacheDir; using android::idmap2::utils::kIdmapCacheDir;
@@ -49,6 +51,8 @@ using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask
namespace { namespace {
constexpr const char* kFrameworkPath = "/system/framework/framework-res.apk";
Status ok() { Status ok() {
return Status::ok(); return Status::ok();
} }
@@ -109,8 +113,32 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path,
return error("failed to parse idmap header"); return error("failed to parse idmap header");
} }
*_aidl_return = if (strcmp(header->GetTargetPath().data(), target_apk_path.data()) != 0) {
strcmp(header->GetTargetPath().data(), target_apk_path.data()) == 0 && header->IsUpToDate(); *_aidl_return = false;
return ok();
}
if (target_apk_path != kFrameworkPath) {
*_aidl_return = (bool) header->IsUpToDate();
} else {
if (!android_crc_) {
// Loading the framework zip can take several milliseconds. Cache the crc of the framework
// resource APK to reduce repeated work during boot.
const auto target_zip = idmap2::ZipFile::Open(target_apk_path);
if (!target_zip) {
return error(base::StringPrintf("failed to open target %s", target_apk_path.c_str()));
}
const auto target_crc = GetPackageCrc(*target_zip);
if (!target_crc) {
return error(target_crc.GetErrorMessage());
}
android_crc_ = *target_crc;
}
*_aidl_return = (bool) header->IsUpToDate(android_crc_.value());
}
// TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed // TODO(b/119328308): Check that the set of fulfilled policies of the overlay has not changed
return ok(); return ok();

View File

@@ -46,6 +46,10 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 {
const std::string& overlay_apk_path, int32_t fulfilled_policies, const std::string& overlay_apk_path, int32_t fulfilled_policies,
bool enforce_overlayable, int32_t user_id, bool enforce_overlayable, int32_t user_id,
aidl::nullable<std::string>* _aidl_return) override; aidl::nullable<std::string>* _aidl_return) override;
private:
// Cache the crc of the android framework package since the crc cannot change without a reboot.
std::optional<uint32_t> android_crc_;
}; };
} // namespace android::os } // namespace android::os

View File

@@ -74,6 +74,7 @@
#include "androidfw/ResourceTypes.h" #include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h" #include "androidfw/StringPiece.h"
#include "idmap2/ResourceMapping.h" #include "idmap2/ResourceMapping.h"
#include "idmap2/ZipFile.h"
namespace android::idmap2 { namespace android::idmap2 {
@@ -93,6 +94,9 @@ static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVer
// terminating null) // terminating null)
static constexpr const size_t kIdmapStringLength = 256; static constexpr const size_t kIdmapStringLength = 256;
// Retrieves a crc generated using all of the files within the zip that can affect idmap generation.
Result<uint32_t> GetPackageCrc(const ZipFile& zip_info);
class IdmapHeader { class IdmapHeader {
public: public:
static std::unique_ptr<const IdmapHeader> FromBinaryStream(std::istream& stream); static std::unique_ptr<const IdmapHeader> FromBinaryStream(std::istream& stream);
@@ -129,6 +133,7 @@ class IdmapHeader {
// field *must* be incremented. Because of this, we know that if the idmap // field *must* be incremented. Because of this, we know that if the idmap
// header is up-to-date the entire file is up-to-date. // header is up-to-date the entire file is up-to-date.
Result<Unit> IsUpToDate() const; Result<Unit> IsUpToDate() const;
Result<Unit> IsUpToDate(uint32_t target_crc_) const;
void accept(Visitor* v) const; void accept(Visitor* v) const;

View File

@@ -100,7 +100,9 @@ Result<std::string> ReadString(std::istream& stream) {
return buf; return buf;
} }
Result<uint32_t> GetCrc(const ZipFile& zip) { } // namespace
Result<uint32_t> GetPackageCrc(const ZipFile& zip) {
const Result<uint32_t> a = zip.Crc("resources.arsc"); const Result<uint32_t> a = zip.Crc("resources.arsc");
const Result<uint32_t> b = zip.Crc("AndroidManifest.xml"); const Result<uint32_t> b = zip.Crc("AndroidManifest.xml");
return a && b return a && b
@@ -108,8 +110,6 @@ Result<uint32_t> GetCrc(const ZipFile& zip) {
: Error("failed to get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc"); : Error("failed to get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc");
} }
} // namespace
std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) { std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) {
std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader()); std::unique_ptr<IdmapHeader> idmap_header(new IdmapHeader());
@@ -130,6 +130,20 @@ std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& s
} }
Result<Unit> IdmapHeader::IsUpToDate() const { Result<Unit> IdmapHeader::IsUpToDate() const {
const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path_);
if (!target_zip) {
return Error("failed to open target %s", GetTargetPath().to_string().c_str());
}
Result<uint32_t> target_crc = GetPackageCrc(*target_zip);
if (!target_crc) {
return Error("failed to get target crc");
}
return IsUpToDate(*target_crc);
}
Result<Unit> IdmapHeader::IsUpToDate(uint32_t target_crc) const {
if (magic_ != kIdmapMagic) { if (magic_ != kIdmapMagic) {
return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic); return Error("bad magic: actual 0x%08x, expected 0x%08x", magic_, kIdmapMagic);
} }
@@ -138,19 +152,9 @@ Result<Unit> IdmapHeader::IsUpToDate() const {
return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion); return Error("bad version: actual 0x%08x, expected 0x%08x", version_, kIdmapCurrentVersion);
} }
const std::unique_ptr<const ZipFile> target_zip = ZipFile::Open(target_path_); if (target_crc_ != target_crc) {
if (!target_zip) {
return Error("failed to open target %s", GetTargetPath().to_string().c_str());
}
Result<uint32_t> target_crc = GetCrc(*target_zip);
if (!target_crc) {
return Error("failed to get target crc");
}
if (target_crc_ != *target_crc) {
return Error("bad target crc: idmap version 0x%08x, file system version 0x%08x", target_crc_, return Error("bad target crc: idmap version 0x%08x, file system version 0x%08x", target_crc_,
*target_crc); target_crc);
} }
const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path_); const std::unique_ptr<const ZipFile> overlay_zip = ZipFile::Open(overlay_path_);
@@ -158,7 +162,7 @@ Result<Unit> IdmapHeader::IsUpToDate() const {
return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str()); return Error("failed to open overlay %s", GetOverlayPath().to_string().c_str());
} }
Result<uint32_t> overlay_crc = GetCrc(*overlay_zip); Result<uint32_t> overlay_crc = GetPackageCrc(*overlay_zip);
if (!overlay_crc) { if (!overlay_crc) {
return Error("failed to get overlay crc"); return Error("failed to get overlay crc");
} }
@@ -304,13 +308,13 @@ Result<std::unique_ptr<const Idmap>> Idmap::FromApkAssets(const ApkAssets& targe
header->magic_ = kIdmapMagic; header->magic_ = kIdmapMagic;
header->version_ = kIdmapCurrentVersion; header->version_ = kIdmapCurrentVersion;
Result<uint32_t> crc = GetCrc(*target_zip); Result<uint32_t> crc = GetPackageCrc(*target_zip);
if (!crc) { if (!crc) {
return Error(crc.GetError(), "failed to get zip CRC for target"); return Error(crc.GetError(), "failed to get zip CRC for target");
} }
header->target_crc_ = *crc; header->target_crc_ = *crc;
crc = GetCrc(*overlay_zip); crc = GetPackageCrc(*overlay_zip);
if (!crc) { if (!crc) {
return Error(crc.GetError(), "failed to get zip CRC for overlay"); return Error(crc.GetError(), "failed to get zip CRC for overlay");
} }

View File

@@ -44,7 +44,7 @@ class IdmapDaemon {
// The amount of time in milliseconds to wait when attempting to connect to idmap service. // The amount of time in milliseconds to wait when attempting to connect to idmap service.
private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000; private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000;
private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 200; private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 5;
private static final String IDMAP_DAEMON = "idmap2d"; private static final String IDMAP_DAEMON = "idmap2d";

View File

@@ -1120,7 +1120,11 @@ public final class OverlayManagerService extends SystemService {
@Override @Override
public List<PackageInfo> getOverlayPackages(final int userId) { public List<PackageInfo> getOverlayPackages(final int userId) {
return mPackageManagerInternal.getOverlayPackages(userId); final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId);
for (final PackageInfo info : overlays) {
cachePackageInfo(info.packageName, userId, info);
}
return overlays;
} }
@Nullable @Nullable