/* * 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(); }