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