/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "VtsTestabilityChecker.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <vintf/CompatibilityMatrix.h>
#include <vintf/HalManifest.h>
#include <vintf/parse_xml.h>

using namespace testing;

using android::hidl::base::V1_0::IBase;
using android::hidl::manager::V1_0::IServiceManager;
using android::hidl::manager::V1_0::IServiceNotification;
using android::hardware::hidl_array;
using android::hardware::hidl_death_recipient;
using android::hardware::hidl_handle;
using android::hardware::hidl_string;
using android::hardware::hidl_vec;
using android::vintf::Arch;
using android::vintf::CompatibilityMatrix;
using android::vintf::HalManifest;
using android::vintf::ManifestHal;
using android::vintf::MatrixHal;
using android::vintf::Version;
using android::vintf::XmlConverter;
using android::vintf::gCompatibilityMatrixConverter;
using android::vintf::gHalManifestConverter;
using std::set;
using std::string;

namespace android {
namespace vts {

class MockServiceManager : public IServiceManager {
 public:
  template <typename T>
  using R = ::android::hardware::Return<T>;
  using String = const hidl_string &;
  ~MockServiceManager() = default;

#define MOCK_METHOD_CB(name) \
  MOCK_METHOD1(name, R<void>(IServiceManager::name##_cb))

  MOCK_METHOD2(get, R<sp<IBase>>(String, String));
  MOCK_METHOD2(add, R<bool>(String, const sp<IBase> &));
  MOCK_METHOD2(getTransport, R<IServiceManager::Transport>(String, String));
  MOCK_METHOD_CB(list);
  MOCK_METHOD2(listByInterface, R<void>(String, listByInterface_cb));
  MOCK_METHOD3(registerForNotifications,
               R<bool>(String, String, const sp<IServiceNotification> &));
  MOCK_METHOD_CB(debugDump);
  MOCK_METHOD2(registerPassthroughClient, R<void>(String, String));
  MOCK_METHOD_CB(interfaceChain);
  MOCK_METHOD2(debug,
               R<void>(const hidl_handle &, const hidl_vec<hidl_string> &));
  MOCK_METHOD_CB(interfaceDescriptor);
  MOCK_METHOD_CB(getHashChain);
  MOCK_METHOD0(setHalInstrumentation, R<void>());
  MOCK_METHOD2(linkToDeath,
               R<bool>(const sp<hidl_death_recipient> &, uint64_t));
  MOCK_METHOD0(ping, R<void>());
  MOCK_METHOD_CB(getDebugInfo);
  MOCK_METHOD0(notifySyspropsChanged, R<void>());
  MOCK_METHOD1(unlinkToDeath, R<bool>(const sp<hidl_death_recipient> &));
};

class VtsTestabilityCheckerTest : public ::testing::Test {
 public:
  virtual void SetUp() override {
    test_cm_ = testFrameworkCompMatrix();
    test_fm_ = testFrameworkManfiest();
    test_vm_ = testDeviceManifest();
    sm_ = new NiceMock<MockServiceManager>();
    checker_.reset(
        new VtsTestabilityChecker(&test_cm_, &test_fm_, &test_vm_, sm_));
  }
  virtual void TearDown() override {}

  HalManifest testDeviceManifest() {
    HalManifest vm;
    string xml =
        "<manifest version=\"1.0\" type=\"framework\">\n"
        "    <hal format=\"hidl\">\n"
        "        <name>android.hardware.audio</name>\n"
        "        <transport arch=\"32\">passthrough</transport>\n"
        "        <version>2.0</version>\n"
        "        <interface>\n"
        "            <name>IAudio</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"hidl\">\n"
        "        <name>android.hardware.camera</name>\n"
        "        <transport>hwbinder</transport>\n"
        "        <version>1.2</version>\n"
        "        <version>2.5</version>\n"
        "        <interface>\n"
        "            <name>ICamera</name>\n"
        "            <instance>legacy/0</instance>\n"
        "        </interface>\n"
        "        <interface>\n"
        "            <name>IBetterCamera</name>\n"
        "            <instance>camera</instance>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"hidl\">\n"
        "        <name>android.hardware.drm</name>\n"
        "        <transport>hwbinder</transport>\n"
        "        <version>2.0</version>\n"
        "        <interface>\n"
        "            <name>IDrm</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"hidl\">\n"
        "        <name>android.hardware.nfc</name>\n"
        "        <transport>hwbinder</transport>\n"
        "        <version>1.0</version>\n"
        "        <interface>\n"
        "            <name>INfc</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"hidl\">\n"
        "        <name>android.hardware.renderscript</name>\n"
        "        <transport arch=\"32+64\">passthrough</transport>\n"
        "        <version>1.0</version>\n"
        "        <interface>\n"
        "            <name>IRenderscript</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"hidl\">\n"
        "        <name>android.hardware.vibrator</name>\n"
        "        <transport>hwbinder</transport>\n"
        "        <version>1.0</version>\n"
        "        <interface>\n"
        "            <name>IVibrator</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "</manifest>\n";
    gHalManifestConverter(&vm, xml);
    return vm;
  }

  HalManifest testFrameworkManfiest() {
    HalManifest fm;
    string xml =
        "<manifest version=\"1.0\" type=\"framework\">\n"
        "    <hal format=\"hidl\">\n"
        "        <name>android.hardware.nfc</name>\n"
        "        <transport>hwbinder</transport>\n"
        "        <version>1.0</version>\n"
        "        <interface>\n"
        "            <name>INfc</name>\n"
        "            <instance>default</instance>\n"
        "            <instance>fnfc</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "</manifest>\n";
    gHalManifestConverter(&fm, xml);
    return fm;
  }

  CompatibilityMatrix testFrameworkCompMatrix() {
    CompatibilityMatrix cm;
    string xml =
        "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
        "    <hal format=\"native\" optional=\"true\">\n"
        "        <name>android.hardware.audio</name>\n"
        "        <version>2.0-1</version>\n"
        "        <interface>\n"
        "            <name>IAudio</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"native\" optional=\"true\">\n"
        "        <name>android.hardware.camera</name>\n"
        "        <version>2.2-3</version>\n"
        "        <version>4.5-6</version>\n"
        "        <interface>\n"
        "            <name>ICamera</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "        <interface>\n"
        "            <name>IBetterCamera</name>\n"
        "            <instance>camera</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"native\" optional=\"false\">\n"
        "        <name>android.hardware.drm</name>\n"
        "        <version>1.0-1</version>\n"
        "        <interface>\n"
        "            <name>IDrm</name>\n"
        "            <instance>default</instance>\n"
        "            <instance>drm</instance>\n"
        "        </interface>\n"
        "        <interface>\n"
        "            <name>IDrmTest</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"native\" optional=\"false\">\n"
        "        <name>android.hardware.light</name>\n"
        "        <version>2.0-1</version>\n"
        "        <interface>\n"
        "            <name>ILight</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"native\" optional=\"true\">\n"
        "        <name>android.hardware.nfc</name>\n"
        "        <version>1.0-2</version>\n"
        "        <interface>\n"
        "            <name>INfc</name>\n"
        "            <instance>default</instance>\n"
        "            <instance>nfc</instance>\n"
        "        </interface>\n"
        "        <interface>\n"
        "            <name>INfcTest</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"native\" optional=\"true\">\n"
        "        <name>android.hardware.radio</name>\n"
        "        <version>1.0-1</version>\n"
        "        <interface>\n"
        "            <name>IRadio</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "    <hal format=\"native\" optional=\"false\">\n"
        "        <name>android.hardware.vibrator</name>\n"
        "        <version>2.0</version>\n"
        "        <interface>\n"
        "            <name>IVibrator</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n"
        "</compatibility-matrix>\n";
    gCompatibilityMatrixConverter(&cm, xml);
    return cm;
  }

 protected:
  CompatibilityMatrix test_cm_;
  HalManifest test_fm_;
  HalManifest test_vm_;
  sp<MockServiceManager> sm_;
  std::unique_ptr<VtsTestabilityChecker> checker_;
};

TEST_F(VtsTestabilityCheckerTest, CheckComplianceTest) {
  set<string> instances;
  // Check non-existent hal.
  EXPECT_FALSE(checker_->CheckHalForComplianceTest(
      "nonexistent", {1, 0}, "None", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal with unsupported version by vendor.
  EXPECT_FALSE(checker_->CheckHalForComplianceTest(
      "android.hardware.nfc", {2, 0}, "INfc", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal with unsupported interface by vendor.
  EXPECT_FALSE(checker_->CheckHalForComplianceTest(
      "android.hardware.nfc", {1, 0}, "INfcTest", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal with unsupported arch by vendor.
  EXPECT_FALSE(checker_->CheckHalForComplianceTest(
      "android.hardware.audio", {1, 0}, "IAudio", Arch::ARCH_64, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal claimed by framework but not supported by vendor (error case).
  EXPECT_FALSE(checker_->CheckHalForComplianceTest(
      "android.hardware.light", {2, 0}, "ILight", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal interface claimed by framework but not supported by vendor (error
  // case).
  EXPECT_FALSE(checker_->CheckHalForComplianceTest(
      "android.hardware.drm", {1, 0}, "IDrmTest", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());

  // Check hal claimed by framework and supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest("android.hardware.vibrator",
                                                  {1, 0}, "IVibrator",
                                                  Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check hal not claimed by framework but supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest(
      "android.hardware.renderscript", {1, 0}, "IRenderscript", Arch::ARCH_32,
      &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check hal with version not claimed by framework by supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest("android.hardware.vibrator",
                                                  {1, 0}, "IVibrator",
                                                  Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check hal with instance not claimed by framework but supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest(
      "android.hardware.camera", {2, 2}, "ICamera", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"legacy/0"})));

  // Check hal with additional vendor instance not claimed by framework.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest("android.hardware.camera",
                                                  {1, 2}, "IBetterCamera",
                                                  Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default", "camera"})));

  // Check hal supported by both framework and vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest(
      "android.hardware.nfc", {1, 0}, "INfc", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default", "fnfc"})));

  // Check hal instance claimed by framework but not supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest(
      "android.hardware.drm", {2, 0}, "IDrm", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check an optional hal with empty interface (legacy input).
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForComplianceTest(
      "android.hardware.vibrator", {1, 0}, "" /*interface*/, Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());
}

TEST_F(VtsTestabilityCheckerTest, CheckNonComplianceTest) {
  set<string> instances;
  ON_CALL(*sm_, listByInterface(_, _))
      .WillByDefault(
          Invoke([](hidl_string str, IServiceManager::listByInterface_cb cb) {
            if (str == "android.hardware.foo@1.0::IFoo") {
              cb({"default", "footest"});
            } else if (str == "android.hardware.nfc@3.0::INfc") {
              cb({"default"});
            } else if (str == "android.hardware.drm@2.0::IDrm") {
              cb({"drmtest"});
            }
            return hardware::Void();
          }));

  ON_CALL(*sm_, list(_)).WillByDefault(Invoke([](IServiceManager::list_cb cb) {
    cb({"android.hardware.foo@1.0::IFoo/default",
        "android.hardware.foo@1.0::IFoo/footest",
        "android.hardware.nfc@3.0::INfc/default",
        "android.hardware.drm@2.0::IDrm/drmtest"});
    return hardware::Void();
  }));

  // Check non-existent hal.
  EXPECT_FALSE(checker_->CheckHalForNonComplianceTest(
      "non-existent", {1, 0}, "None", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal with unsupported version by vendor.
  EXPECT_FALSE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.nfc", {2, 0}, "INfc", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal with unsupported interface by vendor.
  EXPECT_FALSE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.nfc", {1, 0}, "INfcTest", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal with unsupported arch by vendor.
  EXPECT_FALSE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.audio", {1, 0}, "IAudio", Arch::ARCH_64, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal claimed by framework but not supported by vendor (error case).
  EXPECT_FALSE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.light", {2, 0}, "ILight", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());
  // Check hal interface claimed by framework but not supported by vendor (error
  // case).
  EXPECT_FALSE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.drm", {1, 0}, "IDrmTest", Arch::ARCH_32, &instances));
  EXPECT_TRUE(instances.empty());

  // Check hal claimed by framework and supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.vibrator", {1, 0}, "IVibrator", Arch::ARCH_32,
      &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check hal not claimed by framework but supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.renderscript", {1, 0}, "IRenderscript", Arch::ARCH_32,
      &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check hal with version not claimed by framework by supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.vibrator", {1, 0}, "IVibrator", Arch::ARCH_32,
      &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check hal with instance not claimed by framework but supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.camera", {2, 2}, "ICamera", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"legacy/0"})));

  // Check hal with additional vendor instance not claimed by framework.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.camera", {1, 2}, "IBetterCamera", Arch::ARCH_32,
      &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default", "camera"})));

  // Check hal supported by both framework and vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.nfc", {1, 0}, "INfc", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check an optional hal with empty interface (legacy input).
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.vibrator", {1, 0}, "" /*interface*/, Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());

  // Check hal only registered with hwmanger.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.foo", {1, 0}, "IFoo", Arch::ARCH_EMPTY, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default", "footest"})));

  // Check hal with version only registered with hwmanger.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.nfc", {3, 0}, "INfc", Arch::ARCH_EMPTY, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check hal with additional instance registered with hwmanger.
  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.drm", {2, 0}, "IDrm", Arch::ARCH_EMPTY, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default", "drmtest"})));

  instances.clear();
  EXPECT_TRUE(checker_->CheckHalForNonComplianceTest(
      "android.hardware.foo", {1, 0}, "", Arch::ARCH_EMPTY, &instances));
  EXPECT_TRUE(instances.empty());
}

TEST_F(VtsTestabilityCheckerTest, CheckFrameworkCompatibleHalOptional) {
  set<string> instances;
  // Check non-existent hal.
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "nonexistent", {1, 0}, "None", Arch::ARCH_EMPTY, &instances));
  EXPECT_TRUE(instances.empty());

  // Check hal not required by framework
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.renderscript", {1, 0}, "IRenderscript",
      Arch::ARCH_EMPTY, &instances));
  EXPECT_TRUE(instances.empty());

  // Check hal with unsupported version.
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.camera", {1, 0}, "ICamera", Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());

  // Check hal with non-existent interface.
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.camera", {1, 2}, "None", Arch::ARCH_EMPTY, &instances));
  EXPECT_TRUE(instances.empty());

  // Check an optional hal not supported by vendor.
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.radio", {1, 0}, "IRadio", Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());

  // Check an optional hal with version not supported by vendor.
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.camera", {4, 5}, "ICamera", Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());

  // Check an optional hal with interface not supported by vendor.
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.nfc", {4, 5}, "INfcTest", Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());

  // Check an option passthrough hal with unsupported arch.
  EXPECT_FALSE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.audio", {2, 0}, "IAudio", Arch::ARCH_64, &instances));
  EXPECT_TRUE(instances.empty());

  // Check an optional hal supported by vendor but with no compatible
  // instance.
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.camera", {2, 2}, "ICamera", Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());

  // Check an optional hal supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.camera", {2, 2}, "IBetterCamera", Arch::ARCH_EMPTY,
      &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"camera"})));

  // Check an optional passthrough hal supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.audio", {2, 0}, "IAudio", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check an optional hal with empty interface (legacy input).
  instances.clear();
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.camera", {2, 2}, "" /*interface*/, Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());
}

TEST_F(VtsTestabilityCheckerTest, CheckFrameworkCompatibleHalRequired) {
  set<string> instances;
  // Check a required hal not supported by vendor.
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.light", {2, 0}, "ILight", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check a required hal with version not supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal("android.hardware.vibrator",
                                                    {2, 0}, "IVibrator",
                                                    Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check a required hal with interface not supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.drm", {1, 0}, "IDrmTest", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default"})));

  // Check a required hal supported by vendor.
  instances.clear();
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.drm", {1, 0}, "IDrm", Arch::ARCH_32, &instances));
  EXPECT_THAT(instances, ContainerEq(set<string>({"default", "drm"})));

  // Check an optional hal with empty interface (legacy input).
  instances.clear();
  EXPECT_TRUE(checker_->CheckFrameworkCompatibleHal(
      "android.hardware.vibrator", {2, 0}, "" /*interface*/, Arch::ARCH_EMPTY,
      &instances));
  EXPECT_TRUE(instances.empty());
}

}  // namespace vts
}  // namespace android

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}