1 /*
2  * Copyright 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <getopt.h>
17 #include <json/json.h>
18 #include <iostream>
19 
20 #include <hidl-util/FQName.h>
21 #include <hidl/ServiceManagement.h>
22 #include <vintf/VintfObject.h>
23 
24 #include "VtsTestabilityChecker.h"
25 
26 using android::hidl::manager::V1_0::IServiceManager;
27 using android::vintf::VintfObject;
28 using std::cerr;
29 using std::cout;
30 using std::endl;
31 
32 // Example:
33 // vts_testability_checker --compliance android.hardware.foo@1.0::IFoo
34 // vts_testability_checker -c -b 32 android.hardware.foo@1.0::IFoo
35 // vts_testability_checker android.hardware.foo@1.0
ShowUsage()36 void ShowUsage() {
37   cout << "Usage: vts_hal_testability_checker [options] <hal name>\n"
38           "--compliance:     Whether to check for compliance test.\n"
39           "--bitness:        Test bitness.\n"
40           "--help:           Show help\n";
41   exit(1);
42 }
43 
44 const option long_opts[] = {{"help", no_argument, nullptr, 'h'},
45                             {"compliance", no_argument, nullptr, 'c'},
46                             {"bitness", required_argument, nullptr, 'b'},
47                             {nullptr, 0, nullptr, 0}};
48 
main(int argc,char ** argv)49 int main(int argc, char** argv) {
50   string bitness = "32";
51   bool is_compliance_test = false;
52 
53   while (true) {
54     int opt = getopt_long(argc, argv, "hcb:", long_opts, nullptr);
55     if (opt == -1) {
56       break;
57     }
58 
59     switch (opt) {
60       case 'h':
61       case '?':
62         ShowUsage();
63         return 0;
64       case 'c': {
65         is_compliance_test = true;
66         break;
67       }
68       case 'b': {
69         bitness = string(optarg);
70         if (bitness != "32" && bitness != "64") {
71           cerr << "Invalid bitness " << bitness << endl;
72           return -1;
73         }
74         break;
75       }
76       default:
77         cerr << "getopt_long returned unexpected value " << opt << endl;
78         return -1;
79     }
80   }
81 
82   if (optind != argc - 1) {
83     cerr << "Must specify the hal name (see --help)." << endl;
84     return -1;
85   }
86 
87   android::FQName hal_fq_name;
88   if (!android::FQName::parse(argv[optind], &hal_fq_name)) {
89     cerr << "Invalid hal name: " << argv[optind] << endl;
90     return -1;
91   }
92 
93   string hal_package_name = hal_fq_name.package();
94   size_t hal_major_version = hal_fq_name.getPackageMajorVersion();
95   size_t hal_minor_version = hal_fq_name.getPackageMinorVersion();
96   string hal_interface_name = hal_fq_name.name();
97   Version hal_version(hal_major_version, hal_minor_version);
98 
99   Arch arch;
100   if (bitness == "32") {
101     arch = Arch::ARCH_32;
102   } else if (bitness == "64") {
103     arch = Arch::ARCH_64;
104   }
105 
106   auto framework_comp_matrix = VintfObject::GetFrameworkCompatibilityMatrix();
107   if (!framework_comp_matrix) {
108     cerr << "Failed to get framework compatibility matrix." << endl;
109     return -1;
110   }
111 
112   auto device_hal_manifest = VintfObject::GetDeviceHalManifest();
113   if (!device_hal_manifest) {
114     cerr << "Failed to get device manifest." << endl;
115     return -1;
116   }
117 
118   auto framework_hal_manifest = VintfObject::GetFrameworkHalManifest();
119   if (!framework_hal_manifest) {
120     cerr << "Failed to get framework manifest." << endl;
121     return -1;
122   }
123 
124   android::sp<IServiceManager> sm =
125       ::android::hardware::defaultServiceManager();
126   if (sm == nullptr) {
127     cerr << "failed to get IServiceManager" << endl;
128     return -1;
129   }
130 
131   android::vts::VtsTestabilityChecker checker(framework_comp_matrix.get(),
132                                               framework_hal_manifest.get(),
133                                               device_hal_manifest.get(), sm);
134   set<string> instances;
135   bool result = false;
136   if (is_compliance_test) {
137     result = checker.CheckHalForComplianceTest(
138         hal_package_name, hal_version, hal_interface_name, arch, &instances);
139   } else {
140     result = checker.CheckHalForNonComplianceTest(
141         hal_package_name, hal_version, hal_interface_name, arch, &instances);
142   }
143 
144   // Create json output.
145   Json::Value root(Json::objectValue);
146   root["Testable"] = Json::Value(result);
147   root["instances"] = Json::Value(Json::arrayValue);
148   for (const string& instance : instances) {
149     root["instances"].append(instance);
150   }
151 
152   Json::FastWriter writer;
153   std::string json_output = writer.write(root);
154 
155   cout << json_output;
156   return 0;
157 }
158