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