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 android.hidl.foo@1.0::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 std::string & service,const FqInstance & instance)84 void GetHal(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 // Add to gDeclaredServiceHalMap if getRawServiceInternal() returns (even if
93 // the returned HAL is null). getRawServiceInternal() won't return if the
94 // HAL is in the VINTF but unable to start.
95 std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
96 gDeclaredServiceHalMap[service].push_back(Hal{.service = hal, .fq_instance = instance});
97 }
98
99 class VtsHalBaseV1_0TargetTest : public ::testing::Test {
100 public:
SetUp()101 virtual void SetUp() override {
102 default_manager_ = ::android::hardware::defaultServiceManager();
103
104 ASSERT_NE(default_manager_, nullptr)
105 << "Failed to get default service manager." << std::endl;
106
107 ASSERT_OK(default_manager_->list([&](const auto& list) {
108 for (const auto& name : list) {
109 const std::string strName = name;
110 auto loc = strName.find_first_of('/');
111 if (loc == std::string::npos) {
112 ADD_FAILURE() << "Invalid FQName: " << strName;
113 continue;
114 }
115 const std::string fqName = strName.substr(0, loc);
116 const std::string instance = strName.substr(loc + 1);
117
118 sp<IBase> service = default_manager_->get(fqName, instance);
119 if (service == nullptr) {
120 ADD_FAILURE() << "Null service for " << name << " " << fqName << " "
121 << instance;
122 continue;
123 }
124
125 sp<IBinder> binder = toBinder(service);
126 if (binder == nullptr) {
127 ADD_FAILURE() << "Null binder for " << name;
128 continue;
129 }
130
131 auto iter = all_hals_.find(binder);
132 if (iter != all_hals_.end()) {
133 // include all the names this is registered as for error messages
134 iter->second.name += " " + strName;
135 } else {
136 all_hals_.insert(iter, {binder, Hal{.service = service, .name = strName}});
137 }
138 }
139 }));
140
141 ASSERT_FALSE(all_hals_.empty()); // sanity
142 }
143
EachHal(const std::function<void (const Hal &)> & check)144 void EachHal(const std::function<void(const Hal&)>& check) {
145 for (auto iter = all_hals_.begin(); iter != all_hals_.end(); ++iter) {
146 check(iter->second);
147 }
148 }
149
GetPidInterfacesMap()150 PidInterfacesMap GetPidInterfacesMap() {
151 PidInterfacesMap result;
152 EXPECT_OK(default_manager_->debugDump([&result](const auto& list) {
153 for (const auto& debug_info : list) {
154 if (debug_info.pid != static_cast<int32_t>(IServiceManager::PidConstant::NO_PID)) {
155 FQName fqName;
156 ASSERT_TRUE(fqName.setTo(debug_info.interfaceName.c_str()))
157 << "Unable to parse interface: '" << debug_info.interfaceName.c_str();
158 FqInstance fqInstance;
159 ASSERT_TRUE(fqInstance.setTo(fqName, debug_info.instanceName.c_str()));
160 if (fqInstance.getFqName().string() != IBase::descriptor) {
161 result[debug_info.pid].insert(fqInstance);
162 }
163 }
164 }
165 }));
166 return result;
167 }
168
169 // default service manager
170 sp<IServiceManager> default_manager_;
171
172 // map from underlying instance to actual instance
173 //
174 // this prevents calling the same service twice since the same service
175 // will get registered multiple times for its entire inheritance
176 // hierarchy (or perhaps as different instance names)
177 std::map<sp<IBinder>, Hal> all_hals_;
178 };
179
TEST_F(VtsHalBaseV1_0TargetTest,CanPing)180 TEST_F(VtsHalBaseV1_0TargetTest, CanPing) {
181 EachHal(
182 [&](const Hal& base) { EXPECT_OK(base.service->ping()) << "Cannot ping " << base.name; });
183 }
184
TEST_F(VtsHalBaseV1_0TargetTest,InterfaceChain)185 TEST_F(VtsHalBaseV1_0TargetTest, InterfaceChain) {
186 EachHal([&](const Hal& base) {
187 EXPECT_OK(base.service->interfaceChain([&](const auto& interfaceChain) {
188 // must include IBase + subclasses
189 EXPECT_GT(interfaceChain.size(), 1u) << "Invalid instance name " << base.name;
190 })) << base.name;
191 });
192 }
193
TEST_F(VtsHalBaseV1_0TargetTest,Descriptor)194 TEST_F(VtsHalBaseV1_0TargetTest, Descriptor) {
195 EachHal([&](const Hal& base) {
196 EXPECT_OK(base.service->interfaceDescriptor([&](const auto& descriptor) {
197 // must include IBase + subclasses
198 EXPECT_GT(descriptor.size(), 0u) << base.name;
199 EXPECT_NE(IBase::descriptor, descriptor) << base.name;
200 })) << base.name;
201 });
202 }
203
TEST_F(VtsHalBaseV1_0TargetTest,Death)204 TEST_F(VtsHalBaseV1_0TargetTest, Death) {
205 struct HidlDeathRecipient : hidl_death_recipient {
206 virtual void serviceDied(uint64_t /* cookie */, const wp<IBase>& /* who */){};
207 };
208 sp<hidl_death_recipient> recipient = new HidlDeathRecipient;
209
210 EachHal([&](const Hal& base) {
211 EXPECT_OK(base.service->linkToDeath(recipient, 0 /* cookie */))
212 << "Register death recipient " << base.name;
213 EXPECT_OK(base.service->unlinkToDeath(recipient)) << "Unlink death recipient " << base.name;
214 });
215 }
216
TEST_F(VtsHalBaseV1_0TargetTest,Debug)217 TEST_F(VtsHalBaseV1_0TargetTest, Debug) {
218 EachHal([&](const Hal& base) {
219 // normally one is passed, but this is tested by dumpstate
220 EXPECT_OK(base.service->debug(hidl_handle(), {}))
221 << "Handle empty debug handle " << base.name;
222 });
223 }
224
TEST_F(VtsHalBaseV1_0TargetTest,HashChain)225 TEST_F(VtsHalBaseV1_0TargetTest, HashChain) {
226 EachHal([&](const Hal& base) {
227 EXPECT_OK(base.service->getHashChain([&](const auto& hashChain) {
228 // must include IBase + subclasses
229 EXPECT_NE(0u, hashChain.size()) << "Invalid hash chain " << base.name;
230 })) << base.name;
231 });
232 }
233
TEST_F(VtsHalBaseV1_0TargetTest,ServiceProvidesAndDeclaresTheSameInterfaces)234 TEST_F(VtsHalBaseV1_0TargetTest, ServiceProvidesAndDeclaresTheSameInterfaces) {
235 const Result<ServiceInterfacesMap> service_interfaces_map =
236 android::init::GetOnDeviceServiceInterfacesMap();
237 ASSERT_RESULT_OK(service_interfaces_map);
238
239 std::map<std::string, std::set<FqInstance>> hidl_interfaces_map;
240
241 // Attempt to get handles to all known declared interfaces. This will cause
242 // any non-running lazy HALs to start up.
243 // Results are saved in gDeclaredServiceHalMap.
244 for (const auto& [service, declared_interfaces] : *service_interfaces_map) {
245 if (declared_interfaces.empty()) {
246 LOG(INFO) << "Service '" << service << "' does not declare any interfaces.";
247 }
248 for (const auto& interface : declared_interfaces) {
249 if (interface.find("aidl/") == 0) {
250 LOG(INFO) << "Not testing '" << service << "' AIDL interface: " << interface;
251 } else {
252 FqInstance fqInstance;
253 ASSERT_TRUE(fqInstance.setTo(interface))
254 << "Unable to parse interface: '" << interface << "'";
255
256 std::thread(GetHal, service, fqInstance).detach();
257 hidl_interfaces_map[service].insert(fqInstance);
258 }
259 }
260 }
261 // Allow the threads 5 seconds to attempt to get each HAL. Any HAL whose
262 // thread is stuck during retrieval is excluded from this test.
263 sleep(5);
264
265 std::lock_guard<std::mutex> guard(gDeclaredServiceHalMapMutex);
266 PidInterfacesMap pid_interfaces_map = GetPidInterfacesMap();
267
268 // For each service that had at least one thread return from attempting to
269 // retrieve a HAL:
270 for (const auto& [service, hals] : gDeclaredServiceHalMap) {
271 // Assert that the service is running.
272 pid_t pid = GetServiceDebugPid(service);
273 ASSERT_NE(pid, 0) << "Service '" << service << "' is not running.";
274
275 std::set<FqInstance> declared_interfaces;
276 for (const auto& hal : hals) {
277 declared_interfaces.insert(hal.fq_instance);
278 }
279
280 // Warn for any threads that were stuck when attempting to retrieve a
281 // HAL.
282 std::vector<FqInstance> missing_declared_interfaces;
283 std::set_difference(hidl_interfaces_map[service].begin(),
284 hidl_interfaces_map[service].end(), declared_interfaces.begin(),
285 declared_interfaces.end(),
286 std::back_inserter(missing_declared_interfaces));
287 if (!missing_declared_interfaces.empty()) {
288 LOG(WARNING)
289 << "Service '" << service
290 << "' declares interfaces that are present in the VINTF but unable to start:"
291 << std::endl
292 << FqInstancesToString(missing_declared_interfaces);
293 }
294
295 // Expect that the set of interfaces running at this PID is the same as
296 // the set of interfaces declared by this service.
297 std::set<FqInstance> served_interfaces = pid_interfaces_map[pid];
298 std::vector<FqInstance> served_declared_diff;
299 std::set_symmetric_difference(declared_interfaces.begin(), declared_interfaces.end(),
300 served_interfaces.begin(), served_interfaces.end(),
301 std::back_inserter(served_declared_diff));
302
303 EXPECT_TRUE(served_declared_diff.empty())
304 << "Service '" << service << "' serves and declares different interfaces."
305 << std::endl
306 << " Served:" << std::endl
307 << FqInstancesToString(served_interfaces) << std::endl
308 << " Declared: " << std::endl
309 << FqInstancesToString(declared_interfaces) << std::endl
310 << " Difference: " << std::endl
311 << FqInstancesToString(served_declared_diff);
312 }
313 }
314
main(int argc,char ** argv)315 int main(int argc, char** argv) {
316 ::testing::InitGoogleTest(&argc, argv);
317 return RUN_ALL_TESTS();
318 }
319