You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
4.5 KiB
134 lines
4.5 KiB
/*
|
|
* Copyright 2017 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 <android/hidl/manager/1.0/IServiceManager.h>
|
|
#include <cutils/properties.h>
|
|
#include <hidl/ServiceManagement.h>
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
using namespace android;
|
|
|
|
const string kSysPropHalCoverage = "hal.coverage.enable";
|
|
|
|
// Print usage directions.
|
|
void usage() {
|
|
cout << "usage:\n";
|
|
cout << "vts_coverage_configure flush\t\t\t\t: to flush coverage on all "
|
|
"HALs\n";
|
|
cout << "vts_coverage_configure flush <hal name>@<hal version>\t: to flush "
|
|
"coverage on one HAL name/version instance"
|
|
<< std::endl;
|
|
}
|
|
|
|
// Parse the fully-qualified instance name and call the func with the interface
|
|
// name, instance name, and HAL name.
|
|
template <typename Lambda>
|
|
bool parseFqInstaceName(string fqInstanceName, Lambda &&func) {
|
|
string::size_type n = fqInstanceName.find("/");
|
|
if (n == std::string::npos || fqInstanceName.size() == n + 1) return false;
|
|
|
|
string fqInterfaceName = fqInstanceName.substr(0, n);
|
|
string instanceName = fqInstanceName.substr(n + 1, std::string::npos);
|
|
|
|
n = fqInstanceName.find("::");
|
|
if (n == std::string::npos || fqInstanceName.size() == n + 1) return false;
|
|
string halName = fqInstanceName.substr(0, n);
|
|
std::forward<Lambda>(func)(fqInterfaceName, instanceName, halName);
|
|
return true;
|
|
}
|
|
|
|
// Flush coverage on all HAL processes, or just the provided HAL name if
|
|
// provided.
|
|
bool FlushHALCoverage(string flushHal = "") {
|
|
using ::android::hidl::base::V1_0::IBase;
|
|
using ::android::hidl::manager::V1_0::IServiceManager;
|
|
using ::android::hardware::hidl_string;
|
|
using ::android::hardware::Return;
|
|
|
|
sp<IServiceManager> sm = ::android::hardware::defaultServiceManager();
|
|
|
|
if (sm == nullptr) {
|
|
cerr << "failed to get IServiceManager to poke HAL services." << std::endl;
|
|
return false;
|
|
}
|
|
property_set(kSysPropHalCoverage.c_str(), "true");
|
|
auto listRet = sm->list([&](const auto &interfaces) {
|
|
for (const string &fqInstanceName : interfaces) {
|
|
hidl_string fqInterfaceName;
|
|
hidl_string instanceName;
|
|
string halName;
|
|
|
|
auto cb = [&](string fqIface, string instance, string hal) {
|
|
fqInterfaceName = fqIface;
|
|
instanceName = instance;
|
|
halName = hal;
|
|
};
|
|
if (!parseFqInstaceName(fqInstanceName, cb)) continue;
|
|
if (halName.find("android.hidl") == 0) continue;
|
|
if (flushHal == "" || !flushHal.compare(halName)) {
|
|
Return<sp<IBase>> interfaceRet = sm->get(fqInterfaceName, instanceName);
|
|
if (!interfaceRet.isOk()) {
|
|
cerr << "failed to get service " << fqInstanceName << ": "
|
|
<< interfaceRet.description() << std::endl;
|
|
continue;
|
|
}
|
|
sp<IBase> interface = interfaceRet;
|
|
auto notifyRet = interface->notifySyspropsChanged();
|
|
if (!notifyRet.isOk()) {
|
|
cerr << "failed to notifySyspropsChanged on service "
|
|
<< fqInstanceName << ": " << notifyRet.description()
|
|
<< std::endl;
|
|
}
|
|
cout << "- flushed the coverage for HAL " << fqInstanceName
|
|
<< std::endl;
|
|
}
|
|
}
|
|
});
|
|
property_set(kSysPropHalCoverage.c_str(), "false");
|
|
if (!listRet.isOk()) {
|
|
cerr << "failed to list services: " << listRet.description() << std::endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// The provided binary can be used to flush coverage on one or all HALs.
|
|
// Usage examples:
|
|
// To flush gcov and/or sancov coverage data on all hals: <binary> flush
|
|
// To flush gcov and/or sancov coverage data on one hal: <binary> flush <hal
|
|
// name>@<hal version>
|
|
int main(int argc, char *argv[]) {
|
|
bool flush_coverage = false;
|
|
if (argc < 2) {
|
|
usage();
|
|
return -1;
|
|
}
|
|
if (!strcmp(argv[1], "flush")) {
|
|
flush_coverage = true;
|
|
string halString = "";
|
|
if (argc == 3) {
|
|
halString = string(argv[2]);
|
|
}
|
|
cout << "* flush coverage" << std::endl;
|
|
if (!FlushHALCoverage(halString)) {
|
|
cerr << "failed to flush coverage" << std::endl;
|
|
}
|
|
} else {
|
|
usage();
|
|
}
|
|
return 0;
|
|
}
|