idmap2: switch to improved Result class
Remove the old std::optional based Result class, replace uses with the new std::variant based Result class. Test: make idmap2_tests Change-Id: I401cb36e5af06133a2872d835cf29bfb0b106597
This commit is contained in:
committed by
Ryan Mitchell
parent
dbd7154348
commit
49d835d84e
@@ -28,7 +28,6 @@
|
||||
#include "idmap2/FileUtils.h"
|
||||
#include "idmap2/Idmap.h"
|
||||
#include "idmap2/Policies.h"
|
||||
#include "idmap2/Result.h"
|
||||
#include "idmap2/SysTrace.h"
|
||||
|
||||
using android::ApkAssets;
|
||||
@@ -38,7 +37,6 @@ using android::idmap2::Idmap;
|
||||
using android::idmap2::PoliciesToBitmask;
|
||||
using android::idmap2::PolicyBitmask;
|
||||
using android::idmap2::PolicyFlags;
|
||||
using android::idmap2::Result;
|
||||
using android::idmap2::utils::kIdmapFilePermissionMask;
|
||||
using android::idmap2::utils::UidHasWriteAccessToPath;
|
||||
|
||||
@@ -77,9 +75,11 @@ bool Create(const std::vector<std::string>& args, std::ostream& out_error) {
|
||||
}
|
||||
|
||||
PolicyBitmask fulfilled_policies = 0;
|
||||
if (auto result = PoliciesToBitmask(policies, out_error)) {
|
||||
fulfilled_policies |= *result;
|
||||
auto conv_result = PoliciesToBitmask(policies);
|
||||
if (conv_result) {
|
||||
fulfilled_policies |= *conv_result;
|
||||
} else {
|
||||
out_error << "error: " << conv_result.GetErrorMessage() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ using android::ResTable_config;
|
||||
using android::StringPiece16;
|
||||
using android::base::StringPrintf;
|
||||
using android::idmap2::CommandLineOptions;
|
||||
using android::idmap2::Error;
|
||||
using android::idmap2::IdmapHeader;
|
||||
using android::idmap2::ResourceId;
|
||||
using android::idmap2::Result;
|
||||
@@ -71,17 +72,17 @@ Result<ResourceId> WARN_UNUSED ParseResReference(const AssetManager2& am, const
|
||||
ResourceId resid;
|
||||
resid = strtol(res.c_str(), &endptr, kBaseHex);
|
||||
if (*endptr == '\0') {
|
||||
return {resid};
|
||||
return resid;
|
||||
}
|
||||
|
||||
// next, try to parse as a package:type/name string
|
||||
resid = am.GetResourceId(res, "", fallback_package);
|
||||
if (is_valid_resid(resid)) {
|
||||
return {resid};
|
||||
return resid;
|
||||
}
|
||||
|
||||
// end of the road: res could not be parsed
|
||||
return {};
|
||||
return Error("failed to obtain resource id for %s", res.c_str());
|
||||
}
|
||||
|
||||
Result<std::string> WARN_UNUSED GetValue(const AssetManager2& am, ResourceId resid) {
|
||||
@@ -90,7 +91,7 @@ Result<std::string> WARN_UNUSED GetValue(const AssetManager2& am, ResourceId res
|
||||
uint32_t flags;
|
||||
ApkAssetsCookie cookie = am.GetResource(resid, false, 0, &value, &config, &flags);
|
||||
if (cookie == kInvalidCookie) {
|
||||
return {};
|
||||
return Error("no resource 0x%08x in asset manager", resid);
|
||||
}
|
||||
|
||||
std::string out;
|
||||
@@ -128,31 +129,31 @@ Result<std::string> WARN_UNUSED GetValue(const AssetManager2& am, ResourceId res
|
||||
out.append(StringPrintf("dataType=0x%02x data=0x%08x", value.dataType, value.data));
|
||||
break;
|
||||
}
|
||||
return {out};
|
||||
return out;
|
||||
}
|
||||
|
||||
Result<std::string> GetTargetPackageNameFromManifest(const std::string& apk_path) {
|
||||
const auto zip = ZipFile::Open(apk_path);
|
||||
if (!zip) {
|
||||
return {};
|
||||
return Error("failed to open %s as zip", apk_path.c_str());
|
||||
}
|
||||
const auto entry = zip->Uncompress("AndroidManifest.xml");
|
||||
if (!entry) {
|
||||
return {};
|
||||
return Error("failed to uncompress AndroidManifest.xml in %s", apk_path.c_str());
|
||||
}
|
||||
const auto xml = Xml::Create(entry->buf, entry->size);
|
||||
if (!xml) {
|
||||
return {};
|
||||
return Error("failed to create XML buffer");
|
||||
}
|
||||
const auto tag = xml->FindTag("overlay");
|
||||
if (!tag) {
|
||||
return {};
|
||||
return Error("failed to find <overlay> tag");
|
||||
}
|
||||
const auto iter = tag->find("targetPackage");
|
||||
if (iter == tag->end()) {
|
||||
return {};
|
||||
return Error("failed to find targetPackage attribute");
|
||||
}
|
||||
return {iter->second};
|
||||
return iter->second;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -142,9 +142,9 @@ bool Scan(const std::vector<std::string>& args, std::ostream& out_error) {
|
||||
std::vector<InputOverlay> interesting_apks;
|
||||
for (const std::string& path : *apk_paths) {
|
||||
Result<OverlayManifestInfo> overlay_info =
|
||||
ExtractOverlayManifestInfo(path, out_error,
|
||||
/* assert_overlay */ false);
|
||||
ExtractOverlayManifestInfo(path, /* assert_overlay */ false);
|
||||
if (!overlay_info) {
|
||||
out_error << "error: " << overlay_info.GetErrorMessage() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -163,9 +163,11 @@ bool Scan(const std::vector<std::string>& args, std::ostream& out_error) {
|
||||
|
||||
PolicyBitmask fulfilled_policies;
|
||||
if (!override_policies.empty()) {
|
||||
if (Result<PolicyBitmask> result = PoliciesToBitmask(override_policies, out_error)) {
|
||||
fulfilled_policies = *result;
|
||||
auto conv_result = PoliciesToBitmask(override_policies);
|
||||
if (conv_result) {
|
||||
fulfilled_policies = *conv_result;
|
||||
} else {
|
||||
out_error << "error: " << conv_result.GetErrorMessage() << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "idmap2/FileUtils.h"
|
||||
#include "idmap2/Idmap.h"
|
||||
#include "idmap2/Policies.h"
|
||||
#include "idmap2/Result.h"
|
||||
#include "idmap2/SysTrace.h"
|
||||
|
||||
#include "idmap2d/Idmap2Service.h"
|
||||
@@ -45,7 +44,6 @@ using android::idmap2::BinaryStreamVisitor;
|
||||
using android::idmap2::Idmap;
|
||||
using android::idmap2::IdmapHeader;
|
||||
using android::idmap2::PolicyBitmask;
|
||||
using android::idmap2::Result;
|
||||
using android::idmap2::utils::kIdmapCacheDir;
|
||||
using android::idmap2::utils::kIdmapFilePermissionMask;
|
||||
using android::idmap2::utils::UidHasWriteAccessToPath;
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -33,8 +32,7 @@ using PolicyBitmask = uint32_t;
|
||||
|
||||
// Parses a the string representation of a set of policies into a bitmask. The format of the string
|
||||
// is the same as for the <policy> element.
|
||||
Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies,
|
||||
std::ostream& err);
|
||||
Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies);
|
||||
|
||||
} // namespace android::idmap2
|
||||
|
||||
|
||||
@@ -18,10 +18,8 @@
|
||||
#define IDMAP2_INCLUDE_IDMAP2_RESOURCEUTILS_H_
|
||||
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "android-base/macros.h"
|
||||
#include "androidfw/AssetManager2.h"
|
||||
|
||||
#include "idmap2/Idmap.h"
|
||||
@@ -38,10 +36,9 @@ struct OverlayManifestInfo {
|
||||
};
|
||||
|
||||
Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path,
|
||||
std::ostream& out_error,
|
||||
bool assert_overlay = true);
|
||||
|
||||
Result<std::string> WARN_UNUSED ResToTypeEntryName(const AssetManager2& am, ResourceId resid);
|
||||
Result<std::string> ResToTypeEntryName(const AssetManager2& am, ResourceId resid);
|
||||
|
||||
} // namespace android::idmap2::utils
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#ifndef IDMAP2_INCLUDE_IDMAP2_RESULT_H_
|
||||
#define IDMAP2_INCLUDE_IDMAP2_RESULT_H_
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
@@ -26,13 +25,6 @@
|
||||
|
||||
namespace android::idmap2 {
|
||||
|
||||
template <typename T>
|
||||
using Result = std::optional<T>;
|
||||
|
||||
static constexpr std::nullopt_t kResultError = std::nullopt;
|
||||
|
||||
namespace v2 {
|
||||
|
||||
using Unit = std::monostate;
|
||||
|
||||
class Error {
|
||||
@@ -148,8 +140,6 @@ inline bool Result<T>::is_ok() const {
|
||||
return std::holds_alternative<T>(data_);
|
||||
}
|
||||
|
||||
} // namespace v2
|
||||
|
||||
} // namespace android::idmap2
|
||||
|
||||
#endif // IDMAP2_INCLUDE_IDMAP2_RESULT_H_
|
||||
|
||||
@@ -121,7 +121,9 @@ const LoadedPackage* GetPackageAtIndex0(const LoadedArsc& loaded_arsc) {
|
||||
Result<uint32_t> GetCrc(const ZipFile& zip) {
|
||||
const Result<uint32_t> a = zip.Crc("resources.arsc");
|
||||
const Result<uint32_t> b = zip.Crc("AndroidManifest.xml");
|
||||
return a && b ? Result<uint32_t>(*a ^ *b) : kResultError;
|
||||
return a && b
|
||||
? Result<uint32_t>(*a ^ *b)
|
||||
: Error("Couldn't get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -355,9 +357,9 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Result<utils::OverlayManifestInfo> overlay_info =
|
||||
utils::ExtractOverlayManifestInfo(overlay_apk_path, out_error);
|
||||
auto overlay_info = utils::ExtractOverlayManifestInfo(overlay_apk_path);
|
||||
if (!overlay_info) {
|
||||
out_error << "error: " << overlay_info.GetErrorMessage() << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -39,16 +38,14 @@ const std::map<android::StringPiece, PolicyFlags> kStringToFlag = {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies,
|
||||
std::ostream& err) {
|
||||
Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies) {
|
||||
PolicyBitmask bitmask = 0;
|
||||
for (const std::string& policy : policies) {
|
||||
const auto iter = kStringToFlag.find(policy);
|
||||
if (iter != kStringToFlag.end()) {
|
||||
bitmask |= iter->second;
|
||||
} else {
|
||||
err << "error: unknown policy \"" << policy << "\"";
|
||||
return kResultError;
|
||||
return Error("unknown policy \"%s\"", policy.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ void RawPrintVisitor::visit(const IdmapData::TypeEntry& type_entry) {
|
||||
type_entry.GetEntryOffset() + i);
|
||||
const ResourceId overlay_resid =
|
||||
RESID(last_seen_package_id_, type_entry.GetOverlayTypeId(), entry);
|
||||
Result<std::string> name;
|
||||
Result<std::string> name(Error(""));
|
||||
if (target_package_loaded) {
|
||||
name = utils::ResToTypeEntryName(target_am_, target_resid);
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ using android::util::Utf16ToUtf8;
|
||||
|
||||
namespace android::idmap2::utils {
|
||||
|
||||
Result<std::string> WARN_UNUSED ResToTypeEntryName(const AssetManager2& am, ResourceId resid) {
|
||||
Result<std::string> ResToTypeEntryName(const AssetManager2& am, ResourceId resid) {
|
||||
AssetManager2::ResourceName name;
|
||||
if (!am.GetResourceName(resid, &name)) {
|
||||
return {};
|
||||
return Error("no resource 0x%08x in asset manager", resid);
|
||||
}
|
||||
std::string out;
|
||||
if (name.type != nullptr) {
|
||||
@@ -50,36 +50,31 @@ Result<std::string> WARN_UNUSED ResToTypeEntryName(const AssetManager2& am, Reso
|
||||
} else {
|
||||
out += Utf16ToUtf8(StringPiece16(name.entry16, name.entry_len));
|
||||
}
|
||||
return {out};
|
||||
return out;
|
||||
}
|
||||
|
||||
Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path,
|
||||
std::ostream& out_error,
|
||||
bool assert_overlay) {
|
||||
std::unique_ptr<const ZipFile> zip = ZipFile::Open(path);
|
||||
if (!zip) {
|
||||
out_error << "error: failed to open " << path << " as a zip file" << std::endl;
|
||||
return kResultError;
|
||||
return Error("failed to open %s as a zip file", path.c_str());
|
||||
}
|
||||
|
||||
std::unique_ptr<const MemoryChunk> entry = zip->Uncompress("AndroidManifest.xml");
|
||||
if (!entry) {
|
||||
out_error << "error: failed to uncompress AndroidManifest.xml from " << path << std::endl;
|
||||
return kResultError;
|
||||
return Error("failed to uncompress AndroidManifest.xml from %s", path.c_str());
|
||||
}
|
||||
|
||||
std::unique_ptr<const Xml> xml = Xml::Create(entry->buf, entry->size);
|
||||
if (!xml) {
|
||||
out_error << "error: failed to parse AndroidManifest.xml from " << path << std::endl;
|
||||
return kResultError;
|
||||
return Error("failed to parse AndroidManifest.xml from %s", path.c_str());
|
||||
}
|
||||
|
||||
OverlayManifestInfo info{};
|
||||
const auto tag = xml->FindTag("overlay");
|
||||
if (!tag) {
|
||||
if (assert_overlay) {
|
||||
out_error << "error: <overlay> missing from AndroidManifest.xml of " << path << std::endl;
|
||||
return kResultError;
|
||||
return Error("<overlay> missing from AndroidManifest.xml of %s", path.c_str());
|
||||
}
|
||||
return info;
|
||||
}
|
||||
@@ -87,8 +82,7 @@ Result<OverlayManifestInfo> ExtractOverlayManifestInfo(const std::string& path,
|
||||
auto iter = tag->find("targetPackage");
|
||||
if (iter == tag->end()) {
|
||||
if (assert_overlay) {
|
||||
out_error << "error: android:targetPackage missing from <overlay> of " << path << std::endl;
|
||||
return kResultError;
|
||||
return Error("android:targetPackage missing from <overlay> of %s", path.c_str());
|
||||
}
|
||||
} else {
|
||||
info.target_package = iter->second;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
namespace android::idmap2 {
|
||||
|
||||
// NOLINTNEXTLINE(cert-dcl50-cpp)
|
||||
v2::Error::Error(const char* fmt, ...) {
|
||||
Error::Error(const char* fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
base::StringAppendV(&msg_, fmt, ap);
|
||||
@@ -31,7 +31,7 @@ v2::Error::Error(const char* fmt, ...) {
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cert-dcl50-cpp)
|
||||
v2::Error::Error(const Error& parent, const char* fmt, ...) : msg_(parent.msg_) {
|
||||
Error::Error(const Error& parent, const char* fmt, ...) : msg_(parent.msg_) {
|
||||
msg_.append(" -> ");
|
||||
|
||||
va_list ap;
|
||||
|
||||
@@ -59,7 +59,10 @@ std::unique_ptr<const MemoryChunk> ZipFile::Uncompress(const std::string& entryP
|
||||
Result<uint32_t> ZipFile::Crc(const std::string& entryPath) const {
|
||||
::ZipEntry entry;
|
||||
int32_t status = ::FindEntry(handle_, ::ZipString(entryPath.c_str()), &entry);
|
||||
return status == 0 ? Result<uint32_t>(entry.crc32) : kResultError;
|
||||
if (status != 0) {
|
||||
return Error("failed to find zip entry %s", entryPath.c_str());
|
||||
}
|
||||
return entry.crc32;
|
||||
}
|
||||
|
||||
} // namespace android::idmap2
|
||||
|
||||
@@ -58,21 +58,15 @@ TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) {
|
||||
});
|
||||
ASSERT_THAT(v, NotNull());
|
||||
ASSERT_EQ(v->size(), 10U);
|
||||
ASSERT_EQ(
|
||||
std::set<std::string>(v->begin(), v->end()),
|
||||
std::set<std::string>(
|
||||
{
|
||||
root + "/target/target.apk",
|
||||
root + "/target/target-no-overlayable.apk",
|
||||
root + "/overlay/overlay.apk",
|
||||
root + "/overlay/overlay-no-name.apk",
|
||||
root + "/overlay/overlay-no-name-static.apk",
|
||||
root + "/overlay/overlay-static-1.apk",
|
||||
root + "/overlay/overlay-static-2.apk",
|
||||
root + "/signature-overlay/signature-overlay.apk",
|
||||
root + "/system-overlay/system-overlay.apk",
|
||||
root + "/system-overlay-invalid/system-overlay-invalid.apk"
|
||||
}));
|
||||
ASSERT_EQ(std::set<std::string>(v->begin(), v->end()),
|
||||
std::set<std::string>(
|
||||
{root + "/target/target.apk", root + "/target/target-no-overlayable.apk",
|
||||
root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk",
|
||||
root + "/overlay/overlay-no-name-static.apk",
|
||||
root + "/overlay/overlay-static-1.apk", root + "/overlay/overlay-static-2.apk",
|
||||
root + "/signature-overlay/signature-overlay.apk",
|
||||
root + "/system-overlay/system-overlay.apk",
|
||||
root + "/system-overlay-invalid/system-overlay-invalid.apk"}));
|
||||
}
|
||||
|
||||
TEST(FileUtilsTests, ReadFile) {
|
||||
|
||||
@@ -256,10 +256,10 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
|
||||
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
|
||||
ASSERT_EQ(types[0]->GetEntryCount(), 4U);
|
||||
ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
|
||||
ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_public
|
||||
ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
|
||||
ASSERT_EQ(types[0]->GetEntry(2), 0x0001U); // string/policy_system
|
||||
ASSERT_EQ(types[0]->GetEntry(3), 0x0002U); // string/policy_system_vendor
|
||||
ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_public
|
||||
ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
|
||||
ASSERT_EQ(types[0]->GetEntry(2), 0x0001U); // string/policy_system
|
||||
ASSERT_EQ(types[0]->GetEntry(3), 0x0002U); // string/policy_system_vendor
|
||||
}
|
||||
|
||||
TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) {
|
||||
@@ -267,7 +267,8 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) {
|
||||
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
|
||||
ASSERT_THAT(target_apk, NotNull());
|
||||
|
||||
const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk");
|
||||
const std::string overlay_apk_path(GetTestDataPath() +
|
||||
"/signature-overlay/signature-overlay.apk");
|
||||
std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
|
||||
ASSERT_THAT(overlay_apk, NotNull());
|
||||
|
||||
@@ -294,7 +295,7 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) {
|
||||
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
|
||||
ASSERT_EQ(types[0]->GetEntryCount(), 1U);
|
||||
ASSERT_EQ(types[0]->GetEntryOffset(), 7U);
|
||||
ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature
|
||||
ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature
|
||||
}
|
||||
|
||||
TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled) {
|
||||
@@ -302,7 +303,8 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled)
|
||||
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
|
||||
ASSERT_THAT(target_apk, NotNull());
|
||||
|
||||
const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk");
|
||||
const std::string overlay_apk_path(GetTestDataPath() +
|
||||
"/signature-overlay/signature-overlay.apk");
|
||||
std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
|
||||
ASSERT_THAT(overlay_apk, NotNull());
|
||||
|
||||
@@ -323,7 +325,7 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled)
|
||||
ASSERT_EQ(data->GetHeader()->GetTypeCount(), 0U);
|
||||
|
||||
const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
|
||||
ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing
|
||||
ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing
|
||||
}
|
||||
|
||||
// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
|
||||
@@ -359,10 +361,10 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
|
||||
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
|
||||
ASSERT_EQ(types[0]->GetEntryCount(), 4U);
|
||||
ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
|
||||
ASSERT_EQ(types[0]->GetEntry(0), 0x0003U); // string/policy_public
|
||||
ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
|
||||
ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system
|
||||
ASSERT_EQ(types[0]->GetEntry(3), 0x0006U); // string/policy_system_vendor
|
||||
ASSERT_EQ(types[0]->GetEntry(0), 0x0003U); // string/policy_public
|
||||
ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
|
||||
ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system
|
||||
ASSERT_EQ(types[0]->GetEntry(3), 0x0006U); // string/policy_system_vendor
|
||||
}
|
||||
|
||||
// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
|
||||
|
||||
@@ -27,44 +27,42 @@ using android::idmap2::PolicyFlags;
|
||||
namespace android::idmap2 {
|
||||
|
||||
TEST(PoliciesTests, PoliciesToBitmasks) {
|
||||
const Result<PolicyBitmask> bitmask1 = PoliciesToBitmask({"system"}, std::cerr);
|
||||
ASSERT_NE(bitmask1, kResultError);
|
||||
ASSERT_EQ(bitmask1, PolicyFlags::POLICY_SYSTEM_PARTITION);
|
||||
const auto bitmask1 = PoliciesToBitmask({"system"});
|
||||
ASSERT_TRUE(bitmask1);
|
||||
ASSERT_EQ(*bitmask1, PolicyFlags::POLICY_SYSTEM_PARTITION);
|
||||
|
||||
const Result<PolicyBitmask> bitmask2 = PoliciesToBitmask({"system", "vendor"}, std::cerr);
|
||||
ASSERT_NE(bitmask2, kResultError);
|
||||
ASSERT_EQ(bitmask2, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION);
|
||||
const auto bitmask2 = PoliciesToBitmask({"system", "vendor"});
|
||||
ASSERT_TRUE(bitmask2);
|
||||
ASSERT_EQ(*bitmask2, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION);
|
||||
|
||||
const Result<PolicyBitmask> bitmask3 = PoliciesToBitmask({"vendor", "system"}, std::cerr);
|
||||
ASSERT_NE(bitmask3, kResultError);
|
||||
ASSERT_EQ(bitmask3, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION);
|
||||
const auto bitmask3 = PoliciesToBitmask({"vendor", "system"});
|
||||
ASSERT_TRUE(bitmask3);
|
||||
ASSERT_EQ(*bitmask3, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION);
|
||||
|
||||
const Result<PolicyBitmask> bitmask4 =
|
||||
PoliciesToBitmask({"public", "product", "system", "vendor"}, std::cerr);
|
||||
ASSERT_NE(bitmask4, kResultError);
|
||||
ASSERT_EQ(bitmask4, PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_PRODUCT_PARTITION |
|
||||
PolicyFlags::POLICY_SYSTEM_PARTITION |
|
||||
PolicyFlags::POLICY_VENDOR_PARTITION);
|
||||
const auto bitmask4 = PoliciesToBitmask({"public", "product", "system", "vendor"});
|
||||
ASSERT_TRUE(bitmask4);
|
||||
ASSERT_EQ(*bitmask4, PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_PRODUCT_PARTITION |
|
||||
PolicyFlags::POLICY_SYSTEM_PARTITION |
|
||||
PolicyFlags::POLICY_VENDOR_PARTITION);
|
||||
|
||||
const Result<PolicyBitmask> bitmask5 =
|
||||
PoliciesToBitmask({"system", "system", "system"}, std::cerr);
|
||||
ASSERT_NE(bitmask5, kResultError);
|
||||
ASSERT_EQ(bitmask5, PolicyFlags::POLICY_SYSTEM_PARTITION);
|
||||
const auto bitmask5 = PoliciesToBitmask({"system", "system", "system"});
|
||||
ASSERT_TRUE(bitmask5);
|
||||
ASSERT_EQ(*bitmask5, PolicyFlags::POLICY_SYSTEM_PARTITION);
|
||||
|
||||
const Result<PolicyBitmask> bitmask6 = PoliciesToBitmask({""}, std::cerr);
|
||||
ASSERT_EQ(bitmask6, kResultError);
|
||||
const auto bitmask6 = PoliciesToBitmask({""});
|
||||
ASSERT_FALSE(bitmask6);
|
||||
|
||||
const Result<PolicyBitmask> bitmask7 = PoliciesToBitmask({"foo"}, std::cerr);
|
||||
ASSERT_EQ(bitmask7, kResultError);
|
||||
const auto bitmask7 = PoliciesToBitmask({"foo"});
|
||||
ASSERT_FALSE(bitmask7);
|
||||
|
||||
const Result<PolicyBitmask> bitmask8 = PoliciesToBitmask({"system", "foo"}, std::cerr);
|
||||
ASSERT_EQ(bitmask8, kResultError);
|
||||
const auto bitmask8 = PoliciesToBitmask({"system", "foo"});
|
||||
ASSERT_FALSE(bitmask8);
|
||||
|
||||
const Result<PolicyBitmask> bitmask9 = PoliciesToBitmask({"system", ""}, std::cerr);
|
||||
ASSERT_EQ(bitmask9, kResultError);
|
||||
const auto bitmask9 = PoliciesToBitmask({"system", ""});
|
||||
ASSERT_FALSE(bitmask9);
|
||||
|
||||
const Result<PolicyBitmask> bitmask10 = PoliciesToBitmask({"system "}, std::cerr);
|
||||
ASSERT_EQ(bitmask10, kResultError);
|
||||
const auto bitmask10 = PoliciesToBitmask({"system "});
|
||||
ASSERT_FALSE(bitmask10);
|
||||
}
|
||||
|
||||
} // namespace android::idmap2
|
||||
|
||||
@@ -32,28 +32,28 @@ struct Container {
|
||||
// Tests: Error
|
||||
|
||||
TEST(ResultTests, ErrorTraits) {
|
||||
ASSERT_TRUE(std::is_move_constructible<v2::Error>::value);
|
||||
ASSERT_TRUE(std::is_move_assignable<v2::Error>::value);
|
||||
ASSERT_TRUE(std::is_copy_constructible<v2::Error>::value);
|
||||
ASSERT_TRUE(std::is_copy_assignable<v2::Error>::value);
|
||||
ASSERT_TRUE(std::is_move_constructible<Error>::value);
|
||||
ASSERT_TRUE(std::is_move_assignable<Error>::value);
|
||||
ASSERT_TRUE(std::is_copy_constructible<Error>::value);
|
||||
ASSERT_TRUE(std::is_copy_assignable<Error>::value);
|
||||
}
|
||||
|
||||
TEST(ResultTests, ErrorCtorFormat) {
|
||||
v2::Error e("%s=0x%08x", "resid", 0x7f010002);
|
||||
Error e("%s=0x%08x", "resid", 0x7f010002);
|
||||
ASSERT_EQ(e.GetMessage(), "resid=0x7f010002");
|
||||
}
|
||||
|
||||
TEST(ResultTests, ErrorPropagateParent) {
|
||||
v2::Error e1("foo");
|
||||
Error e1("foo");
|
||||
ASSERT_EQ(e1.GetMessage(), "foo");
|
||||
|
||||
v2::Error e2(e1, "bar");
|
||||
Error e2(e1, "bar");
|
||||
ASSERT_EQ(e2.GetMessage(), "foo -> bar");
|
||||
|
||||
v2::Error e3(e2); // NOLINT(performance-unnecessary-copy-initialization)
|
||||
Error e3(e2); // NOLINT(performance-unnecessary-copy-initialization)
|
||||
ASSERT_EQ(e3.GetMessage(), "foo -> bar");
|
||||
|
||||
v2::Error e4(e3, "%02d", 1);
|
||||
Error e4(e3, "%02d", 1);
|
||||
ASSERT_EQ(e4.GetMessage(), "foo -> bar -> 01");
|
||||
}
|
||||
|
||||
@@ -61,13 +61,13 @@ TEST(ResultTests, ErrorPropagateParent) {
|
||||
|
||||
// Result(const Result&)
|
||||
TEST(ResultTests, CopyConstructor) {
|
||||
v2::Result<uint32_t> r1(42U);
|
||||
Result<uint32_t> r1(42U);
|
||||
|
||||
v2::Result<uint32_t> r2(r1);
|
||||
Result<uint32_t> r2(r1);
|
||||
ASSERT_TRUE(r2);
|
||||
ASSERT_EQ(*r2, 42U);
|
||||
|
||||
v2::Result<uint32_t> r3 = r2;
|
||||
Result<uint32_t> r3 = r2;
|
||||
ASSERT_TRUE(r3);
|
||||
ASSERT_EQ(*r3, 42U);
|
||||
}
|
||||
@@ -75,23 +75,23 @@ TEST(ResultTests, CopyConstructor) {
|
||||
// Result(const T&)
|
||||
TEST(ResultTests, Constructor) {
|
||||
uint32_t v = 42U;
|
||||
v2::Result<uint32_t> r1(v);
|
||||
Result<uint32_t> r1(v);
|
||||
ASSERT_TRUE(r1);
|
||||
ASSERT_EQ(*r1, 42U);
|
||||
|
||||
v2::Error e("foo");
|
||||
v2::Result<uint32_t> r2(e);
|
||||
Error e("foo");
|
||||
Result<uint32_t> r2(e);
|
||||
ASSERT_FALSE(r2);
|
||||
ASSERT_EQ(r2.GetErrorMessage(), "foo");
|
||||
}
|
||||
|
||||
// Result(const T&&)
|
||||
TEST(ResultTests, MoveConstructor) {
|
||||
v2::Result<uint32_t> r1(42U);
|
||||
Result<uint32_t> r1(42U);
|
||||
ASSERT_TRUE(r1);
|
||||
ASSERT_EQ(*r1, 42U);
|
||||
|
||||
v2::Result<uint32_t> r2(v2::Error("foo"));
|
||||
Result<uint32_t> r2(Error("foo"));
|
||||
ASSERT_FALSE(r2);
|
||||
ASSERT_EQ(r2.GetErrorMessage(), "foo");
|
||||
}
|
||||
@@ -99,52 +99,52 @@ TEST(ResultTests, MoveConstructor) {
|
||||
// operator=
|
||||
TEST(ResultTests, CopyAssignmentOperator) {
|
||||
// note: 'Result<...> r2 = r1;' calls the copy ctor
|
||||
v2::Result<uint32_t> r1(42U);
|
||||
v2::Result<uint32_t> r2(0U);
|
||||
Result<uint32_t> r1(42U);
|
||||
Result<uint32_t> r2(0U);
|
||||
r2 = r1;
|
||||
ASSERT_TRUE(r2);
|
||||
ASSERT_EQ(*r2, 42U);
|
||||
|
||||
v2::Result<uint32_t> r3(v2::Error("foo"));
|
||||
Result<uint32_t> r3(Error("foo"));
|
||||
r2 = r3;
|
||||
ASSERT_FALSE(r2);
|
||||
ASSERT_EQ(r2.GetErrorMessage(), "foo");
|
||||
}
|
||||
|
||||
TEST(ResultTests, MoveAssignmentOperator) {
|
||||
v2::Result<uint32_t> r(0U);
|
||||
r = v2::Result<uint32_t>(42U);
|
||||
Result<uint32_t> r(0U);
|
||||
r = Result<uint32_t>(42U);
|
||||
ASSERT_TRUE(r);
|
||||
ASSERT_EQ(*r, 42U);
|
||||
|
||||
r = v2::Result<uint32_t>(v2::Error("foo"));
|
||||
r = Result<uint32_t>(Error("foo"));
|
||||
ASSERT_FALSE(r);
|
||||
ASSERT_EQ(r.GetErrorMessage(), "foo");
|
||||
}
|
||||
|
||||
// operator bool()
|
||||
TEST(ResultTests, BoolOperator) {
|
||||
v2::Result<uint32_t> r1(42U);
|
||||
Result<uint32_t> r1(42U);
|
||||
ASSERT_TRUE(r1);
|
||||
ASSERT_EQ(*r1, 42U);
|
||||
|
||||
v2::Result<uint32_t> r2(v2::Error("foo"));
|
||||
Result<uint32_t> r2(Error("foo"));
|
||||
ASSERT_FALSE(r2);
|
||||
ASSERT_EQ(r2.GetErrorMessage(), "foo");
|
||||
}
|
||||
|
||||
// operator*
|
||||
TEST(ResultTests, IndirectionOperator) {
|
||||
const v2::Result<uint32_t> r1(42U);
|
||||
const Result<uint32_t> r1(42U);
|
||||
ASSERT_TRUE(r1);
|
||||
ASSERT_EQ(*r1, 42U);
|
||||
|
||||
const v2::Result<Container> r2(Container{42U});
|
||||
const Result<Container> r2(Container{42U});
|
||||
ASSERT_TRUE(r2);
|
||||
const Container& c = *r2;
|
||||
ASSERT_EQ(c.value, 42U);
|
||||
|
||||
v2::Result<Container> r3(Container{42U});
|
||||
Result<Container> r3(Container{42U});
|
||||
ASSERT_TRUE(r3);
|
||||
ASSERT_EQ((*r3).value, 42U);
|
||||
(*r3).value = 0U;
|
||||
@@ -153,11 +153,11 @@ TEST(ResultTests, IndirectionOperator) {
|
||||
|
||||
// operator->
|
||||
TEST(ResultTests, DereferenceOperator) {
|
||||
const v2::Result<Container> r1(Container{42U});
|
||||
const Result<Container> r1(Container{42U});
|
||||
ASSERT_TRUE(r1);
|
||||
ASSERT_EQ(r1->value, 42U);
|
||||
|
||||
v2::Result<Container> r2(Container{42U});
|
||||
Result<Container> r2(Container{42U});
|
||||
ASSERT_TRUE(r2);
|
||||
ASSERT_EQ(r2->value, 42U);
|
||||
r2->value = 0U;
|
||||
@@ -167,14 +167,14 @@ TEST(ResultTests, DereferenceOperator) {
|
||||
// Tests: intended use of Result<T>
|
||||
|
||||
TEST(ResultTests, ResultTraits) {
|
||||
ASSERT_TRUE(std::is_move_constructible<v2::Result<uint32_t>>::value);
|
||||
ASSERT_TRUE(std::is_move_assignable<v2::Result<uint32_t>>::value);
|
||||
ASSERT_TRUE(std::is_copy_constructible<v2::Result<uint32_t>>::value);
|
||||
ASSERT_TRUE(std::is_copy_assignable<v2::Result<uint32_t>>::value);
|
||||
ASSERT_TRUE(std::is_move_constructible<Result<uint32_t>>::value);
|
||||
ASSERT_TRUE(std::is_move_assignable<Result<uint32_t>>::value);
|
||||
ASSERT_TRUE(std::is_copy_constructible<Result<uint32_t>>::value);
|
||||
ASSERT_TRUE(std::is_copy_assignable<Result<uint32_t>>::value);
|
||||
}
|
||||
|
||||
TEST(ResultTests, UnitTypeResult) {
|
||||
v2::Result<v2::Unit> r(v2::Unit{});
|
||||
Result<Unit> r(Unit{});
|
||||
ASSERT_TRUE(r);
|
||||
}
|
||||
|
||||
@@ -220,16 +220,16 @@ TEST(ResultTests, ReferenceCount) {
|
||||
ASSERT_FALSE(std::is_copy_assignable<RefCountContainer>::value);
|
||||
|
||||
RefCountData rc{0, 0, 0, 0};
|
||||
{ v2::Result<RefCountContainer> r(RefCountContainer{rc}); }
|
||||
{ Result<RefCountContainer> r(RefCountContainer{rc}); }
|
||||
ASSERT_EQ(rc.ctor, 1);
|
||||
ASSERT_EQ(rc.copy_ctor, 1);
|
||||
ASSERT_EQ(rc.move, 0);
|
||||
ASSERT_EQ(rc.dtor, 2);
|
||||
}
|
||||
|
||||
v2::Result<Container> CreateContainer(bool succeed) {
|
||||
Result<Container> CreateContainer(bool succeed) {
|
||||
if (!succeed) {
|
||||
return v2::Error("foo");
|
||||
return Error("foo");
|
||||
}
|
||||
return Container{42U};
|
||||
}
|
||||
@@ -245,10 +245,10 @@ TEST(ResultTests, FunctionReturn) {
|
||||
ASSERT_EQ(r2.GetError().GetMessage(), "foo");
|
||||
}
|
||||
|
||||
v2::Result<Container> FailToCreateContainer() {
|
||||
Result<Container> FailToCreateContainer() {
|
||||
auto container = CreateContainer(false);
|
||||
if (!container) {
|
||||
return v2::Error(container.GetError(), "bar");
|
||||
return Error(container.GetError(), "bar");
|
||||
}
|
||||
return container;
|
||||
}
|
||||
@@ -264,9 +264,9 @@ struct NoCopyContainer {
|
||||
DISALLOW_COPY_AND_ASSIGN(NoCopyContainer);
|
||||
};
|
||||
|
||||
v2::Result<std::unique_ptr<NoCopyContainer>> CreateNoCopyContainer(bool succeed) {
|
||||
Result<std::unique_ptr<NoCopyContainer>> CreateNoCopyContainer(bool succeed) {
|
||||
if (!succeed) {
|
||||
return v2::Error("foo");
|
||||
return Error("foo");
|
||||
}
|
||||
std::unique_ptr<NoCopyContainer> p(new NoCopyContainer{0U});
|
||||
p->value = 42U;
|
||||
|
||||
Reference in New Issue
Block a user