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