Merge "Skip test when NAN or RTT feature not supported" into rvc-dev
diff --git a/current.txt b/current.txt
index 575c699..e2d1408 100644
--- a/current.txt
+++ b/current.txt
@@ -602,10 +602,11 @@
 eb2fa0c883c2185d514be0b84c179b283753ef0c1b77b45b4f359bd23bba8b75 android.hardware.neuralnetworks@1.0::IPreparedModel
 92e101b30e47bdf526a01c52cecfbe730def5997b8260ab497eb949eb2a6dcdf android.hardware.neuralnetworks@1.0::types
 5f6d3097ba84cb63c430787123f4de1b31c11f90b531b98eae9a8623a5ae962a android.hardware.neuralnetworks@1.1::types
+c2711d8748ccbcc858d5d5ec1abf145d9ab4c0b27db8ca215d7c39665a9b6652 android.hardware.neuralnetworks@1.1::types # b/155508675, b/155662254, b/155238914
 fb382e986c10b8fbb797a8546e8f9ea6d1107bfe6f3fb7e57f6bbbf1f807a906 android.hardware.neuralnetworks@1.2::IDevice
 40e71cd693de5b832325c5d8f081f2ff20a7ba2b89d401cee5b4b3eb0e241681 android.hardware.neuralnetworks@1.2::IPreparedModel
 ee1a0dee5be00a6fe2d4d3270068c78016dcb194d768fe07ed894ea20904037f android.hardware.neuralnetworks@1.2::types
-882b1c042ff842d7c52a794fab60bf6c599ef6b100ce99fa1772615096811d05 android.hardware.neuralnetworks@1.2::types # b/155508675
+9c53b727cfa9efde38ebe3914e1e95939cff29c072a1b8c8f419d24853b98831 android.hardware.neuralnetworks@1.2::types # b/155508675, b/155662254, b/155238914, b/155660285
 a785a57447a81e9c130eef6904c3a5c256076c6a04588c40620ebd6fa2660d77 android.hardware.radio@1.2::types
 1a6e2bd289f22931c526b21916910f1d4c436b7acb9556e4243de4ce8e6cc2e4 android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
 fd65298e1e09e0e3c781ab18305920d757dbe55a3b459ce17814ec5cf6dfee99 android.hardware.wifi@1.0::IWifiP2pIface
@@ -719,7 +720,7 @@
 ee9dc34b9925b8367b1111c72bd6d9d375432735e451572ca5a665d8516a7744 android.hardware.neuralnetworks@1.3::IPreparedModel
 eee3430cc86c97c7b407495863d8fb61da6f1a64b7721e77b9b4909b11b174e9 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
 acf84925f8ee0a651f2ec547ac334034de266479b93af5434f6c1f25e66aba96 android.hardware.neuralnetworks@1.3::types
-07801d19ca8a4f20543dae6b4d0c4d8b87e5161d3c431e973a1839cb7915a666 android.hardware.neuralnetworks@1.3::types # b/155508675
+e9080d04218e98512b63aace9ff3da52f0130238391f15cbbf7df396a3ec9072 android.hardware.neuralnetworks@1.3::types # b/155508675, b/155662254, b/155238914, b/155660285
 b454df853441c12f6e425e8a60dd29fda20f5e6e39b93d1103e4b37495db38aa android.hardware.radio@1.5::IRadio
 fcbb0742a88215ee7a6d7ce0825d253eb2b50391fc6c8c48667f9fd7f6d4549e android.hardware.radio@1.5::IRadioIndication
 b809193970a91ca637a4b0184767315601d32e3ef3d5992ffbc7a8d14a14f015 android.hardware.radio@1.5::IRadioResponse
diff --git a/drm/1.1/vts/functional/AndroidTest.xml b/drm/1.1/vts/functional/AndroidTest.xml
index 65c45ac..24eeb72 100644
--- a/drm/1.1/vts/functional/AndroidTest.xml
+++ b/drm/1.1/vts/functional/AndroidTest.xml
@@ -19,6 +19,10 @@
 
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
 
+    <target_preparer class="com.android.tradefed.targetprep.WifiPreparer" >
+        <option name="verify-only" value="true" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push-file" key="VtsHalDrmV1_1TargetTest" value="/data/local/tmp/VtsHalDrmV1_1TargetTest" />
diff --git a/drm/1.2/vts/functional/AndroidTest.xml b/drm/1.2/vts/functional/AndroidTest.xml
index 5da38ae..3285c37 100644
--- a/drm/1.2/vts/functional/AndroidTest.xml
+++ b/drm/1.2/vts/functional/AndroidTest.xml
@@ -19,6 +19,10 @@
 
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
 
+    <target_preparer class="com.android.tradefed.targetprep.WifiPreparer" >
+        <option name="verify-only" value="true" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push-file" key="VtsHalDrmV1_2TargetTest" value="/data/local/tmp/VtsHalDrmV1_2TargetTest" />
diff --git a/drm/1.3/vts/functional/AndroidTest.xml b/drm/1.3/vts/functional/AndroidTest.xml
index 338430f..9cc8e0c 100644
--- a/drm/1.3/vts/functional/AndroidTest.xml
+++ b/drm/1.3/vts/functional/AndroidTest.xml
@@ -19,6 +19,10 @@
 
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
 
+    <target_preparer class="com.android.tradefed.targetprep.WifiPreparer" >
+        <option name="verify-only" value="true" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push-file" key="VtsHalDrmV1_3TargetTest" value="/data/local/tmp/VtsHalDrmV1_3TargetTest" />
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index da7ba78..c8cdd59 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -126,6 +126,8 @@
      * * 0: A tensor of the same {@link OperandType} as input0.
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If all dimensions are reduced and keep_dims is false, the output
+     *      shape is [1].
      */
     MEAN = 31,
 
@@ -232,6 +234,8 @@
      *      removed.
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If all input dimensions are equal to 1 and are to be squeezed, the
+     *      output shape is [1].
      */
     SQUEEZE = 34,
 
@@ -278,6 +282,8 @@
      *      where k is the number of bits set in shrink_axis_mask.
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If shrink_axis_mask is true for all input dimensions, the output
+     *      shape is [1].
      */
     STRIDED_SLICE = 35,
 
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 9eff7ff..92cf2aa 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1955,6 +1955,8 @@
      * * 0: A tensor of the same {@link OperandType} as input0.
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If all dimensions are reduced and keep_dims is false, the output
+     *      shape is [1].
      */
     MEAN = @1.1::OperationType:MEAN,
 
@@ -2078,6 +2080,8 @@
      *      removed.
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If all input dimensions are equal to 1 and are to be squeezed, the
+     *      output shape is [1].
      */
     SQUEEZE = @1.1::OperationType:SQUEEZE,
 
@@ -2125,6 +2129,8 @@
      *      where k is the number of bits set in shrink_axis_mask.
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If shrink_axis_mask is true for all input dimensions, the output
+     *      shape is [1].
      */
     STRIDED_SLICE = @1.1::OperationType:STRIDED_SLICE,
 
@@ -2239,6 +2245,7 @@
      *
      * Outputs:
      * * 0: An (n - 1)-D {@link OperandType::TENSOR_INT32} tensor.
+     *      If input is 1-dimensional, the output shape is [1].
      */
     // There is no underscore in ARG_MAX to avoid name conflict with
     // the macro defined in libc/kernel/uapi/linux/limits.h.
@@ -2263,6 +2270,7 @@
      *
      * Outputs:
      * * 0: An (n - 1)-D {@link OperandType::TENSOR_INT32} tensor.
+     *      If input is 1-dimensional, the output shape is [1].
      */
     ARGMIN = 40,  // See ARGMAX for naming discussion.
 
diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal
index 83cf442..39ea4c2 100644
--- a/neuralnetworks/1.3/types.hal
+++ b/neuralnetworks/1.3/types.hal
@@ -2012,6 +2012,8 @@
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
      *      {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If all dimensions are reduced and keep_dims is false, the output
+     *      shape is [1].
      */
     MEAN = @1.2::OperationType:MEAN,
 
@@ -2141,6 +2143,8 @@
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
      *      {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If all input dimensions are equal to 1 and are to be squeezed, the
+     *      output shape is [1].
      */
     SQUEEZE = @1.2::OperationType:SQUEEZE,
 
@@ -2190,6 +2194,8 @@
      *      For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
      *      {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
      *      the scale and zeroPoint must be the same as input0.
+     *      If shrink_axis_mask is true for all input dimensions, the output
+     *      shape is [1].
      */
     STRIDED_SLICE = @1.2::OperationType:STRIDED_SLICE,
 
@@ -2313,6 +2319,7 @@
      *
      * Outputs:
      * * 0: An (n - 1)-D {@link OperandType::TENSOR_INT32} tensor.
+     *      If input is 1-dimensional, the output shape is [1].
      */
     // There is no underscore in ARG_MAX to avoid name conflict with
     // the macro defined in libc/kernel/uapi/linux/limits.h.
@@ -2338,6 +2345,7 @@
      *
      * Outputs:
      * * 0: An (n - 1)-D {@link OperandType::TENSOR_INT32} tensor.
+     *      If input is 1-dimensional, the output shape is [1].
      */
     ARGMIN = @1.2::OperationType:ARGMIN,  // See ARGMAX for naming discussion.
 
diff --git a/neuralnetworks/1.3/vts/functional/AndroidTest.xml b/neuralnetworks/1.3/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..30cff2e
--- /dev/null
+++ b/neuralnetworks/1.3/vts/functional/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs VtsHalNeuralnetworksV1_3TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalNeuralnetworksV1_3TargetTest->/data/local/tmp/VtsHalNeuralnetworksV1_3TargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <!-- b/156691406, b/155577050, b/155674368, b/153876253, temporarily disable the test.
+             Must be deleted after corresponding driver issues are fixed.
+        -->
+        <option name="native-test-flag" value="--gtest_filter=-*Validation*:*DynamicOutputShapeTest*:*FencedComputeTest*:*MemoryDomain*:*QuantizationCouplingTest*:*DeadlineTest*:*resize_*_v1_3*:*squeeze*_all*_inputs*:*strided_slice*_all*_inputs*:*transpose*_all*_inputs*:*l2_normalization_axis_corner_case*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalNeuralnetworksV1_3TargetTest" />
+    </test>
+</configuration>
diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp
index ec96e5f..7a21a40 100644
--- a/radio/1.0/vts/functional/vts_test_util.cpp
+++ b/radio/1.0/vts/functional/vts_test_util.cpp
@@ -13,6 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "RadioTest"
+
 #include <vts_test_util.h>
 #include <iostream>
 
@@ -53,4 +55,27 @@
         }
     }
     return testing::AssertionFailure() << "SapError:" + toString(err) + " is returned";
+}
+
+// Runs "pm list features" and attempts to find the specified feature in its output.
+bool deviceSupportsFeature(const char* feature) {
+    bool hasFeature = false;
+    FILE* p = popen("/system/bin/pm list features", "re");
+    if (p) {
+        char* line = NULL;
+        size_t len = 0;
+        while (getline(&line, &len, p) > 0) {
+            if (strstr(line, feature)) {
+                hasFeature = true;
+                break;
+            }
+        }
+        pclose(p);
+    } else {
+        __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "popen failed: %d", errno);
+        _exit(EXIT_FAILURE);
+    }
+    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Feature %s: %ssupported", feature,
+                        hasFeature ? "" : "not ");
+    return hasFeature;
 }
\ No newline at end of file
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index 05b47c9..df8dd77 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -17,6 +17,7 @@
 #include <android-base/logging.h>
 
 #include <android/hardware/radio/1.0/types.h>
+#include <android/log.h>
 #include <gtest/gtest.h>
 
 using ::android::hardware::radio::V1_0::RadioError;
@@ -31,6 +32,8 @@
     CHECK_SAP_ERROR = 4,
 };
 
+static constexpr const char* FEATURE_VOICE_CALL = "android.software.connectionservice";
+
 /*
  * Generate random serial number for radio test
  */
@@ -47,3 +50,8 @@
  * vendor/devices implementations.
  */
 ::testing::AssertionResult CheckAnyOfErrors(SapResultCode err, std::vector<SapResultCode> errors);
+
+/*
+ * Check if device supports feature.
+ */
+bool deviceSupportsFeature(const char* feature);
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 95136bb..e4c0877 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -22,6 +22,13 @@
  * Test IRadio.emergencyDial() for the response returned.
  */
 TEST_P(RadioHidlTest_v1_4, emergencyDial) {
+    if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+        ALOGI("Skipping emergencyDial because voice call is not supported in device");
+        return;
+    } else {
+        ALOGI("Running emergencyDial because voice call is supported in device");
+    }
+
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_0::Dial dialInfo;
@@ -53,6 +60,13 @@
  * Test IRadio.emergencyDial() with specified service and its response returned.
  */
 TEST_P(RadioHidlTest_v1_4, emergencyDial_withServices) {
+    if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+        ALOGI("Skipping emergencyDial because voice call is not supported in device");
+        return;
+    } else {
+        ALOGI("Running emergencyDial because voice call is supported in device");
+    }
+
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_0::Dial dialInfo;
@@ -85,6 +99,13 @@
  * Test IRadio.emergencyDial() with known emergency call routing and its response returned.
  */
 TEST_P(RadioHidlTest_v1_4, emergencyDial_withEmergencyRouting) {
+    if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+        ALOGI("Skipping emergencyDial because voice call is not supported in device");
+        return;
+    } else {
+        ALOGI("Running emergencyDial because voice call is supported in device");
+    }
+
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_0::Dial dialInfo;
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
index fc5071c..d54a959 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
@@ -246,6 +246,120 @@
     return AssertionResult(status == Result::SUCCESS);
 }
 
+void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
+                                         vector<FrontendStatus> expectStatuses) {
+    ASSERT_TRUE(mFrontend) << "Frontend is not opened yet.";
+    Result status;
+    vector<FrontendStatus> realStatuses;
+
+    mFrontend->getStatus(statusTypes, [&](Result result, const hidl_vec<FrontendStatus>& statuses) {
+        status = result;
+        realStatuses = statuses;
+    });
+
+    ASSERT_TRUE(realStatuses.size() == statusTypes.size());
+    for (int i = 0; i < statusTypes.size(); i++) {
+        FrontendStatusType type = statusTypes[i];
+        switch (type) {
+            case FrontendStatusType::DEMOD_LOCK: {
+                ASSERT_TRUE(realStatuses[i].isDemodLocked() == expectStatuses[i].isDemodLocked());
+                break;
+            }
+            case FrontendStatusType::SNR: {
+                ASSERT_TRUE(realStatuses[i].snr() == expectStatuses[i].snr());
+                break;
+            }
+            case FrontendStatusType::BER: {
+                ASSERT_TRUE(realStatuses[i].ber() == expectStatuses[i].ber());
+                break;
+            }
+            case FrontendStatusType::PER: {
+                ASSERT_TRUE(realStatuses[i].per() == expectStatuses[i].per());
+                break;
+            }
+            case FrontendStatusType::PRE_BER: {
+                ASSERT_TRUE(realStatuses[i].preBer() == expectStatuses[i].preBer());
+                break;
+            }
+            case FrontendStatusType::SIGNAL_QUALITY: {
+                ASSERT_TRUE(realStatuses[i].signalQuality() == expectStatuses[i].signalQuality());
+                break;
+            }
+            case FrontendStatusType::SIGNAL_STRENGTH: {
+                ASSERT_TRUE(realStatuses[i].signalStrength() == expectStatuses[i].signalStrength());
+                break;
+            }
+            case FrontendStatusType::SYMBOL_RATE: {
+                ASSERT_TRUE(realStatuses[i].symbolRate() == expectStatuses[i].symbolRate());
+                break;
+            }
+            case FrontendStatusType::FEC: {
+                ASSERT_TRUE(realStatuses[i].innerFec() == expectStatuses[i].innerFec());
+                break;
+            }
+            case FrontendStatusType::MODULATION: {
+                // TODO: check modulation status
+                break;
+            }
+            case FrontendStatusType::SPECTRAL: {
+                ASSERT_TRUE(realStatuses[i].inversion() == expectStatuses[i].inversion());
+                break;
+            }
+            case FrontendStatusType::LNB_VOLTAGE: {
+                ASSERT_TRUE(realStatuses[i].lnbVoltage() == expectStatuses[i].lnbVoltage());
+                break;
+            }
+            case FrontendStatusType::PLP_ID: {
+                ASSERT_TRUE(realStatuses[i].plpId() == expectStatuses[i].plpId());
+                break;
+            }
+            case FrontendStatusType::EWBS: {
+                ASSERT_TRUE(realStatuses[i].isEWBS() == expectStatuses[i].isEWBS());
+                break;
+            }
+            case FrontendStatusType::AGC: {
+                ASSERT_TRUE(realStatuses[i].agc() == expectStatuses[i].agc());
+                break;
+            }
+            case FrontendStatusType::LNA: {
+                ASSERT_TRUE(realStatuses[i].isLnaOn() == expectStatuses[i].isLnaOn());
+                break;
+            }
+            case FrontendStatusType::LAYER_ERROR: {
+                vector<bool> realLayberError = realStatuses[i].isLayerError();
+                vector<bool> expectLayerError = expectStatuses[i].isLayerError();
+                ASSERT_TRUE(realLayberError.size() == expectLayerError.size());
+                for (int i = 0; i < realLayberError.size(); i++) {
+                    ASSERT_TRUE(realLayberError[i] == expectLayerError[i]);
+                }
+                break;
+            }
+            case FrontendStatusType::MER: {
+                ASSERT_TRUE(realStatuses[i].mer() == expectStatuses[i].mer());
+                break;
+            }
+            case FrontendStatusType::FREQ_OFFSET: {
+                ASSERT_TRUE(realStatuses[i].freqOffset() == expectStatuses[i].freqOffset());
+                break;
+            }
+            case FrontendStatusType::HIERARCHY: {
+                ASSERT_TRUE(realStatuses[i].hierarchy() == expectStatuses[i].hierarchy());
+                break;
+            }
+            case FrontendStatusType::RF_LOCK: {
+                ASSERT_TRUE(realStatuses[i].isRfLocked() == expectStatuses[i].isRfLocked());
+                break;
+            }
+            case FrontendStatusType::ATSC3_PLP_INFO:
+                // TODO: verify plpinfo
+                break;
+            default:
+                continue;
+        }
+    }
+    ASSERT_TRUE(status == Result::SUCCESS);
+}
+
 AssertionResult FrontendTests::tuneFrontend(FrontendConfig config) {
     EXPECT_TRUE(mFrontendCallback)
             << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
@@ -294,6 +408,7 @@
     ASSERT_TRUE(openFrontendById(feId));
     ASSERT_TRUE(setFrontendCallback());
     ASSERT_TRUE(tuneFrontend(frontendConf));
+    verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
     ASSERT_TRUE(stopTuneFrontend());
     ASSERT_TRUE(closeFrontend());
 }
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h
index 1a9bec9..2bdc8fd 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.h
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.h
@@ -109,6 +109,8 @@
     AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
     AssertionResult stopScanFrontend();
     AssertionResult tuneFrontend(FrontendConfig config);
+    void verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
+                              vector<FrontendStatus> expectStatuses);
     AssertionResult stopTuneFrontend();
     AssertionResult closeFrontend();
 
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
index b84013b..287f673 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -40,6 +40,8 @@
 using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
 using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
 using android::hardware::tv::tuner::V1_0::FrontendSettings;
+using android::hardware::tv::tuner::V1_0::FrontendStatus;
+using android::hardware::tv::tuner::V1_0::FrontendStatusType;
 using android::hardware::tv::tuner::V1_0::FrontendType;
 using android::hardware::tv::tuner::V1_0::PlaybackSettings;
 using android::hardware::tv::tuner::V1_0::RecordSettings;
@@ -88,6 +90,8 @@
 struct FrontendConfig {
     FrontendType type;
     FrontendSettings settings;
+    vector<FrontendStatusType> tuneStatusTypes;
+    vector<FrontendStatus> expectTuneStatuses;
 };
 
 struct ChannelConfig {
@@ -127,6 +131,14 @@
             .standard = FrontendDvbtStandard::T,
     };
     frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings);
+    vector<FrontendStatusType> types;
+    types.push_back(FrontendStatusType::DEMOD_LOCK);
+    FrontendStatus status;
+    status.isDemodLocked(true);
+    vector<FrontendStatus> statuses;
+    statuses.push_back(status);
+    frontendArray[DVBT].tuneStatusTypes = types;
+    frontendArray[DVBT].expectTuneStatuses = statuses;
     frontendArray[DVBS].type = FrontendType::DVBS;
 };