183 lines
5.2 KiB
C++
183 lines
5.2 KiB
C++
|
|
|
||
|
|
/*
|
||
|
|
* 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
|