Home | History | Annotate | Download | only in vintf
      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 <chrono>
     18 #include <functional>
     19 #include <future>
     20 #include <iostream>
     21 #include <map>
     22 #include <set>
     23 #include <sstream>
     24 #include <string>
     25 #include <thread>
     26 #include <vector>
     27 
     28 #include <android/hidl/manager/1.0/IServiceManager.h>
     29 #include <gtest/gtest.h>
     30 #include <hidl-hash/Hash.h>
     31 #include <hidl-util/FQName.h>
     32 #include <hidl/ServiceManagement.h>
     33 #include <vintf/HalManifest.h>
     34 #include <vintf/VintfObject.h>
     35 
     36 using android::FQName;
     37 using android::Hash;
     38 using android::hardware::hidl_array;
     39 using android::hardware::hidl_string;
     40 using android::hardware::hidl_vec;
     41 using android::hidl::manager::V1_0::IServiceManager;
     42 using android::sp;
     43 using android::vintf::HalManifest;
     44 using android::vintf::Transport;
     45 using android::vintf::Version;
     46 using android::vintf::VintfObject;
     47 
     48 using std::cout;
     49 using std::endl;
     50 using std::map;
     51 using std::set;
     52 using std::string;
     53 using std::vector;
     54 using HalVerifyFn =
     55     std::function<void(const FQName &fq_name, const string &instance_name)>;
     56 using HashCharArray = hidl_array<unsigned char, 32>;
     57 
     58 // Path to directory on target containing test data.
     59 static const string kDataDir = "/data/local/tmp/";
     60 
     61 // Name of file containing HAL hashes.
     62 static const string kHashFileName = "current.txt";
     63 
     64 // Map from package name to package root.
     65 static const map<string, string> kPackageRoot = {
     66     {"android.frameworks", "frameworks/hardware/interfaces/"},
     67     {"android.hardware", "hardware/interfaces/"},
     68     {"android.hidl", "system/libhidl/transport/"},
     69     {"android.system", "system/hardware/interfaces/"},
     70 };
     71 
     72 // HALs that are allowed to be passthrough under Treble rules.
     73 static const set<string> kPassthroughHals = {
     74     "android.hardware.graphics.mapper", "android.hardware.renderscript",
     75 };
     76 
     77 // For a given interface returns package root if known. Returns empty string
     78 // otherwise.
     79 static const string PackageRoot(const FQName &fq_iface_name) {
     80   for (const auto &package_root : kPackageRoot) {
     81     if (fq_iface_name.inPackage(package_root.first)) {
     82       return package_root.second;
     83     }
     84   }
     85   return "";
     86 }
     87 
     88 // Returns true iff HAL interface is Google-defined.
     89 static bool IsGoogleDefinedIface(const FQName &fq_iface_name) {
     90   // Package roots are only known for Google-defined packages.
     91   return !PackageRoot(fq_iface_name).empty();
     92 }
     93 
     94 // Returns true iff HAL interface is exempt from following rules:
     95 // 1. If an interface is declared in VINTF, it has to be served on the device.
     96 static bool IsExempt(const FQName &fq_iface_name) {
     97   static const set<string> exempt_hals_ = {};
     98   string hal_name = fq_iface_name.package();
     99   // Radio-releated and non-Google HAL interfaces are given exemptions.
    100   return exempt_hals_.find(hal_name) != exempt_hals_.end() ||
    101          !IsGoogleDefinedIface(fq_iface_name);
    102 }
    103 
    104 // Returns the set of released hashes for a given HAL interface.
    105 static set<string> ReleasedHashes(const FQName &fq_iface_name) {
    106   set<string> released_hashes{};
    107   string err = "";
    108 
    109   string file_path = kDataDir + PackageRoot(fq_iface_name) + kHashFileName;
    110   auto hashes = Hash::lookupHash(file_path, fq_iface_name.string(), &err);
    111   released_hashes.insert(hashes.begin(), hashes.end());
    112   return released_hashes;
    113 }
    114 
    115 class VtsTrebleVintfTest : public ::testing::Test {
    116  public:
    117   virtual void SetUp() override {
    118     default_manager_ = ::android::hardware::defaultServiceManager();
    119     ASSERT_NE(default_manager_, nullptr)
    120         << "Failed to get default service manager." << endl;
    121 
    122     passthrough_manager_ = ::android::hardware::getPassthroughServiceManager();
    123     ASSERT_NE(passthrough_manager_, nullptr)
    124         << "Failed to get passthrough service manager." << endl;
    125 
    126     vendor_manifest_ = VintfObject::GetDeviceHalManifest();
    127     ASSERT_NE(vendor_manifest_, nullptr)
    128         << "Failed to get vendor HAL manifest." << endl;
    129   }
    130 
    131   // Applies given function to each HAL instance in VINTF.
    132   void ForEachHalInstance(HalVerifyFn);
    133   // Retrieves an existing HAL service.
    134   sp<android::hidl::base::V1_0::IBase> GetHalService(
    135       const FQName &fq_name, const string &instance_name);
    136 
    137   // Default service manager.
    138   sp<IServiceManager> default_manager_;
    139   // Passthrough service manager.
    140   sp<IServiceManager> passthrough_manager_;
    141   // Vendor hal manifest.
    142   const HalManifest *vendor_manifest_;
    143 };
    144 
    145 void VtsTrebleVintfTest::ForEachHalInstance(HalVerifyFn fn) {
    146   auto hal_names = vendor_manifest_->getHalNames();
    147   for (const auto &hal_name : hal_names) {
    148     auto versions = vendor_manifest_->getSupportedVersions(hal_name);
    149     auto iface_names = vendor_manifest_->getInterfaceNames(hal_name);
    150     for (const auto &iface_name : iface_names) {
    151       auto instance_names =
    152           vendor_manifest_->getInstances(hal_name, iface_name);
    153       for (const auto &version : versions) {
    154         for (const auto &instance_name : instance_names) {
    155           string major_ver = std::to_string(version.majorVer);
    156           string minor_ver = std::to_string(version.minorVer);
    157           string full_ver = major_ver + "." + minor_ver;
    158           FQName fq_name{hal_name, full_ver, iface_name};
    159 
    160           auto future_result =
    161               std::async([&]() { fn(fq_name, instance_name); });
    162           auto timeout = std::chrono::milliseconds(500);
    163           std::future_status status = future_result.wait_for(timeout);
    164           if (status != std::future_status::ready) {
    165             cout << "Timed out on: " << fq_name.string() << " " << instance_name
    166                  << endl;
    167           }
    168         }
    169       }
    170     }
    171   }
    172 }
    173 
    174 sp<android::hidl::base::V1_0::IBase> VtsTrebleVintfTest::GetHalService(
    175     const FQName &fq_name, const string &instance_name) {
    176   string hal_name = fq_name.package();
    177   Version version{fq_name.getPackageMajorVersion(),
    178                   fq_name.getPackageMinorVersion()};
    179   string iface_name = fq_name.name();
    180   string fq_iface_name = fq_name.string();
    181   cout << "Getting service of: " << fq_iface_name << endl;
    182 
    183   Transport transport = vendor_manifest_->getTransport(
    184       hal_name, version, iface_name, instance_name);
    185 
    186   android::sp<android::hidl::base::V1_0::IBase> hal_service = nullptr;
    187   if (transport == Transport::HWBINDER) {
    188     hal_service = default_manager_->get(fq_iface_name, instance_name);
    189   } else if (transport == Transport::PASSTHROUGH) {
    190     hal_service = passthrough_manager_->get(fq_iface_name, instance_name);
    191   }
    192   return hal_service;
    193 }
    194 
    195 // Tests that all HAL entries in VINTF has all required fields filled out.
    196 TEST_F(VtsTrebleVintfTest, HalEntriesAreComplete) {
    197   auto hal_names = vendor_manifest_->getHalNames();
    198   for (const auto &hal_name : hal_names) {
    199     auto versions = vendor_manifest_->getSupportedVersions(hal_name);
    200     EXPECT_FALSE(versions.empty())
    201         << hal_name << " has no version specified in VINTF.";
    202     auto iface_names = vendor_manifest_->getInterfaceNames(hal_name);
    203     EXPECT_FALSE(iface_names.empty())
    204         << hal_name << " has no interface specified in VINTF.";
    205     for (const auto &iface_name : iface_names) {
    206       auto instances = vendor_manifest_->getInstances(hal_name, iface_name);
    207       EXPECT_FALSE(instances.empty())
    208           << hal_name << " has no instance specified in VINTF.";
    209     }
    210   }
    211 }
    212 
    213 // Tests that no HAL outside of the allowed set is specified as passthrough in
    214 // VINTF.
    215 TEST_F(VtsTrebleVintfTest, HalsAreBinderized) {
    216   // Verifies that HAL is binderized unless it's allowed to be passthrough.
    217   HalVerifyFn is_binderized = [this](const FQName &fq_name,
    218                                      const string &instance_name) {
    219     cout << "Verifying transport method of: " << fq_name.string() << endl;
    220     string hal_name = fq_name.package();
    221     Version version{fq_name.getPackageMajorVersion(),
    222                     fq_name.getPackageMinorVersion()};
    223     string iface_name = fq_name.name();
    224 
    225     Transport transport = vendor_manifest_->getTransport(
    226         hal_name, version, iface_name, instance_name);
    227 
    228     EXPECT_NE(transport, Transport::EMPTY)
    229         << hal_name << " has no transport specified in VINTF.";
    230 
    231     if (transport == Transport::PASSTHROUGH) {
    232       EXPECT_NE(kPassthroughHals.find(hal_name), kPassthroughHals.end())
    233           << hal_name << " can't be passthrough under Treble rules.";
    234     }
    235   };
    236 
    237   ForEachHalInstance(is_binderized);
    238 }
    239 
    240 // Tests that all HALs specified in the VINTF are available through service
    241 // manager.
    242 TEST_F(VtsTrebleVintfTest, VintfHalsAreServed) {
    243   // Verifies that HAL is available through service manager.
    244   HalVerifyFn is_available = [this](const FQName &fq_name,
    245                                     const string &instance_name) {
    246     if (IsExempt(fq_name)) {
    247       cout << fq_name.string() << " is exempt." << endl;
    248       return;
    249     }
    250 
    251     sp<android::hidl::base::V1_0::IBase> hal_service =
    252         GetHalService(fq_name, instance_name);
    253     EXPECT_NE(hal_service, nullptr)
    254         << fq_name.string() << " not available." << endl;
    255   };
    256 
    257   ForEachHalInstance(is_available);
    258 }
    259 
    260 // Tests that HAL interfaces are officially released.
    261 TEST_F(VtsTrebleVintfTest, InterfacesAreReleased) {
    262   // Verifies that HAL are released by fetching the hash of the interface and
    263   // comparing it to the set of known hashes of released interfaces.
    264   HalVerifyFn is_released = [this](const FQName &fq_name,
    265                                    const string &instance_name) {
    266     sp<android::hidl::base::V1_0::IBase> hal_service =
    267         GetHalService(fq_name, instance_name);
    268 
    269     if (hal_service == nullptr) {
    270       if (IsExempt(fq_name)) {
    271         cout << fq_name.string() << " is exempt." << endl;
    272       } else {
    273         ADD_FAILURE() << fq_name.package() << " not available." << endl;
    274       }
    275       return;
    276     }
    277 
    278     vector<string> iface_chain{};
    279     hal_service->interfaceChain(
    280         [&iface_chain](const hidl_vec<hidl_string> &chain) {
    281           for (const auto &iface_name : chain) {
    282             iface_chain.push_back(iface_name);
    283           }
    284         });
    285 
    286     vector<string> hash_chain{};
    287     hal_service->getHashChain(
    288         [&hash_chain](const hidl_vec<HashCharArray> &chain) {
    289           for (const HashCharArray &hash_array : chain) {
    290             vector<uint8_t> hash{hash_array.data(),
    291                                  hash_array.data() + hash_array.size()};
    292             hash_chain.push_back(Hash::hexString(hash));
    293           }
    294         });
    295 
    296     ASSERT_EQ(iface_chain.size(), hash_chain.size());
    297     for (size_t i = 0; i < iface_chain.size(); ++i) {
    298       FQName fq_iface_name{iface_chain[i]};
    299       string hash = hash_chain[i];
    300 
    301       if (IsGoogleDefinedIface(fq_iface_name)) {
    302         set<string> released_hashes = ReleasedHashes(fq_iface_name);
    303         EXPECT_NE(released_hashes.find(hash), released_hashes.end())
    304             << "Hash not found. This interface was not released." << endl
    305             << "Interface name: " << fq_iface_name.string() << endl
    306             << "Hash: " << hash << endl;
    307       }
    308     }
    309   };
    310 
    311   ForEachHalInstance(is_released);
    312 }
    313 
    314 // Tests that vendor and framework are compatible.
    315 TEST(CompatiblityTest, VendorFrameworkCompatibility) {
    316   string error;
    317 
    318   EXPECT_TRUE(VintfObject::GetDeviceHalManifest()->checkCompatibility(
    319       *VintfObject::GetFrameworkCompatibilityMatrix(), &error))
    320       << error;
    321 
    322   EXPECT_TRUE(VintfObject::GetFrameworkHalManifest()->checkCompatibility(
    323       *VintfObject::GetDeviceCompatibilityMatrix(), &error))
    324       << error;
    325 
    326   // AVB version is not a compliance requirement.
    327   EXPECT_TRUE(VintfObject::GetRuntimeInfo()->checkCompatibility(
    328       *VintfObject::GetFrameworkCompatibilityMatrix(), &error,
    329       ::android::vintf::DISABLE_AVB_CHECK))
    330       << error;
    331 
    332   EXPECT_EQ(0, VintfObject::CheckCompatibility(
    333                    {}, &error, ::android::vintf::DISABLE_AVB_CHECK))
    334       << error;
    335 }
    336 
    337 int main(int argc, char **argv) {
    338   ::testing::InitGoogleTest(&argc, argv);
    339   return RUN_ALL_TESTS();
    340 }
    341