1 /*
2 * Copyright (C) 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
17 #include "VtsTrebleVintfTestBase.h"
18
19 #include <android-base/logging.h>
20 #include <android-base/properties.h>
21 #include <android-base/strings.h>
22 #include <android/hidl/manager/1.0/IServiceManager.h>
23 #include <binder/IServiceManager.h>
24 #include <gtest/gtest.h>
25 #include <hidl-hash/Hash.h>
26 #include <hidl-util/FQName.h>
27 #include <hidl-util/FqInstance.h>
28 #include <hidl/HidlTransportUtils.h>
29 #include <hidl/ServiceManagement.h>
30 #include <procpartition/procpartition.h>
31 #include <vintf/HalManifest.h>
32 #include <vintf/VintfObject.h>
33 #include <vintf/parse_string.h>
34
35 #include <chrono>
36 #include <condition_variable>
37 #include <functional>
38 #include <future>
39 #include <iostream>
40 #include <map>
41 #include <mutex>
42 #include <set>
43 #include <sstream>
44 #include <string>
45 #include <thread>
46 #include <vector>
47
48 #include "SingleManifestTest.h"
49 #include "utils.h"
50
51 namespace android {
52 namespace vintf {
53 namespace testing {
54
55 using android::FqInstance;
56 using android::FQName;
57 using android::Hash;
58 using android::sp;
59 using android::hardware::hidl_array;
60 using android::hardware::hidl_string;
61 using android::hardware::hidl_vec;
62 using android::hardware::Return;
63 using android::hidl::base::V1_0::IBase;
64 using android::hidl::manager::V1_0::IServiceManager;
65 using android::procpartition::Partition;
66 using android::vintf::HalManifest;
67 using android::vintf::Level;
68 using android::vintf::ManifestHal;
69 using android::vintf::Transport;
70 using android::vintf::Version;
71 using android::vintf::VintfObject;
72 using android::vintf::operator<<;
73 using android::vintf::to_string;
74 using android::vintf::toFQNameString;
75
76 using std::cout;
77 using std::endl;
78 using std::map;
79 using std::set;
80 using std::string;
81 using std::vector;
82
SetUp()83 void VtsTrebleVintfTestBase::SetUp() {
84 default_manager_ = ::android::hardware::defaultServiceManager();
85 ASSERT_NE(default_manager_, nullptr)
86 << "Failed to get default service manager." << endl;
87 }
88
ForEachHidlHalInstance(const HalManifestPtr & manifest,HidlVerifyFn fn)89 void VtsTrebleVintfTestBase::ForEachHidlHalInstance(
90 const HalManifestPtr &manifest, HidlVerifyFn fn) {
91 manifest->forEachInstance([manifest, fn](const auto &manifest_instance) {
92 if (manifest_instance.format() != HalFormat::HIDL) {
93 return true; // continue to next instance
94 }
95 const FQName fq_name{manifest_instance.package(),
96 to_string(manifest_instance.version()),
97 manifest_instance.interface()};
98 const Transport transport = manifest_instance.transport();
99 const std::string instance_name = manifest_instance.instance();
100
101 auto future_result =
102 std::async([&]() { fn(fq_name, instance_name, transport); });
103 int timeout_multiplier = base::GetIntProperty("ro.hw_timeout_multiplier", 1);
104 auto timeout = timeout_multiplier * std::chrono::seconds(1);
105 std::future_status status = future_result.wait_for(timeout);
106 if (status != std::future_status::ready) {
107 cout << "Timed out on: " << fq_name.string() << " " << instance_name
108 << endl;
109 }
110 return true; // continue to next instance
111 });
112 }
113
ForEachAidlHalInstance(const HalManifestPtr & manifest,AidlVerifyFn fn)114 void VtsTrebleVintfTestBase::ForEachAidlHalInstance(
115 const HalManifestPtr &manifest, AidlVerifyFn fn) {
116 manifest->forEachInstance([manifest, fn](const auto &manifest_instance) {
117 if (manifest_instance.format() != HalFormat::AIDL) {
118 return true; // continue to next instance
119 }
120 const std::string &package = manifest_instance.package();
121 uint64_t version = manifest_instance.version().minorVer;
122 const std::string &interface = manifest_instance.interface();
123 const std::string &instance = manifest_instance.instance();
124 const std::optional<std::string> &updatable_via_apex =
125 manifest_instance.updatableViaApex();
126
127 auto future_result = std::async([&]() {
128 fn(package, version, interface, instance, updatable_via_apex);
129 });
130 int timeout_multiplier = base::GetIntProperty("ro.hw_timeout_multiplier", 1);
131 auto timeout = timeout_multiplier * std::chrono::seconds(1);
132 std::future_status status = future_result.wait_for(timeout);
133 if (status != std::future_status::ready) {
134 cout << "Timed out on: " << package << "." << interface << "/" << instance
135 << endl;
136 }
137 return true; // continue to next instance
138 });
139 }
140
GetHidlService(const FQName & fq_name,const string & instance_name,Transport transport,bool log)141 sp<IBase> VtsTrebleVintfTestBase::GetHidlService(const FQName &fq_name,
142 const string &instance_name,
143 Transport transport,
144 bool log) {
145 return GetHidlService(fq_name.string(), instance_name, transport, log);
146 }
147
GetHidlService(const string & fq_name,const string & instance_name,Transport transport,bool log)148 sp<IBase> VtsTrebleVintfTestBase::GetHidlService(const string &fq_name,
149 const string &instance_name,
150 Transport transport,
151 bool log) {
152 using android::hardware::details::getRawServiceInternal;
153
154 if (log) {
155 cout << "Getting: " << fq_name << "/" << instance_name << endl;
156 }
157
158 // getService blocks until a service is available. In 100% of other cases
159 // where getService is used, it should be called directly. However, this test
160 // enforces that various services are actually available when they are
161 // declared, it must make a couple of precautions in case the service isn't
162 // actually available so that the proper failure can be reported.
163
164 auto task = std::packaged_task<sp<IBase>()>([fq_name, instance_name]() {
165 return getRawServiceInternal(fq_name, instance_name, true /* retry */,
166 false /* getStub */);
167 });
168 int timeout_multiplier = base::GetIntProperty("ro.hw_timeout_multiplier", 1);
169 auto max_time = timeout_multiplier * std::chrono::seconds(1);
170
171 std::future<sp<IBase>> future = task.get_future();
172 std::thread(std::move(task)).detach();
173 auto status = future.wait_for(max_time);
174
175 if (status != std::future_status::ready) return nullptr;
176
177 sp<IBase> base = future.get();
178 if (base == nullptr) return nullptr;
179
180 bool wantRemote = transport == Transport::HWBINDER;
181 if (base->isRemote() != wantRemote) return nullptr;
182
183 return base;
184 }
185
GetAidlService(const string & name)186 sp<IBinder> VtsTrebleVintfTestBase::GetAidlService(const string &name) {
187 auto task = std::packaged_task<sp<IBinder>()>([name]() {
188 return defaultServiceManager()->waitForService(String16(name.c_str()));
189 });
190
191 int timeout_multiplier = base::GetIntProperty("ro.hw_timeout_multiplier", 1);
192 // TODO(b/205347235)
193 auto max_time = timeout_multiplier * std::chrono::seconds(2);
194 auto future = task.get_future();
195 std::thread(std::move(task)).detach();
196 auto status = future.wait_for(max_time);
197
198 return status == std::future_status::ready ? future.get() : nullptr;
199 }
200
GetInstanceNames(const sp<IServiceManager> & manager,const FQName & fq_name)201 vector<string> VtsTrebleVintfTestBase::GetInstanceNames(
202 const sp<IServiceManager> &manager, const FQName &fq_name) {
203 vector<string> ret;
204 auto status =
205 manager->listByInterface(fq_name.string(), [&](const auto &out) {
206 for (const auto &e : out) ret.push_back(e);
207 });
208 EXPECT_TRUE(status.isOk()) << status.description();
209 return ret;
210 }
211
GetInterfaceChain(const sp<IBase> & service)212 vector<string> VtsTrebleVintfTestBase::GetInterfaceChain(
213 const sp<IBase> &service) {
214 vector<string> iface_chain{};
215 service->interfaceChain([&iface_chain](const hidl_vec<hidl_string> &chain) {
216 for (const auto &iface_name : chain) {
217 iface_chain.push_back(iface_name);
218 }
219 });
220 return iface_chain;
221 }
222
GetPartition(sp<IBase> hal_service)223 Partition VtsTrebleVintfTestBase::GetPartition(sp<IBase> hal_service) {
224 Partition partition = Partition::UNKNOWN;
225 auto ret = hal_service->getDebugInfo(
226 [&](const auto &info) { partition = PartitionOfProcess(info.pid); });
227 EXPECT_TRUE(ret.isOk());
228 return partition;
229 }
230
GetPassthroughHals(HalManifestPtr manifest)231 set<string> VtsTrebleVintfTestBase::GetPassthroughHals(
232 HalManifestPtr manifest) {
233 std::set<std::string> manifest_passthrough_hals_;
234
235 auto add_manifest_hals = [&manifest_passthrough_hals_](
236 const FQName &fq_name,
237 const string &instance_name,
238 Transport transport) {
239 if (transport == Transport::HWBINDER) {
240 // ignore
241 } else if (transport == Transport::PASSTHROUGH) {
242 // 1.n in manifest => 1.0, 1.1, ... 1.n are all served (if they exist)
243 FQName fq = fq_name;
244 while (true) {
245 manifest_passthrough_hals_.insert(fq.string() + "/" + instance_name);
246 if (fq.getPackageMinorVersion() <= 0) break;
247 fq = fq.downRev();
248 }
249 } else {
250 ADD_FAILURE() << "Unrecognized transport: " << transport;
251 }
252 };
253 ForEachHidlHalInstance(manifest, add_manifest_hals);
254 return manifest_passthrough_hals_;
255 }
256
GetHwbinderHals(HalManifestPtr manifest)257 set<string> VtsTrebleVintfTestBase::GetHwbinderHals(HalManifestPtr manifest) {
258 std::set<std::string> manifest_hwbinder_hals_;
259
260 auto add_manifest_hals = [&manifest_hwbinder_hals_](
261 const FQName &fq_name,
262 const string &instance_name,
263 Transport transport) {
264 if (transport == Transport::HWBINDER) {
265 // 1.n in manifest => 1.0, 1.1, ... 1.n are all served (if they exist)
266 FQName fq = fq_name;
267 while (true) {
268 manifest_hwbinder_hals_.insert(fq.string() + "/" + instance_name);
269 if (fq.getPackageMinorVersion() <= 0) break;
270 fq = fq.downRev();
271 }
272 } else if (transport == Transport::PASSTHROUGH) {
273 // ignore
274 } else {
275 ADD_FAILURE() << "Unrecognized transport: " << transport;
276 }
277 };
278 ForEachHidlHalInstance(manifest, add_manifest_hals);
279 return manifest_hwbinder_hals_;
280 }
281
282 } // namespace testing
283 } // namespace vintf
284 } // namespace android
285