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 #define LOG_TAG "vts_ibase_test"
17
18 #include <algorithm>
19 #include <functional>
20 #include <map>
21 #include <mutex>
22 #include <string>
23 #include <thread>
24 #include <vector>
25
26 #include <android-base/logging.h>
27 #include <android-base/properties.h>
28 #include <android-base/strings.h>
29 #include <android/hidl/base/1.0/IBase.h>
30 #include <android/hidl/manager/1.0/IServiceManager.h>
31 #include <gtest/gtest.h>
32 #include <hidl-util/FqInstance.h>
33 #include <hidl/HidlBinderSupport.h>
34 #include <hidl/ServiceManagement.h>
35 #include <init-test-utils/service_utils.h>
36
37 using android::FqInstance;
38 using android::FQName;
39 using android::sp;
40 using android::wp;
41 using android::base::Result;
42 using android::hardware::hidl_array;
43 using android::hardware::hidl_death_recipient;
44 using android::hardware::hidl_handle;
45 using android::hardware::hidl_string;
46 using android::hardware::hidl_vec;
47 using android::hardware::IBinder;
48 using android::hardware::toBinder;
49 using android::hidl::base::V1_0::IBase;
50 using android::hidl::manager::V1_0::IServiceManager;
51 using android::init::ServiceInterfacesMap;
52 using PidInterfacesMap = std::map<pid_t, std::set<FqInstance>>;
53
54 template <typename T>
isOk(const::android::hardware::Return<T> & ret)55 static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<T>& ret) {
56 return ret.isOk() ? (::testing::AssertionSuccess() << ret.description())
57 : (::testing::AssertionFailure() << ret.description());
58 }
59 #define ASSERT_OK(__ret__) ASSERT_TRUE(isOk(__ret__))
60 #define EXPECT_OK(__ret__) EXPECT_TRUE(isOk(__ret__))
61
62 struct Hal {
63 sp<IBase> service;
64 std::string name; // space separated list of [email protected]::IFoo/instance-name
65 FqInstance fq_instance;
66 };
67
68 template <typename T>
FqInstancesToString(const T & instances)69 std::string FqInstancesToString(const T& instances) {
70 std::set<std::string> instance_strings;
71 for (const FqInstance& instance : instances) {
72 instance_strings.insert(instance.string());
73 }
74 return android::base::Join(instance_strings, "\n");
75 }
76
GetServiceDebugPid(const std::string & service)77 pid_t GetServiceDebugPid(const std::string& service) {
78 return android::base::GetIntProperty("init.svc_debug_pid." + service, 0);
79 }
80
81 std::map<std::string, std::vector<Hal>> gDeclaredServiceHalMap;
82 std::mutex gDeclaredServiceHalMapMutex;
83
GetHal(const sp<IServiceManager> & manager,const std::string & service,const FqInstance & instance)84 void GetHal(const sp<IServiceManager> &manager, const std::string& service, const FqInstance& instance) {
85 if (instance.getFqName().string() == IBase::descriptor) {
86 return;
87 }
88
89 sp<IBase> hal = android::hardware::details::getRawServiceInternal(
90 instance.getFqName().string(), instance.getInstance(), true /*retry*/,
91 false /*getStub*/);
92
93 // Check transport of manifest to support hardware SKU:
94 // Don't add service to gDeclaredServiceHalMap if hal instance is null and
95 // the transport of the declared interface is not present in manifest. Because
96 // manufacturer may disable this hal service in the current hardware SKU,
97 // but enable it in the other hardware SKU.
98 if (hal == nullptr && manager != nullptr) {
99 auto transport = manager->getTransport(instance.getFqName().string(),
100 instance.getInstance());
101 if(transport == IServiceManager::Transport::EMPTY){
102 LOG(WARNING)
103 << "Ignore, because Service '" << service << "' is not running,"
104 << " its interface '" << instance.string() << "' is not present in manifest.";
105 return;
106 }
107 }
108
109 // Add to gDeclaredServiceHalMap if getRawServiceInternal() returns (even if
110 // the returned HAL is null). getRawServiceInternal() won't return if the
111 // HAL is in the VINTF but unable to start.
112 std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
113 gDeclaredServiceHalMap[service].push_back(Hal{.service = hal, .fq_instance = instance});
114 }
115
116 class VtsHalBaseV1_0TargetTest : public ::testing::Test {
117 public:
SetUp()118 virtual void SetUp() override {
119 default_manager_ = ::android::hardware::defaultServiceManager();
120
121 ASSERT_NE(default_manager_, nullptr)
122 << "Failed to get default service manager." << std::endl;
123
124 ASSERT_OK(default_manager_->list([&](const auto& list) {
125 for (const auto& name : list) {
126 const std::string strName = name;
127 auto loc = strName.find_first_of('/');
128 if (loc == std::string::npos) {
129 ADD_FAILURE() << "Invalid FQName: " << strName;
130 continue;
131 }
132 const std::string fqName = strName.substr(0, loc);
133 const std::string instance = strName.substr(loc + 1);
134
135 sp<IBase> service = default_manager_->get(fqName, instance);
136 if (service == nullptr) {
137 ADD_FAILURE() << "Null service for " << name << " " << fqName << " "
138 << instance;
139 continue;
140 }
141
142 sp<IBinder> binder = toBinder(service);
143 if (binder == nullptr) {
144 ADD_FAILURE() << "Null binder for " << name;
145 continue;
146 }
147
148 auto iter = all_hals_.find(binder);
149 if (iter != all_hals_.end()) {
150 // include all the names this is registered as for error messages
151 iter->second.name += " " + strName;
152 } else {
153 all_hals_.insert(iter, {binder, Hal{.service = service, .name = strName}});
154 }
155 }
156 }));
157
158 if (all_hals_.empty()) {
159 GTEST_SKIP() << "No HIDL HAls on this device.";
160 }
161 }
162
EachHal(const std::function<void (const Hal &)> & check)163 void EachHal(const std::function<void(const Hal&)>& check) {
164 for (auto iter = all_hals_.begin(); iter != all_hals_.end(); ++iter) {
165 check(iter->second);
166 }
167 }
168
GetPidInterfacesMap()169 PidInterfacesMap GetPidInterfacesMap() {
170 PidInterfacesMap result;
171 EXPECT_OK(default_manager_->debugDump([&result](const auto& list) {
172 for (const auto& debug_info : list) {
173 if (debug_info.pid != static_cast<int32_t>(IServiceManager::PidConstant::NO_PID)) {
174 FQName fqName;
175 ASSERT_TRUE(fqName.setTo(debug_info.interfaceName.c_str()))
176 << "Unable to parse interface: '" << debug_info.interfaceName.c_str();
177 FqInstance fqInstance;
178 ASSERT_TRUE(fqInstance.setTo(fqName, debug_info.instanceName.c_str()));
179 if (fqInstance.getFqName().string() != IBase::descriptor) {
180 result[debug_info.pid].insert(fqInstance);
181 }
182 }
183 }
184 }));
185 return result;
186 }
187
188 // default service manager
189 sp<IServiceManager> default_manager_;
190
191 // map from underlying instance to actual instance
192 //
193 // this prevents calling the same service twice since the same service
194 // will get registered multiple times for its entire inheritance
195 // hierarchy (or perhaps as different instance names)
196 std::map<sp<IBinder>, Hal> all_hals_;
197 };
198
TEST_F(VtsHalBaseV1_0TargetTest,CanPing)199 TEST_F(VtsHalBaseV1_0TargetTest, CanPing) {
200 EachHal(
201 [&](const Hal& base) { EXPECT_OK(base.service->ping()) << "Cannot ping " << base.name; });
202 }
203
TEST_F(VtsHalBaseV1_0TargetTest,InterfaceChain)204 TEST_F(VtsHalBaseV1_0TargetTest, InterfaceChain) {
205 EachHal([&](const Hal& base) {
206 EXPECT_OK(base.service->interfaceChain([&](const auto& interfaceChain) {
207 // must include IBase + subclasses
208 EXPECT_GT(interfaceChain.size(), 1u) << "Invalid instance name " << base.name;
209 })) << base.name;
210 });
211 }
212
TEST_F(VtsHalBaseV1_0TargetTest,Descriptor)213 TEST_F(VtsHalBaseV1_0TargetTest, Descriptor) {
214 EachHal([&](const Hal& base) {
215 EXPECT_OK(base.service->interfaceDescriptor([&](const auto& descriptor) {
216 // must include IBase + subclasses
217 EXPECT_GT(descriptor.size(), 0u) << base.name;
218 EXPECT_NE(IBase::descriptor, descriptor) << base.name;
219 })) << base.name;
220 });
221 }
222
TEST_F(VtsHalBaseV1_0TargetTest,Death)223 TEST_F(VtsHalBaseV1_0TargetTest, Death) {
224 struct HidlDeathRecipient : hidl_death_recipient {
225 virtual void serviceDied(uint64_t /* cookie */, const wp<IBase>& /* who */){};
226 };
227 sp<hidl_death_recipient> recipient = new HidlDeathRecipient;
228
229 EachHal([&](const Hal& base) {
230 EXPECT_OK(base.service->linkToDeath(recipient, 0 /* cookie */))
231 << "Register death recipient " << base.name;
232 EXPECT_OK(base.service->unlinkToDeath(recipient)) << "Unlink death recipient " << base.name;
233 });
234 }
235
TEST_F(VtsHalBaseV1_0TargetTest,Debug)236 TEST_F(VtsHalBaseV1_0TargetTest, Debug) {
237 EachHal([&](const Hal& base) {
238 // normally one is passed, but this is tested by dumpstate
239 EXPECT_OK(base.service->debug(hidl_handle(), {}))
240 << "Handle empty debug handle " << base.name;
241 });
242 }
243
TEST_F(VtsHalBaseV1_0TargetTest,HashChain)244 TEST_F(VtsHalBaseV1_0TargetTest, HashChain) {
245 EachHal([&](const Hal& base) {
246 EXPECT_OK(base.service->getHashChain([&](const auto& hashChain) {
247 // must include IBase + subclasses
248 EXPECT_NE(0u, hashChain.size()) << "Invalid hash chain " << base.name;
249 })) << base.name;
250 });
251 }
252
TEST_F(VtsHalBaseV1_0TargetTest,ServiceProvidesAndDeclaresTheSameInterfaces)253 TEST_F(VtsHalBaseV1_0TargetTest, ServiceProvidesAndDeclaresTheSameInterfaces) {
254 const Result<ServiceInterfacesMap> service_interfaces_map =
255 android::init::GetOnDeviceServiceInterfacesMap();
256 ASSERT_RESULT_OK(service_interfaces_map);
257 auto service_manager = ::android::hardware::defaultServiceManager();
258
259 std::map<std::string, std::set<FqInstance>> hidl_interfaces_map;
260
261 // Attempt to get handles to all known declared interfaces. This will cause
262 // any non-running lazy HALs to start up.
263 // Results are saved in gDeclaredServiceHalMap.
264 for (const auto& [service, declared_interfaces] : *service_interfaces_map) {
265 if (declared_interfaces.empty()) {
266 LOG(INFO) << "Service '" << service << "' does not declare any interfaces.";
267 }
268 for (const auto& interface : declared_interfaces) {
269 if (interface.find("aidl/") == 0) {
270 LOG(INFO) << "Not testing '" << service << "' AIDL interface: " << interface;
271 } else {
272 FqInstance fqInstance;
273 ASSERT_TRUE(fqInstance.setTo(interface))
274 << "Unable to parse interface: '" << interface << "'";
275
276 std::thread(GetHal, service_manager, service, fqInstance).detach();
277 hidl_interfaces_map[service].insert(fqInstance);
278 }
279 }
280 }
281 // Allow the threads 5 seconds to attempt to get each HAL. Any HAL whose
282 // thread is stuck during retrieval is excluded from this test.
283 sleep(5);
284
285 std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
286 PidInterfacesMap pid_interfaces_map = GetPidInterfacesMap();
287
288 // For each service that had at least one thread return from attempting to
289 // retrieve a HAL:
290 for (const auto& [service, hals] : gDeclaredServiceHalMap) {
291 // Assert that the service is running.
292 pid_t pid = GetServiceDebugPid(service);
293 ASSERT_NE(pid, 0) << "Service '" << service << "' is not running.";
294
295 std::set<FqInstance> declared_interfaces;
296 for (const auto& hal : hals) {
297 declared_interfaces.insert(hal.fq_instance);
298 }
299
300 // Warn for any threads that were stuck when attempting to retrieve a
301 // HAL.
302 std::vector<FqInstance> missing_declared_interfaces;
303 std::set_difference(hidl_interfaces_map[service].begin(),
304 hidl_interfaces_map[service].end(), declared_interfaces.begin(),
305 declared_interfaces.end(),
306 std::back_inserter(missing_declared_interfaces));
307 if (!missing_declared_interfaces.empty()) {
308 LOG(WARNING)
309 << "Service '" << service
310 << "' declares interfaces that are present in the VINTF but unable to start:"
311 << std::endl
312 << FqInstancesToString(missing_declared_interfaces);
313 }
314
315 // Expect that the set of interfaces running at this PID is the same as
316 // the set of interfaces declared by this service.
317 std::set<FqInstance> served_interfaces = pid_interfaces_map[pid];
318 std::vector<FqInstance> served_declared_diff;
319 std::set_symmetric_difference(declared_interfaces.begin(), declared_interfaces.end(),
320 served_interfaces.begin(), served_interfaces.end(),
321 std::back_inserter(served_declared_diff));
322
323 EXPECT_TRUE(served_declared_diff.empty())
324 << "Service '" << service << "' serves and declares different interfaces."
325 << std::endl
326 << " Served:" << std::endl
327 << FqInstancesToString(served_interfaces) << std::endl
328 << " Declared: " << std::endl
329 << FqInstancesToString(declared_interfaces) << std::endl
330 << " Difference: " << std::endl
331 << FqInstancesToString(served_declared_diff);
332 }
333 }
334
main(int argc,char ** argv)335 int main(int argc, char** argv) {
336 ::testing::InitGoogleTest(&argc, argv);
337 return RUN_ALL_TESTS();
338 }
339