• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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