blob: c749539dad74f483b820217e9e0f818a999e9dde [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "utils.h"
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <map>
#include <set>
#include <string>
#include <vector>
using android::base::GetUintProperty;
namespace android {
namespace vintf {
namespace testing {
// Path to directory on target containing test data.
const string kDataDir = "/data/local/tmp/";
// Name of file containing HAL hashes.
const string kHashFileName = "current.txt";
// Map from package name to package root.
const map<string, string> kPackageRoot = {
{"android.frameworks", "frameworks/hardware/interfaces/"},
{"android.hardware", "hardware/interfaces/"},
{"android.hidl", "system/libhidl/transport/"},
{"android.system", "system/hardware/interfaces/"},
};
// HALs that are allowed to be passthrough under Treble rules.
const set<string> kPassthroughHals = {
"android.hardware.graphics.mapper", "android.hardware.renderscript",
"android.hidl.memory",
};
std::string SanitizeTestCaseName(std::string original) {
for (char &c : original) {
if (!isalnum(c)) {
c = '_';
}
}
return original;
}
HidlInstance::HidlInstance(const ManifestInstance &other)
: ManifestInstance(other) {
CHECK_EQ(format(), HalFormat::HIDL);
}
ostream &operator<<(ostream &os, const HidlInstance& val) {
return os << val.transport() << " HAL " << val.fq_name().string() << "/"
<< val.instance_name();
}
string HidlInstance::test_case_name() const {
return SanitizeTestCaseName(fq_name().string() + "/" + instance_name());
}
AidlInstance::AidlInstance(const ManifestInstance &other)
: ManifestInstance(other) {
CHECK_EQ(format(), HalFormat::AIDL);
}
string AidlInstance::test_case_name() const {
return SanitizeTestCaseName(
toAidlFqnameString(package(), interface(), instance()) + "_V" +
to_string(version()));
}
ostream &operator<<(ostream &os, const AidlInstance& val) {
os << toAidlFqnameString(val.package(), val.interface(), val.instance())
<< ", Version " << val.version();
if (val.updatable_via_apex()) {
os << ", updatable_via_apex = " << *val.updatable_via_apex();
}
return os;
}
NativeInstance::NativeInstance(const ManifestInstance &other)
: ManifestInstance(other) {
CHECK_EQ(format(), HalFormat::NATIVE);
}
string NativeInstance::test_case_name() const {
return SanitizeTestCaseName(
toAidlFqnameString(package(), interface(), instance()) + "_V" +
to_string(version()));
}
ostream &operator<<(ostream &os, const NativeInstance &val) {
os << "Native HAL { package: " << val.package()
<< " version: " << val.major_version() << "." << val.minor_version()
<< " interface: " << val.interface() << " instance: " << val.instance()
<< " }";
return os;
}
uint64_t GetBoardApiLevel() {
return GetUintProperty<uint64_t>("ro.vendor.api_level", 0);
}
// For a given interface returns package root if known. Returns empty string
// otherwise.
const string PackageRoot(const FQName &fq_iface_name) {
for (const auto &package_root : kPackageRoot) {
if (fq_iface_name.inPackage(package_root.first)) {
return package_root.second;
}
}
return "";
}
// Returns true iff HAL interface is Android platform.
bool IsAndroidPlatformInterface(const FQName &fq_iface_name) {
// Package roots are only known for Android platform packages.
return !PackageRoot(fq_iface_name).empty();
}
// Returns the set of released hashes for a given HAL interface.
set<string> ReleasedHashes(const FQName &fq_iface_name) {
set<string> released_hashes{};
string err = "";
string file_path = kDataDir + PackageRoot(fq_iface_name) + kHashFileName;
auto hashes = Hash::lookupHash(file_path, fq_iface_name.string(), &err);
released_hashes.insert(hashes.begin(), hashes.end());
return released_hashes;
}
// Returns the partition that a HAL is associated with.
Partition PartitionOfProcess(int32_t pid) {
auto partition = android::procpartition::getPartition(pid);
// TODO(b/70033981): remove once ODM and Vendor manifests are distinguished
if (partition == Partition::ODM) {
partition = Partition::VENDOR;
}
return partition;
}
Partition PartitionOfType(SchemaType type) {
switch (type) {
case SchemaType::DEVICE:
return Partition::VENDOR;
case SchemaType::FRAMEWORK:
return Partition::SYSTEM;
}
return Partition::UNKNOWN;
}
} // namespace testing
} // namespace vintf
} // namespace android
namespace std {
void PrintTo(const android::vintf::testing::HalManifestPtr &v, ostream *os) {
if (v == nullptr) {
*os << "nullptr";
return;
}
*os << to_string(v->type()) << " manifest";
}
} // namespace std